diff options
author | Kyle Mestery <kmestery@cisco.com> | 2012-12-05 16:06:46 -0500 |
---|---|---|
committer | Jesse Gross <jesse@nicira.com> | 2012-12-05 18:11:06 -0800 |
commit | 79f827fa8be86099eb1523a51acc5dd1a5901505 (patch) | |
tree | ab29403493c6df4e0b09588af892f3576e432fdd /lib/netdev-vport.c | |
parent | 5b8ab80c0897d9cc91488505a447dcf4a4e4b448 (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.c | 31 |
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 } |