svn commit: r287065 - in projects/routing/sys: net netinet netinet6
Alexander V. Chernikov
melifaro at FreeBSD.org
Sun Aug 23 18:27:30 UTC 2015
Author: melifaro
Date: Sun Aug 23 18:27:28 2015
New Revision: 287065
URL: https://svnweb.freebsd.org/changeset/base/287065
Log:
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.
Modified:
projects/routing/sys/net/rt_nhops.c
projects/routing/sys/net/rt_nhops.h
projects/routing/sys/netinet/in.c
projects/routing/sys/netinet6/in6.c
Modified: projects/routing/sys/net/rt_nhops.c
==============================================================================
--- projects/routing/sys/net/rt_nhops.c Sun Aug 23 18:26:42 2015 (r287064)
+++ projects/routing/sys/net/rt_nhops.c Sun Aug 23 18:27:28 2015 (r287065)
@@ -498,6 +498,42 @@ fib4_lookup_nh_basic(uint32_t fibnum, st
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.
Modified: projects/routing/sys/net/rt_nhops.h
==============================================================================
--- projects/routing/sys/net/rt_nhops.h Sun Aug 23 18:26:42 2015 (r287064)
+++ projects/routing/sys/net/rt_nhops.h Sun Aug 23 18:27:28 2015 (r287065)
@@ -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,
Modified: projects/routing/sys/netinet/in.c
==============================================================================
--- projects/routing/sys/netinet/in.c Sun Aug 23 18:26:42 2015 (r287064)
+++ projects/routing/sys/netinet/in.c Sun Aug 23 18:27:28 2015 (r287065)
@@ -58,7 +58,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>
@@ -71,6 +70,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 *);
@@ -1037,16 +1038,14 @@ in_lltable_prefix_free(struct lltable *l
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 = ((const struct sockaddr_in *)l3addr)->sin_addr;
+ if (fib4_lookup_nh_ifp(ifp->if_fib, dst, 0, &nh4) != 0)
return (EINVAL);
/*
@@ -1054,57 +1053,26 @@ in_lltable_rtcheck(struct ifnet *ifp, u_
* 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);
- return (EINVAL);
- }
- }
-
- /*
- * 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);
+ 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);
}
- sa = (const char *)rt_key(rt);
- addr = (const char *)l3addr;
- len = ((const struct sockaddr_in *)l3addr)->sin_len;
- lim = addr + len;
+ return (0);
+ }
- 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);
}
Modified: projects/routing/sys/netinet6/in6.c
==============================================================================
--- projects/routing/sys/netinet6/in6.c Sun Aug 23 18:26:42 2015 (r287064)
+++ projects/routing/sys/netinet6/in6.c Sun Aug 23 18:27:28 2015 (r287065)
@@ -110,6 +110,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)
@@ -2146,17 +2148,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(&((const 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
@@ -2166,17 +2171,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;
}
More information about the svn-src-projects
mailing list