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