History

net: ip: add skb drop reasons to ip forwarding

Replace kfree_skb() which is used in ip6_forward() and ip_forward() with kfree_skb_reason(). The new drop reason 'SKB_DROP_REASON_PKT_TOO_BIG' is introduced for the case that the length of the packet exceeds MTU and can't fragment.

Menglong Dong committed 4 years ago

Commit 2edc1a31 parent 3ae42cc4 files · +20 −6Browse files

Unified · Split

4 files
  1. include/linux/skbuff.h +3 −0
  2. include/trace/events/skb.h +1 −0
  3. net/ipv4/ip_forward.c +10 −3
  4. net/ipv6/ip6_output.c +6 −3
include/linux/skbuff.h+3−0
@@ -453,6 +453,9 @@ enum skb_drop_reason { · 452 unmodified lines
453453 SKB_DROP_REASON_IP_INNOROUTES, /* network unreachable, corresponding
454454 * to IPSTATS_MIB_INADDRERRORS
455455 */
456+ SKB_DROP_REASON_PKT_TOO_BIG, /* packet size is too big (maybe exceed
457+ * the MTU)
458+ */
456459 SKB_DROP_REASON_MAX,
457460 };
458461
include/trace/events/skb.h+1−0
@@ -65,6 +65,7 @@ · 64 unmodified lines
6565 EM(SKB_DROP_REASON_INVALID_PROTO, INVALID_PROTO) \
6666 EM(SKB_DROP_REASON_IP_INADDRERRORS, IP_INADDRERRORS) \
6767 EM(SKB_DROP_REASON_IP_INNOROUTES, IP_INNOROUTES) \
68+ EM(SKB_DROP_REASON_PKT_TOO_BIG, PKT_TOO_BIG) \
6869 EMe(SKB_DROP_REASON_MAX, MAX)
6970
7071 #undef EM
net/ipv4/ip_forward.c+10−3
@@ -90,6 +90,7 @@ int ip_forward(struct sk_buff *skb) · 89 unmodified lines
9090 struct rtable *rt; /* Route we use */
9191 struct ip_options *opt = &(IPCB(skb)->opt);
9292 struct net *net;
93+ SKB_DR(reason);
9394
9495 /* that should never happen */
9596 if (skb->pkt_type != PACKET_HOST)
@@ -101,8 +102,10 @@ int ip_forward(struct sk_buff *skb) · 5 unmodified lines
101102 if (skb_warn_if_lro(skb))
102103 goto drop;
103104
104− if (!xfrm4_policy_check(NULL, XFRM_POLICY_FWD, skb))
105+ if (!xfrm4_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
106+ SKB_DR_SET(reason, XFRM_POLICY);
105107 goto drop;
108+ }
106109
107110 if (IPCB(skb)->opt.router_alert && ip_call_ra_chain(skb))
108111 return NET_RX_SUCCESS;
@@ -118,8 +121,10 @@ int ip_forward(struct sk_buff *skb) · 9 unmodified lines
118121 if (ip_hdr(skb)->ttl <= 1)
119122 goto too_many_hops;
120123
121− if (!xfrm4_route_forward(skb))
124+ if (!xfrm4_route_forward(skb)) {
125+ SKB_DR_SET(reason, XFRM_POLICY);
122126 goto drop;
127+ }
123128
124129 rt = skb_rtable(skb);
125130
@@ -132,6 +137,7 @@ int ip_forward(struct sk_buff *skb) · 6 unmodified lines
132137 IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS);
133138 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
134139 htonl(mtu));
140+ SKB_DR_SET(reason, PKT_TOO_BIG);
135141 goto drop;
136142 }
137143
@@ -169,7 +175,8 @@ too_many_hops: · 31 unmodified lines
169175 /* Tell the sender its packet died... */
170176 __IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS);
171177 icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0);
178+ SKB_DR_SET(reason, IP_INHDR);
172179 drop:
173− kfree_skb(skb);
180+ kfree_skb_reason(skb, reason);
174181 return NET_RX_DROP;
175182 }
net/ipv6/ip6_output.c+6−3
@@ -469,6 +469,7 @@ int ip6_forward(struct sk_buff *skb) · 468 unmodified lines
469469 struct inet6_skb_parm *opt = IP6CB(skb);
470470 struct net *net = dev_net(dst->dev);
471471 struct inet6_dev *idev;
472+ SKB_DR(reason);
472473 u32 mtu;
473474
474475 idev = __in6_dev_get_safely(dev_get_by_index_rcu(net, IP6CB(skb)->iif));
@@ -518,7 +519,7 @@ int ip6_forward(struct sk_buff *skb) · 43 unmodified lines
518519 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0);
519520 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
520521
521− kfree_skb(skb);
522+ kfree_skb_reason(skb, SKB_DROP_REASON_IP_INHDR);
522523 return -ETIMEDOUT;
523524 }
524525
@@ -537,6 +538,7 @@ int ip6_forward(struct sk_buff *skb) · 12 unmodified lines
537538
538539 if (!xfrm6_route_forward(skb)) {
539540 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
541+ SKB_DR_SET(reason, XFRM_POLICY);
540542 goto drop;
541543 }
542544 dst = skb_dst(skb);
@@ -596,7 +598,7 @@ int ip6_forward(struct sk_buff *skb) · 53 unmodified lines
596598 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INTOOBIGERRORS);
597599 __IP6_INC_STATS(net, ip6_dst_idev(dst),
598600 IPSTATS_MIB_FRAGFAILS);
599− kfree_skb(skb);
601+ kfree_skb_reason(skb, SKB_DROP_REASON_PKT_TOO_BIG);
600602 return -EMSGSIZE;
601603 }
602604
@@ -618,8 +620,9 @@ int ip6_forward(struct sk_buff *skb) · 15 unmodified lines
618620
619621 error:
620622 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INADDRERRORS);
623+ SKB_DR_SET(reason, IP_INADDRERRORS);
621624 drop:
622− kfree_skb(skb);
625+ kfree_skb_reason(skb, reason);
623626 return -EINVAL;
624627 }
625628