Skip to content
Snippets Groups Projects
0060-ar71xx-add-unaligned-access-hacks-for-VXLAN.patch 4.88 KiB
Newer Older
  • Learn to ignore specific revisions
  • From: Matthias Schiffer <mschiffer@universe-factory.net>
    Date: Wed, 24 Jan 2018 21:34:54 +0100
    Subject: ar71xx: add unaligned access hacks for VXLAN
    
    Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
    
    diff --git a/target/linux/ar71xx/patches-4.4/910-unaligned_access_hacks.patch b/target/linux/ar71xx/patches-4.4/910-unaligned_access_hacks.patch
    
    Matthias Schiffer's avatar
    Matthias Schiffer committed
    index 72d964df639ba2a91071fbdc893bf500ece51a48..19b1d6fc7fc8af37515fe4b5f188e856441a2436 100644
    
    --- a/target/linux/ar71xx/patches-4.4/910-unaligned_access_hacks.patch
    +++ b/target/linux/ar71xx/patches-4.4/910-unaligned_access_hacks.patch
    @@ -929,3 +929,119 @@
      	};
      	if (skb->ip_summed != CHECKSUM_PARTIAL) {
      		*sum = csum_fold(csum_partial(diff, sizeof(diff),
    +--- a/drivers/net/vxlan.c
    ++++ b/drivers/net/vxlan.c
    +@@ -1759,8 +1759,8 @@ static int vxlan6_xmit_skb(struct dst_en
    + 	}
    + 
    + 	vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
    +-	vxh->vx_flags = htonl(VXLAN_HF_VNI);
    +-	vxh->vx_vni = vni;
    ++	net_hdr_word(&vxh->vx_flags) = htonl(VXLAN_HF_VNI);
    ++	net_hdr_word(&vxh->vx_vni) = vni;
    + 
    + 	if (type & SKB_GSO_TUNNEL_REMCSUM) {
    + 		u32 data = (skb_checksum_start_offset(skb) - hdrlen) >>
    +@@ -1769,8 +1769,8 @@ static int vxlan6_xmit_skb(struct dst_en
    + 		if (skb->csum_offset == offsetof(struct udphdr, check))
    + 			data |= VXLAN_RCO_UDP;
    + 
    +-		vxh->vx_vni |= htonl(data);
    +-		vxh->vx_flags |= htonl(VXLAN_HF_RCO);
    ++		net_hdr_word(&vxh->vx_vni) |= htonl(data);
    ++		net_hdr_word(&vxh->vx_flags) |= htonl(VXLAN_HF_RCO);
    + 
    + 		if (!skb_is_gso(skb)) {
    + 			skb->ip_summed = CHECKSUM_NONE;
    +@@ -1838,8 +1838,8 @@ static int vxlan_xmit_skb(struct rtable
    + 		return PTR_ERR(skb);
    + 
    + 	vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
    +-	vxh->vx_flags = htonl(VXLAN_HF_VNI);
    +-	vxh->vx_vni = vni;
    ++	net_hdr_word(&vxh->vx_flags) = htonl(VXLAN_HF_VNI);
    ++	net_hdr_word(&vxh->vx_vni) = vni;
    + 
    + 	if (type & SKB_GSO_TUNNEL_REMCSUM) {
    + 		u32 data = (skb_checksum_start_offset(skb) - hdrlen) >>
    +@@ -1848,8 +1848,8 @@ static int vxlan_xmit_skb(struct rtable
    + 		if (skb->csum_offset == offsetof(struct udphdr, check))
    + 			data |= VXLAN_RCO_UDP;
    + 
    +-		vxh->vx_vni |= htonl(data);
    +-		vxh->vx_flags |= htonl(VXLAN_HF_RCO);
    ++		net_hdr_word(&vxh->vx_vni) |= htonl(data);
    ++		net_hdr_word(&vxh->vx_flags) |= htonl(VXLAN_HF_RCO);
    + 
    + 		if (!skb_is_gso(skb)) {
    + 			skb->ip_summed = CHECKSUM_NONE;
    +--- a/include/linux/etherdevice.h
    ++++ b/include/linux/etherdevice.h
    +@@ -409,7 +409,7 @@ static inline bool is_etherdev_addr(cons
    +  * @b: Pointer to Ethernet header
    +  *
    +  * Compare two Ethernet headers, returns 0 if equal.
    +- * This assumes that the network header (i.e., IP header) is 4-byte
    ++ * This assumes that the network header (i.e., IP header) is 2-byte
    +  * aligned OR the platform can handle unaligned access.  This is the
    +  * case for all packets coming into netif_receive_skb or similar
    +  * entry points.
    +@@ -432,11 +432,12 @@ static inline unsigned long compare_ethe
    + 	fold |= *(unsigned long *)(a + 6) ^ *(unsigned long *)(b + 6);
    + 	return fold;
    + #else
    +-	u32 *a32 = (u32 *)((u8 *)a + 2);
    +-	u32 *b32 = (u32 *)((u8 *)b + 2);
    ++	const u16 *a16 = a;
    ++	const u16 *b16 = b;
    + 
    +-	return (*(u16 *)a ^ *(u16 *)b) | (a32[0] ^ b32[0]) |
    +-	       (a32[1] ^ b32[1]) | (a32[2] ^ b32[2]);
    ++	return (a16[0] ^ b16[0]) | (a16[1] ^ b16[1]) | (a16[2] ^ b16[2]) |
    ++	       (a16[3] ^ b16[3]) | (a16[4] ^ b16[4]) | (a16[5] ^ b16[5]) |
    ++	       (a16[6] ^ b16[6]);
    + #endif
    + }
    + 
    +--- a/net/ipv4/tcp_offload.c
    ++++ b/net/ipv4/tcp_offload.c
    +@@ -221,7 +221,7 @@ struct sk_buff **tcp_gro_receive(struct
    + 
    + 		th2 = tcp_hdr(p);
    + 
    +-		if (*(u32 *)&th->source ^ *(u32 *)&th2->source) {
    ++		if (net_hdr_word(&th->source) ^ net_hdr_word(&th2->source)) {
    + 			NAPI_GRO_CB(p)->same_flow = 0;
    + 			continue;
    + 		}
    +@@ -239,8 +239,8 @@ found:
    + 		  ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH));
    + 	flush |= (__force int)(th->ack_seq ^ th2->ack_seq);
    + 	for (i = sizeof(*th); i < thlen; i += 4)
    +-		flush |= *(u32 *)((u8 *)th + i) ^
    +-			 *(u32 *)((u8 *)th2 + i);
    ++		flush |= net_hdr_word((u8 *)th + i) ^
    ++			 net_hdr_word((u8 *)th2 + i);
    + 
    + 	mss = skb_shinfo(p)->gso_size;
    + 
    +--- a/net/ipv6/netfilter/ip6table_mangle.c
    ++++ b/net/ipv6/netfilter/ip6table_mangle.c
    +@@ -55,7 +55,7 @@ ip6t_mangle_out(struct sk_buff *skb, con
    + 	hop_limit = ipv6_hdr(skb)->hop_limit;
    + 
    + 	/* flowlabel and prio (includes version, which shouldn't change either */
    +-	flowlabel = *((u_int32_t *)ipv6_hdr(skb));
    ++	flowlabel = net_hdr_word(ipv6_hdr(skb));
    + 
    + 	ret = ip6t_do_table(skb, state, state->net->ipv6.ip6table_mangle);
    + 
    +@@ -64,7 +64,7 @@ ip6t_mangle_out(struct sk_buff *skb, con
    + 	     !ipv6_addr_equal(&ipv6_hdr(skb)->daddr, &daddr) ||
    + 	     skb->mark != mark ||
    + 	     ipv6_hdr(skb)->hop_limit != hop_limit ||
    +-	     flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) {
    ++	     flowlabel != net_hdr_word(ipv6_hdr(skb)))) {
    + 		err = ip6_route_me_harder(state->net, skb);
    + 		if (err < 0)
    + 			ret = NF_DROP_ERR(err);