Module Name: src Committed By: yamaguchi Date: Thu Jun 14 08:33:18 UTC 2018
Modified Files: src/sys/net: if_vlan.c Log Message: Fix to check whether the address has been added before delete The list named ifv_mc_listhead saves multicast addresses that are added through SIOCADDMULTI. Each nodes added to the list are used for deleting the related address from a parent I/F when remove the configuration of parent I/F. In carp(4) and OpenBSD's vlan(4), the lists is used to check a parameter of SIOCDELMULTI in addition to the use. Based on them, the check is added to vlan(4) ok ozaki-r@ To generate a diff of this commit: cvs rdiff -u -r1.128 -r1.129 src/sys/net/if_vlan.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/if_vlan.c diff -u src/sys/net/if_vlan.c:1.128 src/sys/net/if_vlan.c:1.129 --- src/sys/net/if_vlan.c:1.128 Thu Jun 14 08:06:07 2018 +++ src/sys/net/if_vlan.c Thu Jun 14 08:33:18 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: if_vlan.c,v 1.128 2018/06/14 08:06:07 yamaguchi Exp $ */ +/* $NetBSD: if_vlan.c,v 1.129 2018/06/14 08:33:18 yamaguchi Exp $ */ /* * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc. @@ -78,7 +78,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.128 2018/06/14 08:06:07 yamaguchi Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.129 2018/06/14 08:33:18 yamaguchi Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -1229,6 +1229,17 @@ vlan_ether_delmulti(struct ifvlan *ifv, ETHER_LOCK(&ifv->ifv_ec); enm = ether_lookup_multi(addrlo, addrhi, &ifv->ifv_ec); ETHER_UNLOCK(&ifv->ifv_ec); + if (enm == NULL) + return EINVAL; + + LIST_FOREACH(mc, &ifv->ifv_mc_listhead, mc_entries) { + if (mc->mc_enm == enm) + break; + } + + /* We woun't delete entries we didn't add */ + if (mc == NULL) + return EINVAL; error = ether_delmulti(sa, &ifv->ifv_ec); if (error != ENETRESET) @@ -1242,17 +1253,11 @@ vlan_ether_delmulti(struct ifvlan *ifv, if (error == 0) { /* And forget about this address. */ - for (mc = LIST_FIRST(&ifv->ifv_mc_listhead); mc != NULL; - mc = LIST_NEXT(mc, mc_entries)) { - if (mc->mc_enm == enm) { - LIST_REMOVE(mc, mc_entries); - free(mc, M_DEVBUF); - break; - } - } - KASSERT(mc != NULL); - } else + LIST_REMOVE(mc, mc_entries); + free(mc, M_DEVBUF); + } else { (void)ether_addmulti(sa, &ifv->ifv_ec); + } return error; } @@ -1276,7 +1281,7 @@ vlan_ether_purgemulti(struct ifvlan *ifv while ((mc = LIST_FIRST(&ifv->ifv_mc_listhead)) != NULL) { IFNET_LOCK(mib->ifvm_p); (void)if_mcast_op(mib->ifvm_p, SIOCDELMULTI, - (const struct sockaddr *)&mc->mc_addr); + sstocsa(&mc->mc_addr)); IFNET_UNLOCK(mib->ifvm_p); LIST_REMOVE(mc, mc_entries); free(mc, M_DEVBUF);