Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 Jun 2009 04:00:29 +0000 (UTC)
From:      Kip Macy <kmacy@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r193423 - in user/kmacy/releng_7_2_fcs/sys: net netinet netinet6
Message-ID:  <200906040400.n5440TV3076520@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kmacy
Date: Thu Jun  4 04:00:29 2009
New Revision: 193423
URL: http://svn.freebsd.org/changeset/base/193423

Log:
  MFC L2 prefix cleanup and dhcp fixes

Modified:
  user/kmacy/releng_7_2_fcs/sys/net/if_llatbl.c
  user/kmacy/releng_7_2_fcs/sys/net/if_llatbl.h
  user/kmacy/releng_7_2_fcs/sys/netinet/in.c
  user/kmacy/releng_7_2_fcs/sys/netinet6/in6.c

Modified: user/kmacy/releng_7_2_fcs/sys/net/if_llatbl.c
==============================================================================
--- user/kmacy/releng_7_2_fcs/sys/net/if_llatbl.c	Thu Jun  4 03:59:20 2009	(r193422)
+++ user/kmacy/releng_7_2_fcs/sys/net/if_llatbl.c	Thu Jun  4 04:00:29 2009	(r193423)
@@ -195,6 +195,23 @@ lltable_drain(int af)
 	IFNET_RUNLOCK();
 }
 
+void
+lltable_prefix_free(int af, struct sockaddr *prefix, struct sockaddr *mask)
+{
+	struct lltable *llt;
+
+	IFNET_RLOCK();
+	SLIST_FOREACH(llt, &lltables, llt_link) {
+		if (llt->llt_af != af)
+			continue;
+
+		llt->llt_prefix_free(llt, prefix, mask);
+	}
+	IFNET_RUNLOCK();
+}
+
+
+
 /*
  * Create a new lltable.
  */

