1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2024-11-01 21:38:26 +02:00
openwrt-xburst/target/linux/ar71xx/patches-2.6.39/910-unaligned_access_hacks.patch
nbd 8fb4b275c2 ar71xx: add some hacks to work around the misalignment in IP packets received on AR71xx and AR91xx ethernet MACs
decreases CPU load with the default firewall for routing 95 mbit/s from 78% to 55%

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@27878 3c298f89-4303-0410-b956-a3cf2f4a3e73
2011-08-02 15:12:08 +00:00

118 lines
2.4 KiB
Diff

--- a/arch/mips/include/asm/checksum.h
+++ b/arch/mips/include/asm/checksum.h
@@ -12,6 +12,7 @@
#define _ASM_CHECKSUM_H
#include <linux/in6.h>
+#include <linux/unaligned/packed_struct.h>
#include <asm/uaccess.h>
@@ -104,26 +105,30 @@ static inline __sum16 ip_fast_csum(const
const unsigned int *stop = word + ihl;
unsigned int csum;
int carry;
+ unsigned int w;
- csum = word[0];
- csum += word[1];
- carry = (csum < word[1]);
+ csum = __get_unaligned_cpu32(word++);
+
+ w = __get_unaligned_cpu32(word++);
+ csum += w;
+ carry = (csum < w);
csum += carry;
- csum += word[2];
- carry = (csum < word[2]);
+ w = __get_unaligned_cpu32(word++);
+ csum += w;
+ carry = (csum < w);
csum += carry;
- csum += word[3];
- carry = (csum < word[3]);
+ w = __get_unaligned_cpu32(word++);
+ csum += w;
+ carry = (csum < w);
csum += carry;
- word += 4;
do {
- csum += *word;
- carry = (csum < *word);
+ w = __get_unaligned_cpu32(word++);
+ csum += w;
+ carry = (csum < w);
csum += carry;
- word++;
} while (word != stop);
return csum_fold(csum);
--- a/include/linux/ip.h
+++ b/include/linux/ip.h
@@ -102,7 +102,7 @@ struct iphdr {
__be32 saddr;
__be32 daddr;
/*The options start here. */
-};
+} __packed;
#ifdef __KERNEL__
#include <linux/skbuff.h>
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -126,7 +126,7 @@ struct ipv6hdr {
struct in6_addr saddr;
struct in6_addr daddr;
-};
+} __packed;
#ifdef __KERNEL__
/*
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -54,7 +54,7 @@ struct tcphdr {
__be16 window;
__sum16 check;
__be16 urg_ptr;
-};
+} __packed;
/*
* The union cast uses a gcc extension to avoid aliasing problems
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -24,7 +24,7 @@ struct udphdr {
__be16 dest;
__be16 len;
__sum16 check;
-};
+} __packed;
/* UDP socket options */
#define UDP_CORK 1 /* Never send partially complete segments */
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -14,6 +14,7 @@
#include <linux/skbuff.h>
#include <linux/icmp.h>
#include <linux/sysctl.h>
+#include <linux/unaligned/packed_struct.h>
#include <net/route.h>
#include <net/ip.h>
@@ -44,8 +45,8 @@ static bool ipv4_pkt_to_tuple(const stru
if (ap == NULL)
return false;
- tuple->src.u3.ip = ap[0];
- tuple->dst.u3.ip = ap[1];
+ tuple->src.u3.ip = __get_unaligned_cpu32(ap++);
+ tuple->dst.u3.ip = __get_unaligned_cpu32(ap);
return true;
}