PERFORCE change 80553 for review
Robert Watson
rwatson at FreeBSD.org
Tue Jul 19 21:23:35 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=80553
Change 80553 by rwatson at rwatson_zoo on 2005/07/19 21:22:39
Merge change 80537 from rwatson_netperf to netsmp:
Re-formulate and lock down if_delmulti().
Comment on an inconsistency or two in the implementation.
Affected files ...
.. //depot/projects/netsmp/src/sys/net/if.c#3 edit
Differences ...
==== //depot/projects/netsmp/src/sys/net/if.c#3 (text+ko) ====
@@ -2023,6 +2023,8 @@
/*
* Must generate the message while holding the lock so that 'ifma'
* pointer is still valid.
+ *
+ * XXXRW: How come we don't announce ll_ifma?
*/
rt_newmaddrmsg(RTM_NEWMADDR, ifma);
IF_ADDR_UNLOCK(ifp);
@@ -2049,72 +2051,50 @@
int
if_delmulti(struct ifnet *ifp, struct sockaddr *sa)
{
- struct ifmultiaddr *ifma;
- int s;
+ struct ifmultiaddr *ifma, *ll_ifma;
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
- if (sa_equal(sa, ifma->ifma_addr))
- break;
- if (ifma == NULL)
+ IF_ADDR_LOCK(ifp);
+ ifma = if_findmulti(ifp, sa);
+ if (ifma == NULL) {
+ IF_ADDR_UNLOCK(ifp);
return ENOENT;
+ }
if (ifma->ifma_refcount > 1) {
ifma->ifma_refcount--;
+ IF_ADDR_UNLOCK(ifp);
return 0;
}
- rt_newmaddrmsg(RTM_DELMADDR, ifma);
sa = ifma->ifma_lladdr;
- s = splimp();
- TAILQ_REMOVE(&ifp->if_multiaddrs, ifma, ifma_link);
+ ll_ifma = if_findmulti(ifp, sa);
+
/*
- * Make sure the interface driver is notified
- * in the case of a link layer mcast group being left.
+ * XXXRW: How come we don't announce ll_ifma?
*/
- if (ifp->if_ioctl && ifma->ifma_addr->sa_family == AF_LINK && sa == 0) {
- IFF_LOCKGIANT(ifp);
- (void) (*ifp->if_ioctl)(ifp, SIOCDELMULTI, 0);
- IFF_UNLOCKGIANT(ifp);
+ rt_newmaddrmsg(RTM_DELMADDR, ifma);
+
+ TAILQ_REMOVE(&ifp->if_multiaddrs, ifma, ifma_link);
+ if_freemulti(ifma);
+
+ if (ll_ifma != NULL) {
+ if (ll_ifma->ifma_refcount == 1) {
+ TAILQ_REMOVE(&ifp->if_multiaddrs, ll_ifma, ifma_link);
+ if_freemulti(ll_ifma);
+ } else
+ ll_ifma->ifma_refcount--;
}
- splx(s);
- free(ifma->ifma_addr, M_IFMADDR);
- free(ifma, M_IFMADDR);
- if (sa == NULL)
- return 0;
+ IF_ADDR_UNLOCK(ifp);
/*
- * Now look for the link-layer address which corresponds to
- * this network address. It had been squirreled away in
- * ifma->ifma_lladdr for this purpose (so we don't have
- * to call ifp->if_resolvemulti() again), and we saved that
- * value in sa above. If some nasty deleted the
- * link-layer address out from underneath us, we can deal because
- * the address we stored was is not the same as the one which was
- * in the record for the link-layer address. (So we don't complain
- * in that case.)
+ * Make sure the interface driver is notified
+ * in the case of a link layer mcast group being left.
*/
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
- if (sa_equal(sa, ifma->ifma_addr))
- break;
- if (ifma == NULL)
- return 0;
-
- if (ifma->ifma_refcount > 1) {
- ifma->ifma_refcount--;
- return 0;
- }
-
- s = splimp();
- TAILQ_REMOVE(&ifp->if_multiaddrs, ifma, ifma_link);
- if (ifp->if_ioctl != NULL) {
+ if (ifp->if_ioctl) {
IFF_LOCKGIANT(ifp);
(void) (*ifp->if_ioctl)(ifp, SIOCDELMULTI, 0);
IFF_UNLOCKGIANT(ifp);
}
- splx(s);
- free(ifma->ifma_addr, M_IFMADDR);
- free(sa, M_IFMADDR);
- free(ifma, M_IFMADDR);
return 0;
}
More information about the p4-projects
mailing list