summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/geneve.c2
-rw-r--r--drivers/net/vxlan.c2
-rw-r--r--include/linux/netdevice.h22
-rw-r--r--include/net/geneve.h3
-rw-r--r--include/net/udp_tunnel.h6
-rw-r--r--include/net/vxlan.h4
-rw-r--r--net/ipv4/udp_tunnel.c10
7 files changed, 41 insertions, 8 deletions
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index af6f676ca444..aa61708bea69 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -1497,7 +1497,7 @@ static int geneve_netdevice_event(struct notifier_block *unused,
{
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
- if (event == NETDEV_OFFLOAD_PUSH_GENEVE)
+ if (event == NETDEV_UDP_TUNNEL_PUSH_INFO)
geneve_push_rx_ports(dev);
return NOTIFY_DONE;
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index adbd979da22d..31aeec967175 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -3239,7 +3239,7 @@ static int vxlan_netdevice_event(struct notifier_block *unused,
if (event == NETDEV_UNREGISTER)
vxlan_handle_lowerdev_unregister(vn, dev);
- else if (event == NETDEV_OFFLOAD_PUSH_VXLAN)
+ else if (event == NETDEV_UDP_TUNNEL_PUSH_INFO)
vxlan_push_rx_ports(dev);
return NOTIFY_DONE;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 890158e99159..577d2a1814b1 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -61,6 +61,8 @@ struct wireless_dev;
/* 802.15.4 specific */
struct wpan_dev;
struct mpls_dev;
+/* UDP Tunnel offloads */
+struct udp_tunnel_info;
void netdev_set_default_ethtool_ops(struct net_device *dev,
const struct ethtool_ops *ops);
@@ -1050,6 +1052,19 @@ struct tc_to_netdev {
* address family that vxlan is not listening to anymore. The operation
* is protected by the vxlan_net->sock_lock.
*
+ * void (*ndo_udp_tunnel_add)(struct net_device *dev,
+ * struct udp_tunnel_info *ti);
+ * Called by UDP tunnel to notify a driver about the UDP port and socket
+ * address family that a UDP tunnel is listnening to. It is called only
+ * when a new port starts listening. The operation is protected by the
+ * RTNL.
+ *
+ * void (*ndo_udp_tunnel_del)(struct net_device *dev,
+ * struct udp_tunnel_info *ti);
+ * Called by UDP tunnel to notify the driver about a UDP port and socket
+ * address family that the UDP tunnel is not listening to anymore. The
+ * operation is protected by the RTNL.
+ *
* void* (*ndo_dfwd_add_station)(struct net_device *pdev,
* struct net_device *dev)
* Called by upper layer devices to accelerate switching or other
@@ -1269,6 +1284,10 @@ struct net_device_ops {
void (*ndo_del_geneve_port)(struct net_device *dev,
sa_family_t sa_family,
__be16 port);
+ void (*ndo_udp_tunnel_add)(struct net_device *dev,
+ struct udp_tunnel_info *ti);
+ void (*ndo_udp_tunnel_del)(struct net_device *dev,
+ struct udp_tunnel_info *ti);
void* (*ndo_dfwd_add_station)(struct net_device *pdev,
struct net_device *dev);
void (*ndo_dfwd_del_station)(struct net_device *pdev,
@@ -2255,8 +2274,7 @@ struct netdev_lag_lower_state_info {
#define NETDEV_BONDING_INFO 0x0019
#define NETDEV_PRECHANGEUPPER 0x001A
#define NETDEV_CHANGELOWERSTATE 0x001B
-#define NETDEV_OFFLOAD_PUSH_VXLAN 0x001C
-#define NETDEV_OFFLOAD_PUSH_GENEVE 0x001D
+#define NETDEV_UDP_TUNNEL_PUSH_INFO 0x001C
int register_netdevice_notifier(struct notifier_block *nb);
int unregister_netdevice_notifier(struct notifier_block *nb);
diff --git a/include/net/geneve.h b/include/net/geneve.h
index f8aff18d6702..3410c4b5a382 100644
--- a/include/net/geneve.h
+++ b/include/net/geneve.h
@@ -61,8 +61,7 @@ struct genevehdr {
static inline void geneve_get_rx_port(struct net_device *netdev)
{
- ASSERT_RTNL();
- call_netdevice_notifiers(NETDEV_OFFLOAD_PUSH_GENEVE, netdev);
+ udp_tunnel_get_rx_info(netdev);
}
#ifdef CONFIG_INET
diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
index 71afbea873a0..1c9408a04213 100644
--- a/include/net/udp_tunnel.h
+++ b/include/net/udp_tunnel.h
@@ -117,6 +117,12 @@ void udp_tunnel_push_rx_port(struct net_device *dev, struct socket *sock,
void udp_tunnel_notify_add_rx_port(struct socket *sock, unsigned short type);
void udp_tunnel_notify_del_rx_port(struct socket *sock, unsigned short type);
+static inline void udp_tunnel_get_rx_info(struct net_device *dev)
+{
+ ASSERT_RTNL();
+ call_netdevice_notifiers(NETDEV_UDP_TUNNEL_PUSH_INFO, dev);
+}
+
/* Transmit the skb using UDP encapsulation. */
void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
__be32 src, __be32 dst, __u8 tos, __u8 ttl,
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index 7d944941f32f..c62e2ed1c3af 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -4,6 +4,7 @@
#include <linux/if_vlan.h>
#include <net/udp_tunnel.h>
#include <net/dst_metadata.h>
+#include <net/udp_tunnel.h>
/* VXLAN protocol (RFC 7348) header:
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -390,8 +391,7 @@ static inline __be32 vxlan_compute_rco(unsigned int start, unsigned int offset)
static inline void vxlan_get_rx_port(struct net_device *netdev)
{
- ASSERT_RTNL();
- call_netdevice_notifiers(NETDEV_OFFLOAD_PUSH_VXLAN, netdev);
+ udp_tunnel_get_rx_info(netdev);
}
static inline unsigned short vxlan_get_sk_family(struct vxlan_sock *vs)
diff --git a/net/ipv4/udp_tunnel.c b/net/ipv4/udp_tunnel.c
index 8174753e6494..683e494d9000 100644
--- a/net/ipv4/udp_tunnel.c
+++ b/net/ipv4/udp_tunnel.c
@@ -79,6 +79,11 @@ EXPORT_SYMBOL_GPL(setup_udp_tunnel_sock);
static void __udp_tunnel_push_rx_port(struct net_device *dev,
struct udp_tunnel_info *ti)
{
+ if (dev->netdev_ops->ndo_udp_tunnel_add) {
+ dev->netdev_ops->ndo_udp_tunnel_add(dev, ti);
+ return;
+ }
+
switch (ti->type) {
case UDP_TUNNEL_TYPE_VXLAN:
if (!dev->netdev_ops->ndo_add_vxlan_port)
@@ -137,6 +142,11 @@ EXPORT_SYMBOL_GPL(udp_tunnel_notify_add_rx_port);
static void __udp_tunnel_pull_rx_port(struct net_device *dev,
struct udp_tunnel_info *ti)
{
+ if (dev->netdev_ops->ndo_udp_tunnel_del) {
+ dev->netdev_ops->ndo_udp_tunnel_del(dev, ti);
+ return;
+ }
+
switch (ti->type) {
case UDP_TUNNEL_TYPE_VXLAN:
if (!dev->netdev_ops->ndo_del_vxlan_port)