diff options
author | Florian Westphal <fw@strlen.de> | 2014-01-26 04:58:16 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-01-27 01:38:23 -0500 |
commit | de960aa9ab4decc3304959f69533eef64d05d8e8 (patch) | |
tree | 1f225ca6fef5512f121856b7572534d2ed171e39 /net | |
parent | 77d143de75812596a58d126606f42d1214e09dde (diff) |
net: add and use skb_gso_transport_seglen()
This moves part of Eric Dumazets skb_gso_seglen helper from tbf sched to
skbuff core so it may be reused by upcoming ip forwarding path patch.
Signed-off-by: Florian Westphal <fw@strlen.de>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/skbuff.c | 25 | ||||
-rw-r--r-- | net/sched/sch_tbf.c | 13 |
2 files changed, 28 insertions, 10 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 8f519dbb358b..9ae6d11374d1 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -47,6 +47,8 @@ | |||
47 | #include <linux/in.h> | 47 | #include <linux/in.h> |
48 | #include <linux/inet.h> | 48 | #include <linux/inet.h> |
49 | #include <linux/slab.h> | 49 | #include <linux/slab.h> |
50 | #include <linux/tcp.h> | ||
51 | #include <linux/udp.h> | ||
50 | #include <linux/netdevice.h> | 52 | #include <linux/netdevice.h> |
51 | #ifdef CONFIG_NET_CLS_ACT | 53 | #ifdef CONFIG_NET_CLS_ACT |
52 | #include <net/pkt_sched.h> | 54 | #include <net/pkt_sched.h> |
@@ -3916,3 +3918,26 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet) | |||
3916 | nf_reset_trace(skb); | 3918 | nf_reset_trace(skb); |
3917 | } | 3919 | } |
3918 | EXPORT_SYMBOL_GPL(skb_scrub_packet); | 3920 | EXPORT_SYMBOL_GPL(skb_scrub_packet); |
3921 | |||
3922 | /** | ||
3923 | * skb_gso_transport_seglen - Return length of individual segments of a gso packet | ||
3924 | * | ||
3925 | * @skb: GSO skb | ||
3926 | * | ||
3927 | * skb_gso_transport_seglen is used to determine the real size of the | ||
3928 | * individual segments, including Layer4 headers (TCP/UDP). | ||
3929 | * | ||
3930 | * The MAC/L2 or network (IP, IPv6) headers are not accounted for. | ||
3931 | */ | ||
3932 | unsigned int skb_gso_transport_seglen(const struct sk_buff *skb) | ||
3933 | { | ||
3934 | const struct skb_shared_info *shinfo = skb_shinfo(skb); | ||
3935 | unsigned int hdr_len; | ||
3936 | |||
3937 | if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) | ||
3938 | hdr_len = tcp_hdrlen(skb); | ||
3939 | else | ||
3940 | hdr_len = sizeof(struct udphdr); | ||
3941 | return hdr_len + shinfo->gso_size; | ||
3942 | } | ||
3943 | EXPORT_SYMBOL_GPL(skb_gso_transport_seglen); | ||
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index fbba5b0ec121..1cb413fead89 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <net/netlink.h> | 21 | #include <net/netlink.h> |
22 | #include <net/sch_generic.h> | 22 | #include <net/sch_generic.h> |
23 | #include <net/pkt_sched.h> | 23 | #include <net/pkt_sched.h> |
24 | #include <net/tcp.h> | ||
25 | 24 | ||
26 | 25 | ||
27 | /* Simple Token Bucket Filter. | 26 | /* Simple Token Bucket Filter. |
@@ -148,16 +147,10 @@ static u64 psched_ns_t2l(const struct psched_ratecfg *r, | |||
148 | * Return length of individual segments of a gso packet, | 147 | * Return length of individual segments of a gso packet, |
149 | * including all headers (MAC, IP, TCP/UDP) | 148 | * including all headers (MAC, IP, TCP/UDP) |
150 | */ | 149 | */ |
151 | static unsigned int skb_gso_seglen(const struct sk_buff *skb) | 150 | static unsigned int skb_gso_mac_seglen(const struct sk_buff *skb) |
152 | { | 151 | { |
153 | unsigned int hdr_len = skb_transport_header(skb) - skb_mac_header(skb); | 152 | unsigned int hdr_len = skb_transport_header(skb) - skb_mac_header(skb); |
154 | const struct skb_shared_info *shinfo = skb_shinfo(skb); | 153 | return hdr_len + skb_gso_transport_seglen(skb); |
155 | |||
156 | if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) | ||
157 | hdr_len += tcp_hdrlen(skb); | ||
158 | else | ||
159 | hdr_len += sizeof(struct udphdr); | ||
160 | return hdr_len + shinfo->gso_size; | ||
161 | } | 154 | } |
162 | 155 | ||
163 | /* GSO packet is too big, segment it so that tbf can transmit | 156 | /* GSO packet is too big, segment it so that tbf can transmit |
@@ -202,7 +195,7 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
202 | int ret; | 195 | int ret; |
203 | 196 | ||
204 | if (qdisc_pkt_len(skb) > q->max_size) { | 197 | if (qdisc_pkt_len(skb) > q->max_size) { |
205 | if (skb_is_gso(skb) && skb_gso_seglen(skb) <= q->max_size) | 198 | if (skb_is_gso(skb) && skb_gso_mac_seglen(skb) <= q->max_size) |
206 | return tbf_segment(skb, sch); | 199 | return tbf_segment(skb, sch); |
207 | return qdisc_reshape_fail(skb, sch); | 200 | return qdisc_reshape_fail(skb, sch); |
208 | } | 201 | } |