aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/route.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-11-21 14:45:55 -0800
committerDavid S. Miller <davem@davemloft.net>2019-11-21 14:46:31 -0800
commit7d75c0cb22b71837b376b68fa240c01d4a955fa4 (patch)
treee034d97436dfa8b32deff124f3ab172648aef9e4 /net/ipv4/route.c
parent2c44713ed96da04f5e25b0df4035074b844def04 (diff)
parent02b24941619fcce3d280311ac73b1e461552e9c8 (diff)
downloadkernel_replicant_linux-7d75c0cb22b71837b376b68fa240c01d4a955fa4.tar.gz
kernel_replicant_linux-7d75c0cb22b71837b376b68fa240c01d4a955fa4.tar.bz2
kernel_replicant_linux-7d75c0cb22b71837b376b68fa240c01d4a955fa4.zip
Merge branch 'net-introduce-and-use-route-hint'
Paolo Abeni says: ==================== net: introduce and use route hint This series leverages the listification infrastructure to avoid unnecessary route lookup on ingress packets. In absence of custom rules, packets with equal daddr will usually land on the same dst. When processing packet bursts (lists) we can easily reference the previous dst entry. When we hit the 'same destination' condition we can avoid the route lookup, coping the already available dst. Detailed performance numbers are available in the individual commit messages. v3 -> v4: - move helpers to their own patches (Eric D.) - enable hints for SUBTREE builds (David A.) - re-enable hints for ipv4 forward (David A.) v2 -> v3: - use fib*_has_custom_rules() helpers (David A.) - add ip*_extract_route_hint() helper (Edward C.) - use prev skb as hint instead of copying data (Willem ) v1 -> v2: - fix build issue with !CONFIG_IP*_MULTIPLE_TABLES - fix potential race in ip6_list_rcv_finish() ==================== Acked-by: Edward Cree <ecree@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r--net/ipv4/route.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index dcc4fa10138d..f88c93c38f11 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2019,10 +2019,52 @@ static int ip_mkroute_input(struct sk_buff *skb,
return __mkroute_input(skb, res, in_dev, daddr, saddr, tos);
}
+/* Implements all the saddr-related checks as ip_route_input_slow(),
+ * assuming daddr is valid and the destination is not a local broadcast one.
+ * Uses the provided hint instead of performing a route lookup.
+ */
+int ip_route_use_hint(struct sk_buff *skb, __be32 daddr, __be32 saddr,
+ u8 tos, struct net_device *dev,
+ const struct sk_buff *hint)
+{
+ struct in_device *in_dev = __in_dev_get_rcu(dev);
+ struct rtable *rt = (struct rtable *)hint;
+ struct net *net = dev_net(dev);
+ int err = -EINVAL;
+ u32 tag = 0;
+
+ if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr))
+ goto martian_source;
+
+ if (ipv4_is_zeronet(saddr))
+ goto martian_source;
+
+ if (ipv4_is_loopback(saddr) && !IN_DEV_NET_ROUTE_LOCALNET(in_dev, net))
+ goto martian_source;
+
+ if (rt->rt_type != RTN_LOCAL)
+ goto skip_validate_source;
+
+ tos &= IPTOS_RT_MASK;
+ err = fib_validate_source(skb, saddr, daddr, tos, 0, dev, in_dev, &tag);
+ if (err < 0)
+ goto martian_source;
+
+skip_validate_source:
+ skb_dst_copy(skb, hint);
+ return 0;
+
+martian_source:
+ ip_handle_martian_source(dev, in_dev, skb, daddr, saddr);
+ return err;
+}
+
/*
* NOTE. We drop all the packets that has local source
* addresses, because every properly looped back packet
* must have correct destination already attached by output routine.
+ * Changes in the enforced policies must be applied also to
+ * ip_route_use_hint().
*
* Such approach solves two big problems:
* 1. Not simplex devices are handled properly.