summaryrefslogtreecommitdiffstats
path: root/sys/netgraph
diff options
context:
space:
mode:
authormelifaro <melifaro@FreeBSD.org>2016-01-14 13:14:12 +0000
committermelifaro <melifaro@FreeBSD.org>2016-01-14 13:14:12 +0000
commite438997c5ad54ff6759ae8e26136da3bc3163fe6 (patch)
treeeeb35ad1f5beaf8a2f3a40cecf7071100e5b67a6 /sys/netgraph
parentcb596468343267a3152e121be23e0187d0684a16 (diff)
downloadFreeBSD-src-e438997c5ad54ff6759ae8e26136da3bc3163fe6.zip
FreeBSD-src-e438997c5ad54ff6759ae8e26136da3bc3163fe6.tar.gz
Make ng_netflow(9) use new routing KPI.
Netflow module is supposed to store (along with fields like gateway address and interface index) matched netmask for each record. This (currently) requires returning individual route entries, instead of optimized next-hop structure. Given that, use control-plane rib_lookup_info() function to avoid accessing rtentries directly. While rib_lookup_info() might be slower, than fibX_lookup() flavours, it is more scalable than rtalloc1_fib(), because rtentry mutex is not acquired.
Diffstat (limited to 'sys/netgraph')
-rw-r--r--sys/netgraph/netflow/netflow.c100
1 files changed, 61 insertions, 39 deletions
diff --git a/sys/netgraph/netflow/netflow.c b/sys/netgraph/netflow/netflow.c
index 87ff189..6adffc9 100644
--- a/sys/netgraph/netflow/netflow.c
+++ b/sys/netgraph/netflow/netflow.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/socket.h>
#include <net/if.h>
+#include <net/if_dl.h>
#include <net/if_var.h>
#include <net/route.h>
#include <net/ethernet.h>
@@ -307,8 +308,9 @@ hash_insert(priv_p priv, struct flow_hash_entry *hsh, struct flow_rec *r,
int plen, uint8_t flags, uint8_t tcp_flags)
{
struct flow_entry *fle;
- struct sockaddr_in sin;
- struct rtentry *rt;
+ struct sockaddr_in sin, sin_mask;
+ struct sockaddr_dl rt_gateway;
+ struct rt_addrinfo info;
mtx_assert(&hsh->mtx, MA_OWNED);
@@ -339,23 +341,30 @@ hash_insert(priv_p priv, struct flow_hash_entry *hsh, struct flow_rec *r,
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)
+ rt_gateway.sdl_len = sizeof(rt_gateway);
+ sin_mask.sin_len = sizeof(struct sockaddr_in);
+ bzero(&info, sizeof(info));
+
+ info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&rt_gateway;
+ info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&sin_mask;
+
+ if (rib_lookup_info(r->fib, (struct sockaddr *)&sin, NHR_REF, 0,
+ &info) == 0) {
+ fle->f.fle_o_ifx = info.rti_ifp->if_index;
+
+ if (info.rti_flags & RTF_GATEWAY &&
+ rt_gateway.sdl_family == AF_INET)
fle->f.next_hop =
- ((struct sockaddr_in *)(rt->rt_gateway))->sin_addr;
+ ((struct sockaddr_in *)&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)
+ if (info.rti_addrs & RTA_NETMASK)
+ fle->f.dst_mask = bitcount32(sin_mask.sin_addr.s_addr);
+ else if (info.rti_flags & RTF_HOST)
/* Give up. We can't determine mask :( */
fle->f.dst_mask = 32;
- RTFREE_LOCKED(rt);
+ rib_free_info(&info);
}
}
@@ -365,16 +374,20 @@ hash_insert(priv_p priv, struct flow_hash_entry *hsh, struct flow_rec *r,
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))
+
+ sin_mask.sin_len = sizeof(struct sockaddr_in);
+ bzero(&info, sizeof(info));
+
+ info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&sin_mask;
+
+ if (rib_lookup_info(r->fib, (struct sockaddr *)&sin, 0, 0,
+ &info) == 0) {
+ if (info.rti_addrs & RTA_NETMASK)
fle->f.src_mask =
- bitcount32(((struct sockaddr_in *)rt_mask(rt))->sin_addr.s_addr);
- else if (rt->rt_flags & RTF_HOST)
+ bitcount32(sin_mask.sin_addr.s_addr);
+ else if (info.rti_flags & RTF_HOST)
/* Give up. We can't determine mask :( */
fle->f.src_mask = 32;
-
- RTFREE_LOCKED(rt);
}
}
@@ -390,14 +403,14 @@ hash_insert(priv_p priv, struct flow_hash_entry *hsh, struct flow_rec *r,
bitcount32((x).__u6_addr.__u6_addr32[1]) + \
bitcount32((x).__u6_addr.__u6_addr32[2]) + \
bitcount32((x).__u6_addr.__u6_addr32[3])
-#define RT_MASK6(x) (ipv6_masklen(((struct sockaddr_in6 *)rt_mask(x))->sin6_addr))
static int
hash6_insert(priv_p priv, struct flow_hash_entry *hsh6, struct flow6_rec *r,
int plen, uint8_t flags, uint8_t tcp_flags)
{
struct flow6_entry *fle6;
- struct sockaddr_in6 sin6;
- struct rtentry *rt;
+ struct sockaddr_in6 sin6, sin6_mask;
+ struct sockaddr_dl rt_gateway;
+ struct rt_addrinfo info;
mtx_assert(&hsh6->mtx, MA_OWNED);
@@ -430,22 +443,29 @@ hash6_insert(priv_p priv, struct flow_hash_entry *hsh6, struct flow6_rec *r,
sin6.sin6_family = AF_INET6;
sin6.sin6_addr = r->dst.r_dst6;
- rt = rtalloc1_fib((struct sockaddr *)&sin6, 0, 0, r->fib);
+ rt_gateway.sdl_len = sizeof(rt_gateway);
+ sin6_mask.sin6_len = sizeof(struct sockaddr_in6);
+ bzero(&info, sizeof(info));
+
+ info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&rt_gateway;
+ info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&sin6_mask;
- if (rt != NULL) {
- fle6->f.fle_o_ifx = rt->rt_ifp->if_index;
+ if (rib_lookup_info(r->fib, (struct sockaddr *)&sin6, NHR_REF,
+ 0, &info) == 0) {
+ fle6->f.fle_o_ifx = info.rti_ifp->if_index;
- if (rt->rt_flags & RTF_GATEWAY &&
- rt->rt_gateway->sa_family == AF_INET6)
+ if (info.rti_flags & RTF_GATEWAY &&
+ rt_gateway.sdl_family == AF_INET6)
fle6->f.n.next_hop6 =
- ((struct sockaddr_in6 *)(rt->rt_gateway))->sin6_addr;
+ ((struct sockaddr_in6 *)&rt_gateway)->sin6_addr;
- if (rt_mask(rt))
- fle6->f.dst_mask = RT_MASK6(rt);
+ if (info.rti_addrs & RTA_NETMASK)
+ fle6->f.dst_mask =
+ ipv6_masklen(sin6_mask.sin6_addr);
else
fle6->f.dst_mask = 128;
- RTFREE_LOCKED(rt);
+ rib_free_info(&info);
}
}
@@ -456,15 +476,18 @@ hash6_insert(priv_p priv, struct flow_hash_entry *hsh6, struct flow6_rec *r,
sin6.sin6_family = AF_INET6;
sin6.sin6_addr = r->src.r_src6;
- rt = rtalloc1_fib((struct sockaddr *)&sin6, 0, 0, r->fib);
+ sin6_mask.sin6_len = sizeof(struct sockaddr_in6);
+ bzero(&info, sizeof(info));
- if (rt != NULL) {
- if (rt_mask(rt))
- fle6->f.src_mask = RT_MASK6(rt);
+ info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&sin6_mask;
+
+ if (rib_lookup_info(r->fib, (struct sockaddr *)&sin6, 0, 0,
+ &info) == 0) {
+ if (info.rti_addrs & RTA_NETMASK)
+ fle6->f.src_mask =
+ ipv6_masklen(sin6_mask.sin6_addr);
else
fle6->f.src_mask = 128;
-
- RTFREE_LOCKED(rt);
}
}
@@ -474,7 +497,6 @@ hash6_insert(priv_p priv, struct flow_hash_entry *hsh6, struct flow6_rec *r,
return (0);
}
#undef ipv6_masklen
-#undef RT_MASK6
#endif
OpenPOWER on IntegriCloud