Commit 2204808f authored by Shirley Ma's avatar Shirley Ma Committed by David S. Miller

[IPV6]: Add missing MIB counter increments.

parent a0919ff9
......@@ -159,6 +159,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
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(Ip6InHdrErrors);
kfree_skb(skb);
return -1;
}
......@@ -171,6 +172,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
return 1;
}
IP6_INC_STATS_BH(Ip6InHdrErrors);
return -1;
}
......@@ -234,6 +236,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) ||
skb->pkt_type != PACKET_HOST) {
IP6_INC_STATS_BH(Ip6InAddrErrors);
kfree_skb(skb);
return -1;
}
......@@ -249,11 +252,13 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
}
if (hdr->type != IPV6_SRCRT_TYPE_0) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
return -1;
}
if (hdr->hdrlen & 0x01) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw);
return -1;
}
......@@ -266,6 +271,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
n = hdr->hdrlen >> 1;
if (hdr->segments_left > n) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw);
return -1;
}
......@@ -276,8 +282,11 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
if (skb_cloned(skb)) {
struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
kfree_skb(skb);
if (skb2 == NULL)
/* the copy is a forwarded packet */
if (skb2 == NULL) {
IP6_INC_STATS_BH(Ip6OutDiscards);
return -1;
}
*skbp = skb = skb2;
opt = (struct inet6_skb_parm *)skb2->cb;
hdr = (struct ipv6_rt_hdr *) skb2->h.raw;
......@@ -293,6 +302,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
addr += i - 1;
if (ipv6_addr_is_multicast(addr)) {
IP6_INC_STATS_BH(Ip6InAddrErrors);
kfree_skb(skb);
return -1;
}
......@@ -309,6 +319,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
}
if (skb->dst->dev->flags&IFF_LOOPBACK) {
if (skb->nh.ipv6h->hop_limit <= 1) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
0, skb->dev);
kfree_skb(skb);
......@@ -425,15 +436,18 @@ static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) {
if (net_ratelimit())
printk(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", skb->nh.raw[optoff+1]);
IP6_INC_STATS_BH(Ip6InHdrErrors);
goto drop;
}
pkt_len = ntohl(*(u32*)(skb->nh.raw+optoff+2));
if (pkt_len <= IPV6_MAXPLEN) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
return 0;
}
if (skb->nh.ipv6h->payload_len) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
return 0;
}
......
......@@ -79,8 +79,10 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
if (skb->len < sizeof(struct ipv6hdr))
goto err;
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
goto drop;
}
hdr = skb->nh.ipv6h;
......@@ -94,8 +96,10 @@ 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 (pkt_len + sizeof(struct ipv6hdr) < skb->len) {
if (__pskb_trim(skb, pkt_len + sizeof(struct ipv6hdr)))
if (__pskb_trim(skb, pkt_len + sizeof(struct ipv6hdr))){
IP6_INC_STATS_BH(Ip6InHdrErrors);
goto drop;
}
hdr = skb->nh.ipv6h;
if (skb->ip_summed == CHECKSUM_HW)
skb->ip_summed = CHECKSUM_NONE;
......@@ -206,6 +210,7 @@ static inline int ip6_input_finish(struct sk_buff *skb)
return 0;
discard:
IP6_INC_STATS_BH(Ip6InDiscards);
rcu_read_unlock();
kfree_skb(skb);
return 0;
......
......@@ -87,6 +87,7 @@ static inline int ip6_output_finish(struct sk_buff *skb)
} else if (dst->neighbour)
return dst->neighbour->output(skb);
IP6_INC_STATS_BH(Ip6OutNoRoutes);
kfree_skb(skb);
return -EINVAL;
......@@ -131,6 +132,7 @@ int ip6_output2(struct sk_buff *skb)
ip6_dev_loopback_xmit);
if (skb->nh.ipv6h->hop_limit == 0) {
IP6_INC_STATS(Ip6OutDiscards);
kfree_skb(skb);
return 0;
}
......@@ -167,6 +169,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
dst = ip6_route_output(skb->sk, &fl);
if (dst->error) {
IP6_INC_STATS(Ip6OutNoRoutes);
if (net_ratelimit())
printk(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
dst_release(dst);
......@@ -224,8 +227,10 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
kfree_skb(skb);
skb = skb2;
if (skb == NULL)
if (skb == NULL) {
IP6_INC_STATS(Ip6OutDiscards);
return -ENOBUFS;
}
if (sk)
skb_set_owner_w(skb, sk);
}
......@@ -265,6 +270,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
skb->dev = dst->dev;
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
IP6_INC_STATS(Ip6FragFails);
kfree_skb(skb);
return -EMSGSIZE;
}
......@@ -345,8 +351,10 @@ int ip6_forward(struct sk_buff *skb)
if (ipv6_devconf.forwarding == 0)
goto error;
if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb))
if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
IP6_INC_STATS(Ip6InDiscards);
goto drop;
}
skb->ip_summed = CHECKSUM_NONE;
......@@ -382,8 +390,10 @@ int ip6_forward(struct sk_buff *skb)
return -ETIMEDOUT;
}
if (!xfrm6_route_forward(skb))
if (!xfrm6_route_forward(skb)) {
IP6_INC_STATS(Ip6InDiscards);
goto drop;
}
/* IPv6 specs say nothing about it, but it is clear that we cannot
send redirects to source routed frames.
......@@ -420,12 +430,15 @@ int ip6_forward(struct sk_buff *skb)
skb->dev = dst->dev;
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_pmtu(dst), skb->dev);
IP6_INC_STATS_BH(Ip6InTooBigErrors);
IP6_INC_STATS_BH(Ip6FragFails);
kfree_skb(skb);
return -EMSGSIZE;
}
if (skb_cow(skb, dst->dev->hard_header_len))
if (skb_cow(skb, dst->dev->hard_header_len)) {
IP6_INC_STATS(Ip6OutDiscards);
goto drop;
}
hdr = skb->nh.ipv6h;
......@@ -648,6 +661,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
NETDEBUG(printk(KERN_INFO "IPv6: frag: no memory for new fragment!\n"));
IP6_INC_STATS(Ip6FragFails);
err = -ENOMEM;
goto fail;
}
......@@ -1062,6 +1076,7 @@ int ip6_push_pending_frames(struct sock *sk)
ipv6_addr_copy(&hdr->daddr, final_dst);
skb->dst = dst_clone(&rt->u.dst);
IP6_INC_STATS(Ip6OutRequests);
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output);
if (err) {
if (err > 0)
......@@ -1092,8 +1107,10 @@ void ip6_flush_pending_frames(struct sock *sk)
struct ipv6_pinfo *np = inet6_sk(sk);
struct sk_buff *skb;
while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL)
while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) {
IP6_INC_STATS(Ip6OutDiscards);
kfree_skb(skb);
}
inet->cork.flags &= ~IPCORK_OPT;
......
......@@ -452,6 +452,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
skb->dst = dst;
idev = in6_dev_get(dst->dev);
IP6_INC_STATS(Ip6OutRequests);
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
if (!err) {
ICMP6_INC_STATS(idev, Icmp6OutNeighborAdvertisements);
......@@ -535,6 +536,7 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
/* send it! */
skb->dst = dst;
idev = in6_dev_get(dst->dev);
IP6_INC_STATS(Ip6OutRequests);
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
if (!err) {
ICMP6_INC_STATS(idev, Icmp6OutNeighborSolicits);
......@@ -607,6 +609,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
/* send it! */
skb->dst = dst;
idev = in6_dev_get(dst->dev);
IP6_INC_STATS(Ip6OutRequests);
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
if (!err) {
ICMP6_INC_STATS(idev, Icmp6OutRouterSolicits);
......@@ -1332,6 +1335,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
buff->dst = dst;
idev = in6_dev_get(dst->dev);
IP6_INC_STATS(Ip6OutRequests);
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
if (!err) {
ICMP6_INC_STATS(idev, Icmp6OutRedirects);
......
......@@ -526,6 +526,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
if (err)
goto error_fault;
IP6_INC_STATS(Ip6OutRequests);
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
dst_output);
if (err > 0)
......
......@@ -426,6 +426,7 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1)));
if ((unsigned int)end > IPV6_MAXPLEN) {
IP6_INC_STATS_BH(Ip6InHdrErrors);
icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off - skb->nh.raw);
return;
}
......@@ -452,6 +453,7 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
/* RFC2460 says always send parameter problem in
* this case. -DaveM
*/
IP6_INC_STATS_BH(Ip6InHdrErrors);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
offsetof(struct ipv6hdr, payload_len));
return;
......@@ -570,6 +572,7 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
return;
err:
IP6_INC_STATS(Ip6ReasmFails);
kfree_skb(skb);
}
......@@ -694,10 +697,12 @@ static int ipv6_frag_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
/* Jumbo payload inhibits frag. header */
if (hdr->payload_len==0) {
IP6_INC_STATS(Ip6InHdrErrors);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw);
return -1;
}
if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+sizeof(struct frag_hdr))) {
IP6_INC_STATS(Ip6InHdrErrors);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw);
return -1;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment