0061-ar71xx-add-unaligned-access-hacks-for-VXLAN.patch 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. From: Matthias Schiffer <mschiffer@universe-factory.net>
  2. Date: Wed, 24 Jan 2018 21:34:54 +0100
  3. Subject: ar71xx: add unaligned access hacks for VXLAN
  4. Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
  5. 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
  6. index 8882b1758fed7ac254116fb0cb0e1b95bbe5259f..b06b36317f6bae7827c280ffc7338b6487d762f5 100644
  7. --- a/target/linux/ar71xx/patches-4.4/910-unaligned_access_hacks.patch
  8. +++ b/target/linux/ar71xx/patches-4.4/910-unaligned_access_hacks.patch
  9. @@ -929,3 +929,119 @@
  10. };
  11. if (skb->ip_summed != CHECKSUM_PARTIAL) {
  12. *sum = csum_fold(csum_partial(diff, sizeof(diff),
  13. +--- a/drivers/net/vxlan.c
  14. ++++ b/drivers/net/vxlan.c
  15. +@@ -1759,8 +1759,8 @@ static int vxlan6_xmit_skb(struct dst_en
  16. + }
  17. +
  18. + vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
  19. +- vxh->vx_flags = htonl(VXLAN_HF_VNI);
  20. +- vxh->vx_vni = vni;
  21. ++ net_hdr_word(&vxh->vx_flags) = htonl(VXLAN_HF_VNI);
  22. ++ net_hdr_word(&vxh->vx_vni) = vni;
  23. +
  24. + if (type & SKB_GSO_TUNNEL_REMCSUM) {
  25. + u32 data = (skb_checksum_start_offset(skb) - hdrlen) >>
  26. +@@ -1769,8 +1769,8 @@ static int vxlan6_xmit_skb(struct dst_en
  27. + if (skb->csum_offset == offsetof(struct udphdr, check))
  28. + data |= VXLAN_RCO_UDP;
  29. +
  30. +- vxh->vx_vni |= htonl(data);
  31. +- vxh->vx_flags |= htonl(VXLAN_HF_RCO);
  32. ++ net_hdr_word(&vxh->vx_vni) |= htonl(data);
  33. ++ net_hdr_word(&vxh->vx_flags) |= htonl(VXLAN_HF_RCO);
  34. +
  35. + if (!skb_is_gso(skb)) {
  36. + skb->ip_summed = CHECKSUM_NONE;
  37. +@@ -1838,8 +1838,8 @@ static int vxlan_xmit_skb(struct rtable
  38. + return PTR_ERR(skb);
  39. +
  40. + vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
  41. +- vxh->vx_flags = htonl(VXLAN_HF_VNI);
  42. +- vxh->vx_vni = vni;
  43. ++ net_hdr_word(&vxh->vx_flags) = htonl(VXLAN_HF_VNI);
  44. ++ net_hdr_word(&vxh->vx_vni) = vni;
  45. +
  46. + if (type & SKB_GSO_TUNNEL_REMCSUM) {
  47. + u32 data = (skb_checksum_start_offset(skb) - hdrlen) >>
  48. +@@ -1848,8 +1848,8 @@ static int vxlan_xmit_skb(struct rtable
  49. + if (skb->csum_offset == offsetof(struct udphdr, check))
  50. + data |= VXLAN_RCO_UDP;
  51. +
  52. +- vxh->vx_vni |= htonl(data);
  53. +- vxh->vx_flags |= htonl(VXLAN_HF_RCO);
  54. ++ net_hdr_word(&vxh->vx_vni) |= htonl(data);
  55. ++ net_hdr_word(&vxh->vx_flags) |= htonl(VXLAN_HF_RCO);
  56. +
  57. + if (!skb_is_gso(skb)) {
  58. + skb->ip_summed = CHECKSUM_NONE;
  59. +--- a/include/linux/etherdevice.h
  60. ++++ b/include/linux/etherdevice.h
  61. +@@ -409,7 +409,7 @@ static inline bool is_etherdev_addr(cons
  62. + * @b: Pointer to Ethernet header
  63. + *
  64. + * Compare two Ethernet headers, returns 0 if equal.
  65. +- * This assumes that the network header (i.e., IP header) is 4-byte
  66. ++ * This assumes that the network header (i.e., IP header) is 2-byte
  67. + * aligned OR the platform can handle unaligned access. This is the
  68. + * case for all packets coming into netif_receive_skb or similar
  69. + * entry points.
  70. +@@ -432,11 +432,12 @@ static inline unsigned long compare_ethe
  71. + fold |= *(unsigned long *)(a + 6) ^ *(unsigned long *)(b + 6);
  72. + return fold;
  73. + #else
  74. +- u32 *a32 = (u32 *)((u8 *)a + 2);
  75. +- u32 *b32 = (u32 *)((u8 *)b + 2);
  76. ++ const u16 *a16 = a;
  77. ++ const u16 *b16 = b;
  78. +
  79. +- return (*(u16 *)a ^ *(u16 *)b) | (a32[0] ^ b32[0]) |
  80. +- (a32[1] ^ b32[1]) | (a32[2] ^ b32[2]);
  81. ++ return (a16[0] ^ b16[0]) | (a16[1] ^ b16[1]) | (a16[2] ^ b16[2]) |
  82. ++ (a16[3] ^ b16[3]) | (a16[4] ^ b16[4]) | (a16[5] ^ b16[5]) |
  83. ++ (a16[6] ^ b16[6]);
  84. + #endif
  85. + }
  86. +
  87. +--- a/net/ipv4/tcp_offload.c
  88. ++++ b/net/ipv4/tcp_offload.c
  89. +@@ -221,7 +221,7 @@ struct sk_buff **tcp_gro_receive(struct
  90. +
  91. + th2 = tcp_hdr(p);
  92. +
  93. +- if (*(u32 *)&th->source ^ *(u32 *)&th2->source) {
  94. ++ if (net_hdr_word(&th->source) ^ net_hdr_word(&th2->source)) {
  95. + NAPI_GRO_CB(p)->same_flow = 0;
  96. + continue;
  97. + }
  98. +@@ -239,8 +239,8 @@ found:
  99. + ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH));
  100. + flush |= (__force int)(th->ack_seq ^ th2->ack_seq);
  101. + for (i = sizeof(*th); i < thlen; i += 4)
  102. +- flush |= *(u32 *)((u8 *)th + i) ^
  103. +- *(u32 *)((u8 *)th2 + i);
  104. ++ flush |= net_hdr_word((u8 *)th + i) ^
  105. ++ net_hdr_word((u8 *)th2 + i);
  106. +
  107. + mss = skb_shinfo(p)->gso_size;
  108. +
  109. +--- a/net/ipv6/netfilter/ip6table_mangle.c
  110. ++++ b/net/ipv6/netfilter/ip6table_mangle.c
  111. +@@ -55,7 +55,7 @@ ip6t_mangle_out(struct sk_buff *skb, con
  112. + hop_limit = ipv6_hdr(skb)->hop_limit;
  113. +
  114. + /* flowlabel and prio (includes version, which shouldn't change either */
  115. +- flowlabel = *((u_int32_t *)ipv6_hdr(skb));
  116. ++ flowlabel = net_hdr_word(ipv6_hdr(skb));
  117. +
  118. + ret = ip6t_do_table(skb, state, state->net->ipv6.ip6table_mangle);
  119. +
  120. +@@ -64,7 +64,7 @@ ip6t_mangle_out(struct sk_buff *skb, con
  121. + !ipv6_addr_equal(&ipv6_hdr(skb)->daddr, &daddr) ||
  122. + skb->mark != mark ||
  123. + ipv6_hdr(skb)->hop_limit != hop_limit ||
  124. +- flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) {
  125. ++ flowlabel != net_hdr_word(ipv6_hdr(skb)))) {
  126. + err = ip6_route_me_harder(state->net, skb);
  127. + if (err < 0)
  128. + ret = NF_DROP_ERR(err);