vxlan: Add new UDP encapsulation offload type for VXLAN-GPE
authorAlexander Duyck <aduyck@mirantis.com>
Thu, 16 Jun 2016 19:23:19 +0000 (12:23 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sat, 18 Jun 2016 03:23:32 +0000 (20:23 -0700)
The fact is VXLAN with Generic Protocol Extensions cannot be supported by
the same hardware parsers that support VXLAN.  The protocol extensions
allow for things like a Next Protocol field which in turn allows for things
other than Ethernet to be passed over the tunnel.  Most existing parsers
will not know how to interpret this.

To resolve this I am giving VXLAN-GPE its own UDP encapsulation offload
type.  This way hardware that does support GPE can simply add this type to
the switch statement for VXLAN, and if they don't support it then this will
fix any issues where headers might be interpreted incorrectly.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/vxlan.c
include/net/udp_tunnel.h

index 31aeec9671758ef91bc771315417437010f7e19c..abb9cd2df9e99717213e02b47c3b3c93ff849b44 100644 (file)
@@ -998,6 +998,8 @@ static bool __vxlan_sock_release_prep(struct vxlan_sock *vs)
        spin_lock(&vn->sock_lock);
        hlist_del_rcu(&vs->hlist);
        udp_tunnel_notify_del_rx_port(vs->sock,
+                                     (vs->flags & VXLAN_F_GPE) ?
+                                     UDP_TUNNEL_TYPE_VXLAN_GPE :
                                      UDP_TUNNEL_TYPE_VXLAN);
        spin_unlock(&vn->sock_lock);
 
@@ -2488,6 +2490,8 @@ static void vxlan_push_rx_ports(struct net_device *dev)
        for (i = 0; i < PORT_HASH_SIZE; ++i) {
                hlist_for_each_entry_rcu(vs, &vn->sock_list[i], hlist)
                        udp_tunnel_push_rx_port(dev, vs->sock,
+                                               (vs->flags & VXLAN_F_GPE) ?
+                                               UDP_TUNNEL_TYPE_VXLAN_GPE :
                                                UDP_TUNNEL_TYPE_VXLAN);
        }
        spin_unlock(&vn->sock_lock);
@@ -2691,6 +2695,8 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6,
        spin_lock(&vn->sock_lock);
        hlist_add_head_rcu(&vs->hlist, vs_head(net, port));
        udp_tunnel_notify_add_rx_port(sock,
+                                     (vs->flags & VXLAN_F_GPE) ?
+                                     UDP_TUNNEL_TYPE_VXLAN_GPE :
                                      UDP_TUNNEL_TYPE_VXLAN);
        spin_unlock(&vn->sock_lock);
 
index 1c9408a0421359355b6cc1d31fd417016a101b56..02c5be0374517da8d6912e2a727606a0e2b8b27d 100644 (file)
@@ -103,6 +103,7 @@ void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
 enum udp_parsable_tunnel_type {
        UDP_TUNNEL_TYPE_VXLAN,          /* RFC 7348 */
        UDP_TUNNEL_TYPE_GENEVE,         /* draft-ietf-nvo3-geneve */
+       UDP_TUNNEL_TYPE_VXLAN_GPE,      /* draft-ietf-nvo3-vxlan-gpe */
 };
 
 struct udp_tunnel_info {