Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  Vxlan multicast group handling
0004  *
0005  */
0006 #include <linux/kernel.h>
0007 #include <net/net_namespace.h>
0008 #include <net/sock.h>
0009 #include <linux/igmp.h>
0010 #include <net/vxlan.h>
0011 
0012 #include "vxlan_private.h"
0013 
0014 /* Update multicast group membership when first VNI on
0015  * multicast address is brought up
0016  */
0017 int vxlan_igmp_join(struct vxlan_dev *vxlan, union vxlan_addr *rip,
0018             int rifindex)
0019 {
0020     union vxlan_addr *ip = (rip ? : &vxlan->default_dst.remote_ip);
0021     int ifindex = (rifindex ? : vxlan->default_dst.remote_ifindex);
0022     int ret = -EINVAL;
0023     struct sock *sk;
0024 
0025     if (ip->sa.sa_family == AF_INET) {
0026         struct vxlan_sock *sock4 = rtnl_dereference(vxlan->vn4_sock);
0027         struct ip_mreqn mreq = {
0028             .imr_multiaddr.s_addr   = ip->sin.sin_addr.s_addr,
0029             .imr_ifindex        = ifindex,
0030         };
0031 
0032         sk = sock4->sock->sk;
0033         lock_sock(sk);
0034         ret = ip_mc_join_group(sk, &mreq);
0035         release_sock(sk);
0036 #if IS_ENABLED(CONFIG_IPV6)
0037     } else {
0038         struct vxlan_sock *sock6 = rtnl_dereference(vxlan->vn6_sock);
0039 
0040         sk = sock6->sock->sk;
0041         lock_sock(sk);
0042         ret = ipv6_stub->ipv6_sock_mc_join(sk, ifindex,
0043                            &ip->sin6.sin6_addr);
0044         release_sock(sk);
0045 #endif
0046     }
0047 
0048     return ret;
0049 }
0050 
0051 int vxlan_igmp_leave(struct vxlan_dev *vxlan, union vxlan_addr *rip,
0052              int rifindex)
0053 {
0054     union vxlan_addr *ip = (rip ? : &vxlan->default_dst.remote_ip);
0055     int ifindex = (rifindex ? : vxlan->default_dst.remote_ifindex);
0056     int ret = -EINVAL;
0057     struct sock *sk;
0058 
0059     if (ip->sa.sa_family == AF_INET) {
0060         struct vxlan_sock *sock4 = rtnl_dereference(vxlan->vn4_sock);
0061         struct ip_mreqn mreq = {
0062             .imr_multiaddr.s_addr   = ip->sin.sin_addr.s_addr,
0063             .imr_ifindex        = ifindex,
0064         };
0065 
0066         sk = sock4->sock->sk;
0067         lock_sock(sk);
0068         ret = ip_mc_leave_group(sk, &mreq);
0069         release_sock(sk);
0070 #if IS_ENABLED(CONFIG_IPV6)
0071     } else {
0072         struct vxlan_sock *sock6 = rtnl_dereference(vxlan->vn6_sock);
0073 
0074         sk = sock6->sock->sk;
0075         lock_sock(sk);
0076         ret = ipv6_stub->ipv6_sock_mc_drop(sk, ifindex,
0077                            &ip->sin6.sin6_addr);
0078         release_sock(sk);
0079 #endif
0080     }
0081 
0082     return ret;
0083 }
0084 
0085 static bool vxlan_group_used_match(union vxlan_addr *ip, int ifindex,
0086                    union vxlan_addr *rip, int rifindex)
0087 {
0088     if (!vxlan_addr_multicast(rip))
0089         return false;
0090 
0091     if (!vxlan_addr_equal(rip, ip))
0092         return false;
0093 
0094     if (rifindex != ifindex)
0095         return false;
0096 
0097     return true;
0098 }
0099 
0100 static bool vxlan_group_used_by_vnifilter(struct vxlan_dev *vxlan,
0101                       union vxlan_addr *ip, int ifindex)
0102 {
0103     struct vxlan_vni_group *vg = rtnl_dereference(vxlan->vnigrp);
0104     struct vxlan_vni_node *v, *tmp;
0105 
0106     if (vxlan_group_used_match(ip, ifindex,
0107                    &vxlan->default_dst.remote_ip,
0108                    vxlan->default_dst.remote_ifindex))
0109         return true;
0110 
0111     list_for_each_entry_safe(v, tmp, &vg->vni_list, vlist) {
0112         if (!vxlan_addr_multicast(&v->remote_ip))
0113             continue;
0114 
0115         if (vxlan_group_used_match(ip, ifindex,
0116                        &v->remote_ip,
0117                        vxlan->default_dst.remote_ifindex))
0118             return true;
0119     }
0120 
0121     return false;
0122 }
0123 
0124 /* See if multicast group is already in use by other ID */
0125 bool vxlan_group_used(struct vxlan_net *vn, struct vxlan_dev *dev,
0126               __be32 vni, union vxlan_addr *rip, int rifindex)
0127 {
0128     union vxlan_addr *ip = (rip ? : &dev->default_dst.remote_ip);
0129     int ifindex = (rifindex ? : dev->default_dst.remote_ifindex);
0130     struct vxlan_dev *vxlan;
0131     struct vxlan_sock *sock4;
0132 #if IS_ENABLED(CONFIG_IPV6)
0133     struct vxlan_sock *sock6;
0134 #endif
0135     unsigned short family = dev->default_dst.remote_ip.sa.sa_family;
0136 
0137     sock4 = rtnl_dereference(dev->vn4_sock);
0138 
0139     /* The vxlan_sock is only used by dev, leaving group has
0140      * no effect on other vxlan devices.
0141      */
0142     if (family == AF_INET && sock4 && refcount_read(&sock4->refcnt) == 1)
0143         return false;
0144 
0145 #if IS_ENABLED(CONFIG_IPV6)
0146     sock6 = rtnl_dereference(dev->vn6_sock);
0147     if (family == AF_INET6 && sock6 && refcount_read(&sock6->refcnt) == 1)
0148         return false;
0149 #endif
0150 
0151     list_for_each_entry(vxlan, &vn->vxlan_list, next) {
0152         if (!netif_running(vxlan->dev) || vxlan == dev)
0153             continue;
0154 
0155         if (family == AF_INET &&
0156             rtnl_dereference(vxlan->vn4_sock) != sock4)
0157             continue;
0158 #if IS_ENABLED(CONFIG_IPV6)
0159         if (family == AF_INET6 &&
0160             rtnl_dereference(vxlan->vn6_sock) != sock6)
0161             continue;
0162 #endif
0163         if (vxlan->cfg.flags & VXLAN_F_VNIFILTER) {
0164             if (!vxlan_group_used_by_vnifilter(vxlan, ip, ifindex))
0165                 continue;
0166         } else {
0167             if (!vxlan_group_used_match(ip, ifindex,
0168                             &vxlan->default_dst.remote_ip,
0169                             vxlan->default_dst.remote_ifindex))
0170                 continue;
0171         }
0172 
0173         return true;
0174     }
0175 
0176     return false;
0177 }
0178 
0179 static int vxlan_multicast_join_vnigrp(struct vxlan_dev *vxlan)
0180 {
0181     struct vxlan_vni_group *vg = rtnl_dereference(vxlan->vnigrp);
0182     struct vxlan_vni_node *v, *tmp, *vgood = NULL;
0183     int ret = 0;
0184 
0185     list_for_each_entry_safe(v, tmp, &vg->vni_list, vlist) {
0186         if (!vxlan_addr_multicast(&v->remote_ip))
0187             continue;
0188         /* skip if address is same as default address */
0189         if (vxlan_addr_equal(&v->remote_ip,
0190                      &vxlan->default_dst.remote_ip))
0191             continue;
0192         ret = vxlan_igmp_join(vxlan, &v->remote_ip, 0);
0193         if (ret == -EADDRINUSE)
0194             ret = 0;
0195         if (ret)
0196             goto out;
0197         vgood = v;
0198     }
0199 out:
0200     if (ret) {
0201         list_for_each_entry_safe(v, tmp, &vg->vni_list, vlist) {
0202             if (!vxlan_addr_multicast(&v->remote_ip))
0203                 continue;
0204             if (vxlan_addr_equal(&v->remote_ip,
0205                          &vxlan->default_dst.remote_ip))
0206                 continue;
0207             vxlan_igmp_leave(vxlan, &v->remote_ip, 0);
0208             if (v == vgood)
0209                 break;
0210         }
0211     }
0212 
0213     return ret;
0214 }
0215 
0216 static int vxlan_multicast_leave_vnigrp(struct vxlan_dev *vxlan)
0217 {
0218     struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
0219     struct vxlan_vni_group *vg = rtnl_dereference(vxlan->vnigrp);
0220     struct vxlan_vni_node *v, *tmp;
0221     int last_err = 0, ret;
0222 
0223     list_for_each_entry_safe(v, tmp, &vg->vni_list, vlist) {
0224         if (vxlan_addr_multicast(&v->remote_ip) &&
0225             !vxlan_group_used(vn, vxlan, v->vni, &v->remote_ip,
0226                       0)) {
0227             ret = vxlan_igmp_leave(vxlan, &v->remote_ip, 0);
0228             if (ret)
0229                 last_err = ret;
0230         }
0231     }
0232 
0233     return last_err;
0234 }
0235 
0236 int vxlan_multicast_join(struct vxlan_dev *vxlan)
0237 {
0238     int ret = 0;
0239 
0240     if (vxlan_addr_multicast(&vxlan->default_dst.remote_ip)) {
0241         ret = vxlan_igmp_join(vxlan, &vxlan->default_dst.remote_ip,
0242                       vxlan->default_dst.remote_ifindex);
0243         if (ret == -EADDRINUSE)
0244             ret = 0;
0245         if (ret)
0246             return ret;
0247     }
0248 
0249     if (vxlan->cfg.flags & VXLAN_F_VNIFILTER)
0250         return vxlan_multicast_join_vnigrp(vxlan);
0251 
0252     return 0;
0253 }
0254 
0255 int vxlan_multicast_leave(struct vxlan_dev *vxlan)
0256 {
0257     struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
0258     int ret = 0;
0259 
0260     if (vxlan_addr_multicast(&vxlan->default_dst.remote_ip) &&
0261         !vxlan_group_used(vn, vxlan, 0, NULL, 0)) {
0262         ret = vxlan_igmp_leave(vxlan, &vxlan->default_dst.remote_ip,
0263                        vxlan->default_dst.remote_ifindex);
0264         if (ret)
0265             return ret;
0266     }
0267 
0268     if (vxlan->cfg.flags & VXLAN_F_VNIFILTER)
0269         return vxlan_multicast_leave_vnigrp(vxlan);
0270 
0271     return 0;
0272 }