svn commit: r193423 - in user/kmacy/releng_7_2_fcs/sys: net netinet
netinet6
Kip Macy
kmacy at FreeBSD.org
Thu Jun 4 04:00:30 UTC 2009
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;
More information about the svn-src-user
mailing list