ar71xx: improve unaligned access patches, add a net_hdr_word() macro which assumes...
[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 @@ -104,26 +104,30 @@ static inline __sum16 ip_fast_csum(const
4         const unsigned int *stop = word + ihl;
5         unsigned int csum;
6         int carry;
7 +       unsigned int w;
8  
9 -       csum = word[0];
10 -       csum += word[1];
11 -       carry = (csum < word[1]);
12 +       csum = net_hdr_word(word++);
13 +
14 +       w = net_hdr_word(word++);
15 +       csum += w;
16 +       carry = (csum < w);
17         csum += carry;
18  
19 -       csum += word[2];
20 -       carry = (csum < word[2]);
21 +       w = net_hdr_word(word++);
22 +       csum += w;
23 +       carry = (csum < w);
24         csum += carry;
25  
26 -       csum += word[3];
27 -       carry = (csum < word[3]);
28 +       w = net_hdr_word(word++);
29 +       csum += w;
30 +       carry = (csum < w);
31         csum += carry;
32  
33 -       word += 4;
34         do {
35 -               csum += *word;
36 -               carry = (csum < *word);
37 +               w = net_hdr_word(word++);
38 +               csum += w;
39 +               carry = (csum < w);
40                 csum += carry;
41 -               word++;
42         } while (word != stop);
43  
44         return csum_fold(csum);
45 --- a/include/uapi/linux/ip.h
46 +++ b/include/uapi/linux/ip.h
47 @@ -102,7 +102,7 @@ struct iphdr {
48         __be32  saddr;
49         __be32  daddr;
50         /*The options start here. */
51 -};
52 +} __attribute__((packed, aligned(2)));
53  
54  
55  struct ip_auth_hdr {
56 --- a/include/uapi/linux/ipv6.h
57 +++ b/include/uapi/linux/ipv6.h
58 @@ -123,7 +123,7 @@ struct ipv6hdr {
59  
60         struct  in6_addr        saddr;
61         struct  in6_addr        daddr;
62 -};
63 +} __attribute__((packed, aligned(2)));
64  
65  
66  /* index values for the variables in ipv6_devconf */
67 --- a/include/uapi/linux/tcp.h
68 +++ b/include/uapi/linux/tcp.h
69 @@ -54,7 +54,7 @@ struct tcphdr {
70         __be16  window;
71         __sum16 check;
72         __be16  urg_ptr;
73 -};
74 +} __attribute__((packed, aligned(2)));
75  
76  /*
77   *     The union cast uses a gcc extension to avoid aliasing problems
78 @@ -64,7 +64,7 @@ struct tcphdr {
79  union tcp_word_hdr { 
80         struct tcphdr hdr;
81         __be32            words[5];
82 -}; 
83 +} __attribute__((packed, aligned(2)));
84  
85  #define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words [3]) 
86  
87 --- a/include/uapi/linux/udp.h
88 +++ b/include/uapi/linux/udp.h
89 @@ -24,7 +24,7 @@ struct udphdr {
90         __be16  dest;
91         __be16  len;
92         __sum16 check;
93 -};
94 +} __attribute__((packed, aligned(2)));
95  
96  /* UDP socket options */
97  #define UDP_CORK       1       /* Never send partially complete segments */
98 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
99 +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
100 @@ -14,6 +14,7 @@
101  #include <linux/skbuff.h>
102  #include <linux/icmp.h>
103  #include <linux/sysctl.h>
104 +#include <linux/unaligned/packed_struct.h>
105  #include <net/route.h>
106  #include <net/ip.h>
107  
108 @@ -39,8 +40,8 @@ static bool ipv4_pkt_to_tuple(const stru
109         if (ap == NULL)
110                 return false;
111  
112 -       tuple->src.u3.ip = ap[0];
113 -       tuple->dst.u3.ip = ap[1];
114 +       tuple->src.u3.ip = net_hdr_word(ap++);
115 +       tuple->dst.u3.ip = net_hdr_word(ap);
116  
117         return true;
118  }
119 --- a/include/uapi/linux/icmp.h
120 +++ b/include/uapi/linux/icmp.h
121 @@ -80,7 +80,7 @@ struct icmphdr {
122                 __be16  mtu;
123         } frag;
124    } un;
125 -};
126 +} __attribute__((packed, aligned(2)));
127  
128  
129  /*
130 --- a/net/ipv4/tcp_input.c
131 +++ b/net/ipv4/tcp_input.c
132 @@ -3842,13 +3842,14 @@ static bool tcp_parse_aligned_timestamp(
133  {
134         const __be32 *ptr = (const __be32 *)(th + 1);
135  
136 -       if (*ptr == htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
137 -                         | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
138 +       if (net_hdr_word(ptr) ==
139 +           htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
140 +           (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
141                 tp->rx_opt.saw_tstamp = 1;
142                 ++ptr;
143 -               tp->rx_opt.rcv_tsval = ntohl(*ptr);
144 +               tp->rx_opt.rcv_tsval = get_unaligned_be32(ptr);
145                 ++ptr;
146 -               tp->rx_opt.rcv_tsecr = ntohl(*ptr);
147 +               tp->rx_opt.rcv_tsecr = get_unaligned_be32(ptr);
148                 return true;
149         }
150         return false;
151 --- a/include/uapi/linux/in6.h
152 +++ b/include/uapi/linux/in6.h
153 @@ -36,7 +36,7 @@ struct in6_addr {
154  #define s6_addr                        in6_u.u6_addr8
155  #define s6_addr16              in6_u.u6_addr16
156  #define s6_addr32              in6_u.u6_addr32
157 -};
158 +} __attribute__((packed, aligned(2)));
159  
160  /* IPv6 Wildcard Address (::) and Loopback Address (::1) defined in RFC2553
161   * NOTE: Be aware the IN6ADDR_* constants and in6addr_* externals are defined
162 --- a/net/ipv6/af_inet6.c
163 +++ b/net/ipv6/af_inet6.c
164 @@ -61,6 +61,7 @@
165  #endif
166  
167  #include <asm/uaccess.h>
168 +#include <asm/unaligned.h>
169  #include <linux/mroute6.h>
170  
171  MODULE_AUTHOR("Cast of dozens");
172 @@ -687,7 +688,7 @@ bool ipv6_opt_accepted(const struct sock
173                 if ((opt->hop && (np->rxopt.bits.hopopts ||
174                                   np->rxopt.bits.ohopopts)) ||
175                     ((IPV6_FLOWINFO_MASK &
176 -                     *(__be32 *)skb_network_header(skb)) &&
177 +                     net_hdr_word(skb_network_header(skb))) &&
178                      np->rxopt.bits.rxflow) ||
179                     (opt->srcrt && (np->rxopt.bits.srcrt ||
180                      np->rxopt.bits.osrcrt)) ||
181 @@ -880,7 +881,7 @@ static struct sk_buff **ipv6_gro_receive
182                         continue;
183  
184                 iph2 = ipv6_hdr(p);
185 -               first_word = *(__be32 *)iph ^ *(__be32 *)iph2 ;
186 +               first_word = net_hdr_word(iph) ^ net_hdr_word(iph2);
187  
188                 /* All fields must match except length and Traffic Class. */
189                 if (nlen != skb_network_header_len(p) ||
190 --- a/net/ipv6/route.c
191 +++ b/net/ipv6/route.c
192 @@ -59,6 +59,7 @@
193  #include <net/netlink.h>
194  
195  #include <asm/uaccess.h>
196 +#include <asm/unaligned.h>
197  
198  #ifdef CONFIG_SYSCTL
199  #include <linux/sysctl.h>
200 @@ -938,7 +939,7 @@ void ip6_route_input(struct sk_buff *skb
201                 .flowi6_iif = skb->dev->ifindex,
202                 .daddr = iph->daddr,
203                 .saddr = iph->saddr,
204 -               .flowlabel = (* (__be32 *) iph) & IPV6_FLOWINFO_MASK,
205 +               .flowlabel = net_hdr_word(iph) & IPV6_FLOWINFO_MASK,
206                 .flowi6_mark = skb->mark,
207                 .flowi6_proto = iph->nexthdr,
208         };
209 @@ -1108,7 +1109,7 @@ void ip6_update_pmtu(struct sk_buff *skb
210         fl6.flowi6_flags = 0;
211         fl6.daddr = iph->daddr;
212         fl6.saddr = iph->saddr;
213 -       fl6.flowlabel = (*(__be32 *) iph) & IPV6_FLOWINFO_MASK;
214 +       fl6.flowlabel = net_hdr_word(iph) & IPV6_FLOWINFO_MASK,
215  
216         dst = ip6_route_output(net, NULL, &fl6);
217         if (!dst->error)
218 @@ -1136,7 +1137,7 @@ void ip6_redirect(struct sk_buff *skb, s
219         fl6.flowi6_flags = 0;
220         fl6.daddr = iph->daddr;
221         fl6.saddr = iph->saddr;
222 -       fl6.flowlabel = (*(__be32 *) iph) & IPV6_FLOWINFO_MASK;
223 +       fl6.flowlabel = net_hdr_word(iph) & IPV6_FLOWINFO_MASK,
224  
225         dst = ip6_route_output(net, NULL, &fl6);
226         if (!dst->error)
227 --- a/net/ipv6/tcp_ipv6.c
228 +++ b/net/ipv6/tcp_ipv6.c
229 @@ -64,6 +64,7 @@
230  #include <net/secure_seq.h>
231  #include <net/tcp_memcontrol.h>
232  
233 +#include <asm/unaligned.h>
234  #include <asm/uaccess.h>
235  
236  #include <linux/proc_fs.h>
237 @@ -851,10 +852,10 @@ static void tcp_v6_send_response(struct 
238         topt = (__be32 *)(t1 + 1);
239  
240         if (ts) {
241 -               *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
242 -                               (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
243 -               *topt++ = htonl(tcp_time_stamp);
244 -               *topt++ = htonl(ts);
245 +               put_unaligned_be32((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
246 +                       (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP, topt++);
247 +               put_unaligned_be32(tcp_time_stamp, topt++);
248 +               put_unaligned_be32(ts, topt++);
249         }
250  
251  #ifdef CONFIG_TCP_MD5SIG
252 --- a/include/linux/ipv6.h
253 +++ b/include/linux/ipv6.h
254 @@ -4,6 +4,7 @@
255  #include <uapi/linux/ipv6.h>
256  
257  #define ipv6_optlen(p)  (((p)->hdrlen+1) << 3)
258 +
259  /*
260   * This structure contains configuration options per IPv6 link.
261   */
262 --- a/net/ipv6/datagram.c
263 +++ b/net/ipv6/datagram.c
264 @@ -360,12 +360,12 @@ int ipv6_recv_error(struct sock *sk, str
265                                 *(struct in6_addr *)(nh + serr->addr_offset);
266                         if (np->sndflow)
267                                 sin->sin6_flowinfo =
268 -                                       (*(__be32 *)(nh + serr->addr_offset - 24) &
269 -                                        IPV6_FLOWINFO_MASK);
270 +                                       net_hdr_word(nh + serr->addr_offset - 24) &
271 +                                        IPV6_FLOWINFO_MASK;
272                         if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
273                                 sin->sin6_scope_id = IP6CB(skb)->iif;
274                 } else {
275 -                       ipv6_addr_set_v4mapped(*(__be32 *)(nh + serr->addr_offset),
276 +                       ipv6_addr_set_v4mapped(net_hdr_word(nh + serr->addr_offset),
277                                                &sin->sin6_addr);
278                 }
279         }
280 @@ -492,9 +492,10 @@ int datagram_recv_ctl(struct sock *sk, s
281                 put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
282         }
283  
284 -       if (np->rxopt.bits.rxflow && (*(__be32 *)nh & IPV6_FLOWINFO_MASK)) {
285 -               __be32 flowinfo = *(__be32 *)nh & IPV6_FLOWINFO_MASK;
286 -               put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
287 +       if (np->rxopt.bits.rxflow) {
288 +               __be32 flowinfo = net_hdr_word(nh) & IPV6_FLOWINFO_MASK;
289 +               if (flowinfo)
290 +                       put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
291         }
292  
293         /* HbH is allowed only once */
294 @@ -680,12 +681,12 @@ int datagram_send_ctl(struct net *net, s
295                         }
296  
297                         if (fl6->flowlabel&IPV6_FLOWINFO_MASK) {
298 -                               if ((fl6->flowlabel^*(__be32 *)CMSG_DATA(cmsg))&~IPV6_FLOWINFO_MASK) {
299 +                               if ((fl6->flowlabel^net_hdr_word(CMSG_DATA(cmsg)))&~IPV6_FLOWINFO_MASK) {
300                                         err = -EINVAL;
301                                         goto exit_f;
302                                 }
303                         }
304 -                       fl6->flowlabel = IPV6_FLOWINFO_MASK & *(__be32 *)CMSG_DATA(cmsg);
305 +                       fl6->flowlabel = IPV6_FLOWINFO_MASK & net_hdr_word(CMSG_DATA(cmsg));
306                         break;
307  
308                 case IPV6_2292HOPOPTS:
309 --- a/net/ipv6/ip6_gre.c
310 +++ b/net/ipv6/ip6_gre.c
311 @@ -445,7 +445,7 @@ static void ip6gre_err(struct sk_buff *s
312  
313         t = ip6gre_tunnel_lookup(skb->dev, &ipv6h->daddr, &ipv6h->saddr,
314                                 flags & GRE_KEY ?
315 -                               *(((__be32 *)p) + (grehlen / 4) - 1) : 0,
316 +                               net_hdr_word(((__be32 *)p) + (grehlen / 4) - 1) : 0,
317                                 p[1]);
318         if (t == NULL)
319                 return;
320 @@ -537,11 +537,11 @@ static int ip6gre_rcv(struct sk_buff *sk
321                         offset += 4;
322                 }
323                 if (flags&GRE_KEY) {
324 -                       key = *(__be32 *)(h + offset);
325 +                       key = net_hdr_word(h + offset);
326                         offset += 4;
327                 }
328                 if (flags&GRE_SEQ) {
329 -                       seqno = ntohl(*(__be32 *)(h + offset));
330 +                       seqno = ntohl(net_hdr_word(h + offset));
331                         offset += 4;
332                 }
333         }
334 @@ -788,7 +788,7 @@ static netdev_tx_t ip6gre_xmit2(struct s
335          *      Push down and install the IP header.
336          */
337         ipv6h = ipv6_hdr(skb);
338 -       *(__be32 *)ipv6h = fl6->flowlabel | htonl(0x60000000);
339 +       net_hdr_word(ipv6h) = fl6->flowlabel | htonl(0x60000000);
340         dsfield = INET_ECN_encapsulate(0, dsfield);
341         ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield);
342         ipv6h->hop_limit = tunnel->parms.hop_limit;
343 @@ -805,7 +805,7 @@ static netdev_tx_t ip6gre_xmit2(struct s
344  
345                 if (tunnel->parms.o_flags&GRE_SEQ) {
346                         ++tunnel->o_seqno;
347 -                       *ptr = htonl(tunnel->o_seqno);
348 +                       net_hdr_word(ptr) = htonl(tunnel->o_seqno);
349                         ptr--;
350                 }
351                 if (tunnel->parms.o_flags&GRE_KEY) {
352 @@ -913,9 +913,9 @@ static inline int ip6gre_xmit_ipv6(struc
353  
354         dsfield = ipv6_get_dsfield(ipv6h);
355         if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
356 -               fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK);
357 +               fl6.flowlabel |= net_hdr_word(ipv6h) & IPV6_TCLASS_MASK;
358         if (t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL)
359 -               fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_FLOWLABEL_MASK);
360 +               fl6.flowlabel |= net_hdr_word(ipv6h) & IPV6_FLOWLABEL_MASK;
361         if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
362                 fl6.flowi6_mark = skb->mark;
363  
364 @@ -1256,7 +1256,7 @@ static int ip6gre_header(struct sk_buff 
365         struct ipv6hdr *ipv6h = (struct ipv6hdr *)skb_push(skb, t->hlen);
366         __be16 *p = (__be16 *)(ipv6h+1);
367  
368 -       *(__be32 *)ipv6h = t->fl.u.ip6.flowlabel | htonl(0x60000000);
369 +       net_hdr_word(ipv6h) = t->fl.u.ip6.flowlabel | htonl(0x60000000);
370         ipv6h->hop_limit = t->parms.hop_limit;
371         ipv6h->nexthdr = NEXTHDR_GRE;
372         ipv6h->saddr = t->parms.laddr;
373 --- a/net/ipv6/ip6_output.c
374 +++ b/net/ipv6/ip6_output.c
375 @@ -216,7 +216,7 @@ int ip6_xmit(struct sock *sk, struct sk_
376         if (hlimit < 0)
377                 hlimit = ip6_dst_hoplimit(dst);
378  
379 -       *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl6->flowlabel;
380 +       net_hdr_word(hdr) = htonl(0x60000000 | (tclass << 20)) | fl6->flowlabel;
381  
382         hdr->payload_len = htons(seg_len);
383         hdr->nexthdr = proto;
384 --- a/net/ipv6/ip6_tunnel.c
385 +++ b/net/ipv6/ip6_tunnel.c
386 @@ -1110,9 +1110,9 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str
387  
388         dsfield = ipv6_get_dsfield(ipv6h);
389         if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
390 -               fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK);
391 +               fl6.flowlabel |= net_hdr_word(ipv6h) & IPV6_TCLASS_MASK;
392         if (t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL)
393 -               fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_FLOWLABEL_MASK);
394 +               fl6.flowlabel |= net_hdr_word(ipv6h) & IPV6_FLOWLABEL_MASK;
395         if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
396                 fl6.flowi6_mark = skb->mark;
397  
398 --- a/net/ipv6/exthdrs.c
399 +++ b/net/ipv6/exthdrs.c
400 @@ -622,7 +622,7 @@ static bool ipv6_hop_jumbo(struct sk_buf
401                 goto drop;
402         }
403  
404 -       pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
405 +       pkt_len = ntohl(net_hdr_word(nh + optoff + 2));
406         if (pkt_len <= IPV6_MAXPLEN) {
407                 IP6_INC_STATS_BH(net, ipv6_skb_idev(skb),
408                                  IPSTATS_MIB_INHDRERRORS);
409 --- a/include/linux/types.h
410 +++ b/include/linux/types.h
411 @@ -211,5 +211,11 @@ struct callback_head {
412  };
413  #define rcu_head callback_head
414  
415 +struct net_hdr_word {
416 +       u32 words[1];
417 +} __attribute__((packed, aligned(2)));
418 +
419 +#define net_hdr_word(_p) (((struct net_hdr_word *) (_p))->words[0])
420 +
421  #endif /*  __ASSEMBLY__ */
422  #endif /* _LINUX_TYPES_H */
423 --- a/net/ipv4/af_inet.c
424 +++ b/net/ipv4/af_inet.c
425 @@ -1388,8 +1388,8 @@ static struct sk_buff **inet_gro_receive
426         if (unlikely(ip_fast_csum((u8 *)iph, 5)))
427                 goto out_unlock;
428  
429 -       id = ntohl(*(__be32 *)&iph->id);
430 -       flush = (u16)((ntohl(*(__be32 *)iph) ^ skb_gro_len(skb)) | (id ^ IP_DF));
431 +       id = ntohl(net_hdr_word(&iph->id));
432 +       flush = (u16)((ntohl(net_hdr_word(iph)) ^ skb_gro_len(skb)) | (id ^ IP_DF));
433         id >>= 16;
434  
435         for (p = *head; p; p = p->next) {
436 --- a/net/ipv4/route.c
437 +++ b/net/ipv4/route.c
438 @@ -465,7 +465,7 @@ static struct neighbour *ipv4_neigh_look
439         else if (skb)
440                 pkey = &ip_hdr(skb)->daddr;
441  
442 -       n = __ipv4_neigh_lookup(dev, *(__force u32 *)pkey);
443 +       n = __ipv4_neigh_lookup(dev, net_hdr_word(pkey));
444         if (n)
445                 return n;
446         return neigh_create(&arp_tbl, pkey, dev);
447 --- a/net/ipv4/tcp_output.c
448 +++ b/net/ipv4/tcp_output.c
449 @@ -456,15 +456,17 @@ static void tcp_options_write(__be32 *pt
450          */
451         if (unlikely(OPTION_MD5 & options)) {
452                 if (unlikely(OPTION_COOKIE_EXTENSION & options)) {
453 -                       *ptr++ = htonl((TCPOPT_COOKIE << 24) |
454 -                                      (TCPOLEN_COOKIE_BASE << 16) |
455 -                                      (TCPOPT_MD5SIG << 8) |
456 -                                      TCPOLEN_MD5SIG);
457 +                       net_hdr_word(ptr++) =
458 +                               htonl((TCPOPT_COOKIE << 24) |
459 +                                     (TCPOLEN_COOKIE_BASE << 16) |
460 +                                     (TCPOPT_MD5SIG << 8) |
461 +                                     TCPOLEN_MD5SIG);
462                 } else {
463 -                       *ptr++ = htonl((TCPOPT_NOP << 24) |
464 -                                      (TCPOPT_NOP << 16) |
465 -                                      (TCPOPT_MD5SIG << 8) |
466 -                                      TCPOLEN_MD5SIG);
467 +                       net_hdr_word(ptr++) =
468 +                               htonl((TCPOPT_NOP << 24) |
469 +                                     (TCPOPT_NOP << 16) |
470 +                                     (TCPOPT_MD5SIG << 8) |
471 +                                     TCPOLEN_MD5SIG);
472                 }
473                 options &= ~OPTION_COOKIE_EXTENSION;
474                 /* overload cookie hash location */
475 @@ -473,26 +475,28 @@ static void tcp_options_write(__be32 *pt
476         }
477  
478         if (unlikely(opts->mss)) {
479 -               *ptr++ = htonl((TCPOPT_MSS << 24) |
480 -                              (TCPOLEN_MSS << 16) |
481 -                              opts->mss);
482 +               net_hdr_word(ptr++) =
483 +                       htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) |
484 +                             opts->mss);
485         }
486  
487         if (likely(OPTION_TS & options)) {
488                 if (unlikely(OPTION_SACK_ADVERTISE & options)) {
489 -                       *ptr++ = htonl((TCPOPT_SACK_PERM << 24) |
490 -                                      (TCPOLEN_SACK_PERM << 16) |
491 -                                      (TCPOPT_TIMESTAMP << 8) |
492 -                                      TCPOLEN_TIMESTAMP);
493 +                       net_hdr_word(ptr++) =
494 +                               htonl((TCPOPT_SACK_PERM << 24) |
495 +                                     (TCPOLEN_SACK_PERM << 16) |
496 +                                     (TCPOPT_TIMESTAMP << 8) |
497 +                                     TCPOLEN_TIMESTAMP);
498                         options &= ~OPTION_SACK_ADVERTISE;
499                 } else {
500 -                       *ptr++ = htonl((TCPOPT_NOP << 24) |
501 -                                      (TCPOPT_NOP << 16) |
502 -                                      (TCPOPT_TIMESTAMP << 8) |
503 -                                      TCPOLEN_TIMESTAMP);
504 +                       net_hdr_word(ptr++) =
505 +                               htonl((TCPOPT_NOP << 24) |
506 +                                     (TCPOPT_NOP << 16) |
507 +                                     (TCPOPT_TIMESTAMP << 8) |
508 +                                     TCPOLEN_TIMESTAMP);
509                 }
510 -               *ptr++ = htonl(opts->tsval);
511 -               *ptr++ = htonl(opts->tsecr);
512 +               net_hdr_word(ptr++) = htonl(opts->tsval);
513 +               net_hdr_word(ptr++) = htonl(opts->tsecr);
514         }
515  
516         /* Specification requires after timestamp, so do it now.
517 @@ -512,19 +516,20 @@ static void tcp_options_write(__be32 *pt
518                         __u8 *p = (__u8 *)ptr;
519  
520                         /* 16-bit multiple */
521 -                       *p++ = TCPOPT_COOKIE;
522 -                       *p++ = TCPOLEN_COOKIE_BASE + cookie_size;
523 -                       *p++ = *cookie_copy++;
524 -                       *p++ = *cookie_copy++;
525 +                       net_hdr_word(p++) = TCPOPT_COOKIE;
526 +                       net_hdr_word(p++) = TCPOLEN_COOKIE_BASE + cookie_size;
527 +                       net_hdr_word(p++) = *cookie_copy++;
528 +                       net_hdr_word(p++) = *cookie_copy++;
529                         ptr++;
530                         cookie_size -= 2;
531                 } else {
532                         /* 32-bit multiple */
533 -                       *ptr++ = htonl(((TCPOPT_NOP << 24) |
534 -                                       (TCPOPT_NOP << 16) |
535 -                                       (TCPOPT_COOKIE << 8) |
536 -                                       TCPOLEN_COOKIE_BASE) +
537 -                                      cookie_size);
538 +                       net_hdr_word(ptr++) =
539 +                               htonl(((TCPOPT_NOP << 24) |
540 +                                      (TCPOPT_NOP << 16) |
541 +                                      (TCPOPT_COOKIE << 8) |
542 +                                      TCPOLEN_COOKIE_BASE) +
543 +                                     cookie_size);
544                 }
545  
546                 if (cookie_size > 0) {
547 @@ -534,17 +539,19 @@ static void tcp_options_write(__be32 *pt
548         }
549  
550         if (unlikely(OPTION_SACK_ADVERTISE & options)) {
551 -               *ptr++ = htonl((TCPOPT_NOP << 24) |
552 -                              (TCPOPT_NOP << 16) |
553 -                              (TCPOPT_SACK_PERM << 8) |
554 -                              TCPOLEN_SACK_PERM);
555 +               net_hdr_word(ptr++) =
556 +                       htonl((TCPOPT_NOP << 24) |
557 +                             (TCPOPT_NOP << 16) |
558 +                             (TCPOPT_SACK_PERM << 8) |
559 +                             TCPOLEN_SACK_PERM);
560         }
561  
562         if (unlikely(OPTION_WSCALE & options)) {
563 -               *ptr++ = htonl((TCPOPT_NOP << 24) |
564 -                              (TCPOPT_WINDOW << 16) |
565 -                              (TCPOLEN_WINDOW << 8) |
566 -                              opts->ws);
567 +               net_hdr_word(ptr++) =
568 +                       htonl((TCPOPT_NOP << 24) |
569 +                             (TCPOPT_WINDOW << 16) |
570 +                             (TCPOLEN_WINDOW << 8) |
571 +                             opts->ws);
572         }
573  
574         if (unlikely(opts->num_sack_blocks)) {
575 @@ -552,16 +559,17 @@ static void tcp_options_write(__be32 *pt
576                         tp->duplicate_sack : tp->selective_acks;
577                 int this_sack;
578  
579 -               *ptr++ = htonl((TCPOPT_NOP  << 24) |
580 -                              (TCPOPT_NOP  << 16) |
581 -                              (TCPOPT_SACK <<  8) |
582 -                              (TCPOLEN_SACK_BASE + (opts->num_sack_blocks *
583 +               net_hdr_word(ptr++) =
584 +                       htonl((TCPOPT_NOP << 24) |
585 +                             (TCPOPT_NOP << 16) |
586 +                             (TCPOPT_SACK << 8) |
587 +                             (TCPOLEN_SACK_BASE + (opts->num_sack_blocks *
588                                                      TCPOLEN_SACK_PERBLOCK)));
589  
590                 for (this_sack = 0; this_sack < opts->num_sack_blocks;
591                      ++this_sack) {
592 -                       *ptr++ = htonl(sp[this_sack].start_seq);
593 -                       *ptr++ = htonl(sp[this_sack].end_seq);
594 +                       net_hdr_word(ptr++) = htonl(sp[this_sack].start_seq);
595 +                       net_hdr_word(ptr++) = htonl(sp[this_sack].end_seq);
596                 }
597  
598                 tp->rx_opt.dsack = 0;
599 @@ -570,9 +578,10 @@ static void tcp_options_write(__be32 *pt
600         if (unlikely(OPTION_FAST_OPEN_COOKIE & options)) {
601                 struct tcp_fastopen_cookie *foc = opts->fastopen_cookie;
602  
603 -               *ptr++ = htonl((TCPOPT_EXP << 24) |
604 -                              ((TCPOLEN_EXP_FASTOPEN_BASE + foc->len) << 16) |
605 -                              TCPOPT_FASTOPEN_MAGIC);
606 +               net_hdr_word(ptr++) =
607 +                       htonl((TCPOPT_EXP << 24) |
608 +                             ((TCPOLEN_EXP_FASTOPEN_BASE + foc->len) << 16) |
609 +                             TCPOPT_FASTOPEN_MAGIC);
610  
611                 memcpy(ptr, foc->val, foc->len);
612                 if ((foc->len & 3) == 2) {
613 --- a/net/ipv4/igmp.c
614 +++ b/net/ipv4/igmp.c
615 @@ -470,7 +470,7 @@ static struct sk_buff *add_grec(struct s
616                 if (!skb)
617                         return NULL;
618                 psrc = (__be32 *)skb_put(skb, sizeof(__be32));
619 -               *psrc = psf->sf_inaddr;
620 +               net_hdr_word(psrc) = psf->sf_inaddr;
621                 scount++; stotal++;
622                 if ((type == IGMPV3_ALLOW_NEW_SOURCES ||
623                      type == IGMPV3_BLOCK_OLD_SOURCES) && psf->sf_crcount) {
624 --- a/net/ipv4/ip_gre.c
625 +++ b/net/ipv4/ip_gre.c
626 @@ -533,7 +533,7 @@ static void ipgre_err(struct sk_buff *sk
627                 return;
628  
629         if (flags & GRE_KEY)
630 -               key = *(((__be32 *)p) + (grehlen / 4) - 1);
631 +               key = net_hdr_word(((__be32 *)p) + (grehlen / 4) - 1);
632  
633         switch (type) {
634         default: