From a28716da6f6043ede3c1550906b9d8cd0f1d1b32 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Thu, 12 Aug 2010 19:27:19 -0400 Subject: [PATCH] netdev-tunnel: Add CAPWAP userspace interface. Provide a userspace interface to the CAPWAP UDP transport tunneling mechanism in the kernel. Signed-off-by: Jesse Gross --- lib/netdev-provider.h | 1 + lib/netdev-tunnel.c | 75 ++++++++++++++++++++++++++++++++++++++++--- lib/netdev.c | 1 + vswitchd/vswitch.xml | 55 +++++++++++++++++++++++++++++++ 4 files changed, 127 insertions(+), 5 deletions(-) diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h index 52f440fa..619ba8be 100644 --- a/lib/netdev-provider.h +++ b/lib/netdev-provider.h @@ -550,6 +550,7 @@ extern const struct netdev_class netdev_linux_class; extern const struct netdev_class netdev_tap_class; extern const struct netdev_class netdev_patch_class; extern const struct netdev_class netdev_gre_class; +extern const struct netdev_class netdev_capwap_class; #ifdef __cplusplus } diff --git a/lib/netdev-tunnel.c b/lib/netdev-tunnel.c index 0497cbbc..d0ecd98e 100644 --- a/lib/netdev-tunnel.c +++ b/lib/netdev-tunnel.c @@ -82,20 +82,20 @@ parse_config(const char *name, const char *type, const struct shash *args, } else { config->saddr = in_addr.s_addr; } - } else if (!strcmp(node->name, "key")) { + } else if (!strcmp(node->name, "key") && !strcmp(type, "gre")) { if (!strcmp(node->data, "flow")) { config->flags |= TNL_F_IN_KEY_MATCH; config->flags |= TNL_F_OUT_KEY_ACTION; } else { config->out_key = config->in_key = htonl(atoi(node->data)); } - } else if (!strcmp(node->name, "in_key")) { + } else if (!strcmp(node->name, "in_key") && !strcmp(type, "gre")) { if (!strcmp(node->data, "flow")) { config->flags |= TNL_F_IN_KEY_MATCH; } else { config->in_key = htonl(atoi(node->data)); } - } else if (!strcmp(node->name, "out_key")) { + } else if (!strcmp(node->name, "out_key") && !strcmp(type, "gre")) { if (!strcmp(node->data, "flow")) { config->flags |= TNL_F_OUT_KEY_ACTION; } else { @@ -113,7 +113,7 @@ parse_config(const char *name, const char *type, const struct shash *args, } else { config->ttl = atoi(node->data); } - } else if (!strcmp(node->name, "csum")) { + } else if (!strcmp(node->name, "csum") && !strcmp(type, "gre")) { if (!strcmp(node->data, "true")) { config->flags |= TNL_F_CSUM; } @@ -169,7 +169,12 @@ netdev_tunnel_create(const char *name, const char *type, } netdev_dev = xmalloc(sizeof *netdev_dev); - netdev_dev_init(&netdev_dev->netdev_dev, name, &netdev_gre_class); + + if (!strcmp(type, "gre")) { + netdev_dev_init(&netdev_dev->netdev_dev, name, &netdev_gre_class); + } else { + netdev_dev_init(&netdev_dev->netdev_dev, name, &netdev_capwap_class); + } *netdev_devp = &netdev_dev->netdev_dev; return 0; @@ -283,3 +288,63 @@ const struct netdev_class netdev_gre_class = { netdev_vport_poll_add, netdev_vport_poll_remove, }; + +const struct netdev_class netdev_capwap_class = { + "capwap", + + NULL, /* init */ + NULL, /* run */ + NULL, /* wait */ + + netdev_tunnel_create, + netdev_tunnel_destroy, + netdev_tunnel_reconfigure, + + netdev_tunnel_open, + netdev_tunnel_close, + + NULL, /* enumerate */ + + NULL, /* recv */ + NULL, /* recv_wait */ + NULL, /* drain */ + + NULL, /* send */ + NULL, /* send_wait */ + + netdev_vport_set_etheraddr, + netdev_vport_get_etheraddr, + netdev_vport_get_mtu, + NULL, /* get_ifindex */ + netdev_vport_get_carrier, + netdev_vport_get_stats, + netdev_vport_set_stats, + + NULL, /* get_features */ + NULL, /* set_advertisements */ + NULL, /* get_vlan_vid */ + + NULL, /* set_policing */ + NULL, /* get_qos_types */ + NULL, /* get_qos_capabilities */ + NULL, /* get_qos */ + NULL, /* set_qos */ + NULL, /* get_queue */ + NULL, /* set_queue */ + NULL, /* delete_queue */ + NULL, /* get_queue_stats */ + NULL, /* dump_queues */ + NULL, /* dump_queue_stats */ + + NULL, /* get_in4 */ + NULL, /* set_in4 */ + NULL, /* get_in6 */ + NULL, /* add_router */ + NULL, /* get_next_hop */ + NULL, /* arp_lookup */ + + netdev_vport_update_flags, + + netdev_vport_poll_add, + netdev_vport_poll_remove, +}; diff --git a/lib/netdev.c b/lib/netdev.c index 3e355581..371bc205 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -47,6 +47,7 @@ static const struct netdev_class *base_netdev_classes[] = { &netdev_tap_class, &netdev_patch_class, &netdev_gre_class, + &netdev_capwap_class, #endif }; diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index ce1c7140..32d1ee41 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -529,6 +529,61 @@ Default is enabled, set to false to disable. +
capwap
+
Ethernet tunneling over the UDP transport portion of CAPWAP + (RFC 5415). This allows interoperability with certain switches + where GRE is not available. Note that only the tunneling component + of the protocol is implemented. Due to the non-standard use of + CAPWAP, UDP ports 58881 and 58882 are used as the source and + destinations ports respectivedly. Each tunnel must be uniquely + identified by the combination of remote_ip and + local_ip. If two ports are defined that are the same + except one includes local_ip and the other does not, + the more specific one is matched first. CAPWAP support is not + available on all platforms. Currently it is only supported in the + Linux kernel module with kernel versions >= 2.6.25. The following + options may be specified in the column: +
+
remote_ip
+
Required. The tunnel endpoint.
+
+
+
local_ip
+
Optional. The destination IP that received packets must + match. Default is to match all addresses.
+
+
+
tos
+
Optional. The value of the ToS bits to be set on the + encapsulating packet. It may also be the word + inherit, in which case the ToS will be copied from + the inner packet if it is IPv4 or IPv6 (otherwise it will be + 0). Note that the ECN fields are always inherited. Default is + 0.
+
+
+
ttl
+
Optional. The TTL to be set on the encapsulating packet. + It may also be the word inherit, in which case the + TTL will be copied from the inner packet if it is IPv4 or IPv6 + (otherwise it will be the system default, typically 64). + Default is the system default TTL.
+
+
+
pmtud
+
Optional. Enable tunnel path MTU discovery. If enabled + ``ICMP destination unreachable - fragmentation'' needed + messages will be generated for IPv4 packets with the DF bit set + and IPv6 packets above the minimum MTU if the packet size + exceeds the path MTU minus the size of the tunnel headers. It + also forces the encapsulating packet DF bit to be set (it is + always set if the inner packet implies path MTU discovery). + Note that this option causes behavior that is typically + reserved for routers and therefore is not entirely in + compliance with the IEEE 802.1D specification for bridges. + Default is enabled, set to false to disable.
+
+
patch

-- 2.30.2