1 // SPDX-License-Identifier: GPL-2.0-only
3 * Vxlan multicast group handling
6 #include <linux/kernel.h>
7 #include <net/net_namespace.h>
9 #include <linux/igmp.h>
10 #include <net/vxlan.h>
12 #include "vxlan_private.h"
14 /* Update multicast group membership when first VNI on
15 * multicast address is brought up
17 int vxlan_igmp_join(struct vxlan_dev
*vxlan
, union vxlan_addr
*rip
,
20 union vxlan_addr
*ip
= (rip
? : &vxlan
->default_dst
.remote_ip
);
21 int ifindex
= (rifindex
? : vxlan
->default_dst
.remote_ifindex
);
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
,
34 ret
= ip_mc_join_group(sk
, &mreq
);
36 #if IS_ENABLED(CONFIG_IPV6)
38 struct vxlan_sock
*sock6
= rtnl_dereference(vxlan
->vn6_sock
);
42 ret
= ipv6_stub
->ipv6_sock_mc_join(sk
, ifindex
,
51 int vxlan_igmp_leave(struct vxlan_dev
*vxlan
, union vxlan_addr
*rip
,
54 union vxlan_addr
*ip
= (rip
? : &vxlan
->default_dst
.remote_ip
);
55 int ifindex
= (rifindex
? : vxlan
->default_dst
.remote_ifindex
);
59 if (ip
->sa
.sa_family
== AF_INET
) {
60 struct vxlan_sock
*sock4
= rtnl_dereference(vxlan
->vn4_sock
);
61 struct ip_mreqn mreq
= {
62 .imr_multiaddr
.s_addr
= ip
->sin
.sin_addr
.s_addr
,
63 .imr_ifindex
= ifindex
,
68 ret
= ip_mc_leave_group(sk
, &mreq
);
70 #if IS_ENABLED(CONFIG_IPV6)
72 struct vxlan_sock
*sock6
= rtnl_dereference(vxlan
->vn6_sock
);
76 ret
= ipv6_stub
->ipv6_sock_mc_drop(sk
, ifindex
,
85 static bool vxlan_group_used_match(union vxlan_addr
*ip
, int ifindex
,
86 union vxlan_addr
*rip
, int rifindex
)
88 if (!vxlan_addr_multicast(rip
))
91 if (!vxlan_addr_equal(rip
, ip
))
94 if (rifindex
!= ifindex
)
100 static bool vxlan_group_used_by_vnifilter(struct vxlan_dev
*vxlan
,
101 union vxlan_addr
*ip
, int ifindex
)
103 struct vxlan_vni_group
*vg
= rtnl_dereference(vxlan
->vnigrp
);
104 struct vxlan_vni_node
*v
, *tmp
;
106 if (vxlan_group_used_match(ip
, ifindex
,
107 &vxlan
->default_dst
.remote_ip
,
108 vxlan
->default_dst
.remote_ifindex
))
111 list_for_each_entry_safe(v
, tmp
, &vg
->vni_list
, vlist
) {
112 if (!vxlan_addr_multicast(&v
->remote_ip
))
115 if (vxlan_group_used_match(ip
, ifindex
,
117 vxlan
->default_dst
.remote_ifindex
))
124 /* See if multicast group is already in use by other ID */
125 bool vxlan_group_used(struct vxlan_net
*vn
, struct vxlan_dev
*dev
,
126 __be32 vni
, union vxlan_addr
*rip
, int rifindex
)
128 union vxlan_addr
*ip
= (rip
? : &dev
->default_dst
.remote_ip
);
129 int ifindex
= (rifindex
? : dev
->default_dst
.remote_ifindex
);
130 struct vxlan_dev
*vxlan
;
131 struct vxlan_sock
*sock4
;
132 #if IS_ENABLED(CONFIG_IPV6)
133 struct vxlan_sock
*sock6
;
135 unsigned short family
= dev
->default_dst
.remote_ip
.sa
.sa_family
;
137 sock4
= rtnl_dereference(dev
->vn4_sock
);
139 /* The vxlan_sock is only used by dev, leaving group has
140 * no effect on other vxlan devices.
142 if (family
== AF_INET
&& sock4
&& refcount_read(&sock4
->refcnt
) == 1)
145 #if IS_ENABLED(CONFIG_IPV6)
146 sock6
= rtnl_dereference(dev
->vn6_sock
);
147 if (family
== AF_INET6
&& sock6
&& refcount_read(&sock6
->refcnt
) == 1)
151 list_for_each_entry(vxlan
, &vn
->vxlan_list
, next
) {
152 if (!netif_running(vxlan
->dev
) || vxlan
== dev
)
155 if (family
== AF_INET
&&
156 rtnl_dereference(vxlan
->vn4_sock
) != sock4
)
158 #if IS_ENABLED(CONFIG_IPV6)
159 if (family
== AF_INET6
&&
160 rtnl_dereference(vxlan
->vn6_sock
) != sock6
)
163 if (vxlan
->cfg
.flags
& VXLAN_F_VNIFILTER
) {
164 if (!vxlan_group_used_by_vnifilter(vxlan
, ip
, ifindex
))
167 if (!vxlan_group_used_match(ip
, ifindex
,
168 &vxlan
->default_dst
.remote_ip
,
169 vxlan
->default_dst
.remote_ifindex
))
179 static int vxlan_multicast_join_vnigrp(struct vxlan_dev
*vxlan
)
181 struct vxlan_vni_group
*vg
= rtnl_dereference(vxlan
->vnigrp
);
182 struct vxlan_vni_node
*v
, *tmp
, *vgood
= NULL
;
185 list_for_each_entry_safe(v
, tmp
, &vg
->vni_list
, vlist
) {
186 if (!vxlan_addr_multicast(&v
->remote_ip
))
188 /* skip if address is same as default address */
189 if (vxlan_addr_equal(&v
->remote_ip
,
190 &vxlan
->default_dst
.remote_ip
))
192 ret
= vxlan_igmp_join(vxlan
, &v
->remote_ip
, 0);
193 if (ret
== -EADDRINUSE
)
201 list_for_each_entry_safe(v
, tmp
, &vg
->vni_list
, vlist
) {
202 if (!vxlan_addr_multicast(&v
->remote_ip
))
204 if (vxlan_addr_equal(&v
->remote_ip
,
205 &vxlan
->default_dst
.remote_ip
))
207 vxlan_igmp_leave(vxlan
, &v
->remote_ip
, 0);
216 static int vxlan_multicast_leave_vnigrp(struct vxlan_dev
*vxlan
)
218 struct vxlan_net
*vn
= net_generic(vxlan
->net
, vxlan_net_id
);
219 struct vxlan_vni_group
*vg
= rtnl_dereference(vxlan
->vnigrp
);
220 struct vxlan_vni_node
*v
, *tmp
;
221 int last_err
= 0, ret
;
223 list_for_each_entry_safe(v
, tmp
, &vg
->vni_list
, vlist
) {
224 if (vxlan_addr_multicast(&v
->remote_ip
) &&
225 !vxlan_group_used(vn
, vxlan
, v
->vni
, &v
->remote_ip
,
227 ret
= vxlan_igmp_leave(vxlan
, &v
->remote_ip
, 0);
236 int vxlan_multicast_join(struct vxlan_dev
*vxlan
)
240 if (vxlan_addr_multicast(&vxlan
->default_dst
.remote_ip
)) {
241 ret
= vxlan_igmp_join(vxlan
, &vxlan
->default_dst
.remote_ip
,
242 vxlan
->default_dst
.remote_ifindex
);
243 if (ret
== -EADDRINUSE
)
249 if (vxlan
->cfg
.flags
& VXLAN_F_VNIFILTER
)
250 return vxlan_multicast_join_vnigrp(vxlan
);
255 int vxlan_multicast_leave(struct vxlan_dev
*vxlan
)
257 struct vxlan_net
*vn
= net_generic(vxlan
->net
, vxlan_net_id
);
260 if (vxlan_addr_multicast(&vxlan
->default_dst
.remote_ip
) &&
261 !vxlan_group_used(vn
, vxlan
, 0, NULL
, 0)) {
262 ret
= vxlan_igmp_leave(vxlan
, &vxlan
->default_dst
.remote_ip
,
263 vxlan
->default_dst
.remote_ifindex
);
268 if (vxlan
->cfg
.flags
& VXLAN_F_VNIFILTER
)
269 return vxlan_multicast_leave_vnigrp(vxlan
);