net: use indirect calls helpers for L3 handler hooks
authorPaolo Abeni <pabeni@redhat.com>
Fri, 3 May 2019 15:01:37 +0000 (17:01 +0200)
committerDavid S. Miller <davem@davemloft.net>
Sun, 5 May 2019 17:38:04 +0000 (10:38 -0700)
So that we avoid another indirect call per RX packet in the common
case.

Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/ip_input.c
net/ipv6/ip6_input.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c

index 1132d6d1796a4f7c947da76b9b39e7fbe11d3399..8d78de4b030487ebc4d683a33a2185ebc4700aac 100644 (file)
 #include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/indirect_call_wrapper.h>
 
 #include <net/snmp.h>
 #include <net/ip.h>
@@ -188,6 +189,8 @@ bool ip_call_ra_chain(struct sk_buff *skb)
        return false;
 }
 
+INDIRECT_CALLABLE_DECLARE(int udp_rcv(struct sk_buff *));
+INDIRECT_CALLABLE_DECLARE(int tcp_v4_rcv(struct sk_buff *));
 void ip_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int protocol)
 {
        const struct net_protocol *ipprot;
@@ -205,7 +208,8 @@ resubmit:
                        }
                        nf_reset(skb);
                }
-               ret = ipprot->handler(skb);
+               ret = INDIRECT_CALL_2(ipprot->handler, tcp_v4_rcv, udp_rcv,
+                                     skb);
                if (ret < 0) {
                        protocol = -ret;
                        goto resubmit;
index c7ed2b6d5a1dd192cc776231ede06cef8f78065d..adf06159837f70e2d9c14459868ab8ca12cd46cc 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/icmpv6.h>
 #include <linux/mroute6.h>
 #include <linux/slab.h>
+#include <linux/indirect_call_wrapper.h>
 
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv6.h>
@@ -316,6 +317,9 @@ void ipv6_list_rcv(struct list_head *head, struct packet_type *pt,
        ip6_sublist_rcv(&sublist, curr_dev, curr_net);
 }
 
+INDIRECT_CALLABLE_DECLARE(int udpv6_rcv(struct sk_buff *));
+INDIRECT_CALLABLE_DECLARE(int tcp_v6_rcv(struct sk_buff *));
+
 /*
  *     Deliver the packet to the host
  */
@@ -391,7 +395,8 @@ resubmit_final:
                    !xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
                        goto discard;
 
-               ret = ipprot->handler(skb);
+               ret = INDIRECT_CALL_2(ipprot->handler, tcp_v6_rcv, udpv6_rcv,
+                                     skb);
                if (ret > 0) {
                        if (ipprot->flags & INET6_PROTO_FINAL) {
                                /* Not an extension header, most likely UDP
index 82018bdce863165eba72e1ccf0c12ee558042ae8..d58bf84e0f9a176d7fcd642b137d65de79ca9df4 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
 #include <linux/random.h>
+#include <linux/indirect_call_wrapper.h>
 
 #include <net/tcp.h>
 #include <net/ndisc.h>
@@ -1435,7 +1436,7 @@ static void tcp_v6_fill_cb(struct sk_buff *skb, const struct ipv6hdr *hdr,
                        skb->tstamp || skb_hwtstamps(skb)->hwtstamp;
 }
 
-static int tcp_v6_rcv(struct sk_buff *skb)
+INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
 {
        struct sk_buff *skb_to_free;
        int sdif = inet6_sdif(skb);
index 2464fba569b4eb39452bd81f94cbe80227368fc9..b3fcafaf5576b6d96cbc0bb068b401958b73f1d5 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/skbuff.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
+#include <linux/indirect_call_wrapper.h>
 
 #include <net/addrconf.h>
 #include <net/ndisc.h>
@@ -1021,7 +1022,7 @@ static void udp_v6_early_demux(struct sk_buff *skb)
        }
 }
 
-static __inline__ int udpv6_rcv(struct sk_buff *skb)
+INDIRECT_CALLABLE_SCOPE int udpv6_rcv(struct sk_buff *skb)
 {
        return __udp6_lib_rcv(skb, &udp_table, IPPROTO_UDP);
 }