1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Vxlan multicast group handling 4 * 5 */ 6 #include <linux/kernel.h> 7 #include <net/net_namespace.h> 8 #include <net/sock.h> 9 #include <linux/igmp.h> 10 #include <net/vxlan.h> 11 12 #include "vxlan_private.h" 13 14 /* Update multicast group membership when first VNI on 15 * multicast address is brought up 16 */ 17 int vxlan_igmp_join(struct vxlan_dev *vxlan, union vxlan_addr *rip, 18 int rifindex) 19 { 20 union vxlan_addr *ip = (rip ? : &vxlan->default_dst.remote_ip); 21 int ifindex = (rifindex ? : vxlan->default_dst.remote_ifindex); 22 int ret = -EINVAL; 23 struct sock *sk; 24 25 if (ip->sa.sa_family == AF_INET) { 26 struct vxlan_sock *sock4 = rtnl_dereference(vxlan->vn4_sock); 27 struct ip_mreqn mreq = { 28 .imr_multiaddr.s_addr = ip->sin.sin_addr.s_addr, 29 .imr_ifindex = ifindex, 30 }; 31 32 sk = sock4->sock->sk; 33 lock_sock(sk); 34 ret = ip_mc_join_group(sk, &mreq); 35 release_sock(sk); 36 #if IS_ENABLED(CONFIG_IPV6) 37 } else { 38 struct vxlan_sock *sock6 = rtnl_dereference(vxlan->vn6_sock); 39 40 sk = sock6->sock->sk; 41 lock_sock(sk); 42 ret = ipv6_sock_mc_join(sk, ifindex, &ip->sin6.sin6_addr); 43 release_sock(sk); 44 #endif 45 } 46 47 return ret; 48 } 49 50 int vxlan_igmp_leave(struct vxlan_dev *vxlan, union vxlan_addr *rip, 51 int rifindex) 52 { 53 union vxlan_addr *ip = (rip ? : &vxlan->default_dst.remote_ip); 54 int ifindex = (rifindex ? : vxlan->default_dst.remote_ifindex); 55 int ret = -EINVAL; 56 struct sock *sk; 57 58 if (ip->sa.sa_family == AF_INET) { 59 struct vxlan_sock *sock4 = rtnl_dereference(vxlan->vn4_sock); 60 struct ip_mreqn mreq = { 61 .imr_multiaddr.s_addr = ip->sin.sin_addr.s_addr, 62 .imr_ifindex = ifindex, 63 }; 64 65 sk = sock4->sock->sk; 66 lock_sock(sk); 67 ret = ip_mc_leave_group(sk, &mreq); 68 release_sock(sk); 69 #if IS_ENABLED(CONFIG_IPV6) 70 } else { 71 struct vxlan_sock *sock6 = rtnl_dereference(vxlan->vn6_sock); 72 73 sk = sock6->sock->sk; 74 lock_sock(sk); 75 ret = ipv6_sock_mc_drop(sk, ifindex, &ip->sin6.sin6_addr); 76 release_sock(sk); 77 #endif 78 } 79 80 return ret; 81 } 82 83 static bool vxlan_group_used_match(union vxlan_addr *ip, int ifindex, 84 union vxlan_addr *rip, int rifindex) 85 { 86 if (!vxlan_addr_multicast(rip)) 87 return false; 88 89 if (!vxlan_addr_equal(rip, ip)) 90 return false; 91 92 if (rifindex != ifindex) 93 return false; 94 95 return true; 96 } 97 98 static bool vxlan_group_used_by_vnifilter(struct vxlan_dev *vxlan, 99 union vxlan_addr *ip, int ifindex) 100 { 101 struct vxlan_vni_group *vg = rtnl_dereference(vxlan->vnigrp); 102 struct vxlan_vni_node *v, *tmp; 103 104 if (vxlan_group_used_match(ip, ifindex, 105 &vxlan->default_dst.remote_ip, 106 vxlan->default_dst.remote_ifindex)) 107 return true; 108 109 list_for_each_entry_safe(v, tmp, &vg->vni_list, vlist) { 110 if (!vxlan_addr_multicast(&v->remote_ip)) 111 continue; 112 113 if (vxlan_group_used_match(ip, ifindex, 114 &v->remote_ip, 115 vxlan->default_dst.remote_ifindex)) 116 return true; 117 } 118 119 return false; 120 } 121 122 /* See if multicast group is already in use by other ID */ 123 bool vxlan_group_used(struct vxlan_net *vn, struct vxlan_dev *dev, 124 __be32 vni, union vxlan_addr *rip, int rifindex) 125 { 126 union vxlan_addr *ip = (rip ? : &dev->default_dst.remote_ip); 127 int ifindex = (rifindex ? : dev->default_dst.remote_ifindex); 128 struct vxlan_dev *vxlan; 129 struct vxlan_sock *sock4; 130 #if IS_ENABLED(CONFIG_IPV6) 131 struct vxlan_sock *sock6; 132 #endif 133 unsigned short family = dev->default_dst.remote_ip.sa.sa_family; 134 135 sock4 = rtnl_dereference(dev->vn4_sock); 136 137 /* The vxlan_sock is only used by dev, leaving group has 138 * no effect on other vxlan devices. 139 */ 140 if (family == AF_INET && sock4 && refcount_read(&sock4->refcnt) == 1) 141 return false; 142 143 #if IS_ENABLED(CONFIG_IPV6) 144 sock6 = rtnl_dereference(dev->vn6_sock); 145 if (family == AF_INET6 && sock6 && refcount_read(&sock6->refcnt) == 1) 146 return false; 147 #endif 148 149 list_for_each_entry(vxlan, &vn->vxlan_list, next) { 150 if (!netif_running(vxlan->dev) || vxlan == dev) 151 continue; 152 153 if (family == AF_INET && 154 rtnl_dereference(vxlan->vn4_sock) != sock4) 155 continue; 156 #if IS_ENABLED(CONFIG_IPV6) 157 if (family == AF_INET6 && 158 rtnl_dereference(vxlan->vn6_sock) != sock6) 159 continue; 160 #endif 161 if (vxlan->cfg.flags & VXLAN_F_VNIFILTER) { 162 if (!vxlan_group_used_by_vnifilter(vxlan, ip, ifindex)) 163 continue; 164 } else { 165 if (!vxlan_group_used_match(ip, ifindex, 166 &vxlan->default_dst.remote_ip, 167 vxlan->default_dst.remote_ifindex)) 168 continue; 169 } 170 171 return true; 172 } 173 174 return false; 175 } 176 177 static int vxlan_multicast_join_vnigrp(struct vxlan_dev *vxlan) 178 { 179 struct vxlan_vni_group *vg = rtnl_dereference(vxlan->vnigrp); 180 struct vxlan_vni_node *v, *tmp, *vgood = NULL; 181 int ret = 0; 182 183 list_for_each_entry_safe(v, tmp, &vg->vni_list, vlist) { 184 if (!vxlan_addr_multicast(&v->remote_ip)) 185 continue; 186 /* skip if address is same as default address */ 187 if (vxlan_addr_equal(&v->remote_ip, 188 &vxlan->default_dst.remote_ip)) 189 continue; 190 ret = vxlan_igmp_join(vxlan, &v->remote_ip, 0); 191 if (ret == -EADDRINUSE) 192 ret = 0; 193 if (ret) 194 goto out; 195 vgood = v; 196 } 197 out: 198 if (ret) { 199 list_for_each_entry_safe(v, tmp, &vg->vni_list, vlist) { 200 if (!vxlan_addr_multicast(&v->remote_ip)) 201 continue; 202 if (vxlan_addr_equal(&v->remote_ip, 203 &vxlan->default_dst.remote_ip)) 204 continue; 205 vxlan_igmp_leave(vxlan, &v->remote_ip, 0); 206 if (v == vgood) 207 break; 208 } 209 } 210 211 return ret; 212 } 213 214 static int vxlan_multicast_leave_vnigrp(struct vxlan_dev *vxlan) 215 { 216 struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id); 217 struct vxlan_vni_group *vg = rtnl_dereference(vxlan->vnigrp); 218 struct vxlan_vni_node *v, *tmp; 219 int last_err = 0, ret; 220 221 list_for_each_entry_safe(v, tmp, &vg->vni_list, vlist) { 222 if (vxlan_addr_multicast(&v->remote_ip) && 223 !vxlan_group_used(vn, vxlan, v->vni, &v->remote_ip, 224 0)) { 225 ret = vxlan_igmp_leave(vxlan, &v->remote_ip, 0); 226 if (ret) 227 last_err = ret; 228 } 229 } 230 231 return last_err; 232 } 233 234 int vxlan_multicast_join(struct vxlan_dev *vxlan) 235 { 236 int ret = 0; 237 238 if (vxlan_addr_multicast(&vxlan->default_dst.remote_ip)) { 239 ret = vxlan_igmp_join(vxlan, &vxlan->default_dst.remote_ip, 240 vxlan->default_dst.remote_ifindex); 241 if (ret == -EADDRINUSE) 242 ret = 0; 243 if (ret) 244 return ret; 245 } 246 247 if (vxlan->cfg.flags & VXLAN_F_VNIFILTER) 248 return vxlan_multicast_join_vnigrp(vxlan); 249 250 return 0; 251 } 252 253 int vxlan_multicast_leave(struct vxlan_dev *vxlan) 254 { 255 struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id); 256 int ret = 0; 257 258 if (vxlan_addr_multicast(&vxlan->default_dst.remote_ip) && 259 !vxlan_group_used(vn, vxlan, 0, NULL, 0)) { 260 ret = vxlan_igmp_leave(vxlan, &vxlan->default_dst.remote_ip, 261 vxlan->default_dst.remote_ifindex); 262 if (ret) 263 return ret; 264 } 265 266 if (vxlan->cfg.flags & VXLAN_F_VNIFILTER) 267 return vxlan_multicast_leave_vnigrp(vxlan); 268 269 return 0; 270 } 271