Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d468f02 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ipv4/GRO: Make GRO conform to RFC 6864"

parents 4cdedb54 3f59047e
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -2169,13 +2169,10 @@ struct napi_gro_cb {
	/* Used in GRE, set in fou/gue_gro_receive */
	u8	is_fou:1;

	/* Used to determine if flush_id can be ignored */
	u8	is_atomic:1;

	/* Number of gro_receive callbacks this packet already went through */
	u8 recursion_counter:4;

	/* 1 bit hole */
	/* 2 bit hole */

	/* used to support CHECKSUM_COMPLETE for tunneling protocols */
	__wsum	csum;
+1 −1
Original line number Diff line number Diff line
@@ -4568,6 +4568,7 @@ static void gro_list_prepare(struct napi_struct *napi, struct sk_buff *skb)
		unsigned long diffs;

		NAPI_GRO_CB(p)->flush = 0;
		NAPI_GRO_CB(p)->flush_id = 0;

		if (hash != skb_get_hash_raw(p)) {
			NAPI_GRO_CB(p)->same_flow = 0;
@@ -4659,7 +4660,6 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff
		NAPI_GRO_CB(skb)->encap_mark = 0;
		NAPI_GRO_CB(skb)->recursion_counter = 0;
		NAPI_GRO_CB(skb)->is_fou = 0;
		NAPI_GRO_CB(skb)->is_atomic = 1;
		NAPI_GRO_CB(skb)->gro_remcsum_start = 0;

		/* Setup for GRO checksum validation */
+12 −24
Original line number Diff line number Diff line
@@ -1362,7 +1362,6 @@ struct sk_buff **inet_gro_receive(struct sk_buff **head, struct sk_buff *skb)

	for (p = *head; p; p = p->next) {
		struct iphdr *iph2;
		u16 flush_id;

		if (!NAPI_GRO_CB(p)->same_flow)
			continue;
@@ -1388,34 +1387,23 @@ struct sk_buff **inet_gro_receive(struct sk_buff **head, struct sk_buff *skb)

		NAPI_GRO_CB(p)->flush |= flush;

		/* We need to store of the IP ID check to be included later
		 * when we can verify that this packet does in fact belong
		 * to a given flow.
		/* For non-atomic datagrams we need to save the IP ID offset
		 * to be included later.  If the frame has the DF bit set
		 * we must ignore the IP ID value as per RFC 6864.
		 */
		flush_id = (u16)(id - ntohs(iph2->id));

		/* This bit of code makes it much easier for us to identify
		 * the cases where we are doing atomic vs non-atomic IP ID
		 * checks.  Specifically an atomic check can return IP ID
		 * values 0 - 0xFFFF, while a non-atomic check can only
		 * return 0 or 0xFFFF.
		 */
		if (!NAPI_GRO_CB(p)->is_atomic ||
		    !(iph->frag_off & htons(IP_DF))) {
			flush_id ^= NAPI_GRO_CB(p)->count;
			flush_id = flush_id ? 0xFFFF : 0;
		}
		if (iph2->frag_off & htons(IP_DF))
			continue;

		/* If the previous IP ID value was based on an atomic
		 * datagram we can overwrite the value and ignore it.
		/* We must save the offset as it is possible to have multiple
		 * flows using the same protocol and address pairs so we
		 * need to wait until we can validate this is part of the
		 * same flow with a 5-tuple or better to avoid unnecessary
		 * collisions between flows.
		 */
		if (NAPI_GRO_CB(skb)->is_atomic)
			NAPI_GRO_CB(p)->flush_id = flush_id;
		else
			NAPI_GRO_CB(p)->flush_id |= flush_id;
		NAPI_GRO_CB(p)->flush_id |= ntohs(iph2->id) ^
					    (u16)(id - NAPI_GRO_CB(p)->count);
	}

	NAPI_GRO_CB(skb)->is_atomic = !!(iph->frag_off & htons(IP_DF));
	NAPI_GRO_CB(skb)->flush |= flush;
	skb_set_network_header(skb, off);
	/* The above will be needed by the transport layer if there is one
+1 −15
Original line number Diff line number Diff line
@@ -230,7 +230,7 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb)

found:
	/* Include the IP ID check below from the inner most IP hdr */
	flush = NAPI_GRO_CB(p)->flush;
	flush = NAPI_GRO_CB(p)->flush | NAPI_GRO_CB(p)->flush_id;
	flush |= (__force int)(flags & TCP_FLAG_CWR);
	flush |= (__force int)((flags ^ tcp_flag_word(th2)) &
		  ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH));
@@ -239,17 +239,6 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb)
		flush |= *(u32 *)((u8 *)th + i) ^
			 *(u32 *)((u8 *)th2 + i);

	/* When we receive our second frame we can made a decision on if we
	 * continue this flow as an atomic flow with a fixed ID or if we use
	 * an incrementing ID.
	 */
	if (NAPI_GRO_CB(p)->flush_id != 1 ||
	    NAPI_GRO_CB(p)->count != 1 ||
	    !NAPI_GRO_CB(p)->is_atomic)
		flush |= NAPI_GRO_CB(p)->flush_id;
	else
		NAPI_GRO_CB(p)->is_atomic = false;

	mss = skb_shinfo(p)->gso_size;

	flush |= (len - 1) >= mss;
@@ -318,9 +307,6 @@ static int tcp4_gro_complete(struct sk_buff *skb, int thoff)
				  iph->daddr, 0);
	skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4;

	if (NAPI_GRO_CB(skb)->is_atomic)
		skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_FIXEDID;

	return tcp_gro_complete(skb);
}

+0 −7
Original line number Diff line number Diff line
@@ -237,15 +237,8 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
		/* flush if Traffic Class fields are different */
		NAPI_GRO_CB(p)->flush |= !!(first_word & htonl(0x0FF00000));
		NAPI_GRO_CB(p)->flush |= flush;

		/* If the previous IP ID value was based on an atomic
		 * datagram we can overwrite the value and ignore it.
		 */
		if (NAPI_GRO_CB(skb)->is_atomic)
			NAPI_GRO_CB(p)->flush_id = 0;
	}

	NAPI_GRO_CB(skb)->is_atomic = true;
	NAPI_GRO_CB(skb)->flush |= flush;

	skb_gro_postpull_rcsum(skb, iph, nlen);