aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMarko Zec <zec@FreeBSD.org>2011-07-08 09:38:33 +0000
committerMarko Zec <zec@FreeBSD.org>2011-07-08 09:38:33 +0000
commit13e255fab7ed6787771c1ffebed568759a3ba22b (patch)
treeaad8ef2126dd98c18ff880e797ec2c49495f9e91 /sys
parent728fc2d6330af42ad3e0655c9ac41868c6dd0028 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if_llatbl.h3
-rw-r--r--sys/netinet/in.c14
-rw-r--r--sys/netinet6/in6.c2
3 files changed, 12 insertions, 7 deletions
diff --git a/sys/net/if_llatbl.h b/sys/net/if_llatbl.h
index 1f30f37bafc2..4b1835332368 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 7ae8477cd101..c0901178d990 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 9558d1ba8a1d..39e77e999b8f 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;
}