Ver código fonte

net_sched: better precise estimation on packet length for untrusted packets

gso_segs were reset to zero when kernel receive packets from untrusted
source. But we use this zero value to estimate precise packet len which is
wrong. So this patch tries to estimate the correct gso_segs value before using
it in qdisc_pkt_len_init().

Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Jason Wang 12 anos atrás
pai
commit
15e5a03071
1 arquivos alterados com 7 adições e 1 exclusões
  1. 7 1
      net/core/dev.c

+ 7 - 1
net/core/dev.c

@@ -2588,6 +2588,7 @@ static void qdisc_pkt_len_init(struct sk_buff *skb)
 	 */
 	 */
 	if (shinfo->gso_size)  {
 	if (shinfo->gso_size)  {
 		unsigned int hdr_len;
 		unsigned int hdr_len;
+		u16 gso_segs = shinfo->gso_segs;
 
 
 		/* mac layer + network layer */
 		/* mac layer + network layer */
 		hdr_len = skb_transport_header(skb) - skb_mac_header(skb);
 		hdr_len = skb_transport_header(skb) - skb_mac_header(skb);
@@ -2597,7 +2598,12 @@ static void qdisc_pkt_len_init(struct sk_buff *skb)
 			hdr_len += tcp_hdrlen(skb);
 			hdr_len += tcp_hdrlen(skb);
 		else
 		else
 			hdr_len += sizeof(struct udphdr);
 			hdr_len += sizeof(struct udphdr);
-		qdisc_skb_cb(skb)->pkt_len += (shinfo->gso_segs - 1) * hdr_len;
+
+		if (shinfo->gso_type & SKB_GSO_DODGY)
+			gso_segs = DIV_ROUND_UP(skb->len - hdr_len,
+						shinfo->gso_size);
+
+		qdisc_skb_cb(skb)->pkt_len += (gso_segs - 1) * hdr_len;
 	}
 	}
 }
 }