diff options
| author | Stephen Suryaputra <ssuryaextr@gmail.com> | 2018-04-16 13:42:16 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2018-04-17 13:39:51 -0400 |
| commit | bdb7cc643fc9db8d6ed9a2b9e524e27ac5882029 (patch) | |
| tree | a0682f0b12435422ac8699fe2fe29c2a7f5dcd63 /net/ipv6/exthdrs.c | |
| parent | 032234d8231909ac049f22ea3b408487e1c103eb (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.c | 55 |
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 | ||
| 281 | static int ipv6_destopt_rcv(struct sk_buff *skb) | 281 | static 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); |
| 296 | fail_and_free: | 297 | fail_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() */ |
| 482 | static int ipv6_rthdr_rcv(struct sk_buff *skb) | 480 | static 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 | ||
| 665 | unknown_rh: | 655 | unknown_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) | |||
| 755 | static bool ipv6_hop_jumbo(struct sk_buff *skb, int optoff) | 745 | static 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 | ||
