svn commit: r274212 - in projects/routing/sys: net netgraph/netflow
Alexander V. Chernikov
melifaro at FreeBSD.org
Fri Nov 7 02:04:49 UTC 2014
Author: melifaro
Date: Fri Nov 7 02:04:48 2014
New Revision: 274212
URL: https://svnweb.freebsd.org/changeset/base/274212
Log:
Add new rib4/rib6 series of functions returning per-rte info
packed on stack.
Convert ng_netflow to use new routing API.
Modified:
projects/routing/sys/net/rt_nhops.c
projects/routing/sys/net/rt_nhops.h
projects/routing/sys/netgraph/netflow/netflow.c
Modified: projects/routing/sys/net/rt_nhops.c
==============================================================================
--- projects/routing/sys/net/rt_nhops.c Fri Nov 7 01:48:12 2014 (r274211)
+++ projects/routing/sys/net/rt_nhops.c Fri Nov 7 02:04:48 2014 (r274212)
@@ -117,6 +117,8 @@ int fwd_destroy_fib(struct fwd_module *f
static inline uint16_t fib_rte_to_nh_flags(int rt_flags);
#ifdef INET
+static void rib4_rte_to_nh_extended(struct rtentry *rte, struct in_addr dst,
+ struct rt4_extended *prt4);
static void fib4_rte_to_nh_extended(struct rtentry *rte, struct in_addr dst,
struct nhop4_extended *pnh4);
static void fib4_rte_to_nh_basic(struct rtentry *rte, struct in_addr dst,
@@ -452,6 +454,39 @@ fib4_rte_to_nh_extended(struct rtentry *
pnh4->nh_src = IA_SIN(ia)->sin_addr;
}
+static void
+rib4_rte_to_nh_extended(struct rtentry *rte, struct in_addr dst,
+ struct rt4_extended *prt4)
+{
+ struct sockaddr_in *gw;
+ struct in_ifaddr *ia;
+
+ /* Do explicit nexthop zero unless we're copying it */
+ memset(prt4, 0, sizeof(*prt4));
+
+ gw = ((struct sockaddr_in *)rt_key(rte));
+ prt4->rt_addr = gw->sin_addr;
+ gw = ((struct sockaddr_in *)rt_mask(rte));
+ prt4->rt_mask.s_addr = (gw != NULL) ?
+ gw->sin_addr.s_addr : INADDR_BROADCAST;
+
+ if (rte->rt_flags & RTF_GATEWAY) {
+ gw = (struct sockaddr_in *)rte->rt_gateway;
+ prt4->rt_gateway = gw->sin_addr;
+ } else
+ prt4->rt_gateway = dst;
+
+ prt4->rt_lifp = rte->rt_ifp;
+ prt4->rt_aifp = rte->rt_ifa->ifa_ifp;
+ prt4->rt_flags = rte->rt_flags;
+ prt4->rt_mtu = min(rte->rt_mtu, rte->rt_ifp->if_mtu);
+
+ prt4->rt_nhop = 0; /* XXX: fill real nexthop */
+
+ ia = ifatoia(rte->rt_ifa);
+ prt4->rt_src = IA_SIN(ia)->sin_addr;
+}
+
/*
* Performs IPv4 route table lookup on @dst. Returns 0 on success.
* Stores nexthop info provided @pnh4 structure.
@@ -588,6 +623,50 @@ fib4_free_nh_ext(uint32_t fibnum, struct
}
+int
+rib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst, uint32_t flowid,
+ uint32_t flags, struct rt4_extended *prt4)
+{
+ struct radix_node_head *rnh;
+ struct radix_node *rn;
+ struct sockaddr_in sin;
+ struct rtentry *rte;
+
+ KASSERT((fibnum < rt_numfibs), ("rib4_lookup_nh_ext: 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)) {
+ rib4_rte_to_nh_extended(rte, dst, prt4);
+ if ((flags & NHOP_LOOKUP_REF) != 0) {
+ /* TODO: Do lwref on egress ifp's */
+ }
+ RADIX_NODE_HEAD_RUNLOCK(rnh);
+ return (0);
+ }
+ }
+ RADIX_NODE_HEAD_RUNLOCK(rnh);
+
+ return (ENOENT);
+}
+
+void
+rib4_free_nh_ext(uint32_t fibnum, struct rt4_extended *prt4)
+{
+
+}
+
#endif
#ifdef INET6
@@ -898,6 +977,36 @@ fib6_lla_to_nh_extended(struct in6_addr
}
static int
+rib6_lla_to_nh_extended(struct in6_addr *dst, uint32_t scopeid,
+ struct rt6_extended *prt6)
+{
+ struct ifnet *ifp;
+
+ ifp = ifnet_byindex_locked(scopeid);
+ if (ifp == NULL)
+ return (ENOENT);
+
+ /* Do explicit nexthop zero unless we're copying it */
+ memset(prt6, 0, sizeof(*prt6));
+
+ prt6->rt_addr.s6_addr16[0] = htons(0xFE80);
+ prt6->rt_mask = 64; /* XXX check RFC */
+
+ prt6->rt_aifp = ifp;
+ prt6->rt_lifp = ifp;
+ /* Check id this is for-us address */
+ if (in6_ifawithifp_lla(ifp, dst)) {
+ if ((ifp = V_loif) != NULL)
+ prt6->rt_lifp = ifp;
+ }
+
+ prt6->rt_mtu = IN6_LINKMTU(ifp);
+ /* No flags set */
+
+ return (0);
+}
+
+static int
fib6_lla_to_nh(struct in6_addr *dst, uint32_t scopeid,
struct nhop_prepend *nh, struct ifnet **lifp)
{
@@ -979,6 +1088,37 @@ fib6_rte_to_nh_extended(struct rtentry *
ia = ifatoia6(rte->rt_ifa);
}
+#define ipv6_masklen(x) bitcount32((x).__u6_addr.__u6_addr32[0]) + \
+ bitcount32((x).__u6_addr.__u6_addr32[1]) + \
+ bitcount32((x).__u6_addr.__u6_addr32[2]) + \
+ bitcount32((x).__u6_addr.__u6_addr32[3])
+static void
+rib6_rte_to_nh_extended(struct rtentry *rte, struct in6_addr *dst,
+ struct rt6_extended *prt6)
+{
+ struct sockaddr_in6 *gw;
+
+ /* Do explicit nexthop zero unless we're copying it */
+ memset(prt6, 0, sizeof(*prt6));
+
+ gw = ((struct sockaddr_in6 *)rt_key(rte));
+ prt6->rt_addr = gw->sin6_addr;
+ gw = ((struct sockaddr_in6 *)rt_mask(rte));
+ prt6->rt_mask = (gw != NULL) ? ipv6_masklen(gw->sin6_addr) : 128;
+
+ if (rte->rt_flags & RTF_GATEWAY) {
+ gw = (struct sockaddr_in6 *)rte->rt_gateway;
+ prt6->rt_gateway = gw->sin6_addr;
+ in6_clearscope(&prt6->rt_gateway);
+ } else
+ prt6->rt_gateway = *dst;
+
+ prt6->rt_lifp = rte->rt_ifp;
+ prt6->rt_aifp = ifnet_byindex(fib6_get_ifa(rte));
+ prt6->rt_flags = fib_rte_to_nh_flags(rte->rt_flags);
+ prt6->rt_mtu = min(rte->rt_mtu, IN6_LINKMTU(rte->rt_ifp));
+}
+
int
fib6_lookup_nh_ifp(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid,
uint32_t flowid, struct nhop6_basic *pnh6)
@@ -990,6 +1130,7 @@ fib6_lookup_nh_ifp(uint32_t fibnum, stru
if (IN6_IS_SCOPE_LINKLOCAL(dst)) {
/* Do not lookup link-local addresses in rtable */
+ /* XXX: Check if dst is local */
return (fib6_lla_to_nh_basic(dst, scopeid, pnh6));
}
@@ -1124,6 +1265,59 @@ fib6_free_nh_ext(uint32_t fibnum, struct
}
+int
+rib6_lookup_nh_ext(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid,
+ uint32_t flowid, uint32_t flags, struct rt6_extended *prt6)
+{
+ struct radix_node_head *rnh;
+ struct radix_node *rn;
+ struct sockaddr_in6 sin6;
+ struct rtentry *rte;
+
+ if (IN6_IS_SCOPE_LINKLOCAL(dst)) {
+ /* Do not lookup link-local addresses in rtable */
+ /* XXX: Do lwref on egress ifp */
+ return (rib6_lla_to_nh_extended(dst, scopeid, prt6));
+ }
+
+ KASSERT((fibnum < rt_numfibs), ("rib6_lookup_nh_ext: bad fibnum"));
+ rnh = rt_tables_get_rnh(fibnum, AF_INET6);
+ if (rnh == NULL)
+ return (ENOENT);
+
+ /* Prepare lookup key */
+ memset(&sin6, 0, sizeof(sin6));
+ sin6.sin6_len = sizeof(struct sockaddr_in6);
+ sin6.sin6_addr = *dst;
+ sin6.sin6_scope_id = scopeid;
+ sa6_embedscope(&sin6, 0);
+
+ RADIX_NODE_HEAD_RLOCK(rnh);
+ rn = rnh->rnh_matchaddr((void *)&sin6, 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)) {
+ rib6_rte_to_nh_extended(rte, dst, prt6);
+ if ((flags & NHOP_LOOKUP_REF) != 0) {
+ /* TODO: Do lwref on egress ifp's */
+ }
+ RADIX_NODE_HEAD_RUNLOCK(rnh);
+
+ return (0);
+ }
+ }
+ RADIX_NODE_HEAD_RUNLOCK(rnh);
+
+ return (ENOENT);
+}
+
+void
+rib6_free_nh_ext(uint32_t fibnum, struct nhop6_extended *prt6)
+{
+
+}
+
#endif
void
Modified: projects/routing/sys/net/rt_nhops.h
==============================================================================
--- projects/routing/sys/net/rt_nhops.h Fri Nov 7 01:48:12 2014 (r274211)
+++ projects/routing/sys/net/rt_nhops.h Fri Nov 7 02:04:48 2014 (r274212)
@@ -180,23 +180,28 @@ struct nhop6_extended {
};
/* route info used for control plane purposes */
-struct rt4_basic {
+struct rt4_extended {
struct in_addr rt_addr; /* route prefix */
struct in_addr rt_gateway; /* GW used */
+ struct ifnet *rt_lifp; /* logical interface */
+ struct ifnet *rt_aifp; /* address interface */
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 */
+ struct in_addr rt_src;
uint16_t spare[2];
};
-struct rt6_basic {
+struct rt6_extended {
struct in6_addr rt_addr;
struct in6_addr rt_gateway;
+ struct ifnet *rt_lifp; /* logical interface */
+ struct ifnet *rt_aifp; /* address interface */
int rt_flags;
uint16_t rt_mtu;
uint16_t rt_nhop;
- uint8_t rt_mask;
+ uint8_t rt_mask; /*Hopefully, no more non-config masks */
uint8_t spare[7];
};
@@ -230,6 +235,9 @@ int fib4_lookup_nh_ext(uint32_t fibnum,
uint32_t flowid, uint32_t flags, struct nhop4_extended *pnh4);
void fib4_free_nh_ext(uint32_t fibnum, struct nhop4_extended *pnh4);
#define NHOP_LOOKUP_REF 0x01
+int rib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst, uint32_t flowid,
+ uint32_t flags, struct rt4_extended *prt4);
+void rib4_free_nh_ext(uint32_t fibnum, struct rt4_extended *prt4);
int fib6_lookup_nh_ifp(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid,
@@ -240,6 +248,9 @@ int fib6_lookup_nh_ext(uint32_t fibnum,
uint32_t scopeid, uint32_t flowid, uint32_t flags,
struct nhop6_extended *pnh6);
void fib6_free_nh_ext(uint32_t fibnum, struct nhop6_extended *pnh6);
+int rib6_lookup_nh_ext(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid,
+ uint32_t flowid, uint32_t flags, struct rt6_extended *prt6);
+void rib6_free_nh_ext(uint32_t fibnum, struct nhop6_extended *prt6);
void fib_free_nh_ext(uint32_t fibnum, struct nhopu_extended *pnhu);
Modified: projects/routing/sys/netgraph/netflow/netflow.c
==============================================================================
--- projects/routing/sys/netgraph/netflow/netflow.c Fri Nov 7 01:48:12 2014 (r274211)
+++ projects/routing/sys/netgraph/netflow/netflow.c Fri Nov 7 02:04:48 2014 (r274212)
@@ -45,7 +45,6 @@ __FBSDID("$FreeBSD$");
#include <net/if.h>
#include <net/if_var.h>
#include <net/route.h>
-#include <net/route_internal.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
@@ -53,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip6.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
+#include <net/rt_nhops.h>
#include <netgraph/ng_message.h>
#include <netgraph/netgraph.h>
@@ -307,8 +307,7 @@ hash_insert(priv_p priv, struct flow_has
int plen, uint8_t flags, uint8_t tcp_flags)
{
struct flow_entry *fle;
- struct sockaddr_in sin;
- struct rtentry *rt;
+ struct rt4_extended rt4;
mtx_assert(&hsh->mtx, MA_OWNED);
@@ -335,46 +334,20 @@ hash_insert(priv_p priv, struct flow_has
* fill in out_ifx, dst_mask, nexthop, and dst_as in future releases.
*/
if ((flags & NG_NETFLOW_CONF_NODSTLOOKUP) == 0) {
- bzero(&sin, sizeof(sin));
- sin.sin_len = sizeof(struct sockaddr_in);
- sin.sin_family = AF_INET;
- sin.sin_addr = fle->f.r.r_dst;
- rt = rtalloc1_fib((struct sockaddr *)&sin, 0, 0, r->fib);
- if (rt != NULL) {
- fle->f.fle_o_ifx = rt->rt_ifp->if_index;
-
- if (rt->rt_flags & RTF_GATEWAY &&
- rt->rt_gateway->sa_family == AF_INET)
- fle->f.next_hop =
- ((struct sockaddr_in *)(rt->rt_gateway))->sin_addr;
-
- if (rt_mask(rt))
- fle->f.dst_mask =
- bitcount32(((struct sockaddr_in *)rt_mask(rt))->sin_addr.s_addr);
- else if (rt->rt_flags & RTF_HOST)
- /* Give up. We can't determine mask :( */
- fle->f.dst_mask = 32;
-
- RTFREE_LOCKED(rt);
+ if (rib4_lookup_nh_ext(r->fib, fle->f.r.r_dst, 0, 0, &rt4) != 0) {
+ fle->f.fle_o_ifx = rt4.rt_lifp->if_index;
+ if (rt4.rt_flags & RTF_GATEWAY)
+ fle->f.next_hop = rt4.rt_gateway;
+ fle->f.dst_mask = bitcount32(rt4.rt_mask.s_addr);
}
}
/* Do route lookup on source address, to fill in src_mask. */
if ((flags & NG_NETFLOW_CONF_NOSRCLOOKUP) == 0) {
- bzero(&sin, sizeof(sin));
- sin.sin_len = sizeof(struct sockaddr_in);
- sin.sin_family = AF_INET;
- sin.sin_addr = fle->f.r.r_src;
- rt = rtalloc1_fib((struct sockaddr *)&sin, 0, 0, r->fib);
- if (rt != NULL) {
- if (rt_mask(rt))
- fle->f.src_mask =
- bitcount32(((struct sockaddr_in *)rt_mask(rt))->sin_addr.s_addr);
- else if (rt->rt_flags & RTF_HOST)
- /* Give up. We can't determine mask :( */
- fle->f.src_mask = 32;
-
- RTFREE_LOCKED(rt);
+ if (rib4_lookup_nh_ext(r->fib, fle->f.r.r_src, 0, 0, &rt4) != 0) {
+ if (rt4.rt_flags & RTF_GATEWAY)
+ fle->f.next_hop = rt4.rt_gateway;
+ fle->f.src_mask = bitcount32(rt4.rt_mask.s_addr);
}
}
@@ -396,9 +369,7 @@ hash6_insert(priv_p priv, struct flow_ha
int plen, uint8_t flags, uint8_t tcp_flags)
{
struct flow6_entry *fle6;
- struct sockaddr_in6 *src, *dst;
- struct rtentry *rt;
- struct route_in6 rin6;
+ struct rt6_extended rt6;
mtx_assert(&hsh6->mtx, MA_OWNED);
@@ -426,51 +397,18 @@ hash6_insert(priv_p priv, struct flow_ha
* fill in out_ifx, dst_mask, nexthop, and dst_as in future releases.
*/
if ((flags & NG_NETFLOW_CONF_NODSTLOOKUP) == 0) {
- bzero(&rin6, sizeof(struct route_in6));
- dst = (struct sockaddr_in6 *)&rin6.ro_dst;
- dst->sin6_len = sizeof(struct sockaddr_in6);
- dst->sin6_family = AF_INET6;
- dst->sin6_addr = r->dst.r_dst6;
-
- rin6.ro_rt = rtalloc1_fib((struct sockaddr *)dst, 0, 0, r->fib);
-
- if (rin6.ro_rt != NULL) {
- rt = rin6.ro_rt;
- fle6->f.fle_o_ifx = rt->rt_ifp->if_index;
-
- if (rt->rt_flags & RTF_GATEWAY &&
- rt->rt_gateway->sa_family == AF_INET6)
- fle6->f.n.next_hop6 =
- ((struct sockaddr_in6 *)(rt->rt_gateway))->sin6_addr;
-
- if (rt_mask(rt))
- fle6->f.dst_mask = RT_MASK6(rt);
- else
- fle6->f.dst_mask = 128;
-
- RTFREE_LOCKED(rt);
+ if (rib6_lookup_nh_ext(r->fib, &r->dst.r_dst6, 0, 0, 0, &rt6) == 0) {
+ fle6->f.fle_o_ifx = rt6.rt_lifp->if_index;
+ if ((rt6.rt_flags & RTF_GATEWAY) != 0)
+ fle6->f.n.next_hop6 = rt6.rt_gateway;
+ fle6->f.dst_mask = rt6.rt_mask;
}
}
if ((flags & NG_NETFLOW_CONF_NODSTLOOKUP) == 0) {
/* Do route lookup on source address, to fill in src_mask. */
- bzero(&rin6, sizeof(struct route_in6));
- src = (struct sockaddr_in6 *)&rin6.ro_dst;
- src->sin6_len = sizeof(struct sockaddr_in6);
- src->sin6_family = AF_INET6;
- src->sin6_addr = r->src.r_src6;
-
- rin6.ro_rt = rtalloc1_fib((struct sockaddr *)src, 0, 0, r->fib);
-
- if (rin6.ro_rt != NULL) {
- rt = rin6.ro_rt;
-
- if (rt_mask(rt))
- fle6->f.src_mask = RT_MASK6(rt);
- else
- fle6->f.src_mask = 128;
-
- RTFREE_LOCKED(rt);
+ if (rib6_lookup_nh_ext(r->fib, &r->src.r_src6, 0, 0, 0, &rt6) == 0) {
+ fle6->f.dst_mask = rt6.rt_mask;
}
}
More information about the svn-src-projects
mailing list