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;
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;
}
{
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);
ovs_be32 saddr = htonl(0);
uint32_t flags;
- flags = TNL_F_DF_DEFAULT | TNL_F_HDR_CACHE;
+ if (!strcmp(type, "capwap")) {
+ VLOG_WARN_ONCE("CAPWAP tunnel support is deprecated.");
+ }
+
+ flags = TNL_F_DF_DEFAULT;
if (!strcmp(type, "gre") || !strcmp(type, "gre64")) {
is_gre = true;
} else if (!strcmp(type, "ipsec_gre") || !strcmp(type, "ipsec_gre64")) {
is_gre = true;
is_ipsec = true;
flags |= TNL_F_IPSEC;
- flags &= ~TNL_F_HDR_CACHE;
+ } else if (!strcmp(type, "vxlan")) {
+ needs_dst_port = true;
}
SMAP_FOR_EACH (node, args) {
} 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;
"concerns.", name);
flags |= TNL_F_PMTUD;
}
- } else if (!strcmp(node->key, "header_cache")) {
- if (!strcmp(node->value, "false")) {
- flags &= ~TNL_F_HDR_CACHE;
- }
} else if (!strcmp(node->key, "peer_cert") && is_ipsec) {
if (smap_get(args, "certificate")) {
ipsec_mech_set = true;
}
}
+ /* 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) {
[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;
return error;
}
- flags = nl_attr_get_u32(a[OVS_TUNNEL_ATTR_FLAGS]);
- if (!(flags & TNL_F_HDR_CACHE) == !(flags & TNL_F_IPSEC)) {
- smap_add(args, "header_cache",
- flags & TNL_F_HDR_CACHE ? "true" : "false");
- }
daddr = nl_attr_get_be32(a[OVS_TUNNEL_ATTR_DST_IPV4]);
smap_add_format(args, "remote_ip", IP_FMT, IP_ARGS(&daddr));
}
}
+ flags = nl_attr_get_u32(a[OVS_TUNNEL_ATTR_FLAGS]);
if (flags & TNL_F_TTL_INHERIT) {
smap_add(args, "ttl", "inherit");
} else if (a[OVS_TUNNEL_ATTR_TTL]) {
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");
}
{ "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 }