Modified: user/kmacy/releng_7_2_fcs/sys/net/if_llatbl.h
==============================================================================
--- user/kmacy/releng_7_2_fcs/sys/net/if_llatbl.h	Thu Jun  4 03:59:20 2009	(r193422)
+++ user/kmacy/releng_7_2_fcs/sys/net/if_llatbl.h	Thu Jun  4 04:00:29 2009	(r193423)
@@ -147,6 +147,9 @@ struct lltable {
 
 	struct llentry *	(*llt_new)(const struct sockaddr *, u_int);
 	void			(*llt_free)(struct lltable *, struct llentry *);
+	void			(*llt_prefix_free)(struct lltable *,
+				    const struct sockaddr *prefix,
+				    const struct sockaddr *mask);
 	struct llentry *	(*llt_lookup)(struct lltable *, u_int flags,
 				    const struct sockaddr *l3addr);
 	int			(*llt_rtcheck)(struct ifnet *,
@@ -174,6 +177,8 @@ MALLOC_DECLARE(M_LLTABLE);
 
 struct lltable *lltable_init(struct ifnet *, int);
 void		lltable_free(struct lltable *);
+void		lltable_prefix_free(int, struct sockaddr *, 
+                       struct sockaddr *);
 void		lltable_drain(int);
 int		lltable_sysctl_dumparp(int, struct sysctl_req *);
 

Modified: user/kmacy/releng_7_2_fcs/sys/netinet/in.c
==============================================================================
--- user/kmacy/releng_7_2_fcs/sys/netinet/in.c	Thu Jun  4 03:59:20 2009	(r193422)
+++ user/kmacy/releng_7_2_fcs/sys/netinet/in.c	Thu Jun  4 04:00:29 2009	(r193423)
@@ -927,6 +927,7 @@ in_scrubprefix(struct in_ifaddr *target)
 	struct in_ifaddr *ia;
 	struct in_addr prefix, mask, p;
 	int error;
+	struct sockaddr_in prefix0, mask0;
 	struct rt_addrinfo info;
 	struct sockaddr_dl null_sdl;
 
@@ -996,6 +997,20 @@ in_scrubprefix(struct in_ifaddr *target)
 	}
 
 	/*
+	 * remove all L2 entries on the given prefix
+	 */
+	bzero(&prefix0, sizeof(prefix0));
+	prefix0.sin_len = sizeof(prefix0);
+	prefix0.sin_family = AF_INET;
+	prefix0.sin_addr.s_addr = target->ia_subnet;
+	bzero(&mask0, sizeof(mask0));
+	mask0.sin_len = sizeof(mask0);
+	mask0.sin_family = AF_INET;
+	mask0.sin_addr.s_addr = target->ia_subnetmask;
+	lltable_prefix_free(AF_INET, (struct sockaddr *)&prefix0, 
+			    (struct sockaddr *)&mask0);
+
+	/*
 	 * As no-one seem to have this prefix, we can remove the route.
 	 */
 	rtinit(&(target->ia_ifa), (int)RTM_DELETE, rtinitflags(target));
@@ -1121,6 +1136,34 @@ in_lltable_free(struct lltable *llt, str
 	free(lle, M_LLTABLE);
 }
 
+
+#define IN_ARE_MASKED_ADDR_EQUAL(d, a, m)	(			\
+	    (((ntohl((d)->sin_addr.s_addr) ^ (a)->sin_addr.s_addr) & (m)->sin_addr.s_addr)) == 0 )
+
+static void
+in_lltable_prefix_free(struct lltable *llt, 
+		       const struct sockaddr *prefix,
+		       const struct sockaddr *mask)
+{
+	const struct sockaddr_in *pfx = (const struct sockaddr_in *)prefix;
+	const struct sockaddr_in *msk = (const struct sockaddr_in *)mask;
+	struct llentry *lle, *next;
+	register int i;
+
+	for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
+		LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
+
+			if (IN_ARE_MASKED_ADDR_EQUAL((struct sockaddr_in *)L3_ADDR(lle), 
+						     pfx, msk)) {
+				callout_drain(&lle->la_timer);
+				LLE_WLOCK(lle);
+				llentry_free(lle);
+			}
+		}
+	}
+}
+
+
 static int
 in_lltable_rtcheck(struct ifnet *ifp, const struct sockaddr *l3addr)
 {
@@ -1307,6 +1350,7 @@ in_domifattach(struct ifnet *ifp)
 	if (llt != NULL) {
 		llt->llt_new = in_lltable_new;
 		llt->llt_free = in_lltable_free;
+		llt->llt_prefix_free = in_lltable_prefix_free;
 		llt->llt_rtcheck = in_lltable_rtcheck;
 		llt->llt_lookup = in_lltable_lookup;
 		llt->llt_dump = in_lltable_dump;

Modified: user/kmacy/releng_7_2_fcs/sys/netinet6/in6.c
==============================================================================
--- user/kmacy/releng_7_2_fcs/sys/netinet6/in6.c	Thu Jun  4 03:59:20 2009	(r193422)
+++ user/kmacy/releng_7_2_fcs/sys/netinet6/in6.c	Thu Jun  4 04:00:29 2009	(r193423)
@@ -2297,6 +2297,30 @@ in6_lltable_free(struct lltable *llt, st
 	free(lle, M_LLTABLE);
 }
 
+static void
+in6_lltable_prefix_free(struct lltable *llt, 
+			const struct sockaddr *prefix,
+			const struct sockaddr *mask)
+{
+	const struct sockaddr_in6 *pfx = (const struct sockaddr_in6 *)prefix;
+	const struct sockaddr_in6 *msk = (const struct sockaddr_in6 *)mask;
+	struct llentry *lle, *next;
+	register int i;
+
+	for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
+		LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
+			if (IN6_ARE_MASKED_ADDR_EQUAL(
+				    &((struct sockaddr_in6 *)L3_ADDR(lle))->sin6_addr, 
+				    &pfx->sin6_addr, 
+				    &msk->sin6_addr)) {
+				callout_drain(&lle->la_timer);
+				LLE_WLOCK(lle);
+				llentry_free(lle);
+			}
+		}
+	}
+}
+
 static int
 in6_lltable_rtcheck(struct ifnet *ifp, const struct sockaddr *l3addr)
 {
@@ -2503,6 +2527,7 @@ in6_domifattach(struct ifnet *ifp)
 	if (ext->lltable != NULL) {
 		ext->lltable->llt_new = in6_lltable_new;
 		ext->lltable->llt_free = in6_lltable_free;
+		ext->lltable->llt_prefix_free = in6_lltable_prefix_free;
 		ext->lltable->llt_rtcheck = in6_lltable_rtcheck;
 		ext->lltable->llt_lookup = in6_lltable_lookup;
 		ext->lltable->llt_dump = in6_lltable_dump;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906040400.n5440TV3076520>