summaryrefslogtreecommitdiffstats
path: root/sys/netinet/in.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/in.c')
-rw-r--r--sys/netinet/in.c48
1 files changed, 29 insertions, 19 deletions
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index c30c1f3..80b1448 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -1106,34 +1106,48 @@ in_lltable_free_entry(struct lltable *llt, struct llentry *lle)
static int
in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr)
{
- struct rtentry *rt;
+ struct rt_addrinfo info;
+ struct sockaddr_in rt_key, rt_mask;
+ struct sockaddr rt_gateway;
+ int rt_flags;
KASSERT(l3addr->sa_family == AF_INET,
("sin_family %d", l3addr->sa_family));
- /* XXX rtalloc1_fib should take a const param */
- rt = rtalloc1_fib(__DECONST(struct sockaddr *, l3addr), 0, 0,
- ifp->if_fib);
+ bzero(&rt_key, sizeof(rt_key));
+ rt_key.sin_len = sizeof(rt_key);
+ bzero(&rt_mask, sizeof(rt_mask));
+ rt_mask.sin_len = sizeof(rt_mask);
+ bzero(&rt_gateway, sizeof(rt_gateway));
+ rt_gateway.sa_len = sizeof(rt_gateway);
- if (rt == NULL)
+ bzero(&info, sizeof(info));
+ info.rti_info[RTAX_DST] = (struct sockaddr *)&rt_key;
+ info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&rt_mask;
+ info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&rt_gateway;
+
+ if (rib_lookup_info(ifp->if_fib, l3addr, NHR_REF, 0, &info) != 0)
return (EINVAL);
+ rt_flags = info.rti_flags;
+
/*
* If the gateway for an existing host route matches the target L3
* address, which is a special route inserted by some implementation
* such as MANET, and the interface is of the correct type, then
* allow for ARP to proceed.
*/
- if (rt->rt_flags & RTF_GATEWAY) {
- if (!(rt->rt_flags & RTF_HOST) || !rt->rt_ifp ||
- rt->rt_ifp->if_type != IFT_ETHER ||
- (rt->rt_ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) != 0 ||
- memcmp(rt->rt_gateway->sa_data, l3addr->sa_data,
+ if (rt_flags & RTF_GATEWAY) {
+ if (!(rt_flags & RTF_HOST) || !info.rti_ifp ||
+ info.rti_ifp->if_type != IFT_ETHER ||
+ (info.rti_ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) != 0 ||
+ memcmp(rt_gateway.sa_data, l3addr->sa_data,
sizeof(in_addr_t)) != 0) {
- RTFREE_LOCKED(rt);
+ rib_free_info(&info);
return (EINVAL);
}
}
+ rib_free_info(&info);
/*
* Make sure that at least the destination address is covered
@@ -1142,21 +1156,19 @@ in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr
* on one interface and the corresponding outgoing packet leaves
* another interface.
*/
- if (!(rt->rt_flags & RTF_HOST) && rt->rt_ifp != ifp) {
+ if (!(rt_flags & RTF_HOST) && info.rti_ifp != ifp) {
const char *sa, *mask, *addr, *lim;
int len;
- mask = (const char *)rt_mask(rt);
+ mask = (const char *)&rt_mask;
/*
* Just being extra cautious to avoid some custom
* code getting into trouble.
*/
- if (mask == NULL) {
- RTFREE_LOCKED(rt);
+ if ((info.rti_addrs & RTA_NETMASK) == 0)
return (EINVAL);
- }
- sa = (const char *)rt_key(rt);
+ sa = (const char *)&rt_key;
addr = (const char *)l3addr;
len = ((const struct sockaddr_in *)l3addr)->sin_len;
lim = addr + len;
@@ -1167,13 +1179,11 @@ in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr
log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
#endif
- RTFREE_LOCKED(rt);
return (EINVAL);
}
}
}
- RTFREE_LOCKED(rt);
return (0);
}
OpenPOWER on IntegriCloud