summaryrefslogtreecommitdiffstats
path: root/net/ipv6/exthdrs.c
diff options
context:
space:
mode:
authorStephen Suryaputra <ssuryaextr@gmail.com>2018-04-16 13:42:16 -0400
committerDavid S. Miller <davem@davemloft.net>2018-04-17 13:39:51 -0400
commitbdb7cc643fc9db8d6ed9a2b9e524e27ac5882029 (patch)
treea0682f0b12435422ac8699fe2fe29c2a7f5dcd63 /net/ipv6/exthdrs.c
parent032234d8231909ac049f22ea3b408487e1c103eb (diff)
ipv6: Count interface receive statistics on the ingress netdev
The statistics such as InHdrErrors should be counted on the ingress netdev rather than on the dev from the dst, which is the egress. Signed-off-by: Stephen Suryaputra <ssuryaextr@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/exthdrs.c')
-rw-r--r--net/ipv6/exthdrs.c55
1 files changed, 21 insertions, 34 deletions
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index bc68eb661970..5bc2bf3733ab 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -280,6 +280,7 @@ static const struct tlvtype_proc tlvprocdestopt_lst[] = {
280 280
281static int ipv6_destopt_rcv(struct sk_buff *skb) 281static int ipv6_destopt_rcv(struct sk_buff *skb)
282{ 282{
283 struct inet6_dev *idev = __in6_dev_get(skb->dev);
283 struct inet6_skb_parm *opt = IP6CB(skb); 284 struct inet6_skb_parm *opt = IP6CB(skb);
284#if IS_ENABLED(CONFIG_IPV6_MIP6) 285#if IS_ENABLED(CONFIG_IPV6_MIP6)
285 __u16 dstbuf; 286 __u16 dstbuf;
@@ -291,7 +292,7 @@ static int ipv6_destopt_rcv(struct sk_buff *skb)
291 if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || 292 if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
292 !pskb_may_pull(skb, (skb_transport_offset(skb) + 293 !pskb_may_pull(skb, (skb_transport_offset(skb) +
293 ((skb_transport_header(skb)[1] + 1) << 3)))) { 294 ((skb_transport_header(skb)[1] + 1) << 3)))) {
294 __IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst), 295 __IP6_INC_STATS(dev_net(dst->dev), idev,
295 IPSTATS_MIB_INHDRERRORS); 296 IPSTATS_MIB_INHDRERRORS);
296fail_and_free: 297fail_and_free:
297 kfree_skb(skb); 298 kfree_skb(skb);
@@ -319,8 +320,7 @@ fail_and_free:
319 return 1; 320 return 1;
320 } 321 }
321 322
322 __IP6_INC_STATS(dev_net(dst->dev), 323 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
323 ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS);
324 return -1; 324 return -1;
325} 325}
326 326
@@ -416,8 +416,7 @@ looped_back:
416 } 416 }
417 417
418 if (hdr->segments_left >= (hdr->hdrlen >> 1)) { 418 if (hdr->segments_left >= (hdr->hdrlen >> 1)) {
419 __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), 419 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
420 IPSTATS_MIB_INHDRERRORS);
421 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, 420 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
422 ((&hdr->segments_left) - 421 ((&hdr->segments_left) -
423 skb_network_header(skb))); 422 skb_network_header(skb)));
@@ -456,8 +455,7 @@ looped_back:
456 455
457 if (skb_dst(skb)->dev->flags & IFF_LOOPBACK) { 456 if (skb_dst(skb)->dev->flags & IFF_LOOPBACK) {
458 if (ipv6_hdr(skb)->hop_limit <= 1) { 457 if (ipv6_hdr(skb)->hop_limit <= 1) {
459 __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), 458 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
460 IPSTATS_MIB_INHDRERRORS);
461 icmpv6_send(skb, ICMPV6_TIME_EXCEED, 459 icmpv6_send(skb, ICMPV6_TIME_EXCEED,
462 ICMPV6_EXC_HOPLIMIT, 0); 460 ICMPV6_EXC_HOPLIMIT, 0);
463 kfree_skb(skb); 461 kfree_skb(skb);
@@ -481,10 +479,10 @@ looped_back:
481/* called with rcu_read_lock() */ 479/* called with rcu_read_lock() */
482static int ipv6_rthdr_rcv(struct sk_buff *skb) 480static int ipv6_rthdr_rcv(struct sk_buff *skb)
483{ 481{
482 struct inet6_dev *idev = __in6_dev_get(skb->dev);
484 struct inet6_skb_parm *opt = IP6CB(skb); 483 struct inet6_skb_parm *opt = IP6CB(skb);
485 struct in6_addr *addr = NULL; 484 struct in6_addr *addr = NULL;
486 struct in6_addr daddr; 485 struct in6_addr daddr;
487 struct inet6_dev *idev;
488 int n, i; 486 int n, i;
489 struct ipv6_rt_hdr *hdr; 487 struct ipv6_rt_hdr *hdr;
490 struct rt0_hdr *rthdr; 488 struct rt0_hdr *rthdr;
@@ -498,8 +496,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
498 if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || 496 if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
499 !pskb_may_pull(skb, (skb_transport_offset(skb) + 497 !pskb_may_pull(skb, (skb_transport_offset(skb) +
500 ((skb_transport_header(skb)[1] + 1) << 3)))) { 498 ((skb_transport_header(skb)[1] + 1) << 3)))) {
501 __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), 499 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
502 IPSTATS_MIB_INHDRERRORS);
503 kfree_skb(skb); 500 kfree_skb(skb);
504 return -1; 501 return -1;
505 } 502 }
@@ -508,8 +505,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
508 505
509 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) || 506 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) ||
510 skb->pkt_type != PACKET_HOST) { 507 skb->pkt_type != PACKET_HOST) {
511 __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), 508 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INADDRERRORS);
512 IPSTATS_MIB_INADDRERRORS);
513 kfree_skb(skb); 509 kfree_skb(skb);
514 return -1; 510 return -1;
515 } 511 }
@@ -527,7 +523,7 @@ looped_back:
527 * processed by own 523 * processed by own
528 */ 524 */
529 if (!addr) { 525 if (!addr) {
530 __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), 526 __IP6_INC_STATS(net, idev,
531 IPSTATS_MIB_INADDRERRORS); 527 IPSTATS_MIB_INADDRERRORS);
532 kfree_skb(skb); 528 kfree_skb(skb);
533 return -1; 529 return -1;
@@ -553,8 +549,7 @@ looped_back:
553 goto unknown_rh; 549 goto unknown_rh;
554 /* Silently discard invalid RTH type 2 */ 550 /* Silently discard invalid RTH type 2 */
555 if (hdr->hdrlen != 2 || hdr->segments_left != 1) { 551 if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
556 __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), 552 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
557 IPSTATS_MIB_INHDRERRORS);
558 kfree_skb(skb); 553 kfree_skb(skb);
559 return -1; 554 return -1;
560 } 555 }
@@ -572,8 +567,7 @@ looped_back:
572 n = hdr->hdrlen >> 1; 567 n = hdr->hdrlen >> 1;
573 568
574 if (hdr->segments_left > n) { 569 if (hdr->segments_left > n) {
575 __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), 570 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
576 IPSTATS_MIB_INHDRERRORS);
577 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, 571 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
578 ((&hdr->segments_left) - 572 ((&hdr->segments_left) -
579 skb_network_header(skb))); 573 skb_network_header(skb)));
@@ -609,14 +603,12 @@ looped_back:
609 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr, 603 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
610 (xfrm_address_t *)&ipv6_hdr(skb)->saddr, 604 (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
611 IPPROTO_ROUTING) < 0) { 605 IPPROTO_ROUTING) < 0) {
612 __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), 606 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INADDRERRORS);
613 IPSTATS_MIB_INADDRERRORS);
614 kfree_skb(skb); 607 kfree_skb(skb);
615 return -1; 608 return -1;
616 } 609 }
617 if (!ipv6_chk_home_addr(dev_net(skb_dst(skb)->dev), addr)) { 610 if (!ipv6_chk_home_addr(dev_net(skb_dst(skb)->dev), addr)) {
618 __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), 611 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INADDRERRORS);
619 IPSTATS_MIB_INADDRERRORS);
620 kfree_skb(skb); 612 kfree_skb(skb);
621 return -1; 613 return -1;
622 } 614 }
@@ -627,8 +619,7 @@ looped_back:
627 } 619 }
628 620
629 if (ipv6_addr_is_multicast(addr)) { 621 if (ipv6_addr_is_multicast(addr)) {
630 __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), 622 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INADDRERRORS);
631 IPSTATS_MIB_INADDRERRORS);
632 kfree_skb(skb); 623 kfree_skb(skb);
633 return -1; 624 return -1;
634 } 625 }
@@ -647,8 +638,7 @@ looped_back:
647 638
648 if (skb_dst(skb)->dev->flags&IFF_LOOPBACK) { 639 if (skb_dst(skb)->dev->flags&IFF_LOOPBACK) {
649 if (ipv6_hdr(skb)->hop_limit <= 1) { 640 if (ipv6_hdr(skb)->hop_limit <= 1) {
650 __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), 641 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
651 IPSTATS_MIB_INHDRERRORS);
652 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 642 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
653 0); 643 0);
654 kfree_skb(skb); 644 kfree_skb(skb);
@@ -663,7 +653,7 @@ looped_back:
663 return -1; 653 return -1;
664 654
665unknown_rh: 655unknown_rh:
666 __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_INHDRERRORS); 656 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
667 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, 657 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
668 (&hdr->type) - skb_network_header(skb)); 658 (&hdr->type) - skb_network_header(skb));
669 return -1; 659 return -1;
@@ -755,34 +745,31 @@ static bool ipv6_hop_ra(struct sk_buff *skb, int optoff)
755static bool ipv6_hop_jumbo(struct sk_buff *skb, int optoff) 745static bool ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
756{ 746{
757 const unsigned char *nh = skb_network_header(skb); 747 const unsigned char *nh = skb_network_header(skb);
748 struct inet6_dev *idev = __in6_dev_get_safely(skb->dev);
758 struct net *net = ipv6_skb_net(skb); 749 struct net *net = ipv6_skb_net(skb);
759 u32 pkt_len; 750 u32 pkt_len;
760 751
761 if (nh[optoff + 1] != 4 || (optoff & 3) != 2) { 752 if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
762 net_dbg_ratelimited("ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", 753 net_dbg_ratelimited("ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
763 nh[optoff+1]); 754 nh[optoff+1]);
764 __IP6_INC_STATS(net, ipv6_skb_idev(skb), 755 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
765 IPSTATS_MIB_INHDRERRORS);
766 goto drop; 756 goto drop;
767 } 757 }
768 758
769 pkt_len = ntohl(*(__be32 *)(nh + optoff + 2)); 759 pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
770 if (pkt_len <= IPV6_MAXPLEN) { 760 if (pkt_len <= IPV6_MAXPLEN) {
771 __IP6_INC_STATS(net, ipv6_skb_idev(skb), 761 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
772 IPSTATS_MIB_INHDRERRORS);
773 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); 762 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
774 return false; 763 return false;
775 } 764 }
776 if (ipv6_hdr(skb)->payload_len) { 765 if (ipv6_hdr(skb)->payload_len) {
777 __IP6_INC_STATS(net, ipv6_skb_idev(skb), 766 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
778 IPSTATS_MIB_INHDRERRORS);
779 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); 767 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
780 return false; 768 return false;
781 } 769 }
782 770
783 if (pkt_len > skb->len - sizeof(struct ipv6hdr)) { 771 if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
784 __IP6_INC_STATS(net, ipv6_skb_idev(skb), 772 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INTRUNCATEDPKTS);
785 IPSTATS_MIB_INTRUNCATEDPKTS);
786 goto drop; 773 goto drop;
787 } 774 }
788 775