So that we avoid another indirect call per RX packet in the common
case.

Signed-off-by: Paolo Abeni <pab...@redhat.com>
---
 net/ipv4/ip_input.c  | 6 +++++-
 net/ipv6/ip6_input.c | 7 ++++++-
 net/ipv6/tcp_ipv6.c  | 3 ++-
 net/ipv6/udp.c       | 3 ++-
 4 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 1132d6d1796a..8d78de4b0304 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -130,6 +130,7 @@
 #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 @@ void ip_protocol_deliver_rcu(struct net *net, struct 
sk_buff *skb, int protocol)
                        }
                        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;
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index c7ed2b6d5a1d..adf06159837f 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -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 @@ void ip6_protocol_deliver_rcu(struct net *net, struct 
sk_buff *skb, int nexthdr,
                    !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
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 82018bdce863..d58bf84e0f9a 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -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);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 2464fba569b4..b3fcafaf5576 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -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);
 }
-- 
2.20.1

Reply via email to