@@ -372,15 +372,12 @@ static struct socket *geneve_create_sock(struct net *net, bool ipv6,
static void geneve_notify_add_rx_port(struct geneve_sock *gs)
{
struct sock *sk = gs->sock->sk;
- sa_family_t sa_family = sk->sk_family;
+ struct net *net = sock_net(sk);
int err;
- if (sa_family == AF_INET) {
- err = udp_add_offload(&gs->udp_offloads);
- if (err)
- pr_warn("geneve: udp_add_offload failed with status %d\n",
- err);
- }
+ err = udp_add_offload(&gs->udp_offloads, net);
+ if (err)
+ pr_warn("geneve: udp_add_offload failed with status %d\n", err);
}
static int geneve_hlen(struct genevehdr *gh)
@@ -522,10 +519,9 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port,
static void geneve_notify_del_rx_port(struct geneve_sock *gs)
{
struct sock *sk = gs->sock->sk;
- sa_family_t sa_family = sk->sk_family;
+ struct net *net = sock_net(sk);
- if (sa_family == AF_INET)
- udp_del_offload(&gs->udp_offloads);
+ udp_del_offload(&gs->udp_offloads, net);
}
static void __geneve_sock_release(struct geneve_sock *gs)
@@ -613,47 +613,22 @@ static int vxlan_gro_complete(struct sk_buff *skb, int nhoff,
/* Notify netdevs that UDP port started listening */
static void vxlan_notify_add_rx_port(struct vxlan_sock *vs)
{
- struct net_device *dev;
struct sock *sk = vs->sock->sk;
struct net *net = sock_net(sk);
- sa_family_t sa_family = vxlan_get_sk_family(vs);
- __be16 port = inet_sk(sk)->inet_sport;
int err;
- if (sa_family == AF_INET) {
- err = udp_add_offload(&vs->udp_offloads);
- if (err)
- pr_warn("vxlan: udp_add_offload failed with status %d\n", err);
- }
-
- rcu_read_lock();
- for_each_netdev_rcu(net, dev) {
- if (dev->netdev_ops->ndo_add_udp_tunnel_port)
- dev->netdev_ops->ndo_add_udp_tunnel_port(dev, sa_family,
- port, UDP_TUNNEL_VXLAN);
- }
- rcu_read_unlock();
+ err = udp_add_offload(&vs->udp_offloads, net);
+ if (err)
+ pr_warn("vxlan: udp_add_offload failed with status %d\n", err);
}
/* Notify netdevs that UDP port is no more listening */
static void vxlan_notify_del_rx_port(struct vxlan_sock *vs)
{
- struct net_device *dev;
struct sock *sk = vs->sock->sk;
struct net *net = sock_net(sk);
- sa_family_t sa_family = vxlan_get_sk_family(vs);
- __be16 port = inet_sk(sk)->inet_sport;
-
- rcu_read_lock();
- for_each_netdev_rcu(net, dev) {
- if (dev->netdev_ops->ndo_del_udp_tunnel_port)
- dev->netdev_ops->ndo_del_udp_tunnel_port(dev, sa_family,
- port, UDP_TUNNEL_VXLAN);
- }
- rcu_read_unlock();
- if (sa_family == AF_INET)
- udp_del_offload(&vs->udp_offloads);
+ udp_del_offload(&vs->udp_offloads, net);
}
/* Add new entry to forwarding table -- assumes lock held */
@@ -107,8 +107,8 @@ int inet_del_offload(const struct net_offload *prot, unsigned char num);
void inet_register_protosw(struct inet_protosw *p);
void inet_unregister_protosw(struct inet_protosw *p);
-int udp_add_offload(struct udp_offload *prot);
-void udp_del_offload(struct udp_offload *prot);
+int udp_add_offload(struct udp_offload *prot, struct net *net);
+void udp_del_offload(struct udp_offload *prot, struct net *net);
void udp_offload_get_port(struct net_device *dev);
@@ -411,9 +411,9 @@ static void fou_release(struct fou *fou)
{
struct socket *sock = fou->sock;
struct sock *sk = sock->sk;
+ struct net *net = sock_net(sk);
- if (sk->sk_family == AF_INET)
- udp_del_offload(&fou->udp_offloads);
+ udp_del_offload(&fou->udp_offloads, net);
list_del(&fou->list);
udp_tunnel_sock_release(sock);
@@ -496,11 +496,9 @@ static int fou_create(struct net *net, struct fou_cfg *cfg,
sk->sk_allocation = GFP_ATOMIC;
- if (cfg->udp_config.family == AF_INET) {
- err = udp_add_offload(&fou->udp_offloads);
- if (err)
- goto error;
- }
+ err = udp_add_offload(&fou->udp_offloads, net);
+ if (err)
+ goto error;
err = fou_add_to_port_list(net, fou);
if (err)
@@ -241,9 +241,10 @@ out:
return segs;
}
-int udp_add_offload(struct udp_offload *uo)
+int udp_add_offload(struct udp_offload *uo, struct net *net)
{
struct udp_offload_priv *new_offload = kzalloc(sizeof(*new_offload), GFP_ATOMIC);
+ struct net_device *dev;
if (!new_offload)
return -ENOMEM;
@@ -253,6 +254,11 @@ int udp_add_offload(struct udp_offload *uo)
spin_lock(&udp_offload_lock);
new_offload->next = udp_offload_base;
rcu_assign_pointer(udp_offload_base, new_offload);
+ for_each_netdev_rcu(net, dev) {
+ if (dev->netdev_ops->ndo_add_udp_tunnel_port)
+ dev->netdev_ops->ndo_add_udp_tunnel_port(dev,
+ uo->family, uo->port, uo->tunnel_type);
+ }
spin_unlock(&udp_offload_lock);
return 0;
@@ -265,13 +271,19 @@ static void udp_offload_free_routine(struct rcu_head *head)
kfree(ou_priv);
}
-void udp_del_offload(struct udp_offload *uo)
+void udp_del_offload(struct udp_offload *uo, struct net *net)
{
struct udp_offload_priv __rcu **head = &udp_offload_base;
struct udp_offload_priv *uo_priv;
+ struct net_device *dev;
spin_lock(&udp_offload_lock);
+ for_each_netdev_rcu(net, dev) {
+ if (dev->netdev_ops->ndo_add_udp_tunnel_port)
+ dev->netdev_ops->ndo_del_udp_tunnel_port(dev,
+ uo->family, uo->port, uo->tunnel_type);
+ }
uo_priv = udp_deref_protected(*head);
for (; uo_priv != NULL;
uo_priv = udp_deref_protected(*head)) {