Skip to content

Commit ab48b74

Browse files
edumazetksacilotto
authored andcommitted
ipv6: icmp6: avoid indirect call for icmpv6_send()
BugLink: https://bugs.launchpad.net/bugs/1918974 commit cc7a21b upstream. If IPv6 is builtin, we do not need an expensive indirect call to reach icmp6_send(). v2: put inline keyword before the type to avoid sparse warnings. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Kamal Mostafa <kamal@canonical.com> Signed-off-by: Kelsey Skunberg <kelsey.skunberg@canonical.com>
1 parent 9d56bae commit ab48b74

File tree

3 files changed

+29
-8
lines changed

3 files changed

+29
-8
lines changed

include/linux/icmpv6.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,32 @@ static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff *skb)
1313
#include <linux/netdevice.h>
1414

1515
#if IS_ENABLED(CONFIG_IPV6)
16-
extern void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info);
1716

1817
typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info,
1918
const struct in6_addr *force_saddr);
19+
#if IS_BUILTIN(CONFIG_IPV6)
20+
void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
21+
const struct in6_addr *force_saddr);
22+
static inline void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
23+
{
24+
icmp6_send(skb, type, code, info, NULL);
25+
}
26+
static inline int inet6_register_icmp_sender(ip6_icmp_send_t *fn)
27+
{
28+
BUILD_BUG_ON(fn != icmp6_send);
29+
return 0;
30+
}
31+
static inline int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn)
32+
{
33+
BUILD_BUG_ON(fn != icmp6_send);
34+
return 0;
35+
}
36+
#else
37+
extern void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info);
2038
extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
2139
extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
40+
#endif
41+
2242
int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
2343
unsigned int data_len);
2444

net/ipv6/icmp.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -426,8 +426,8 @@ static int icmp6_iif(const struct sk_buff *skb)
426426
/*
427427
* Send an ICMP message in response to a packet in error
428428
*/
429-
static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
430-
const struct in6_addr *force_saddr)
429+
void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
430+
const struct in6_addr *force_saddr)
431431
{
432432
struct inet6_dev *idev = NULL;
433433
struct ipv6hdr *hdr = ipv6_hdr(skb);
@@ -600,6 +600,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
600600
out_bh_enable:
601601
local_bh_enable();
602602
}
603+
EXPORT_SYMBOL(icmp6_send);
603604

604605
/* Slightly more convenient version of icmp6_send.
605606
*/

net/ipv6/ip6_icmp.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
#if IS_ENABLED(CONFIG_IPV6)
1111

12+
#if !IS_BUILTIN(CONFIG_IPV6)
13+
1214
static ip6_icmp_send_t __rcu *ip6_icmp_send;
1315

1416
int inet6_register_icmp_sender(ip6_icmp_send_t *fn)
@@ -37,14 +39,12 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
3739

3840
rcu_read_lock();
3941
send = rcu_dereference(ip6_icmp_send);
40-
41-
if (!send)
42-
goto out;
43-
send(skb, type, code, info, NULL);
44-
out:
42+
if (send)
43+
send(skb, type, code, info, NULL);
4544
rcu_read_unlock();
4645
}
4746
EXPORT_SYMBOL(icmpv6_send);
47+
#endif
4848

4949
#if IS_ENABLED(CONFIG_NF_NAT)
5050
#include <net/netfilter/nf_conntrack.h>

0 commit comments

Comments
 (0)