Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Florian Westphal and committed by
David S. Miller
de960aa9 77d143de

+29 -10
+1
include/linux/skbuff.h
··· 2456 2456 void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len); 2457 2457 int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen); 2458 2458 void skb_scrub_packet(struct sk_buff *skb, bool xnet); 2459 + unsigned int skb_gso_transport_seglen(const struct sk_buff *skb); 2459 2460 struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features); 2460 2461 2461 2462 struct skb_checksum_ops {
+25
net/core/skbuff.c
··· 47 47 #include <linux/in.h> 48 48 #include <linux/inet.h> 49 49 #include <linux/slab.h> 50 + #include <linux/tcp.h> 51 + #include <linux/udp.h> 50 52 #include <linux/netdevice.h> 51 53 #ifdef CONFIG_NET_CLS_ACT 52 54 #include <net/pkt_sched.h> ··· 3918 3916 nf_reset_trace(skb); 3919 3917 } 3920 3918 EXPORT_SYMBOL_GPL(skb_scrub_packet); 3919 + 3920 + /** 3921 + * skb_gso_transport_seglen - Return length of individual segments of a gso packet 3922 + * 3923 + * @skb: GSO skb 3924 + * 3925 + * skb_gso_transport_seglen is used to determine the real size of the 3926 + * individual segments, including Layer4 headers (TCP/UDP). 3927 + * 3928 + * The MAC/L2 or network (IP, IPv6) headers are not accounted for. 3929 + */ 3930 + unsigned int skb_gso_transport_seglen(const struct sk_buff *skb) 3931 + { 3932 + const struct skb_shared_info *shinfo = skb_shinfo(skb); 3933 + unsigned int hdr_len; 3934 + 3935 + if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) 3936 + hdr_len = tcp_hdrlen(skb); 3937 + else 3938 + hdr_len = sizeof(struct udphdr); 3939 + return hdr_len + shinfo->gso_size; 3940 + } 3941 + EXPORT_SYMBOL_GPL(skb_gso_transport_seglen);
+3 -10
net/sched/sch_tbf.c
··· 21 21 #include <net/netlink.h> 22 22 #include <net/sch_generic.h> 23 23 #include <net/pkt_sched.h> 24 - #include <net/tcp.h> 25 24 26 25 27 26 /* Simple Token Bucket Filter. ··· 147 148 * Return length of individual segments of a gso packet, 148 149 * including all headers (MAC, IP, TCP/UDP) 149 150 */ 150 - static unsigned int skb_gso_seglen(const struct sk_buff *skb) 151 + static unsigned int skb_gso_mac_seglen(const struct sk_buff *skb) 151 152 { 152 153 unsigned int hdr_len = skb_transport_header(skb) - skb_mac_header(skb); 153 - const struct skb_shared_info *shinfo = skb_shinfo(skb); 154 - 155 - if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) 156 - hdr_len += tcp_hdrlen(skb); 157 - else 158 - hdr_len += sizeof(struct udphdr); 159 - return hdr_len + shinfo->gso_size; 154 + return hdr_len + skb_gso_transport_seglen(skb); 160 155 } 161 156 162 157 /* GSO packet is too big, segment it so that tbf can transmit ··· 195 202 int ret; 196 203 197 204 if (qdisc_pkt_len(skb) > q->max_size) { 198 - if (skb_is_gso(skb) && skb_gso_seglen(skb) <= q->max_size) 205 + if (skb_is_gso(skb) && skb_gso_mac_seglen(skb) <= q->max_size) 199 206 return tbf_segment(skb, sch); 200 207 return qdisc_reshape_fail(skb, sch); 201 208 }