mirror of https://gitee.com/openkylin/linux.git
[IPV4]: fix IPv4 leave-group group matching
This patch fixes the multicast group matching for IP_DROP_MEMBERSHIP, similar to the IP_ADD_MEMBERSHIP fix in a prior patch. Groups are identifiedby <group address,interface> and including the interface address in the match will fail if a leave-group is done by address when the join was done by index, or if different addresses on the same interface are used in the join and leave. Signed-off-by: David L Stevens <dlstevens@us.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
9951f036fe
commit
84b42baef7
|
@ -1687,24 +1687,25 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
|
|||
{
|
||||
struct inet_sock *inet = inet_sk(sk);
|
||||
struct ip_mc_socklist *iml, **imlp;
|
||||
struct in_device *in_dev;
|
||||
u32 group = imr->imr_multiaddr.s_addr;
|
||||
u32 ifindex;
|
||||
|
||||
rtnl_lock();
|
||||
in_dev = ip_mc_find_dev(imr);
|
||||
if (!in_dev) {
|
||||
rtnl_unlock();
|
||||
return -ENODEV;
|
||||
}
|
||||
ifindex = imr->imr_ifindex;
|
||||
for (imlp = &inet->mc_list; (iml = *imlp) != NULL; imlp = &iml->next) {
|
||||
if (iml->multi.imr_multiaddr.s_addr==imr->imr_multiaddr.s_addr &&
|
||||
iml->multi.imr_address.s_addr==imr->imr_address.s_addr &&
|
||||
(!imr->imr_ifindex || iml->multi.imr_ifindex==imr->imr_ifindex)) {
|
||||
struct in_device *in_dev;
|
||||
|
||||
in_dev = inetdev_by_index(iml->multi.imr_ifindex);
|
||||
if (in_dev)
|
||||
(void) ip_mc_leave_src(sk, iml, in_dev);
|
||||
if (iml->multi.imr_multiaddr.s_addr == group &&
|
||||
iml->multi.imr_ifindex == ifindex) {
|
||||
(void) ip_mc_leave_src(sk, iml, in_dev);
|
||||
|
||||
*imlp = iml->next;
|
||||
|
||||
if (in_dev) {
|
||||
ip_mc_dec_group(in_dev, imr->imr_multiaddr.s_addr);
|
||||
in_dev_put(in_dev);
|
||||
}
|
||||
ip_mc_dec_group(in_dev, group);
|
||||
rtnl_unlock();
|
||||
sock_kfree_s(sk, iml, sizeof(*iml));
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue