geneve: Add geneve udp port offload for ethernet devices
authorSinghai, Anjali <anjali.singhai@intel.com>
Mon, 14 Dec 2015 20:21:17 +0000 (12:21 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 16 Dec 2015 15:58:46 +0000 (10:58 -0500)
Add ndo_ops to add/del UDP ports to a device that supports geneve
offload.

v2: Comment fix.

Signed-off-by: Anjali Singhai Jain <anjali.singhai@intel.com>
Signed-off-by: Kiran Patil <kiran.patil@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/geneve.c
include/linux/netdevice.h

index 0750d7a..89325e4 100644 (file)
@@ -380,8 +380,11 @@ static struct socket *geneve_create_sock(struct net *net, bool ipv6,
 
 static void geneve_notify_add_rx_port(struct geneve_sock *gs)
 {
+       struct net_device *dev;
        struct sock *sk = gs->sock->sk;
+       struct net *net = sock_net(sk);
        sa_family_t sa_family = sk->sk_family;
+       __be16 port = inet_sk(sk)->inet_sport;
        int err;
 
        if (sa_family == AF_INET) {
@@ -390,6 +393,14 @@ static void geneve_notify_add_rx_port(struct geneve_sock *gs)
                        pr_warn("geneve: udp_add_offload failed with status %d\n",
                                err);
        }
+
+       rcu_read_lock();
+       for_each_netdev_rcu(net, dev) {
+               if (dev->netdev_ops->ndo_add_geneve_port)
+                       dev->netdev_ops->ndo_add_geneve_port(dev, sa_family,
+                                                            port);
+       }
+       rcu_read_unlock();
 }
 
 static int geneve_hlen(struct genevehdr *gh)
@@ -530,8 +541,20 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port,
 
 static void geneve_notify_del_rx_port(struct geneve_sock *gs)
 {
+       struct net_device *dev;
        struct sock *sk = gs->sock->sk;
+       struct net *net = sock_net(sk);
        sa_family_t sa_family = sk->sk_family;
+       __be16 port = inet_sk(sk)->inet_sport;
+
+       rcu_read_lock();
+       for_each_netdev_rcu(net, dev) {
+               if (dev->netdev_ops->ndo_del_geneve_port)
+                       dev->netdev_ops->ndo_del_geneve_port(dev, sa_family,
+                                                            port);
+       }
+
+       rcu_read_unlock();
 
        if (sa_family == AF_INET)
                udp_del_offload(&gs->udp_offloads);
index 9fb6395..81b26a5 100644 (file)
@@ -1013,6 +1013,19 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
  *     a new port starts listening. The operation is protected by the
  *     vxlan_net->sock_lock.
  *
+ * void (*ndo_add_geneve_port)(struct net_device *dev,
+ *                           sa_family_t sa_family, __be16 port);
+ *     Called by geneve to notify a driver about the UDP port and socket
+ *     address family that geneve is listnening to. It is called only when
+ *     a new port starts listening. The operation is protected by the
+ *     geneve_net->sock_lock.
+ *
+ * void (*ndo_del_geneve_port)(struct net_device *dev,
+ *                           sa_family_t sa_family, __be16 port);
+ *     Called by geneve to notify the driver about a UDP port and socket
+ *     address family that geneve is not listening to anymore. The operation
+ *     is protected by the geneve_net->sock_lock.
+ *
  * void (*ndo_del_vxlan_port)(struct  net_device *dev,
  *                           sa_family_t sa_family, __be16 port);
  *     Called by vxlan to notify the driver about a UDP port and socket
@@ -1217,7 +1230,12 @@ struct net_device_ops {
        void                    (*ndo_del_vxlan_port)(struct  net_device *dev,
                                                      sa_family_t sa_family,
                                                      __be16 port);
-
+       void                    (*ndo_add_geneve_port)(struct  net_device *dev,
+                                                      sa_family_t sa_family,
+                                                      __be16 port);
+       void                    (*ndo_del_geneve_port)(struct  net_device *dev,
+                                                      sa_family_t sa_family,
+                                                      __be16 port);
        void*                   (*ndo_dfwd_add_station)(struct net_device *pdev,
                                                        struct net_device *dev);
        void                    (*ndo_dfwd_del_station)(struct net_device *pdev,