* [PATCH v2 net-next] ipv6: icmp6: avoid indirect call for icmpv6_send()
@ 2020-06-19 19:02 Eric Dumazet
2020-06-20 0:43 ` kernel test robot
2020-06-20 1:53 ` kernel test robot
0 siblings, 2 replies; 5+ messages in thread
From: Eric Dumazet @ 2020-06-19 19:02 UTC (permalink / raw)
To: David S . Miller; +Cc: netdev, Eric Dumazet, Eric Dumazet, Jakub Kicinski
If IPv6 is builtin, we do not need an expensive indirect call
to reach cmp6_send().
v2: put inline keyword before the type to avoid sparse warnings.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/linux/icmpv6.h | 22 +++++++++++++++++++++-
net/ipv6/icmp.c | 5 +++--
net/ipv6/ip6_icmp.c | 10 +++++-----
3 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
index 33d37960231441d63a1d7a3d611da916734fc2cd..1b3371ae819362466c88fad6fe4ee7c9907390c7 100644
--- a/include/linux/icmpv6.h
+++ b/include/linux/icmpv6.h
@@ -13,12 +13,32 @@ static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff *skb)
#include <linux/netdevice.h>
#if IS_ENABLED(CONFIG_IPV6)
-extern void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info);
typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info,
const struct in6_addr *force_saddr);
+#if IS_BUILTIN(CONFIG_IPV6)
+void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+ const struct in6_addr *force_saddr);
+static inline void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
+{
+ icmp6_send(skb, type, code, info, NULL);
+}
+static inline int inet6_register_icmp_sender(ip6_icmp_send_t *fn)
+{
+ BUILD_BUG_ON(fn != icmp6_send);
+ return 0;
+}
+static inline int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn)
+{
+ BUILD_BUG_ON(fn != icmp6_send);
+ return 0;
+}
+#else
+extern void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info);
extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
+#endif
+
int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
unsigned int data_len);
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index fc5000370030d67094ba11f15aaaaaa7ba519cde..91e0f2fd2523e6fb7d47c5a92e997c90ad53b9fc 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -439,8 +439,8 @@ static int icmp6_iif(const struct sk_buff *skb)
/*
* Send an ICMP message in response to a packet in error
*/
-static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
- const struct in6_addr *force_saddr)
+void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+ const struct in6_addr *force_saddr)
{
struct inet6_dev *idev = NULL;
struct ipv6hdr *hdr = ipv6_hdr(skb);
@@ -625,6 +625,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
out_bh_enable:
local_bh_enable();
}
+EXPORT_SYMBOL(icmp6_send);
/* Slightly more convenient version of icmp6_send.
*/
diff --git a/net/ipv6/ip6_icmp.c b/net/ipv6/ip6_icmp.c
index e0086758b6ee3c3e91568e59028838c770fac795..70c8c2f36c980cd95db10380a1702a6d08e8c223 100644
--- a/net/ipv6/ip6_icmp.c
+++ b/net/ipv6/ip6_icmp.c
@@ -9,6 +9,8 @@
#if IS_ENABLED(CONFIG_IPV6)
+#if !IS_BUILTIN(CONFIG_IPV6)
+
static ip6_icmp_send_t __rcu *ip6_icmp_send;
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)
rcu_read_lock();
send = rcu_dereference(ip6_icmp_send);
-
- if (!send)
- goto out;
- send(skb, type, code, info, NULL);
-out:
+ if (send)
+ send(skb, type, code, info, NULL);
rcu_read_unlock();
}
EXPORT_SYMBOL(icmpv6_send);
+#endif
#if IS_ENABLED(CONFIG_NF_NAT)
#include <net/netfilter/nf_conntrack.h>
--
2.27.0.111.gc72c7da667-goog
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2 net-next] ipv6: icmp6: avoid indirect call for icmpv6_send()
2020-06-19 19:02 [PATCH v2 net-next] ipv6: icmp6: avoid indirect call for icmpv6_send() Eric Dumazet
@ 2020-06-20 0:43 ` kernel test robot
2020-06-20 1:53 ` kernel test robot
1 sibling, 0 replies; 5+ messages in thread
From: kernel test robot @ 2020-06-20 0:43 UTC (permalink / raw)
To: Eric Dumazet, David S . Miller
Cc: kbuild-all, clang-built-linux, netdev, Eric Dumazet, Jakub Kicinski
[-- Attachment #1: Type: text/plain, Size: 7810 bytes --]
Hi Eric,
I love your patch! Perhaps something to improve:
[auto build test WARNING on net-next/master]
url: https://github.com/0day-ci/linux/commits/Eric-Dumazet/ipv6-icmp6-avoid-indirect-call-for-icmpv6_send/20200620-030444
base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 0fb9fbab405351aa0c18973881c4103e4da886b6
config: riscv-randconfig-r033-20200619 (attached as .config)
compiler: clang version 11.0.0 (https://github.com/llvm/llvm-project 487ca07fcc75d52755c9fe2ee05bcb3b6eeeec44)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install riscv cross compiling tool for clang build
# apt-get install binutils-riscv64-linux-gnu
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=riscv
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>, old ones prefixed by <<):
>> net/ipv6/icmp.c:442:6: warning: no previous prototype for function 'icmp6_send' [-Wmissing-prototypes]
void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
^
net/ipv6/icmp.c:442:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
^
static
1 warning generated.
vim +/icmp6_send +442 net/ipv6/icmp.c
438
439 /*
440 * Send an ICMP message in response to a packet in error
441 */
> 442 void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
443 const struct in6_addr *force_saddr)
444 {
445 struct inet6_dev *idev = NULL;
446 struct ipv6hdr *hdr = ipv6_hdr(skb);
447 struct sock *sk;
448 struct net *net;
449 struct ipv6_pinfo *np;
450 const struct in6_addr *saddr = NULL;
451 struct dst_entry *dst;
452 struct icmp6hdr tmp_hdr;
453 struct flowi6 fl6;
454 struct icmpv6_msg msg;
455 struct ipcm6_cookie ipc6;
456 int iif = 0;
457 int addr_type = 0;
458 int len;
459 u32 mark;
460
461 if ((u8 *)hdr < skb->head ||
462 (skb_network_header(skb) + sizeof(*hdr)) > skb_tail_pointer(skb))
463 return;
464
465 if (!skb->dev)
466 return;
467 net = dev_net(skb->dev);
468 mark = IP6_REPLY_MARK(net, skb->mark);
469 /*
470 * Make sure we respect the rules
471 * i.e. RFC 1885 2.4(e)
472 * Rule (e.1) is enforced by not using icmp6_send
473 * in any code that processes icmp errors.
474 */
475 addr_type = ipv6_addr_type(&hdr->daddr);
476
477 if (ipv6_chk_addr(net, &hdr->daddr, skb->dev, 0) ||
478 ipv6_chk_acast_addr_src(net, skb->dev, &hdr->daddr))
479 saddr = &hdr->daddr;
480
481 /*
482 * Dest addr check
483 */
484
485 if (addr_type & IPV6_ADDR_MULTICAST || skb->pkt_type != PACKET_HOST) {
486 if (type != ICMPV6_PKT_TOOBIG &&
487 !(type == ICMPV6_PARAMPROB &&
488 code == ICMPV6_UNK_OPTION &&
489 (opt_unrec(skb, info))))
490 return;
491
492 saddr = NULL;
493 }
494
495 addr_type = ipv6_addr_type(&hdr->saddr);
496
497 /*
498 * Source addr check
499 */
500
501 if (__ipv6_addr_needs_scope_id(addr_type)) {
502 iif = icmp6_iif(skb);
503 } else {
504 dst = skb_dst(skb);
505 iif = l3mdev_master_ifindex(dst ? dst->dev : skb->dev);
506 }
507
508 /*
509 * Must not send error if the source does not uniquely
510 * identify a single node (RFC2463 Section 2.4).
511 * We check unspecified / multicast addresses here,
512 * and anycast addresses will be checked later.
513 */
514 if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) {
515 net_dbg_ratelimited("icmp6_send: addr_any/mcast source [%pI6c > %pI6c]\n",
516 &hdr->saddr, &hdr->daddr);
517 return;
518 }
519
520 /*
521 * Never answer to a ICMP packet.
522 */
523 if (is_ineligible(skb)) {
524 net_dbg_ratelimited("icmp6_send: no reply to icmp error [%pI6c > %pI6c]\n",
525 &hdr->saddr, &hdr->daddr);
526 return;
527 }
528
529 /* Needed by both icmp_global_allow and icmpv6_xmit_lock */
530 local_bh_disable();
531
532 /* Check global sysctl_icmp_msgs_per_sec ratelimit */
533 if (!(skb->dev->flags & IFF_LOOPBACK) && !icmpv6_global_allow(net, type))
534 goto out_bh_enable;
535
536 mip6_addr_swap(skb);
537
538 sk = icmpv6_xmit_lock(net);
539 if (!sk)
540 goto out_bh_enable;
541
542 memset(&fl6, 0, sizeof(fl6));
543 fl6.flowi6_proto = IPPROTO_ICMPV6;
544 fl6.daddr = hdr->saddr;
545 if (force_saddr)
546 saddr = force_saddr;
547 if (saddr) {
548 fl6.saddr = *saddr;
549 } else if (!icmpv6_rt_has_prefsrc(sk, type, &fl6)) {
550 /* select a more meaningful saddr from input if */
551 struct net_device *in_netdev;
552
553 in_netdev = dev_get_by_index(net, IP6CB(skb)->iif);
554 if (in_netdev) {
555 ipv6_dev_get_saddr(net, in_netdev, &fl6.daddr,
556 inet6_sk(sk)->srcprefs,
557 &fl6.saddr);
558 dev_put(in_netdev);
559 }
560 }
561 fl6.flowi6_mark = mark;
562 fl6.flowi6_oif = iif;
563 fl6.fl6_icmp_type = type;
564 fl6.fl6_icmp_code = code;
565 fl6.flowi6_uid = sock_net_uid(net, NULL);
566 fl6.mp_hash = rt6_multipath_hash(net, &fl6, skb, NULL);
567 security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
568
569 sk->sk_mark = mark;
570 np = inet6_sk(sk);
571
572 if (!icmpv6_xrlim_allow(sk, type, &fl6))
573 goto out;
574
575 tmp_hdr.icmp6_type = type;
576 tmp_hdr.icmp6_code = code;
577 tmp_hdr.icmp6_cksum = 0;
578 tmp_hdr.icmp6_pointer = htonl(info);
579
580 if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
581 fl6.flowi6_oif = np->mcast_oif;
582 else if (!fl6.flowi6_oif)
583 fl6.flowi6_oif = np->ucast_oif;
584
585 ipcm6_init_sk(&ipc6, np);
586 fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
587
588 dst = icmpv6_route_lookup(net, skb, sk, &fl6);
589 if (IS_ERR(dst))
590 goto out;
591
592 ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
593
594 msg.skb = skb;
595 msg.offset = skb_network_offset(skb);
596 msg.type = type;
597
598 len = skb->len - msg.offset;
599 len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) - sizeof(struct icmp6hdr));
600 if (len < 0) {
601 net_dbg_ratelimited("icmp: len problem [%pI6c > %pI6c]\n",
602 &hdr->saddr, &hdr->daddr);
603 goto out_dst_release;
604 }
605
606 rcu_read_lock();
607 idev = __in6_dev_get(skb->dev);
608
609 if (ip6_append_data(sk, icmpv6_getfrag, &msg,
610 len + sizeof(struct icmp6hdr),
611 sizeof(struct icmp6hdr),
612 &ipc6, &fl6, (struct rt6_info *)dst,
613 MSG_DONTWAIT)) {
614 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS);
615 ip6_flush_pending_frames(sk);
616 } else {
617 icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr,
618 len + sizeof(struct icmp6hdr));
619 }
620 rcu_read_unlock();
621 out_dst_release:
622 dst_release(dst);
623 out:
624 icmpv6_xmit_unlock(sk);
625 out_bh_enable:
626 local_bh_enable();
627 }
628 EXPORT_SYMBOL(icmp6_send);
629
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 31496 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 net-next] ipv6: icmp6: avoid indirect call for icmpv6_send()
@ 2020-06-20 0:43 ` kernel test robot
0 siblings, 0 replies; 5+ messages in thread
From: kernel test robot @ 2020-06-20 0:43 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 8042 bytes --]
Hi Eric,
I love your patch! Perhaps something to improve:
[auto build test WARNING on net-next/master]
url: https://github.com/0day-ci/linux/commits/Eric-Dumazet/ipv6-icmp6-avoid-indirect-call-for-icmpv6_send/20200620-030444
base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 0fb9fbab405351aa0c18973881c4103e4da886b6
config: riscv-randconfig-r033-20200619 (attached as .config)
compiler: clang version 11.0.0 (https://github.com/llvm/llvm-project 487ca07fcc75d52755c9fe2ee05bcb3b6eeeec44)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install riscv cross compiling tool for clang build
# apt-get install binutils-riscv64-linux-gnu
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=riscv
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>, old ones prefixed by <<):
>> net/ipv6/icmp.c:442:6: warning: no previous prototype for function 'icmp6_send' [-Wmissing-prototypes]
void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
^
net/ipv6/icmp.c:442:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
^
static
1 warning generated.
vim +/icmp6_send +442 net/ipv6/icmp.c
438
439 /*
440 * Send an ICMP message in response to a packet in error
441 */
> 442 void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
443 const struct in6_addr *force_saddr)
444 {
445 struct inet6_dev *idev = NULL;
446 struct ipv6hdr *hdr = ipv6_hdr(skb);
447 struct sock *sk;
448 struct net *net;
449 struct ipv6_pinfo *np;
450 const struct in6_addr *saddr = NULL;
451 struct dst_entry *dst;
452 struct icmp6hdr tmp_hdr;
453 struct flowi6 fl6;
454 struct icmpv6_msg msg;
455 struct ipcm6_cookie ipc6;
456 int iif = 0;
457 int addr_type = 0;
458 int len;
459 u32 mark;
460
461 if ((u8 *)hdr < skb->head ||
462 (skb_network_header(skb) + sizeof(*hdr)) > skb_tail_pointer(skb))
463 return;
464
465 if (!skb->dev)
466 return;
467 net = dev_net(skb->dev);
468 mark = IP6_REPLY_MARK(net, skb->mark);
469 /*
470 * Make sure we respect the rules
471 * i.e. RFC 1885 2.4(e)
472 * Rule (e.1) is enforced by not using icmp6_send
473 * in any code that processes icmp errors.
474 */
475 addr_type = ipv6_addr_type(&hdr->daddr);
476
477 if (ipv6_chk_addr(net, &hdr->daddr, skb->dev, 0) ||
478 ipv6_chk_acast_addr_src(net, skb->dev, &hdr->daddr))
479 saddr = &hdr->daddr;
480
481 /*
482 * Dest addr check
483 */
484
485 if (addr_type & IPV6_ADDR_MULTICAST || skb->pkt_type != PACKET_HOST) {
486 if (type != ICMPV6_PKT_TOOBIG &&
487 !(type == ICMPV6_PARAMPROB &&
488 code == ICMPV6_UNK_OPTION &&
489 (opt_unrec(skb, info))))
490 return;
491
492 saddr = NULL;
493 }
494
495 addr_type = ipv6_addr_type(&hdr->saddr);
496
497 /*
498 * Source addr check
499 */
500
501 if (__ipv6_addr_needs_scope_id(addr_type)) {
502 iif = icmp6_iif(skb);
503 } else {
504 dst = skb_dst(skb);
505 iif = l3mdev_master_ifindex(dst ? dst->dev : skb->dev);
506 }
507
508 /*
509 * Must not send error if the source does not uniquely
510 * identify a single node (RFC2463 Section 2.4).
511 * We check unspecified / multicast addresses here,
512 * and anycast addresses will be checked later.
513 */
514 if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) {
515 net_dbg_ratelimited("icmp6_send: addr_any/mcast source [%pI6c > %pI6c]\n",
516 &hdr->saddr, &hdr->daddr);
517 return;
518 }
519
520 /*
521 * Never answer to a ICMP packet.
522 */
523 if (is_ineligible(skb)) {
524 net_dbg_ratelimited("icmp6_send: no reply to icmp error [%pI6c > %pI6c]\n",
525 &hdr->saddr, &hdr->daddr);
526 return;
527 }
528
529 /* Needed by both icmp_global_allow and icmpv6_xmit_lock */
530 local_bh_disable();
531
532 /* Check global sysctl_icmp_msgs_per_sec ratelimit */
533 if (!(skb->dev->flags & IFF_LOOPBACK) && !icmpv6_global_allow(net, type))
534 goto out_bh_enable;
535
536 mip6_addr_swap(skb);
537
538 sk = icmpv6_xmit_lock(net);
539 if (!sk)
540 goto out_bh_enable;
541
542 memset(&fl6, 0, sizeof(fl6));
543 fl6.flowi6_proto = IPPROTO_ICMPV6;
544 fl6.daddr = hdr->saddr;
545 if (force_saddr)
546 saddr = force_saddr;
547 if (saddr) {
548 fl6.saddr = *saddr;
549 } else if (!icmpv6_rt_has_prefsrc(sk, type, &fl6)) {
550 /* select a more meaningful saddr from input if */
551 struct net_device *in_netdev;
552
553 in_netdev = dev_get_by_index(net, IP6CB(skb)->iif);
554 if (in_netdev) {
555 ipv6_dev_get_saddr(net, in_netdev, &fl6.daddr,
556 inet6_sk(sk)->srcprefs,
557 &fl6.saddr);
558 dev_put(in_netdev);
559 }
560 }
561 fl6.flowi6_mark = mark;
562 fl6.flowi6_oif = iif;
563 fl6.fl6_icmp_type = type;
564 fl6.fl6_icmp_code = code;
565 fl6.flowi6_uid = sock_net_uid(net, NULL);
566 fl6.mp_hash = rt6_multipath_hash(net, &fl6, skb, NULL);
567 security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
568
569 sk->sk_mark = mark;
570 np = inet6_sk(sk);
571
572 if (!icmpv6_xrlim_allow(sk, type, &fl6))
573 goto out;
574
575 tmp_hdr.icmp6_type = type;
576 tmp_hdr.icmp6_code = code;
577 tmp_hdr.icmp6_cksum = 0;
578 tmp_hdr.icmp6_pointer = htonl(info);
579
580 if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
581 fl6.flowi6_oif = np->mcast_oif;
582 else if (!fl6.flowi6_oif)
583 fl6.flowi6_oif = np->ucast_oif;
584
585 ipcm6_init_sk(&ipc6, np);
586 fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
587
588 dst = icmpv6_route_lookup(net, skb, sk, &fl6);
589 if (IS_ERR(dst))
590 goto out;
591
592 ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
593
594 msg.skb = skb;
595 msg.offset = skb_network_offset(skb);
596 msg.type = type;
597
598 len = skb->len - msg.offset;
599 len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) - sizeof(struct icmp6hdr));
600 if (len < 0) {
601 net_dbg_ratelimited("icmp: len problem [%pI6c > %pI6c]\n",
602 &hdr->saddr, &hdr->daddr);
603 goto out_dst_release;
604 }
605
606 rcu_read_lock();
607 idev = __in6_dev_get(skb->dev);
608
609 if (ip6_append_data(sk, icmpv6_getfrag, &msg,
610 len + sizeof(struct icmp6hdr),
611 sizeof(struct icmp6hdr),
612 &ipc6, &fl6, (struct rt6_info *)dst,
613 MSG_DONTWAIT)) {
614 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS);
615 ip6_flush_pending_frames(sk);
616 } else {
617 icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr,
618 len + sizeof(struct icmp6hdr));
619 }
620 rcu_read_unlock();
621 out_dst_release:
622 dst_release(dst);
623 out:
624 icmpv6_xmit_unlock(sk);
625 out_bh_enable:
626 local_bh_enable();
627 }
628 EXPORT_SYMBOL(icmp6_send);
629
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 31496 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 net-next] ipv6: icmp6: avoid indirect call for icmpv6_send()
2020-06-19 19:02 [PATCH v2 net-next] ipv6: icmp6: avoid indirect call for icmpv6_send() Eric Dumazet
@ 2020-06-20 1:53 ` kernel test robot
2020-06-20 1:53 ` kernel test robot
1 sibling, 0 replies; 5+ messages in thread
From: kernel test robot @ 2020-06-20 1:53 UTC (permalink / raw)
To: Eric Dumazet, David S . Miller
Cc: kbuild-all, netdev, Eric Dumazet, Jakub Kicinski
[-- Attachment #1: Type: text/plain, Size: 8538 bytes --]
Hi Eric,
I love your patch! Perhaps something to improve:
[auto build test WARNING on net-next/master]
url: https://github.com/0day-ci/linux/commits/Eric-Dumazet/ipv6-icmp6-avoid-indirect-call-for-icmpv6_send/20200620-030444
base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 0fb9fbab405351aa0c18973881c4103e4da886b6
config: nds32-randconfig-r002-20200619 (attached as .config)
compiler: nds32le-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=nds32
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>, old ones prefixed by <<):
In file included from ./arch/nds32/include/generated/asm/bug.h:1,
from include/linux/bug.h:5,
from include/linux/thread_info.h:12,
from include/asm-generic/preempt.h:5,
from ./arch/nds32/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:51,
from include/linux/seqlock.h:36,
from include/linux/time.h:6,
from include/linux/stat.h:19,
from include/linux/module.h:13,
from net/ipv6/icmp.c:30:
include/linux/dma-mapping.h: In function 'dma_map_resource':
arch/nds32/include/asm/memory.h:82:32: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
82 | #define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr))
| ^~
include/asm-generic/bug.h:144:27: note: in definition of macro 'WARN_ON_ONCE'
144 | int __ret_warn_once = !!(condition); | ^~~~~~~~~
include/linux/dma-mapping.h:352:19: note: in expansion of macro 'pfn_valid'
352 | if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
| ^~~~~~~~~
net/ipv6/icmp.c: At top level:
>> net/ipv6/icmp.c:442:6: warning: no previous prototype for 'icmp6_send' [-Wmissing-prototypes]
442 | void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
| ^~~~~~~~~~
vim +/icmp6_send +442 net/ipv6/icmp.c
438
439 /*
440 * Send an ICMP message in response to a packet in error
441 */
> 442 void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
443 const struct in6_addr *force_saddr)
444 {
445 struct inet6_dev *idev = NULL;
446 struct ipv6hdr *hdr = ipv6_hdr(skb);
447 struct sock *sk;
448 struct net *net;
449 struct ipv6_pinfo *np;
450 const struct in6_addr *saddr = NULL;
451 struct dst_entry *dst;
452 struct icmp6hdr tmp_hdr;
453 struct flowi6 fl6;
454 struct icmpv6_msg msg;
455 struct ipcm6_cookie ipc6;
456 int iif = 0;
457 int addr_type = 0;
458 int len;
459 u32 mark;
460
461 if ((u8 *)hdr < skb->head ||
462 (skb_network_header(skb) + sizeof(*hdr)) > skb_tail_pointer(skb))
463 return;
464
465 if (!skb->dev)
466 return;
467 net = dev_net(skb->dev);
468 mark = IP6_REPLY_MARK(net, skb->mark);
469 /*
470 * Make sure we respect the rules
471 * i.e. RFC 1885 2.4(e)
472 * Rule (e.1) is enforced by not using icmp6_send
473 * in any code that processes icmp errors.
474 */
475 addr_type = ipv6_addr_type(&hdr->daddr);
476
477 if (ipv6_chk_addr(net, &hdr->daddr, skb->dev, 0) ||
478 ipv6_chk_acast_addr_src(net, skb->dev, &hdr->daddr))
479 saddr = &hdr->daddr;
480
481 /*
482 * Dest addr check
483 */
484
485 if (addr_type & IPV6_ADDR_MULTICAST || skb->pkt_type != PACKET_HOST) {
486 if (type != ICMPV6_PKT_TOOBIG &&
487 !(type == ICMPV6_PARAMPROB &&
488 code == ICMPV6_UNK_OPTION &&
489 (opt_unrec(skb, info))))
490 return;
491
492 saddr = NULL;
493 }
494
495 addr_type = ipv6_addr_type(&hdr->saddr);
496
497 /*
498 * Source addr check
499 */
500
501 if (__ipv6_addr_needs_scope_id(addr_type)) {
502 iif = icmp6_iif(skb);
503 } else {
504 dst = skb_dst(skb);
505 iif = l3mdev_master_ifindex(dst ? dst->dev : skb->dev);
506 }
507
508 /*
509 * Must not send error if the source does not uniquely
510 * identify a single node (RFC2463 Section 2.4).
511 * We check unspecified / multicast addresses here,
512 * and anycast addresses will be checked later.
513 */
514 if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) {
515 net_dbg_ratelimited("icmp6_send: addr_any/mcast source [%pI6c > %pI6c]\n",
516 &hdr->saddr, &hdr->daddr);
517 return;
518 }
519
520 /*
521 * Never answer to a ICMP packet.
522 */
523 if (is_ineligible(skb)) {
524 net_dbg_ratelimited("icmp6_send: no reply to icmp error [%pI6c > %pI6c]\n",
525 &hdr->saddr, &hdr->daddr);
526 return;
527 }
528
529 /* Needed by both icmp_global_allow and icmpv6_xmit_lock */
530 local_bh_disable();
531
532 /* Check global sysctl_icmp_msgs_per_sec ratelimit */
533 if (!(skb->dev->flags & IFF_LOOPBACK) && !icmpv6_global_allow(net, type))
534 goto out_bh_enable;
535
536 mip6_addr_swap(skb);
537
538 sk = icmpv6_xmit_lock(net);
539 if (!sk)
540 goto out_bh_enable;
541
542 memset(&fl6, 0, sizeof(fl6));
543 fl6.flowi6_proto = IPPROTO_ICMPV6;
544 fl6.daddr = hdr->saddr;
545 if (force_saddr)
546 saddr = force_saddr;
547 if (saddr) {
548 fl6.saddr = *saddr;
549 } else if (!icmpv6_rt_has_prefsrc(sk, type, &fl6)) {
550 /* select a more meaningful saddr from input if */
551 struct net_device *in_netdev;
552
553 in_netdev = dev_get_by_index(net, IP6CB(skb)->iif);
554 if (in_netdev) {
555 ipv6_dev_get_saddr(net, in_netdev, &fl6.daddr,
556 inet6_sk(sk)->srcprefs,
557 &fl6.saddr);
558 dev_put(in_netdev);
559 }
560 }
561 fl6.flowi6_mark = mark;
562 fl6.flowi6_oif = iif;
563 fl6.fl6_icmp_type = type;
564 fl6.fl6_icmp_code = code;
565 fl6.flowi6_uid = sock_net_uid(net, NULL);
566 fl6.mp_hash = rt6_multipath_hash(net, &fl6, skb, NULL);
567 security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
568
569 sk->sk_mark = mark;
570 np = inet6_sk(sk);
571
572 if (!icmpv6_xrlim_allow(sk, type, &fl6))
573 goto out;
574
575 tmp_hdr.icmp6_type = type;
576 tmp_hdr.icmp6_code = code;
577 tmp_hdr.icmp6_cksum = 0;
578 tmp_hdr.icmp6_pointer = htonl(info);
579
580 if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
581 fl6.flowi6_oif = np->mcast_oif;
582 else if (!fl6.flowi6_oif)
583 fl6.flowi6_oif = np->ucast_oif;
584
585 ipcm6_init_sk(&ipc6, np);
586 fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
587
588 dst = icmpv6_route_lookup(net, skb, sk, &fl6);
589 if (IS_ERR(dst))
590 goto out;
591
592 ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
593
594 msg.skb = skb;
595 msg.offset = skb_network_offset(skb);
596 msg.type = type;
597
598 len = skb->len - msg.offset;
599 len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) - sizeof(struct icmp6hdr));
600 if (len < 0) {
601 net_dbg_ratelimited("icmp: len problem [%pI6c > %pI6c]\n",
602 &hdr->saddr, &hdr->daddr);
603 goto out_dst_release;
604 }
605
606 rcu_read_lock();
607 idev = __in6_dev_get(skb->dev);
608
609 if (ip6_append_data(sk, icmpv6_getfrag, &msg,
610 len + sizeof(struct icmp6hdr),
611 sizeof(struct icmp6hdr),
612 &ipc6, &fl6, (struct rt6_info *)dst,
613 MSG_DONTWAIT)) {
614 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS);
615 ip6_flush_pending_frames(sk);
616 } else {
617 icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr,
618 len + sizeof(struct icmp6hdr));
619 }
620 rcu_read_unlock();
621 out_dst_release:
622 dst_release(dst);
623 out:
624 icmpv6_xmit_unlock(sk);
625 out_bh_enable:
626 local_bh_enable();
627 }
628 EXPORT_SYMBOL(icmp6_send);
629
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28782 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 net-next] ipv6: icmp6: avoid indirect call for icmpv6_send()
@ 2020-06-20 1:53 ` kernel test robot
0 siblings, 0 replies; 5+ messages in thread
From: kernel test robot @ 2020-06-20 1:53 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 8785 bytes --]
Hi Eric,
I love your patch! Perhaps something to improve:
[auto build test WARNING on net-next/master]
url: https://github.com/0day-ci/linux/commits/Eric-Dumazet/ipv6-icmp6-avoid-indirect-call-for-icmpv6_send/20200620-030444
base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 0fb9fbab405351aa0c18973881c4103e4da886b6
config: nds32-randconfig-r002-20200619 (attached as .config)
compiler: nds32le-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=nds32
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>, old ones prefixed by <<):
In file included from ./arch/nds32/include/generated/asm/bug.h:1,
from include/linux/bug.h:5,
from include/linux/thread_info.h:12,
from include/asm-generic/preempt.h:5,
from ./arch/nds32/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:51,
from include/linux/seqlock.h:36,
from include/linux/time.h:6,
from include/linux/stat.h:19,
from include/linux/module.h:13,
from net/ipv6/icmp.c:30:
include/linux/dma-mapping.h: In function 'dma_map_resource':
arch/nds32/include/asm/memory.h:82:32: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
82 | #define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr))
| ^~
include/asm-generic/bug.h:144:27: note: in definition of macro 'WARN_ON_ONCE'
144 | int __ret_warn_once = !!(condition); | ^~~~~~~~~
include/linux/dma-mapping.h:352:19: note: in expansion of macro 'pfn_valid'
352 | if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
| ^~~~~~~~~
net/ipv6/icmp.c: At top level:
>> net/ipv6/icmp.c:442:6: warning: no previous prototype for 'icmp6_send' [-Wmissing-prototypes]
442 | void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
| ^~~~~~~~~~
vim +/icmp6_send +442 net/ipv6/icmp.c
438
439 /*
440 * Send an ICMP message in response to a packet in error
441 */
> 442 void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
443 const struct in6_addr *force_saddr)
444 {
445 struct inet6_dev *idev = NULL;
446 struct ipv6hdr *hdr = ipv6_hdr(skb);
447 struct sock *sk;
448 struct net *net;
449 struct ipv6_pinfo *np;
450 const struct in6_addr *saddr = NULL;
451 struct dst_entry *dst;
452 struct icmp6hdr tmp_hdr;
453 struct flowi6 fl6;
454 struct icmpv6_msg msg;
455 struct ipcm6_cookie ipc6;
456 int iif = 0;
457 int addr_type = 0;
458 int len;
459 u32 mark;
460
461 if ((u8 *)hdr < skb->head ||
462 (skb_network_header(skb) + sizeof(*hdr)) > skb_tail_pointer(skb))
463 return;
464
465 if (!skb->dev)
466 return;
467 net = dev_net(skb->dev);
468 mark = IP6_REPLY_MARK(net, skb->mark);
469 /*
470 * Make sure we respect the rules
471 * i.e. RFC 1885 2.4(e)
472 * Rule (e.1) is enforced by not using icmp6_send
473 * in any code that processes icmp errors.
474 */
475 addr_type = ipv6_addr_type(&hdr->daddr);
476
477 if (ipv6_chk_addr(net, &hdr->daddr, skb->dev, 0) ||
478 ipv6_chk_acast_addr_src(net, skb->dev, &hdr->daddr))
479 saddr = &hdr->daddr;
480
481 /*
482 * Dest addr check
483 */
484
485 if (addr_type & IPV6_ADDR_MULTICAST || skb->pkt_type != PACKET_HOST) {
486 if (type != ICMPV6_PKT_TOOBIG &&
487 !(type == ICMPV6_PARAMPROB &&
488 code == ICMPV6_UNK_OPTION &&
489 (opt_unrec(skb, info))))
490 return;
491
492 saddr = NULL;
493 }
494
495 addr_type = ipv6_addr_type(&hdr->saddr);
496
497 /*
498 * Source addr check
499 */
500
501 if (__ipv6_addr_needs_scope_id(addr_type)) {
502 iif = icmp6_iif(skb);
503 } else {
504 dst = skb_dst(skb);
505 iif = l3mdev_master_ifindex(dst ? dst->dev : skb->dev);
506 }
507
508 /*
509 * Must not send error if the source does not uniquely
510 * identify a single node (RFC2463 Section 2.4).
511 * We check unspecified / multicast addresses here,
512 * and anycast addresses will be checked later.
513 */
514 if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) {
515 net_dbg_ratelimited("icmp6_send: addr_any/mcast source [%pI6c > %pI6c]\n",
516 &hdr->saddr, &hdr->daddr);
517 return;
518 }
519
520 /*
521 * Never answer to a ICMP packet.
522 */
523 if (is_ineligible(skb)) {
524 net_dbg_ratelimited("icmp6_send: no reply to icmp error [%pI6c > %pI6c]\n",
525 &hdr->saddr, &hdr->daddr);
526 return;
527 }
528
529 /* Needed by both icmp_global_allow and icmpv6_xmit_lock */
530 local_bh_disable();
531
532 /* Check global sysctl_icmp_msgs_per_sec ratelimit */
533 if (!(skb->dev->flags & IFF_LOOPBACK) && !icmpv6_global_allow(net, type))
534 goto out_bh_enable;
535
536 mip6_addr_swap(skb);
537
538 sk = icmpv6_xmit_lock(net);
539 if (!sk)
540 goto out_bh_enable;
541
542 memset(&fl6, 0, sizeof(fl6));
543 fl6.flowi6_proto = IPPROTO_ICMPV6;
544 fl6.daddr = hdr->saddr;
545 if (force_saddr)
546 saddr = force_saddr;
547 if (saddr) {
548 fl6.saddr = *saddr;
549 } else if (!icmpv6_rt_has_prefsrc(sk, type, &fl6)) {
550 /* select a more meaningful saddr from input if */
551 struct net_device *in_netdev;
552
553 in_netdev = dev_get_by_index(net, IP6CB(skb)->iif);
554 if (in_netdev) {
555 ipv6_dev_get_saddr(net, in_netdev, &fl6.daddr,
556 inet6_sk(sk)->srcprefs,
557 &fl6.saddr);
558 dev_put(in_netdev);
559 }
560 }
561 fl6.flowi6_mark = mark;
562 fl6.flowi6_oif = iif;
563 fl6.fl6_icmp_type = type;
564 fl6.fl6_icmp_code = code;
565 fl6.flowi6_uid = sock_net_uid(net, NULL);
566 fl6.mp_hash = rt6_multipath_hash(net, &fl6, skb, NULL);
567 security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
568
569 sk->sk_mark = mark;
570 np = inet6_sk(sk);
571
572 if (!icmpv6_xrlim_allow(sk, type, &fl6))
573 goto out;
574
575 tmp_hdr.icmp6_type = type;
576 tmp_hdr.icmp6_code = code;
577 tmp_hdr.icmp6_cksum = 0;
578 tmp_hdr.icmp6_pointer = htonl(info);
579
580 if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
581 fl6.flowi6_oif = np->mcast_oif;
582 else if (!fl6.flowi6_oif)
583 fl6.flowi6_oif = np->ucast_oif;
584
585 ipcm6_init_sk(&ipc6, np);
586 fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
587
588 dst = icmpv6_route_lookup(net, skb, sk, &fl6);
589 if (IS_ERR(dst))
590 goto out;
591
592 ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
593
594 msg.skb = skb;
595 msg.offset = skb_network_offset(skb);
596 msg.type = type;
597
598 len = skb->len - msg.offset;
599 len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) - sizeof(struct icmp6hdr));
600 if (len < 0) {
601 net_dbg_ratelimited("icmp: len problem [%pI6c > %pI6c]\n",
602 &hdr->saddr, &hdr->daddr);
603 goto out_dst_release;
604 }
605
606 rcu_read_lock();
607 idev = __in6_dev_get(skb->dev);
608
609 if (ip6_append_data(sk, icmpv6_getfrag, &msg,
610 len + sizeof(struct icmp6hdr),
611 sizeof(struct icmp6hdr),
612 &ipc6, &fl6, (struct rt6_info *)dst,
613 MSG_DONTWAIT)) {
614 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS);
615 ip6_flush_pending_frames(sk);
616 } else {
617 icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr,
618 len + sizeof(struct icmp6hdr));
619 }
620 rcu_read_unlock();
621 out_dst_release:
622 dst_release(dst);
623 out:
624 icmpv6_xmit_unlock(sk);
625 out_bh_enable:
626 local_bh_enable();
627 }
628 EXPORT_SYMBOL(icmp6_send);
629
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 28782 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2020-06-20 2:11 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-19 19:02 [PATCH v2 net-next] ipv6: icmp6: avoid indirect call for icmpv6_send() Eric Dumazet
2020-06-20 0:43 ` kernel test robot
2020-06-20 0:43 ` kernel test robot
2020-06-20 1:53 ` kernel test robot
2020-06-20 1:53 ` kernel test robot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.