diff --git a/target/linux/ar71xx/patches-3.3/923-comprehensive-tcp-udp-ipv6-ipv4-alignment-fixes.patch b/target/linux/ar71xx/patches-3.3/923-comprehensive-tcp-udp-ipv6-ipv4-alignment-fixes.patch index ee96f9f7a5..cd54147574 100644 --- a/target/linux/ar71xx/patches-3.3/923-comprehensive-tcp-udp-ipv6-ipv4-alignment-fixes.patch +++ b/target/linux/ar71xx/patches-3.3/923-comprehensive-tcp-udp-ipv6-ipv4-alignment-fixes.patch @@ -81,6 +81,19 @@ index f2f7c6c..dce734c 100644 " .set noreorder \n" " .set noat \n" " addu %0, %5 # proto (long in network byte order)\n" +diff --git a/include/linux/icmp.h b/include/linux/icmp.h +index 474f2a5..0e0fca0 100644 +--- a/include/linux/icmp.h ++++ b/include/linux/icmp.h +@@ -80,7 +80,7 @@ struct icmphdr { + __be16 mtu; + } frag; + } un; +-}; ++} __packed; + + #ifdef __KERNEL__ + #include diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h index ba45e6b..5bb0258 100644 --- a/include/linux/icmpv6.h @@ -307,11 +320,42 @@ index bc1b0fd..caef125 100644 sum += (__force u32)saddr->s6_addr32[0]; carry = (sum < (__force u32)saddr->s6_addr32[0]); sum += carry; +diff --git a/include/net/ipv6.h b/include/net/ipv6.h +index e4170a2..67446e6 100644 +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -105,7 +105,7 @@ struct frag_hdr { + __u8 reserved; + __be16 frag_off; + __be32 identification; +-}; ++} __packed; + + #define IP6_MF 0x0001 + +@@ -354,7 +354,7 @@ static inline int __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2, + + /* check incomplete u32 in prefix */ + pbi = prefixlen & 0x1f; +- if (pbi && ((a1[pdw] ^ a2[pdw]) & htonl((0xffffffff) << (32 - pbi)))) ++ if (pbi && ((__get_unaligned_cpu32(&a1[pdw]) ^ __get_unaligned_cpu32(&a2[pdw])) & htonl((0xffffffff) << (32 - pbi)))) + return 0; + + return 1; +@@ -438,7 +438,7 @@ static inline int __ipv6_addr_diff(const void *token1, const void *token2, int a + addrlen >>= 2; + + for (i = 0; i < addrlen; i++) { +- __be32 xb = a1[i] ^ a2[i]; ++ __be32 xb = __get_unaligned_cpu32(&a1[i]) ^ __get_unaligned_cpu32(&a2[i]); + if (xb) + return i * 32 + 31 - __fls(ntohl(xb)); + } diff --git a/include/net/ndisc.h b/include/net/ndisc.h -index a9d350e..5be936d 100644 +index e3133c2..c8e2f13 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h -@@ -62,18 +62,18 @@ struct nd_msg { +@@ -61,18 +61,18 @@ struct nd_msg { struct icmp6hdr icmph; struct in6_addr target; __u8 opt[0]; @@ -333,6 +377,32 @@ index a9d350e..5be936d 100644 struct nd_opt_hdr { __u8 nd_opt_type; +@@ -83,10 +83,10 @@ static inline u32 ndisc_hashfn(const void *pkey, const struct net_device *dev, _ + { + const u32 *p32 = pkey; + +- return (((p32[0] ^ dev->ifindex) * hash_rnd[0]) + +- (p32[1] * hash_rnd[1]) + +- (p32[2] * hash_rnd[2]) + +- (p32[3] * hash_rnd[3])); ++ return (((__get_unaligned_cpu32(&p32[0]) ^ dev->ifindex) * hash_rnd[0]) + ++ (__get_unaligned_cpu32(&p32[1]) * hash_rnd[1]) + ++ (__get_unaligned_cpu32(&p32[2]) * hash_rnd[2]) + ++ (__get_unaligned_cpu32(&p32[3]) * hash_rnd[3])); + } + + static inline struct neighbour *__ipv6_neigh_lookup(struct neigh_table *tbl, struct net_device *dev, const void *pkey) +@@ -104,8 +104,8 @@ static inline struct neighbour *__ipv6_neigh_lookup(struct neigh_table *tbl, str + n = rcu_dereference_bh(n->next)) { + u32 *n32 = (u32 *) n->primary_key; + if (n->dev == dev && +- ((n32[0] ^ p32[0]) | (n32[1] ^ p32[1]) | +- (n32[2] ^ p32[2]) | (n32[3] ^ p32[3])) == 0) { ++ ((n32[0] ^ __get_unaligned_cpu32(&p32[0])) | (n32[1] ^ __get_unaligned_cpu32(&p32[1])) | ++ (n32[2] ^ __get_unaligned_cpu32(&p32[2])) | (n32[3] ^ __get_unaligned_cpu32(&p32[3]))) == 0) { + if (!atomic_inc_not_zero(&n->refcnt)) + n = NULL; + break; diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index a225089..019970f 100644 --- a/net/core/flow_dissector.c @@ -403,7 +473,7 @@ index de9da21..2704407 100644 return true; } diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c -index 22ef5f9..bf3f773 100644 +index 8c85021..4afca01 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2834,7 +2834,7 @@ found: @@ -416,10 +486,10 @@ index 22ef5f9..bf3f773 100644 out_check_final: flush = len < mss; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c -index b5e315f..1a0e649 100644 +index 1c30511..8630e0a 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c -@@ -3944,13 +3944,13 @@ static int tcp_parse_aligned_timestamp(struct tcp_sock *tp, const struct tcphdr +@@ -3948,13 +3948,13 @@ static int tcp_parse_aligned_timestamp(struct tcp_sock *tp, const struct tcphdr { const __be32 *ptr = (const __be32 *)(th + 1); @@ -521,6 +591,19 @@ index 3d641b6..7c072da 100644 if (pkt_len <= IPV6_MAXPLEN) { IP6_INC_STATS_BH(net, ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS); +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index b82bcde..9ce186a 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -141,7 +141,7 @@ static __inline__ __be32 addr_bit_set(const void *token, int fn_bit) + * See include/asm-generic/bitops/le.h. + */ + return (__force __be32)(1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f)) & +- addr[fn_bit >> 5]; ++ __get_unaligned_cpu32(&addr[fn_bit >> 5]); + } + + static __inline__ struct fib6_node * node_alloc(void) diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c index e6af8d7..ef83fab 100644 --- a/net/ipv6/netfilter/ip6t_LOG.c @@ -537,6 +620,25 @@ index e6af8d7..ef83fab 100644 fragment = 0; ptr = ip6hoff + sizeof(struct ipv6hdr); +diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c +index b69fae7..2ffe49a 100644 +--- a/net/ipv6/reassembly.c ++++ b/net/ipv6/reassembly.c +@@ -151,10 +151,10 @@ void ip6_frag_init(struct inet_frag_queue *q, void *a) + struct frag_queue *fq = container_of(q, struct frag_queue, q); + struct ip6_create_arg *arg = a; + +- fq->id = arg->id; +- fq->user = arg->user; +- fq->saddr = *arg->src; +- fq->daddr = *arg->dst; ++ fq->id = __get_unaligned_cpu32(&arg->id); ++ fq->user = __get_unaligned_cpu32(&arg->user); ++ memcpy(&fq->saddr, arg->src, sizeof(struct in6_addr)); ++ memcpy(&fq->daddr, arg->dst, sizeof(struct in6_addr)); + } + EXPORT_SYMBOL(ip6_frag_init); + diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 4d5915d..e1e8bad 100644 --- a/net/ipv6/route.c @@ -565,6 +667,19 @@ index 8ea65e0..eecde59 100644 } fl6->flowi6_proto = nexthdr; return; +diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c +index 3d8981f..04bad951 100644 +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -1651,7 +1651,7 @@ done: + int tc_classify_compat(struct sk_buff *skb, const struct tcf_proto *tp, + struct tcf_result *res) + { +- __be16 protocol = skb->protocol; ++ __be16 protocol = __get_unaligned_cpu16(&skb->protocol); + int err; + + for (; tp; tp = tp->next) { diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 54a0dc2..e9c51b6 100644 --- a/net/xfrm/xfrm_input.c @@ -590,3 +705,16 @@ index 54a0dc2..e9c51b6 100644 return 0; } +diff --git a/scripts/setlocalversion b/scripts/setlocalversion +index 4d40384..0a83f82 100755 +--- a/scripts/setlocalversion ++++ b/scripts/setlocalversion +@@ -52,7 +52,7 @@ scm_version() + # If only the short version is requested, don't bother + # running further git commands + if $short; then +- echo "+" ++ ##echo "+" + return + fi + # If we are past a tagged commit (like diff --git a/target/linux/ar71xx/patches-3.3/928-u32-unaligned.patch b/target/linux/ar71xx/patches-3.3/928-u32-unaligned.patch new file mode 100644 index 0000000000..b8a4241039 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/928-u32-unaligned.patch @@ -0,0 +1,31 @@ +diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c +index 939b627..3df39b0 100644 +--- a/net/sched/cls_u32.c ++++ b/net/sched/cls_u32.c +@@ -142,7 +142,7 @@ next_knode: + data = skb_header_pointer(skb, toff, 4, &hdata); + if (!data) + goto out; +- if ((*data ^ key->val) & key->mask) { ++ if ((__get_unaligned_cpu32(data) ^ key->val) & key->mask) { + n = n->next; + goto next_knode; + } +@@ -193,7 +193,7 @@ check_terminal: + &hdata); + if (!data) + goto out; +- sel = ht->divisor & u32_hash_fold(*data, &n->sel, ++ sel = ht->divisor & u32_hash_fold(__get_unaligned_cpu32(data), &n->sel, + n->fshift); + } + if (!(n->sel.flags & (TC_U32_VAROFFSET | TC_U32_OFFSET | TC_U32_EAT))) +@@ -209,7 +209,7 @@ check_terminal: + 2, &hdata); + if (!data) + goto out; +- off2 += ntohs(n->sel.offmask & *data) >> ++ off2 += ntohs(n->sel.offmask & __get_unaligned_cpu16(data)) >> + n->sel.offshift; + } + off2 &= ~3;