From: Dave Taht <dave.taht@gmail.com>
To: cerowrt-devel@lists.bufferbloat.net
Subject: [Cerowrt-devel] was filled with hope for killing the last traps, now have brick
Date: Sun, 20 Jan 2013 14:24:12 -0500 [thread overview]
Message-ID: <CAA93jw7b8+2EgYFncv3m7WQEzWn9KtpQC1vviatLS+2+Zu-QZg@mail.gmail.com> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 881 bytes --]
Mine and Robert Bradley's latest attempt at killing the last ipv6
instruction traps
with a rollup patch from bugs 419 and 421...
brick the router. It boots, the main green light goes on, then it dies.
Naturally
I left the serial cable at the office...
Of course in the middle of this patch set revision I also updated to 3.7.3
and openwrt head,
so have a few more variables than usual than just us to cope with.
I would not mind eyeballs on this to see if there is an obvious flaw,
otherwise I will progressively bisect from what was known to work
forward as fast as I can. (besides, the hope is to submit this upstream)
net_hdr_word is defined in the 902-unaligned_access_hacks patch in openwrt
head...
now off to find a small, sharp, pointy object...
--
Dave Täht
Fixing bufferbloat with cerowrt:
http://www.teklibre.com/cerowrt/subscribe.html
[-- Attachment #1.2: Type: text/html, Size: 1168 bytes --]
[-- Attachment #2: 903-more-unaligned_access_hacks.patch --]
[-- Type: application/octet-stream, Size: 9570 bytes --]
From fb1fe9159a8854ceece937f43b0cef56abf499ce Mon Sep 17 00:00:00 2001
From: Dave Taht <dave.taht@bufferbloat.net>
Date: Sat, 19 Jan 2013 22:31:40 -0800
Subject: [PATCH] full ipv6 unaligne patchset
---
include/linux/ipv6.h | 2 +-
include/net/addrconf.h | 2 +-
include/net/inet_ecn.h | 4 ++--
include/net/ipv6.h | 10 +++++++---
include/net/ndisc.h | 8 +++++---
include/uapi/linux/in.h | 2 +-
include/uapi/linux/xfrm.h | 2 +-
net/core/secure_seq.c | 9 ++++++---
net/ipv6/ip6_fib.c | 2 +-
net/netfilter/nf_conntrack_proto_tcp.c | 2 +-
net/netfilter/xt_LOG.c | 4 ++--
net/xfrm/xfrm_input.c | 4 ++--
12 files changed, 30 insertions(+), 21 deletions(-)
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 74a90be..8fa93bc 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -74,7 +74,7 @@ static inline struct ipv6hdr *ipipv6_hdr(const struct sk_buff *skb)
static inline __u8 ipv6_tclass(const struct ipv6hdr *iph)
{
- return (ntohl(*(__be32 *)iph) >> 20) & 0xff;
+ return (ntohl(net_hdr_word(iph)) >> 20) & 0xff;
}
/*
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 9e63e76..1fe6a38 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -39,7 +39,7 @@ struct prefix_info {
__be32 reserved2;
struct in6_addr prefix;
-};
+} __attribute__((packed, aligned(2)));
#include <linux/netdevice.h>
diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h
index aab7375..5da1768 100644
--- a/include/net/inet_ecn.h
+++ b/include/net/inet_ecn.h
@@ -115,13 +115,13 @@ static inline int IP6_ECN_set_ce(struct ipv6hdr *iph)
{
if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph)))
return 0;
- *(__be32*)iph |= htonl(INET_ECN_CE << 20);
+ net_hdr_word(iph) |= htonl(INET_ECN_CE << 20);
return 1;
}
static inline void IP6_ECN_clear(struct ipv6hdr *iph)
{
- *(__be32*)iph &= ~htonl(INET_ECN_MASK << 20);
+ net_hdr_word(iph) &= ~htonl(INET_ECN_MASK << 20);
}
static inline void ipv6_copy_dscp(unsigned int dscp, struct ipv6hdr *inner)
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 979bf6c..e2b6975 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -376,6 +376,8 @@ static inline bool __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2,
unsigned int prefixlen)
{
unsigned int pdw, pbi;
+ /* Used for last <32-bit fraction of prefix */
+ u32 pbia1, pbia2;
/* check complete u32 in prefix */
pdw = prefixlen >> 5;
@@ -384,7 +386,9 @@ static inline bool __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))))
+ pbia1 = net_hdr_word(&a1[pdw]);
+ pbia2 = net_hdr_word(&a2[pdw]);
+ if (pbi && ((pbia1 ^ pbia2) & htonl((0xffffffff) << (32 - pbi))))
return false;
return true;
@@ -500,13 +504,13 @@ static inline void ipv6_addr_set_v4mapped(const __be32 addr,
*/
static inline int __ipv6_addr_diff(const void *token1, const void *token2, int addrlen)
{
- const __be32 *a1 = token1, *a2 = token2;
+ const struct in6_addr *a1 = token1, *a2 = token2;
int i;
addrlen >>= 2;
for (i = 0; i < addrlen; i++) {
- __be32 xb = a1[i] ^ a2[i];
+ __be32 xb = a1->s6_addr32[i] ^ a2->s6_addr32[i];
if (xb)
return i * 32 + 31 - __fls(ntohl(xb));
}
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index e61a388..b79fef2 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -76,7 +76,7 @@ struct ra_msg {
struct icmp6hdr icmph;
__be32 reachable_time;
__be32 retrans_timer;
-};
+} __attribute__((packed, aligned(2)));
struct rd_msg {
struct icmp6hdr icmph;
@@ -163,8 +163,10 @@ 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] ^ net_hdr_word(&p32[0])) |
+ (n32[1] ^ net_hdr_word(&p32[1])) |
+ (n32[2] ^ net_hdr_word(&p32[2])) |
+ (n32[3] ^ net_hdr_word(&p32[3]))) == 0) {
if (!atomic_inc_not_zero(&n->refcnt))
n = NULL;
break;
diff --git a/include/uapi/linux/in.h b/include/uapi/linux/in.h
index 9edb441..860de7a 100644
--- a/include/uapi/linux/in.h
+++ b/include/uapi/linux/in.h
@@ -55,7 +55,7 @@ enum {
/* Internet address. */
struct in_addr {
__be32 s_addr;
-};
+} __attribute__((packed, aligned(2)));
#define IP_TOS 1
#define IP_TTL 2
diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h
index 28e493b..74a9d71 100644
--- a/include/uapi/linux/xfrm.h
+++ b/include/uapi/linux/xfrm.h
@@ -13,7 +13,7 @@
typedef union {
__be32 a4;
__be32 a6[4];
-} xfrm_address_t;
+} __attribute__((packed, aligned(2))) xfrm_address_t;
/* Ident of a specific xfrm_state. It is used on input to lookup
* the state by (spi,daddr,ah/esp) or to store information about
diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c
index e61a8bb..4005c6a 100644
--- a/net/core/secure_seq.c
+++ b/net/core/secure_seq.c
@@ -43,10 +43,11 @@ __u32 secure_tcpv6_sequence_number(const __be32 *saddr, const __be32 *daddr,
u32 secret[MD5_MESSAGE_BYTES / 4];
u32 hash[MD5_DIGEST_WORDS];
u32 i;
+ const struct in6_addr *daddr6 = (struct in6_addr *) daddr;
memcpy(hash, saddr, 16);
for (i = 0; i < 4; i++)
- secret[i] = net_secret[i] + (__force u32)daddr[i];
+ secret[i] = net_secret[i] + (__force u32)daddr6->s6_addr32[i];
secret[4] = net_secret[4] +
(((__force u16)sport << 16) + (__force u16)dport);
for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++)
@@ -64,10 +65,11 @@ u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
u32 secret[MD5_MESSAGE_BYTES / 4];
u32 hash[MD5_DIGEST_WORDS];
u32 i;
+ const struct in6_addr *daddr6 = (struct in6_addr *) daddr;
memcpy(hash, saddr, 16);
for (i = 0; i < 4; i++)
- secret[i] = net_secret[i] + (__force u32) daddr[i];
+ secret[i] = net_secret[i] + (__force u32) daddr6->s6_addr32[i];
secret[4] = net_secret[4] + (__force u32)dport;
for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++)
secret[i] = net_secret[i];
@@ -165,10 +167,11 @@ u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr,
u32 hash[MD5_DIGEST_WORDS];
u64 seq;
u32 i;
+ const struct in6_addr *daddr6 = (struct in6_addr *) daddr;
memcpy(hash, saddr, 16);
for (i = 0; i < 4; i++)
- secret[i] = net_secret[i] + daddr[i];
+ secret[i] = net_secret[i] + daddr6->s6_addr32[i];
secret[4] = net_secret[4] +
(((__force u16)sport << 16) + (__force u16)dport);
for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++)
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 24995a9..946abd7 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -144,7 +144,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];
+ net_hdr_word(addr[fn_bit >> 5]);
}
static __inline__ struct fib6_node * node_alloc(void)
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 61f9285..7893df6 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -449,7 +449,7 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
/* Fast path for timestamp-only option */
if (length == TCPOLEN_TSTAMP_ALIGNED
- && *(__be32 *)ptr == htonl((TCPOPT_NOP << 24)
+ && net_hdr_word(ptr) == htonl((TCPOPT_NOP << 24)
| (TCPOPT_NOP << 16)
| (TCPOPT_TIMESTAMP << 8)
| TCPOLEN_TIMESTAMP))
diff --git a/net/netfilter/xt_LOG.c b/net/netfilter/xt_LOG.c
index fa40096..2616ecf 100644
--- a/net/netfilter/xt_LOG.c
+++ b/net/netfilter/xt_LOG.c
@@ -521,9 +521,9 @@ static void dump_ipv6_packet(struct sbuff *m,
/* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */
sb_add(m, "LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
ntohs(ih->payload_len) + sizeof(struct ipv6hdr),
- (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20,
+ (ntohl(net_hdr_word(ih)) & 0x0ff00000) >> 20,
ih->hop_limit,
- (ntohl(*(__be32 *)ih) & 0x000fffff));
+ (ntohl(net_hdr_word(ih)) & 0x000fffff));
fragment = 0;
ptr = ip6hoff + sizeof(struct ipv6hdr);
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index ab2bb42..57bbd3f 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -77,8 +77,8 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
if (!pskb_may_pull(skb, hlen))
return -EINVAL;
- *spi = *(__be32*)(skb_transport_header(skb) + offset);
- *seq = *(__be32*)(skb_transport_header(skb) + offset_seq);
+ *spi = net_hdr_word(skb_transport_header(skb) + offset);
+ *seq = net_hdr_word(skb_transport_header(skb) + offset_seq);
return 0;
}
--
1.7.9.5
diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h
index c2e542b..daeeec9 100644
--- a/include/net/secure_seq.h
+++ b/include/net/secure_seq.h
@@ -2,6 +2,7 @@
#define _NET_SECURE_SEQ
#include <linux/types.h>
+#include <linux/in6.h>
extern __u32 secure_ip_id(__be32 daddr);
extern __u32 secure_ipv6_id(const __be32 daddr[4]);
next reply other threads:[~2013-01-20 19:24 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-20 19:24 Dave Taht [this message]
2013-01-21 8:51 ` Ketan Kulkarni
2013-01-21 9:01 ` Dave Taht
2013-01-21 13:21 ` Ketan Kulkarni
2013-01-21 13:50 ` Ketan Kulkarni
2013-01-21 15:36 ` Robert Bradley
2013-01-21 18:20 ` Dave Taht
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://lists.bufferbloat.net/postorius/lists/cerowrt-devel.lists.bufferbloat.net/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAA93jw7b8+2EgYFncv3m7WQEzWn9KtpQC1vviatLS+2+Zu-QZg@mail.gmail.com \
--to=dave.taht@gmail.com \
--cc=cerowrt-devel@lists.bufferbloat.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox