#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;
}
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);
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;
}
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;
}
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;
}
* 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;
}
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;
}
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;
}
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;
}
*/
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;
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;
}
}
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;
}
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);
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));
+ pkt_len = ntohl(*(__be32*)(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;
}