From 13e255fab7ed6787771c1ffebed568759a3ba22b Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Fri, 8 Jul 2011 09:38:33 +0000 Subject: [PATCH] Permit ARP to proceed for IPv4 host routes for which the gateway is the same as the host address. This already works fine for INET6 and ND6. While here, remove two function pointers from struct lltable which are only initialized but never used. MFC after: 3 days --- sys/net/if_llatbl.h | 3 --- sys/netinet/in.c | 14 ++++++++++++-- sys/netinet6/in6.c | 2 -- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/sys/net/if_llatbl.h b/sys/net/if_llatbl.h index 1f30f37bafc..4b183533236 100644 --- a/sys/net/if_llatbl.h +++ b/sys/net/if_llatbl.h @@ -151,7 +151,6 @@ struct lltable { int llt_af; struct ifnet *llt_ifp; - 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, @@ -159,8 +158,6 @@ struct lltable { u_int flags); struct llentry * (*llt_lookup)(struct lltable *, u_int flags, const struct sockaddr *l3addr); - int (*llt_rtcheck)(struct ifnet *, u_int flags, - const struct sockaddr *); int (*llt_dump)(struct lltable *, struct sysctl_req *); }; diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 7ae8477cd10..c0901178d99 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -1416,6 +1416,18 @@ in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr /* XXX rtalloc1 should take a const param */ rt = rtalloc1(__DECONST(struct sockaddr *, l3addr), 0, 0); + + /* + * If the gateway for an existing host route matches the target L3 + * address, allow for ARP to proceed. + */ + if (rt != NULL && (rt->rt_flags & (RTF_HOST|RTF_GATEWAY)) && + rt->rt_gateway->sa_family == AF_INET && + memcmp(rt->rt_gateway->sa_data, l3addr->sa_data, 4) == 0) { + RTFREE_LOCKED(rt); + return (0); + } + if (rt == NULL || (!(flags & LLE_PUB) && ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_ifp != ifp)))) { @@ -1599,10 +1611,8 @@ in_domifattach(struct ifnet *ifp) llt = lltable_init(ifp, AF_INET); 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; } diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 9558d1ba8a1..39e77e999b8 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -2636,10 +2636,8 @@ in6_domifattach(struct ifnet *ifp) ext->scope6_id = scope6_ifattach(ifp); ext->lltable = lltable_init(ifp, AF_INET6); 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; }