netdev-tunnel: Add CAPWAP userspace interface.
authorJesse Gross <jesse@nicira.com>
Thu, 12 Aug 2010 23:27:19 +0000 (19:27 -0400)
committerJesse Gross <jesse@nicira.com>
Tue, 24 Aug 2010 20:58:00 +0000 (16:58 -0400)
Provide a userspace interface to the CAPWAP UDP transport
tunneling mechanism in the kernel.

Signed-off-by: Jesse Gross <jesse@nicira.com>
lib/netdev-provider.h
lib/netdev-tunnel.c
lib/netdev.c
vswitchd/vswitch.xml

index 52f440fa1052b784061783cd1be7c9cffdc9265f..619ba8be8242039e8698b0a25c75244f808327fe 100644 (file)
@@ -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
 }
index 0497cbbc266e3ad396f713f04bce897135d50033..d0ecd98e204e7e603f6f392f570a282aebcf0292 100644 (file)
@@ -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,
+};
index 3e355581446ea0618b7c32bcb18d7c1cd3f46bf2..371bc205105fe6617be7a31f2d9fc80855e10a10 100644 (file)
@@ -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
 };
 
index ce1c7140740631e90b996ce028b03ac729b04f0c..32d1ee4149ddb6f950fb2ad915c5dd2e90deb630 100644 (file)
                 Default is enabled, set to <code>false</code> to disable.</dd>
             </dl>
           </dd>
+          <dt><code>capwap</code></dt>
+          <dd>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 <code>remote_ip</code> and
+             <code>local_ip</code>.  If two ports are defined that are the same
+             except one includes <code>local_ip</code> 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 <ref column="options"/> column:
+            <dl>
+              <dt><code>remote_ip</code></dt>
+              <dd>Required.  The tunnel endpoint.</dd>
+            </dl>
+            <dl>
+              <dt><code>local_ip</code></dt>
+              <dd>Optional.  The destination IP that received packets must
+                match.  Default is to match all addresses.</dd>
+            </dl>
+            <dl>
+              <dt><code>tos</code></dt>
+              <dd>Optional.  The value of the ToS bits to be set on the
+                encapsulating packet.  It may also be the word
+                <code>inherit</code>, 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.</dd>
+            </dl>
+            <dl>
+              <dt><code>ttl</code></dt>
+              <dd>Optional.  The TTL to be set on the encapsulating packet.
+                It may also be the word <code>inherit</code>, 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.</dd>
+            </dl>
+            <dl>
+              <dt><code>pmtud</code></dt>
+              <dd>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 <code>false</code> to disable.</dd>
+            </dl>
+          </dd>
           <dt><code>patch</code></dt>
           <dd>
             <p>