Convert lle rtchecks to use new routing API.
For inet/ case, this involves reverting r225947 which seem to be pretty strange commit and should be reverted in HEAD ad well.
This commit is contained in:
parent
69b74805d5
commit
064b1bdb2d
@ -498,6 +498,42 @@ fib4_lookup_nh_basic(uint32_t fibnum, struct in_addr dst, uint32_t flowid,
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
int
|
||||
fib4_lookup_nh_ifp(uint32_t fibnum, struct in_addr dst, uint32_t flowid,
|
||||
struct nhop4_basic *pnh4)
|
||||
{
|
||||
struct radix_node_head *rnh;
|
||||
struct radix_node *rn;
|
||||
struct sockaddr_in sin;
|
||||
struct rtentry *rte;
|
||||
|
||||
KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh_ifp: bad fibnum"));
|
||||
rnh = rt_tables_get_rnh(fibnum, AF_INET);
|
||||
if (rnh == NULL)
|
||||
return (ENOENT);
|
||||
|
||||
/* Prepare lookup key */
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_len = sizeof(struct sockaddr_in);
|
||||
sin.sin_addr = dst;
|
||||
|
||||
RADIX_NODE_HEAD_RLOCK(rnh);
|
||||
rn = rnh->rnh_matchaddr((void *)&sin, rnh);
|
||||
if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) {
|
||||
rte = RNTORT(rn);
|
||||
/* Ensure route & ifp is UP */
|
||||
if (RT_LINK_IS_UP(rte->rt_ifp)) {
|
||||
fib4_rte_to_nh_basic(rte, dst, pnh4);
|
||||
RADIX_NODE_HEAD_RUNLOCK(rnh);
|
||||
pnh4->nh_ifp = rte->rt_ifp;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
RADIX_NODE_HEAD_RUNLOCK(rnh);
|
||||
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Performs IPv4 route table lookup on @dst. Returns 0 on success.
|
||||
* Stores extende nexthop info provided @pnh4 structure.
|
||||
|
@ -169,6 +169,7 @@ struct nhop4_extended {
|
||||
uint64_t spare2[2];
|
||||
};
|
||||
|
||||
/* Does not differ from nhop6_basic */
|
||||
struct nhop6_extended {
|
||||
struct ifnet *nh_ifp; /* Logical egress interface */
|
||||
uint16_t nh_mtu; /* nexthop mtu */
|
||||
@ -178,6 +179,27 @@ struct nhop6_extended {
|
||||
uint64_t spare2[2];
|
||||
};
|
||||
|
||||
/* route info used for control plane purposes */
|
||||
struct rt4_basic {
|
||||
struct in_addr rt_addr; /* route prefix */
|
||||
struct in_addr rt_gateway; /* GW used */
|
||||
int rt_flags; /* Copy of rte flags */
|
||||
uint16_t rt_mtu;
|
||||
uint16_t rt_nhop; /* nexthop id (might bi mpath) */
|
||||
struct in_addr rt_mask; /* route mask */
|
||||
uint16_t spare[2];
|
||||
};
|
||||
|
||||
struct rt6_basic {
|
||||
struct in6_addr rt_addr;
|
||||
struct in6_addr rt_gateway;
|
||||
int rt_flags;
|
||||
uint16_t rt_mtu;
|
||||
uint16_t rt_nhop;
|
||||
uint8_t rt_mask;
|
||||
uint8_t spare[7];
|
||||
};
|
||||
|
||||
struct nhopu_extended {
|
||||
union {
|
||||
struct nhop4_extended nh4;
|
||||
@ -200,6 +222,8 @@ struct route_compat {
|
||||
int ro_flags;
|
||||
};
|
||||
|
||||
int fib4_lookup_nh_ifp(uint32_t fibnum, struct in_addr dst, uint32_t flowid,
|
||||
struct nhop4_basic *pnh4);
|
||||
int fib4_lookup_nh_basic(uint32_t fibnum, struct in_addr dst, uint32_t flowid,
|
||||
struct nhop4_basic *pnh4);
|
||||
int fib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst,
|
||||
|
@ -56,7 +56,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <net/if_llatbl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
#include <net/route_internal.h>
|
||||
#include <net/vnet.h>
|
||||
|
||||
#include <netinet/if_ether.h>
|
||||
@ -69,6 +68,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/udp_var.h>
|
||||
|
||||
#include <net/rt_nhops.h>
|
||||
|
||||
static int in_aifaddr_ioctl(u_long, caddr_t, struct ifnet *, struct thread *);
|
||||
static int in_difaddr_ioctl(caddr_t, struct ifnet *, struct thread *);
|
||||
|
||||
@ -1007,16 +1008,14 @@ in_lltable_prefix_free(struct lltable *llt, const struct sockaddr *prefix,
|
||||
static int
|
||||
in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr)
|
||||
{
|
||||
struct rtentry *rt;
|
||||
struct nhop4_basic nh4;
|
||||
struct in_addr dst;
|
||||
|
||||
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);
|
||||
|
||||
if (rt == NULL)
|
||||
dst = ((struct sockaddr_in *)l3addr)->sin_addr;
|
||||
if (fib4_lookup_nh_ifp(ifp->if_fib, dst, 0, &nh4) != 0)
|
||||
return (EINVAL);
|
||||
|
||||
/*
|
||||
@ -1024,57 +1023,26 @@ in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr
|
||||
* 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.
|
||||
* XXX: !RTF_HOST condition (temporarily) skipped.
|
||||
*/
|
||||
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,
|
||||
sizeof(in_addr_t)) != 0) {
|
||||
RTFREE_LOCKED(rt);
|
||||
if (nh4.nh_flags & NHF_GATEWAY) {
|
||||
if (nh4.nh_ifp->if_type != IFT_ETHER ||
|
||||
(nh4.nh_ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) != 0 ||
|
||||
nh4.nh_addr.s_addr != dst.s_addr) {
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure that at least the destination address is covered
|
||||
* by the route. This is for handling the case where 2 or more
|
||||
* interfaces have the same prefix. An incoming packet arrives
|
||||
* on one interface and the corresponding outgoing packet leaves
|
||||
* another interface.
|
||||
*/
|
||||
if (!(rt->rt_flags & RTF_HOST) && rt->rt_ifp != ifp) {
|
||||
const char *sa, *mask, *addr, *lim;
|
||||
int len;
|
||||
|
||||
mask = (const char *)rt_mask(rt);
|
||||
/*
|
||||
* Just being extra cautious to avoid some custom
|
||||
* code getting into trouble.
|
||||
*/
|
||||
if (mask == NULL) {
|
||||
RTFREE_LOCKED(rt);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
sa = (const char *)rt_key(rt);
|
||||
addr = (const char *)l3addr;
|
||||
len = ((const struct sockaddr_in *)l3addr)->sin_len;
|
||||
lim = addr + len;
|
||||
|
||||
for ( ; addr < lim; sa++, mask++, addr++) {
|
||||
if ((*sa ^ *addr) & *mask) {
|
||||
if (((nh4.nh_flags & NHF_GATEWAY) != 0) || nh4.nh_ifp != ifp) {
|
||||
#ifdef DIAGNOSTIC
|
||||
log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
|
||||
inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
|
||||
log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
|
||||
inet_ntoa(dst));
|
||||
#endif
|
||||
RTFREE_LOCKED(rt);
|
||||
return (EINVAL);
|
||||
}
|
||||
}
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
RTFREE_LOCKED(rt);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -108,6 +108,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet6/scope6_var.h>
|
||||
#include <netinet6/in6_pcb.h>
|
||||
|
||||
#include <net/rt_nhops.h>
|
||||
|
||||
VNET_DECLARE(int, icmp6_nodeinfo_oldmcprefix);
|
||||
#define V_icmp6_nodeinfo_oldmcprefix VNET(icmp6_nodeinfo_oldmcprefix)
|
||||
|
||||
@ -2166,17 +2168,20 @@ in6_lltable_rtcheck(struct ifnet *ifp,
|
||||
u_int flags,
|
||||
const struct sockaddr *l3addr)
|
||||
{
|
||||
struct rtentry *rt;
|
||||
struct nhop6_basic nh6;
|
||||
struct in6_addr dst;
|
||||
uint32_t scopeid;
|
||||
int error;
|
||||
char ip6buf[INET6_ADDRSTRLEN];
|
||||
|
||||
KASSERT(l3addr->sa_family == AF_INET6,
|
||||
("sin_family %d", l3addr->sa_family));
|
||||
|
||||
/* Our local addresses are always only installed on the default FIB. */
|
||||
/* XXX rtalloc1 should take a const param */
|
||||
rt = in6_rtalloc1(__DECONST(struct sockaddr *, l3addr), 0, 0,
|
||||
RT_DEFAULT_FIB);
|
||||
if (rt == NULL || (rt->rt_flags & RTF_GATEWAY) || rt->rt_ifp != ifp) {
|
||||
|
||||
in6_splitscope(&((struct sockaddr_in6 *)l3addr)->sin6_addr, &dst, &scopeid);
|
||||
error = fib6_lookup_nh_ifp(RT_DEFAULT_FIB, &dst, scopeid, 0, &nh6);
|
||||
if (error != 0 || ((nh6.nh_flags & NHF_GATEWAY) != 0) || nh6.nh_ifp != ifp) {
|
||||
struct ifaddr *ifa;
|
||||
/*
|
||||
* Create an ND6 cache for an IPv6 neighbor
|
||||
@ -2186,17 +2191,12 @@ in6_lltable_rtcheck(struct ifnet *ifp,
|
||||
ifa = ifaof_ifpforaddr(__DECONST(struct sockaddr *, l3addr), ifp);
|
||||
if (ifa != NULL) {
|
||||
ifa_free(ifa);
|
||||
if (rt != NULL)
|
||||
RTFREE_LOCKED(rt);
|
||||
return 0;
|
||||
}
|
||||
log(LOG_INFO, "IPv6 address: \"%s\" is not on the network\n",
|
||||
ip6_sprintf(ip6buf, &((const struct sockaddr_in6 *)l3addr)->sin6_addr));
|
||||
if (rt != NULL)
|
||||
RTFREE_LOCKED(rt);
|
||||
return EINVAL;
|
||||
}
|
||||
RTFREE_LOCKED(rt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user