7e4cf9feac8a1967498e3e3119453e17731e74a4
[15.05/openwrt.git] / target / linux / ar71xx / patches-3.7 / 902-unaligned_access_hacks.patch
1 --- a/arch/mips/include/asm/checksum.h
2 +++ b/arch/mips/include/asm/checksum.h
3 @@ -12,6 +12,7 @@
4  #define _ASM_CHECKSUM_H
5  
6  #include <linux/in6.h>
7 +#include <linux/unaligned/packed_struct.h>
8  
9  #include <asm/uaccess.h>
10  
11 @@ -104,26 +105,30 @@ static inline __sum16 ip_fast_csum(const
12         const unsigned int *stop = word + ihl;
13         unsigned int csum;
14         int carry;
15 +       unsigned int w;
16  
17 -       csum = word[0];
18 -       csum += word[1];
19 -       carry = (csum < word[1]);
20 +       csum = __get_unaligned_cpu32(word++);
21 +
22 +       w = __get_unaligned_cpu32(word++);
23 +       csum += w;
24 +       carry = (csum < w);
25         csum += carry;
26  
27 -       csum += word[2];
28 -       carry = (csum < word[2]);
29 +       w = __get_unaligned_cpu32(word++);
30 +       csum += w;
31 +       carry = (csum < w);
32         csum += carry;
33  
34 -       csum += word[3];
35 -       carry = (csum < word[3]);
36 +       w = __get_unaligned_cpu32(word++);
37 +       csum += w;
38 +       carry = (csum < w);
39         csum += carry;
40  
41 -       word += 4;
42         do {
43 -               csum += *word;
44 -               carry = (csum < *word);
45 +               w = __get_unaligned_cpu32(word++);
46 +               csum += w;
47 +               carry = (csum < w);
48                 csum += carry;
49 -               word++;
50         } while (word != stop);
51  
52         return csum_fold(csum);
53 --- a/include/uapi/linux/ip.h
54 +++ b/include/uapi/linux/ip.h
55 @@ -102,7 +102,7 @@ struct iphdr {
56         __be32  saddr;
57         __be32  daddr;
58         /*The options start here. */
59 -};
60 +} __packed __attribute__((aligned(2)));
61  
62  
63  struct ip_auth_hdr {
64 --- a/include/uapi/linux/ipv6.h
65 +++ b/include/uapi/linux/ipv6.h
66 @@ -123,7 +123,7 @@ struct ipv6hdr {
67  
68         struct  in6_addr        saddr;
69         struct  in6_addr        daddr;
70 -};
71 +} __packed __attribute__((aligned(2)));
72  
73  
74  /* index values for the variables in ipv6_devconf */
75 --- a/include/uapi/linux/tcp.h
76 +++ b/include/uapi/linux/tcp.h
77 @@ -54,7 +54,7 @@ struct tcphdr {
78         __be16  window;
79         __sum16 check;
80         __be16  urg_ptr;
81 -};
82 +} __packed __attribute__((aligned(2)));
83  
84  /*
85   *     The union cast uses a gcc extension to avoid aliasing problems
86 @@ -64,7 +64,7 @@ struct tcphdr {
87  union tcp_word_hdr { 
88         struct tcphdr hdr;
89         __be32            words[5];
90 -}; 
91 +} __packed __attribute__((aligned(2)));
92  
93  #define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words [3]) 
94  
95 --- a/include/uapi/linux/udp.h
96 +++ b/include/uapi/linux/udp.h
97 @@ -24,7 +24,7 @@ struct udphdr {
98         __be16  dest;
99         __be16  len;
100         __sum16 check;
101 -};
102 +} __packed __attribute__((aligned(2)));
103  
104  /* UDP socket options */
105  #define UDP_CORK       1       /* Never send partially complete segments */
106 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
107 +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
108 @@ -14,6 +14,7 @@
109  #include <linux/skbuff.h>
110  #include <linux/icmp.h>
111  #include <linux/sysctl.h>
112 +#include <linux/unaligned/packed_struct.h>
113  #include <net/route.h>
114  #include <net/ip.h>
115  
116 @@ -39,8 +40,8 @@ static bool ipv4_pkt_to_tuple(const stru
117         if (ap == NULL)
118                 return false;
119  
120 -       tuple->src.u3.ip = ap[0];
121 -       tuple->dst.u3.ip = ap[1];
122 +       tuple->src.u3.ip = __get_unaligned_cpu32(ap++);
123 +       tuple->dst.u3.ip = __get_unaligned_cpu32(ap);
124  
125         return true;
126  }
127 --- a/include/uapi/linux/icmp.h
128 +++ b/include/uapi/linux/icmp.h
129 @@ -80,7 +80,7 @@ struct icmphdr {
130                 __be16  mtu;
131         } frag;
132    } un;
133 -};
134 +} __packed __attribute__((aligned(2)));
135  
136  
137  /*
138 --- a/net/ipv4/tcp_input.c
139 +++ b/net/ipv4/tcp_input.c
140 @@ -3842,13 +3842,14 @@ static bool tcp_parse_aligned_timestamp(
141  {
142         const __be32 *ptr = (const __be32 *)(th + 1);
143  
144 -       if (*ptr == htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
145 -                         | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
146 +       if (__get_unaligned_cpu32(ptr) ==
147 +           htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
148 +           (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
149                 tp->rx_opt.saw_tstamp = 1;
150                 ++ptr;
151 -               tp->rx_opt.rcv_tsval = ntohl(*ptr);
152 +               tp->rx_opt.rcv_tsval = get_unaligned_be32(ptr);
153                 ++ptr;
154 -               tp->rx_opt.rcv_tsecr = ntohl(*ptr);
155 +               tp->rx_opt.rcv_tsecr = get_unaligned_be32(ptr);
156                 return true;
157         }
158         return false;