OSDN Git Service

vxlan_multicast: Move multicast helpers to a separate file
authorRoopa Prabhu <roopa@nvidia.com>
Tue, 1 Mar 2022 05:04:35 +0000 (05:04 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 1 Mar 2022 08:38:02 +0000 (08:38 +0000)
subsequent patches will add more helpers.

Signed-off-by: Roopa Prabhu <roopa@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/vxlan/Makefile
drivers/net/vxlan/vxlan_core.c
drivers/net/vxlan/vxlan_multicast.c [new file with mode: 0644]
drivers/net/vxlan/vxlan_private.h

index 5672661..61c80e9 100644 (file)
@@ -4,4 +4,4 @@
 
 obj-$(CONFIG_VXLAN) += vxlan.o
 
-vxlan-objs := vxlan_core.o
+vxlan-objs := vxlan_core.o vxlan_multicast.o
index 8c193d4..11286e2 100644 (file)
@@ -1445,58 +1445,6 @@ static bool vxlan_snoop(struct net_device *dev,
        return false;
 }
 
-/* See if multicast group is already in use by other ID */
-static bool vxlan_group_used(struct vxlan_net *vn, struct vxlan_dev *dev,
-                            union vxlan_addr *rip, int rifindex)
-{
-       union vxlan_addr *ip = (rip ? : &dev->default_dst.remote_ip);
-       int ifindex = (rifindex ? : dev->default_dst.remote_ifindex);
-       struct vxlan_dev *vxlan;
-       struct vxlan_sock *sock4;
-#if IS_ENABLED(CONFIG_IPV6)
-       struct vxlan_sock *sock6;
-#endif
-       unsigned short family = dev->default_dst.remote_ip.sa.sa_family;
-
-       sock4 = rtnl_dereference(dev->vn4_sock);
-
-       /* The vxlan_sock is only used by dev, leaving group has
-        * no effect on other vxlan devices.
-        */
-       if (family == AF_INET && sock4 && refcount_read(&sock4->refcnt) == 1)
-               return false;
-#if IS_ENABLED(CONFIG_IPV6)
-       sock6 = rtnl_dereference(dev->vn6_sock);
-       if (family == AF_INET6 && sock6 && refcount_read(&sock6->refcnt) == 1)
-               return false;
-#endif
-
-       list_for_each_entry(vxlan, &vn->vxlan_list, next) {
-               if (!netif_running(vxlan->dev) || vxlan == dev)
-                       continue;
-
-               if (family == AF_INET &&
-                   rtnl_dereference(vxlan->vn4_sock) != sock4)
-                       continue;
-#if IS_ENABLED(CONFIG_IPV6)
-               if (family == AF_INET6 &&
-                   rtnl_dereference(vxlan->vn6_sock) != sock6)
-                       continue;
-#endif
-
-               if (!vxlan_addr_equal(&vxlan->default_dst.remote_ip,
-                                     ip))
-                       continue;
-
-               if (vxlan->default_dst.remote_ifindex != ifindex)
-                       continue;
-
-               return true;
-       }
-
-       return false;
-}
-
 static bool __vxlan_sock_release_prep(struct vxlan_sock *vs)
 {
        struct vxlan_net *vn;
@@ -1545,77 +1493,6 @@ static void vxlan_sock_release(struct vxlan_dev *vxlan)
 #endif
 }
 
-/* Update multicast group membership when first VNI on
- * multicast address is brought up
- */
-static int vxlan_igmp_join(struct vxlan_dev *vxlan, union vxlan_addr *rip,
-                          int rifindex)
-{
-       union vxlan_addr *ip = (rip ? : &vxlan->default_dst.remote_ip);
-       int ifindex = (rifindex ? : vxlan->default_dst.remote_ifindex);
-       int ret = -EINVAL;
-       struct sock *sk;
-
-       if (ip->sa.sa_family == AF_INET) {
-               struct vxlan_sock *sock4 = rtnl_dereference(vxlan->vn4_sock);
-               struct ip_mreqn mreq = {
-                       .imr_multiaddr.s_addr   = ip->sin.sin_addr.s_addr,
-                       .imr_ifindex            = ifindex,
-               };
-
-               sk = sock4->sock->sk;
-               lock_sock(sk);
-               ret = ip_mc_join_group(sk, &mreq);
-               release_sock(sk);
-#if IS_ENABLED(CONFIG_IPV6)
-       } else {
-               struct vxlan_sock *sock6 = rtnl_dereference(vxlan->vn6_sock);
-
-               sk = sock6->sock->sk;
-               lock_sock(sk);
-               ret = ipv6_stub->ipv6_sock_mc_join(sk, ifindex,
-                                                  &ip->sin6.sin6_addr);
-               release_sock(sk);
-#endif
-       }
-
-       return ret;
-}
-
-static int vxlan_igmp_leave(struct vxlan_dev *vxlan, union vxlan_addr *rip,
-                           int rifindex)
-{
-       union vxlan_addr *ip = (rip ? : &vxlan->default_dst.remote_ip);
-       int ifindex = (rifindex ? : vxlan->default_dst.remote_ifindex);
-       int ret = -EINVAL;
-       struct sock *sk;
-
-       if (ip->sa.sa_family == AF_INET) {
-               struct vxlan_sock *sock4 = rtnl_dereference(vxlan->vn4_sock);
-               struct ip_mreqn mreq = {
-                       .imr_multiaddr.s_addr   = ip->sin.sin_addr.s_addr,
-                       .imr_ifindex            = ifindex,
-               };
-
-               sk = sock4->sock->sk;
-               lock_sock(sk);
-               ret = ip_mc_leave_group(sk, &mreq);
-               release_sock(sk);
-#if IS_ENABLED(CONFIG_IPV6)
-       } else {
-               struct vxlan_sock *sock6 = rtnl_dereference(vxlan->vn6_sock);
-
-               sk = sock6->sock->sk;
-               lock_sock(sk);
-               ret = ipv6_stub->ipv6_sock_mc_drop(sk, ifindex,
-                                                  &ip->sin6.sin6_addr);
-               release_sock(sk);
-#endif
-       }
-
-       return ret;
-}
-
 static bool vxlan_remcsum(struct vxlanhdr *unparsed,
                          struct sk_buff *skb, u32 vxflags)
 {
diff --git a/drivers/net/vxlan/vxlan_multicast.c b/drivers/net/vxlan/vxlan_multicast.c
new file mode 100644 (file)
index 0000000..b1f5505
--- /dev/null
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *     Vxlan multicast group handling
+ *
+ */
+#include <linux/kernel.h>
+#include <net/net_namespace.h>
+#include <net/sock.h>
+#include <linux/igmp.h>
+#include <net/vxlan.h>
+
+#include "vxlan_private.h"
+
+/* Update multicast group membership when first VNI on
+ * multicast address is brought up
+ */
+int vxlan_igmp_join(struct vxlan_dev *vxlan, union vxlan_addr *rip,
+                   int rifindex)
+{
+       union vxlan_addr *ip = (rip ? : &vxlan->default_dst.remote_ip);
+       int ifindex = (rifindex ? : vxlan->default_dst.remote_ifindex);
+       int ret = -EINVAL;
+       struct sock *sk;
+
+       if (ip->sa.sa_family == AF_INET) {
+               struct vxlan_sock *sock4 = rtnl_dereference(vxlan->vn4_sock);
+               struct ip_mreqn mreq = {
+                       .imr_multiaddr.s_addr   = ip->sin.sin_addr.s_addr,
+                       .imr_ifindex            = ifindex,
+               };
+
+               sk = sock4->sock->sk;
+               lock_sock(sk);
+               ret = ip_mc_join_group(sk, &mreq);
+               release_sock(sk);
+#if IS_ENABLED(CONFIG_IPV6)
+       } else {
+               struct vxlan_sock *sock6 = rtnl_dereference(vxlan->vn6_sock);
+
+               sk = sock6->sock->sk;
+               lock_sock(sk);
+               ret = ipv6_stub->ipv6_sock_mc_join(sk, ifindex,
+                                                  &ip->sin6.sin6_addr);
+               release_sock(sk);
+#endif
+       }
+
+       return ret;
+}
+
+int vxlan_igmp_leave(struct vxlan_dev *vxlan, union vxlan_addr *rip,
+                    int rifindex)
+{
+       union vxlan_addr *ip = (rip ? : &vxlan->default_dst.remote_ip);
+       int ifindex = (rifindex ? : vxlan->default_dst.remote_ifindex);
+       int ret = -EINVAL;
+       struct sock *sk;
+
+       if (ip->sa.sa_family == AF_INET) {
+               struct vxlan_sock *sock4 = rtnl_dereference(vxlan->vn4_sock);
+               struct ip_mreqn mreq = {
+                       .imr_multiaddr.s_addr   = ip->sin.sin_addr.s_addr,
+                       .imr_ifindex            = ifindex,
+               };
+
+               sk = sock4->sock->sk;
+               lock_sock(sk);
+               ret = ip_mc_leave_group(sk, &mreq);
+               release_sock(sk);
+#if IS_ENABLED(CONFIG_IPV6)
+       } else {
+               struct vxlan_sock *sock6 = rtnl_dereference(vxlan->vn6_sock);
+
+               sk = sock6->sock->sk;
+               lock_sock(sk);
+               ret = ipv6_stub->ipv6_sock_mc_drop(sk, ifindex,
+                                                  &ip->sin6.sin6_addr);
+               release_sock(sk);
+#endif
+       }
+
+       return ret;
+}
+
+/* See if multicast group is already in use by other ID */
+bool vxlan_group_used(struct vxlan_net *vn, struct vxlan_dev *dev,
+                     union vxlan_addr *rip, int rifindex)
+{
+       union vxlan_addr *ip = (rip ? : &dev->default_dst.remote_ip);
+       int ifindex = (rifindex ? : dev->default_dst.remote_ifindex);
+       struct vxlan_dev *vxlan;
+       struct vxlan_sock *sock4;
+#if IS_ENABLED(CONFIG_IPV6)
+       struct vxlan_sock *sock6;
+#endif
+       unsigned short family = dev->default_dst.remote_ip.sa.sa_family;
+
+       sock4 = rtnl_dereference(dev->vn4_sock);
+
+       /* The vxlan_sock is only used by dev, leaving group has
+        * no effect on other vxlan devices.
+        */
+       if (family == AF_INET && sock4 && refcount_read(&sock4->refcnt) == 1)
+               return false;
+
+#if IS_ENABLED(CONFIG_IPV6)
+       sock6 = rtnl_dereference(dev->vn6_sock);
+       if (family == AF_INET6 && sock6 && refcount_read(&sock6->refcnt) == 1)
+               return false;
+#endif
+
+       list_for_each_entry(vxlan, &vn->vxlan_list, next) {
+               if (!netif_running(vxlan->dev) || vxlan == dev)
+                       continue;
+
+               if (family == AF_INET &&
+                   rtnl_dereference(vxlan->vn4_sock) != sock4)
+                       continue;
+#if IS_ENABLED(CONFIG_IPV6)
+               if (family == AF_INET6 &&
+                   rtnl_dereference(vxlan->vn6_sock) != sock6)
+                       continue;
+#endif
+               if (!vxlan_addr_equal(&vxlan->default_dst.remote_ip, ip))
+                       continue;
+
+               if (vxlan->default_dst.remote_ifindex != ifindex)
+                       continue;
+
+               return true;
+       }
+
+       return false;
+}
index b21e123..7a94601 100644 (file)
@@ -112,4 +112,11 @@ int vxlan_fdb_update(struct vxlan_dev *vxlan,
                     __u32 ifindex, __u16 ndm_flags, u32 nhid,
                     bool swdev_notify, struct netlink_ext_ack *extack);
 
+/* vxlan_multicast.c */
+int vxlan_igmp_join(struct vxlan_dev *vxlan, union vxlan_addr *rip,
+                   int rifindex);
+int vxlan_igmp_leave(struct vxlan_dev *vxlan, union vxlan_addr *rip,
+                    int rifindex);
+bool vxlan_group_used(struct vxlan_net *vn, struct vxlan_dev *dev,
+                     union vxlan_addr *rip, int rifindex);
 #endif