aboutsummaryrefslogtreecommitdiff
path: root/lib/netdev-vport.c
diff options
context:
space:
mode:
authorKyle Mestery <kmestery@cisco.com>2012-12-05 16:06:46 -0500
committerJesse Gross <jesse@nicira.com>2012-12-05 18:11:06 -0800
commit79f827fa8be86099eb1523a51acc5dd1a5901505 (patch)
treeab29403493c6df4e0b09588af892f3576e432fdd /lib/netdev-vport.c
parent5b8ab80c0897d9cc91488505a447dcf4a4e4b448 (diff)
datapath: Add support for VXLAN tunnels to Open vSwitch
Add support for VXLAN tunnels to Open vSwitch. Add support for setting the destination UDP port on a per-port basis. This is done by adding a "dst_port" parameter to the port configuration. This is only applicable currently to VXLAN tunnels. Please note this currently does not implement any sort of multicast learning. With this patch, VXLAN tunnels must be configured similar to GRE tunnels (e.g. point to point). A subsequent patch will implement a VXLAN control plane in userspace to handle multicast learning. This patch set is based on one posted by Ben Pfaff on Oct. 12, 2011 to the ovs-dev mailing list: http://openvswitch.org/pipermail/dev/2011-October/012051.html The patch has been maintained, updated, and freshened by me and a version of it is available at the following github repository: https://github.com/mestery/ovs-vxlan/tree/vxlan I've tested this patch with multiple VXLAN tunnels between hosts using different UDP port numbers. Performance is on par (though slightly faster) than comparable GRE tunnels. See the following IETF draft for additional information about VXLAN: http://tools.ietf.org/html/draft-mahalingam-dutt-dcops-vxlan-02 Signed-off-by: Kyle Mestery <kmestery@cisco.com> [jesse: simplify error path in vxlan_tunnel_setup, don't print default VXLAN port, and remove dead code] Signed-off-by: Jesse Gross <jesse@nicira.com>
Diffstat (limited to 'lib/netdev-vport.c')
-rw-r--r--lib/netdev-vport.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
index 5171171d..1863d828 100644
--- a/lib/netdev-vport.c
+++ b/lib/netdev-vport.c
@@ -49,6 +49,9 @@
VLOG_DEFINE_THIS_MODULE(netdev_vport);
+/* Default to the OTV port, per the VXLAN IETF draft. */
+#define VXLAN_DST_PORT 8472
+
struct netdev_dev_vport {
struct netdev_dev netdev_dev;
struct ofpbuf *options;
@@ -173,6 +176,9 @@ netdev_vport_get_netdev_type(const struct dpif_linux_vport *vport)
case OVS_VPORT_TYPE_CAPWAP:
return "capwap";
+ case OVS_VPORT_TYPE_VXLAN:
+ return ("vxlan");
+
case OVS_VPORT_TYPE_FT_GRE:
case __OVS_VPORT_TYPE_MAX:
break;
@@ -585,6 +591,8 @@ parse_tunnel_config(const char *name, const char *type,
{
bool is_gre = false;
bool is_ipsec = false;
+ bool needs_dst_port = false;
+ bool found_dst_port = false;
struct smap_node *node;
bool ipsec_mech_set = false;
ovs_be32 daddr = htonl(0);
@@ -602,6 +610,8 @@ parse_tunnel_config(const char *name, const char *type,
is_gre = true;
is_ipsec = true;
flags |= TNL_F_IPSEC;
+ } else if (!strcmp(type, "vxlan")) {
+ needs_dst_port = true;
}
SMAP_FOR_EACH (node, args) {
@@ -638,6 +648,10 @@ parse_tunnel_config(const char *name, const char *type,
} else {
nl_msg_put_u8(options, OVS_TUNNEL_ATTR_TTL, atoi(node->value));
}
+ } else if (!strcmp(node->key, "dst_port") && needs_dst_port) {
+ nl_msg_put_u16(options, OVS_TUNNEL_ATTR_DST_PORT,
+ atoi(node->value));
+ found_dst_port = true;
} else if (!strcmp(node->key, "csum") && is_gre) {
if (!strcmp(node->value, "true")) {
flags |= TNL_F_CSUM;
@@ -694,6 +708,11 @@ parse_tunnel_config(const char *name, const char *type,
}
}
+ /* Add a default destination port for VXLAN if none specified. */
+ if (needs_dst_port && !found_dst_port) {
+ nl_msg_put_u16(options, OVS_TUNNEL_ATTR_DST_PORT, VXLAN_DST_PORT);
+ }
+
if (is_ipsec) {
static pid_t pid = 0;
if (pid <= 0) {
@@ -756,6 +775,7 @@ tnl_port_config_from_nlattr(const struct nlattr *options, size_t options_len,
[OVS_TUNNEL_ATTR_OUT_KEY] = { .type = NL_A_BE64, .optional = true },
[OVS_TUNNEL_ATTR_TOS] = { .type = NL_A_U8, .optional = true },
[OVS_TUNNEL_ATTR_TTL] = { .type = NL_A_U8, .optional = true },
+ [OVS_TUNNEL_ATTR_DST_PORT] = { .type = NL_A_U16, .optional = true },
};
struct ofpbuf buf;
@@ -835,6 +855,13 @@ unparse_tunnel_config(const char *name OVS_UNUSED, const char *type OVS_UNUSED,
smap_add_format(args, "tos", "0x%x", tos);
}
+ if (a[OVS_TUNNEL_ATTR_DST_PORT]) {
+ uint16_t dst_port = nl_attr_get_u16(a[OVS_TUNNEL_ATTR_DST_PORT]);
+ if (dst_port != VXLAN_DST_PORT) {
+ smap_add_format(args, "dst_port", "%d", dst_port);
+ }
+ }
+
if (flags & TNL_F_CSUM) {
smap_add(args, "csum", "true");
}
@@ -990,6 +1017,10 @@ netdev_vport_register(void)
{ "capwap", VPORT_FUNCTIONS(netdev_vport_get_drv_info) },
parse_tunnel_config, unparse_tunnel_config },
+ { OVS_VPORT_TYPE_VXLAN,
+ { "vxlan", VPORT_FUNCTIONS(netdev_vport_get_drv_info) },
+ parse_tunnel_config, unparse_tunnel_config },
+
{ OVS_VPORT_TYPE_PATCH,
{ "patch", VPORT_FUNCTIONS(NULL) },
parse_patch_config, unparse_patch_config }