Loading include/net/if_inet6.h +1 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,7 @@ struct ifacaddr6 struct ipv6_devstat { struct proc_dir_entry *proc_dir_entry; DEFINE_SNMP_STAT(struct ipstats_mib, ipv6); DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6); }; Loading include/net/ipv6.h +18 −3 Original line number Diff line number Diff line Loading @@ -113,9 +113,24 @@ extern int sysctl_mld_max_msf; /* MIBs */ DECLARE_SNMP_STAT(struct ipstats_mib, ipv6_statistics); #define IP6_INC_STATS(field) SNMP_INC_STATS(ipv6_statistics, field) #define IP6_INC_STATS_BH(field) SNMP_INC_STATS_BH(ipv6_statistics, field) #define IP6_INC_STATS_USER(field) SNMP_INC_STATS_USER(ipv6_statistics, field) #define IP6_INC_STATS(idev,field) ({ \ struct inet6_dev *_idev = (idev); \ if (likely(_idev != NULL)) \ SNMP_INC_STATS(_idev->stats.ipv6, field); \ SNMP_INC_STATS(ipv6_statistics, field); \ }) #define IP6_INC_STATS_BH(idev,field) ({ \ struct inet6_dev *_idev = (idev); \ if (likely(_idev != NULL)) \ SNMP_INC_STATS_BH(_idev->stats.ipv6, field); \ SNMP_INC_STATS_BH(ipv6_statistics, field); \ }) #define IP6_INC_STATS_USER(idev,field) ({ \ struct inet6_dev *_idev = (idev); \ if (likely(_idev != NULL)) \ SNMP_INC_STATS_USER(_idev->stats.ipv6, field); \ SNMP_INC_STATS_USER(ipv6_statistics, field); \ }) DECLARE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics); #define ICMP6_INC_STATS(idev, field) ({ \ struct inet6_dev *_idev = (idev); \ Loading net/ipv6/exthdrs.c +38 −19 Original line number Diff line number Diff line Loading @@ -284,10 +284,12 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp) #ifdef CONFIG_IPV6_MIP6 __u16 dstbuf; #endif struct dst_entry *dst; if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) || !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); kfree_skb(skb); return -1; } Loading @@ -298,7 +300,9 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp) dstbuf = opt->dst1; #endif dst = dst_clone(skb->dst); if (ip6_parse_tlv(tlvprocdestopt_lst, skbp)) { dst_release(dst); skb = *skbp; skb->h.raw += ((skb->h.raw[1]+1)<<3); opt = IP6CB(skb); Loading @@ -310,7 +314,8 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp) return 1; } IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); dst_release(dst); return -1; } Loading Loading @@ -365,7 +370,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) || !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); kfree_skb(skb); return -1; } Loading @@ -374,7 +380,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) || skb->pkt_type != PACKET_HOST) { IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); kfree_skb(skb); return -1; } Loading @@ -388,7 +395,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) * processed by own */ if (!addr) { IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); kfree_skb(skb); return -1; } Loading @@ -410,7 +418,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) switch (hdr->type) { case IPV6_SRCRT_TYPE_0: if (hdr->hdrlen & 0x01) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw); return -1; } Loading @@ -419,14 +428,16 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) case IPV6_SRCRT_TYPE_2: /* Silently discard invalid RTH type 2 */ if (hdr->hdrlen != 2 || hdr->segments_left != 1) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); kfree_skb(skb); return -1; } break; #endif default: IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw); return -1; } Loading @@ -439,7 +450,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) n = hdr->hdrlen >> 1; if (hdr->segments_left > n) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw); return -1; } Loading @@ -449,12 +461,14 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) */ if (skb_cloned(skb)) { struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC); kfree_skb(skb); /* the copy is a forwarded packet */ if (skb2 == NULL) { IP6_INC_STATS_BH(IPSTATS_MIB_OUTDISCARDS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_OUTDISCARDS); kfree_skb(skb); return -1; } kfree_skb(skb); *skbp = skb = skb2; opt = IP6CB(skb2); hdr = (struct ipv6_rt_hdr *) skb2->h.raw; Loading @@ -475,12 +489,14 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) if (xfrm6_input_addr(skb, (xfrm_address_t *)addr, (xfrm_address_t *)&skb->nh.ipv6h->saddr, IPPROTO_ROUTING) < 0) { IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); kfree_skb(skb); return -1; } if (!ipv6_chk_home_addr(addr)) { IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); kfree_skb(skb); return -1; } Loading @@ -491,7 +507,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) } if (ipv6_addr_is_multicast(addr)) { IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); kfree_skb(skb); return -1; } Loading @@ -510,7 +527,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) if (skb->dst->dev->flags&IFF_LOOPBACK) { if (skb->nh.ipv6h->hop_limit <= 1) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0, skb->dev); kfree_skb(skb); Loading Loading @@ -632,24 +650,25 @@ static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff) if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) { LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", skb->nh.raw[optoff+1]); IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); goto drop; } pkt_len = ntohl(*(u32*)(skb->nh.raw+optoff+2)); if (pkt_len <= IPV6_MAXPLEN) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); return 0; } if (skb->nh.ipv6h->payload_len) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); return 0; } if (pkt_len > skb->len - sizeof(struct ipv6hdr)) { IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INTRUNCATEDPKTS); goto drop; } Loading net/ipv6/icmp.c +2 −1 Original line number Diff line number Diff line Loading @@ -177,7 +177,8 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type, */ dst = ip6_route_output(sk, fl); if (dst->error) { IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) { res = 1; } else { Loading net/ipv6/ip6_input.c +27 −13 Original line number Diff line number Diff line Loading @@ -60,14 +60,22 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt { struct ipv6hdr *hdr; u32 pkt_len; struct inet6_dev *idev; if (skb->pkt_type == PACKET_OTHERHOST) goto drop; if (skb->pkt_type == PACKET_OTHERHOST) { kfree_skb(skb); return 0; } rcu_read_lock(); IP6_INC_STATS_BH(IPSTATS_MIB_INRECEIVES); idev = __in6_dev_get(skb->dev); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INRECEIVES); if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { IP6_INC_STATS_BH(IPSTATS_MIB_INDISCARDS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDISCARDS); rcu_read_unlock(); goto out; } Loading Loading @@ -104,7 +112,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt if (pkt_len + sizeof(struct ipv6hdr) > skb->len) goto truncated; if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS); goto drop; } hdr = skb->nh.ipv6h; Loading @@ -112,17 +120,21 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt if (hdr->nexthdr == NEXTHDR_HOP) { if (ipv6_parse_hopopts(&skb) < 0) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS); rcu_read_unlock(); return 0; } } rcu_read_unlock(); return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish); truncated: IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INTRUNCATEDPKTS); err: IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS); drop: rcu_read_unlock(); kfree_skb(skb); out: return 0; Loading @@ -140,6 +152,7 @@ static inline int ip6_input_finish(struct sk_buff *skb) unsigned int nhoff; int nexthdr; u8 hash; struct inet6_dev *idev; /* * Parse extension headers Loading @@ -147,6 +160,7 @@ static inline int ip6_input_finish(struct sk_buff *skb) rcu_read_lock(); resubmit: idev = ip6_dst_idev(skb->dst); if (!pskb_pull(skb, skb->h.raw - skb->data)) goto discard; nhoff = IP6CB(skb)->nhoff; Loading Loading @@ -185,24 +199,24 @@ static inline int ip6_input_finish(struct sk_buff *skb) if (ret > 0) goto resubmit; else if (ret == 0) IP6_INC_STATS_BH(IPSTATS_MIB_INDELIVERS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDELIVERS); } else { if (!raw_sk) { if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { IP6_INC_STATS_BH(IPSTATS_MIB_INUNKNOWNPROTOS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INUNKNOWNPROTOS); icmpv6_send(skb, ICMPV6_PARAMPROB, ICMPV6_UNK_NEXTHDR, nhoff, skb->dev); } } else IP6_INC_STATS_BH(IPSTATS_MIB_INDELIVERS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDELIVERS); kfree_skb(skb); } rcu_read_unlock(); return 0; discard: IP6_INC_STATS_BH(IPSTATS_MIB_INDISCARDS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDISCARDS); rcu_read_unlock(); kfree_skb(skb); return 0; Loading @@ -219,7 +233,7 @@ int ip6_mc_input(struct sk_buff *skb) struct ipv6hdr *hdr; int deliver; IP6_INC_STATS_BH(IPSTATS_MIB_INMCASTPKTS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS); hdr = skb->nh.ipv6h; deliver = likely(!(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI))) || Loading Loading
include/net/if_inet6.h +1 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,7 @@ struct ifacaddr6 struct ipv6_devstat { struct proc_dir_entry *proc_dir_entry; DEFINE_SNMP_STAT(struct ipstats_mib, ipv6); DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6); }; Loading
include/net/ipv6.h +18 −3 Original line number Diff line number Diff line Loading @@ -113,9 +113,24 @@ extern int sysctl_mld_max_msf; /* MIBs */ DECLARE_SNMP_STAT(struct ipstats_mib, ipv6_statistics); #define IP6_INC_STATS(field) SNMP_INC_STATS(ipv6_statistics, field) #define IP6_INC_STATS_BH(field) SNMP_INC_STATS_BH(ipv6_statistics, field) #define IP6_INC_STATS_USER(field) SNMP_INC_STATS_USER(ipv6_statistics, field) #define IP6_INC_STATS(idev,field) ({ \ struct inet6_dev *_idev = (idev); \ if (likely(_idev != NULL)) \ SNMP_INC_STATS(_idev->stats.ipv6, field); \ SNMP_INC_STATS(ipv6_statistics, field); \ }) #define IP6_INC_STATS_BH(idev,field) ({ \ struct inet6_dev *_idev = (idev); \ if (likely(_idev != NULL)) \ SNMP_INC_STATS_BH(_idev->stats.ipv6, field); \ SNMP_INC_STATS_BH(ipv6_statistics, field); \ }) #define IP6_INC_STATS_USER(idev,field) ({ \ struct inet6_dev *_idev = (idev); \ if (likely(_idev != NULL)) \ SNMP_INC_STATS_USER(_idev->stats.ipv6, field); \ SNMP_INC_STATS_USER(ipv6_statistics, field); \ }) DECLARE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics); #define ICMP6_INC_STATS(idev, field) ({ \ struct inet6_dev *_idev = (idev); \ Loading
net/ipv6/exthdrs.c +38 −19 Original line number Diff line number Diff line Loading @@ -284,10 +284,12 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp) #ifdef CONFIG_IPV6_MIP6 __u16 dstbuf; #endif struct dst_entry *dst; if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) || !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); kfree_skb(skb); return -1; } Loading @@ -298,7 +300,9 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp) dstbuf = opt->dst1; #endif dst = dst_clone(skb->dst); if (ip6_parse_tlv(tlvprocdestopt_lst, skbp)) { dst_release(dst); skb = *skbp; skb->h.raw += ((skb->h.raw[1]+1)<<3); opt = IP6CB(skb); Loading @@ -310,7 +314,8 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp) return 1; } IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); dst_release(dst); return -1; } Loading Loading @@ -365,7 +370,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) || !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); kfree_skb(skb); return -1; } Loading @@ -374,7 +380,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) || skb->pkt_type != PACKET_HOST) { IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); kfree_skb(skb); return -1; } Loading @@ -388,7 +395,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) * processed by own */ if (!addr) { IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); kfree_skb(skb); return -1; } Loading @@ -410,7 +418,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) switch (hdr->type) { case IPV6_SRCRT_TYPE_0: if (hdr->hdrlen & 0x01) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw); return -1; } Loading @@ -419,14 +428,16 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) case IPV6_SRCRT_TYPE_2: /* Silently discard invalid RTH type 2 */ if (hdr->hdrlen != 2 || hdr->segments_left != 1) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); kfree_skb(skb); return -1; } break; #endif default: IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw); return -1; } Loading @@ -439,7 +450,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) n = hdr->hdrlen >> 1; if (hdr->segments_left > n) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw); return -1; } Loading @@ -449,12 +461,14 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) */ if (skb_cloned(skb)) { struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC); kfree_skb(skb); /* the copy is a forwarded packet */ if (skb2 == NULL) { IP6_INC_STATS_BH(IPSTATS_MIB_OUTDISCARDS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_OUTDISCARDS); kfree_skb(skb); return -1; } kfree_skb(skb); *skbp = skb = skb2; opt = IP6CB(skb2); hdr = (struct ipv6_rt_hdr *) skb2->h.raw; Loading @@ -475,12 +489,14 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) if (xfrm6_input_addr(skb, (xfrm_address_t *)addr, (xfrm_address_t *)&skb->nh.ipv6h->saddr, IPPROTO_ROUTING) < 0) { IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); kfree_skb(skb); return -1; } if (!ipv6_chk_home_addr(addr)) { IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); kfree_skb(skb); return -1; } Loading @@ -491,7 +507,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) } if (ipv6_addr_is_multicast(addr)) { IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); kfree_skb(skb); return -1; } Loading @@ -510,7 +527,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) if (skb->dst->dev->flags&IFF_LOOPBACK) { if (skb->nh.ipv6h->hop_limit <= 1) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0, skb->dev); kfree_skb(skb); Loading Loading @@ -632,24 +650,25 @@ static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff) if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) { LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", skb->nh.raw[optoff+1]); IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); goto drop; } pkt_len = ntohl(*(u32*)(skb->nh.raw+optoff+2)); if (pkt_len <= IPV6_MAXPLEN) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); return 0; } if (skb->nh.ipv6h->payload_len) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); return 0; } if (pkt_len > skb->len - sizeof(struct ipv6hdr)) { IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INTRUNCATEDPKTS); goto drop; } Loading
net/ipv6/icmp.c +2 −1 Original line number Diff line number Diff line Loading @@ -177,7 +177,8 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type, */ dst = ip6_route_output(sk, fl); if (dst->error) { IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) { res = 1; } else { Loading
net/ipv6/ip6_input.c +27 −13 Original line number Diff line number Diff line Loading @@ -60,14 +60,22 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt { struct ipv6hdr *hdr; u32 pkt_len; struct inet6_dev *idev; if (skb->pkt_type == PACKET_OTHERHOST) goto drop; if (skb->pkt_type == PACKET_OTHERHOST) { kfree_skb(skb); return 0; } rcu_read_lock(); IP6_INC_STATS_BH(IPSTATS_MIB_INRECEIVES); idev = __in6_dev_get(skb->dev); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INRECEIVES); if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { IP6_INC_STATS_BH(IPSTATS_MIB_INDISCARDS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDISCARDS); rcu_read_unlock(); goto out; } Loading Loading @@ -104,7 +112,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt if (pkt_len + sizeof(struct ipv6hdr) > skb->len) goto truncated; if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS); goto drop; } hdr = skb->nh.ipv6h; Loading @@ -112,17 +120,21 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt if (hdr->nexthdr == NEXTHDR_HOP) { if (ipv6_parse_hopopts(&skb) < 0) { IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS); rcu_read_unlock(); return 0; } } rcu_read_unlock(); return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish); truncated: IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INTRUNCATEDPKTS); err: IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS); drop: rcu_read_unlock(); kfree_skb(skb); out: return 0; Loading @@ -140,6 +152,7 @@ static inline int ip6_input_finish(struct sk_buff *skb) unsigned int nhoff; int nexthdr; u8 hash; struct inet6_dev *idev; /* * Parse extension headers Loading @@ -147,6 +160,7 @@ static inline int ip6_input_finish(struct sk_buff *skb) rcu_read_lock(); resubmit: idev = ip6_dst_idev(skb->dst); if (!pskb_pull(skb, skb->h.raw - skb->data)) goto discard; nhoff = IP6CB(skb)->nhoff; Loading Loading @@ -185,24 +199,24 @@ static inline int ip6_input_finish(struct sk_buff *skb) if (ret > 0) goto resubmit; else if (ret == 0) IP6_INC_STATS_BH(IPSTATS_MIB_INDELIVERS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDELIVERS); } else { if (!raw_sk) { if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { IP6_INC_STATS_BH(IPSTATS_MIB_INUNKNOWNPROTOS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INUNKNOWNPROTOS); icmpv6_send(skb, ICMPV6_PARAMPROB, ICMPV6_UNK_NEXTHDR, nhoff, skb->dev); } } else IP6_INC_STATS_BH(IPSTATS_MIB_INDELIVERS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDELIVERS); kfree_skb(skb); } rcu_read_unlock(); return 0; discard: IP6_INC_STATS_BH(IPSTATS_MIB_INDISCARDS); IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDISCARDS); rcu_read_unlock(); kfree_skb(skb); return 0; Loading @@ -219,7 +233,7 @@ int ip6_mc_input(struct sk_buff *skb) struct ipv6hdr *hdr; int deliver; IP6_INC_STATS_BH(IPSTATS_MIB_INMCASTPKTS); IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS); hdr = skb->nh.ipv6h; deliver = likely(!(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI))) || Loading