From 3b6a792f6ace33584897d1af08630c9acc0ce221 Mon Sep 17 00:00:00 2001 From: Jiri Slaby <jirislaby@gmail.com> Date: Mon, 6 Nov 2006 14:34:48 -0800 Subject: [PATCH 1/7] [NET]: kconfig, correct traffic shaper As Patrick McHardy <kaber@trash.net> suggested, Traffic Shaper is now obsolete and alternative to it is no longer CBQ, since its problems with virtual devices, alter Kconfig text to reflect this -- put a link to the traffic schedulers as a whole. Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Acked-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: David S. Miller <davem@davemloft.net> --- drivers/net/Kconfig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9cb3ca5806fc..6e863aa9894c 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2833,7 +2833,7 @@ config NET_FC "SCSI generic support". config SHAPER - tristate "Traffic Shaper (EXPERIMENTAL)" + tristate "Traffic Shaper (OBSOLETE)" depends on EXPERIMENTAL ---help--- The traffic shaper is a virtual network device that allows you to @@ -2842,9 +2842,9 @@ config SHAPER these virtual devices. See <file:Documentation/networking/shaper.txt> for more information. - An alternative to this traffic shaper is the experimental - Class-Based Queuing (CBQ) scheduling support which you get if you - say Y to "QoS and/or fair queuing" above. + An alternative to this traffic shaper are traffic schedulers which + you'll get if you say Y to "QoS and/or fair queuing" in + "Networking options". To compile this driver as a module, choose M here: the module will be called shaper. If unsure, say N. From 9e950efa20dc8037c27509666cba6999da9368e8 Mon Sep 17 00:00:00 2001 From: John Heffner <jheffner@psc.edu> Date: Mon, 6 Nov 2006 23:10:51 -0800 Subject: [PATCH 2/7] [TCP]: Don't use highmem in tcp hash size calculation. This patch removes consideration of high memory when determining TCP hash table sizes. Taking into account high memory results in tcp_mem values that are too large. Signed-off-by: John Heffner <jheffner@psc.edu> Signed-off-by: David S. Miller <davem@davemloft.net> --- net/ipv4/tcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 66e9a729f6df..4322318ab332 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2270,7 +2270,7 @@ void __init tcp_init(void) thash_entries, (num_physpages >= 128 * 1024) ? 13 : 15, - HASH_HIGHMEM, + 0, &tcp_hashinfo.ehash_size, NULL, 0); @@ -2286,7 +2286,7 @@ void __init tcp_init(void) tcp_hashinfo.ehash_size, (num_physpages >= 128 * 1024) ? 13 : 15, - HASH_HIGHMEM, + 0, &tcp_hashinfo.bhash_size, NULL, 64 * 1024); From da33e3eb4876c43b78fdc7b7068653239f28714a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger <shemminger@osdl.org> Date: Tue, 7 Nov 2006 14:54:46 -0800 Subject: [PATCH 3/7] [PKT_SCHED] sch_htb: Use hlist_del_init(). Otherwise we can hit paths that (legally) do multiple deletes on the same node and OOPS with the HLIST poison values there instead of NULL. Signed-off-by: David S. Miller <davem@davemloft.net> --- net/sched/sch_htb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 9b9c555c713f..4b52fa78935a 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -1284,8 +1284,7 @@ static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl) struct htb_class, sibling)); /* note: this delete may happen twice (see htb_delete) */ - if (!hlist_unhashed(&cl->hlist)) - hlist_del(&cl->hlist); + hlist_del_init(&cl->hlist); list_del(&cl->sibling); if (cl->prio_activity) @@ -1333,8 +1332,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg) sch_tree_lock(sch); /* delete from hash and active; remainder in destroy_class */ - if (!hlist_unhashed(&cl->hlist)) - hlist_del(&cl->hlist); + hlist_del_init(&cl->hlist); if (cl->prio_activity) htb_deactivate(q, cl); From 8e365eec04c86899fab5db0f49a9c98554069bd0 Mon Sep 17 00:00:00 2001 From: Chris Lalancette <clalance@redhat.com> Date: Tue, 7 Nov 2006 14:56:19 -0800 Subject: [PATCH 4/7] [NETPOLL]: Compute checksum properly in netpoll_send_udp(). Signed-off-by: Chris Lalancette <clalance@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net> --- net/core/netpoll.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 9308af060b44..6589adb14cbf 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -340,6 +340,12 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len) udph->dest = htons(np->remote_port); udph->len = htons(udp_len); udph->check = 0; + udph->check = csum_tcpudp_magic(htonl(np->local_ip), + htonl(np->remote_ip), + udp_len, IPPROTO_UDP, + csum_partial((unsigned char *)udph, udp_len, 0)); + if (udph->check == 0) + udph->check = -1; skb->nh.iph = iph = (struct iphdr *)skb_push(skb, sizeof(*iph)); From 25f484a62e41be8020b9a31bf50a792baa58d2d4 Mon Sep 17 00:00:00 2001 From: Herbert Xu <herbert@gondor.apana.org.au> Date: Tue, 7 Nov 2006 14:57:15 -0800 Subject: [PATCH 5/7] [NET]: Set truesize in pskb_copy Since pskb_copy tacks on the non-linear bits from the original skb, it needs to count them in the truesize field of the new skb. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net> --- net/core/skbuff.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index f735455dc5d1..b8b106358040 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -639,6 +639,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask) n->csum = skb->csum; n->ip_summed = skb->ip_summed; + n->truesize += skb->data_len; n->data_len = skb->data_len; n->len = skb->len; From af2c6a4aaa2253f1e29df8fb59a3d92174d30a33 Mon Sep 17 00:00:00 2001 From: Michael Chan <mchan@broadcom.com> Date: Tue, 7 Nov 2006 14:57:51 -0800 Subject: [PATCH 6/7] [TG3]: Fix array overrun in tg3_read_partno(). Use proper upper limits for the loops and check for all error conditions. The problem was noticed by Adrian Bunk. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net> --- drivers/net/tg3.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 8f059b7968bd..06e4f77b0988 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10212,7 +10212,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) static void __devinit tg3_read_partno(struct tg3 *tp) { unsigned char vpd_data[256]; - int i; + unsigned int i; u32 magic; if (tg3_nvram_read_swab(tp, 0x0, &magic)) @@ -10258,9 +10258,9 @@ static void __devinit tg3_read_partno(struct tg3 *tp) } /* Now parse and find the part number. */ - for (i = 0; i < 256; ) { + for (i = 0; i < 254; ) { unsigned char val = vpd_data[i]; - int block_end; + unsigned int block_end; if (val == 0x82 || val == 0x91) { i = (i + 3 + @@ -10276,21 +10276,26 @@ static void __devinit tg3_read_partno(struct tg3 *tp) (vpd_data[i + 1] + (vpd_data[i + 2] << 8))); i += 3; - while (i < block_end) { + + if (block_end > 256) + goto out_not_found; + + while (i < (block_end - 2)) { if (vpd_data[i + 0] == 'P' && vpd_data[i + 1] == 'N') { int partno_len = vpd_data[i + 2]; - if (partno_len > 24) + i += 3; + if (partno_len > 24 || (partno_len + i) > 256) goto out_not_found; memcpy(tp->board_part_number, - &vpd_data[i + 3], - partno_len); + &vpd_data[i], partno_len); /* Success. */ return; } + i += 3 + vpd_data[i + 2]; } /* Part number not found. */ From 375d9d71838970030c8e0bf0ac2abcc1a3487df8 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse <swhiteho@redhat.com> Date: Tue, 7 Nov 2006 15:09:17 -0800 Subject: [PATCH 7/7] [DECNET]: Endianess fixes (try #2) Here are some fixes to endianess problems spotted by Al Viro. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net> --- net/decnet/af_decnet.c | 23 ++++++++++++----------- net/decnet/dn_nsp_in.c | 8 ++++---- net/decnet/dn_nsp_out.c | 2 +- net/decnet/dn_rules.c | 4 ++-- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 3456cd331835..21f20f21dd32 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -166,7 +166,7 @@ static struct hlist_head *dn_find_list(struct sock *sk) if (scp->addr.sdn_flags & SDF_WILD) return hlist_empty(&dn_wild_sk) ? &dn_wild_sk : NULL; - return &dn_sk_hash[scp->addrloc & DN_SK_HASH_MASK]; + return &dn_sk_hash[dn_ntohs(scp->addrloc) & DN_SK_HASH_MASK]; } /* @@ -180,7 +180,7 @@ static int check_port(__le16 port) if (port == 0) return -1; - sk_for_each(sk, node, &dn_sk_hash[port & DN_SK_HASH_MASK]) { + sk_for_each(sk, node, &dn_sk_hash[dn_ntohs(port) & DN_SK_HASH_MASK]) { struct dn_scp *scp = DN_SK(sk); if (scp->addrloc == port) return -1; @@ -194,12 +194,12 @@ static unsigned short port_alloc(struct sock *sk) static unsigned short port = 0x2000; unsigned short i_port = port; - while(check_port(++port) != 0) { + while(check_port(dn_htons(++port)) != 0) { if (port == i_port) return 0; } - scp->addrloc = port; + scp->addrloc = dn_htons(port); return 1; } @@ -418,7 +418,7 @@ struct sock *dn_find_by_skb(struct sk_buff *skb) struct dn_scp *scp; read_lock(&dn_hash_lock); - sk_for_each(sk, node, &dn_sk_hash[cb->dst_port & DN_SK_HASH_MASK]) { + sk_for_each(sk, node, &dn_sk_hash[dn_ntohs(cb->dst_port) & DN_SK_HASH_MASK]) { scp = DN_SK(sk); if (cb->src != dn_saddr2dn(&scp->peer)) continue; @@ -1016,13 +1016,14 @@ static void dn_access_copy(struct sk_buff *skb, struct accessdata_dn *acc) static void dn_user_copy(struct sk_buff *skb, struct optdata_dn *opt) { - unsigned char *ptr = skb->data; - - opt->opt_optl = *ptr++; - opt->opt_status = 0; - memcpy(opt->opt_data, ptr, opt->opt_optl); - skb_pull(skb, dn_ntohs(opt->opt_optl) + 1); + unsigned char *ptr = skb->data; + u16 len = *ptr++; /* yes, it's 8bit on the wire */ + BUG_ON(len > 16); /* we've checked the contents earlier */ + opt->opt_optl = dn_htons(len); + opt->opt_status = 0; + memcpy(opt->opt_data, ptr, len); + skb_pull(skb, len + 1); } static struct sk_buff *dn_wait_for_connect(struct sock *sk, long *timeo) diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c index 72ecc6e62ec4..7683d4f754d2 100644 --- a/net/decnet/dn_nsp_in.c +++ b/net/decnet/dn_nsp_in.c @@ -360,9 +360,9 @@ static void dn_nsp_conn_conf(struct sock *sk, struct sk_buff *skb) scp->max_window = decnet_no_fc_max_cwnd; if (skb->len > 0) { - unsigned char dlen = *skb->data; + u16 dlen = *skb->data; if ((dlen <= 16) && (dlen <= skb->len)) { - scp->conndata_in.opt_optl = dn_htons((__u16)dlen); + scp->conndata_in.opt_optl = dn_htons(dlen); memcpy(scp->conndata_in.opt_data, skb->data + 1, dlen); } } @@ -404,9 +404,9 @@ static void dn_nsp_disc_init(struct sock *sk, struct sk_buff *skb) memset(scp->discdata_in.opt_data, 0, 16); if (skb->len > 0) { - unsigned char dlen = *skb->data; + u16 dlen = *skb->data; if ((dlen <= 16) && (dlen <= skb->len)) { - scp->discdata_in.opt_optl = dn_htons((__u16)dlen); + scp->discdata_in.opt_optl = dn_htons(dlen); memcpy(scp->discdata_in.opt_data, skb->data + 1, dlen); } } diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c index c2e21cd89b3c..b342e4e8f5f8 100644 --- a/net/decnet/dn_nsp_out.c +++ b/net/decnet/dn_nsp_out.c @@ -526,7 +526,7 @@ void dn_send_conn_conf(struct sock *sk, gfp_t gfp) struct nsp_conn_init_msg *msg; __u8 len = (__u8)dn_ntohs(scp->conndata_out.opt_optl); - if ((skb = dn_alloc_skb(sk, 50 + dn_ntohs(scp->conndata_out.opt_optl), gfp)) == NULL) + if ((skb = dn_alloc_skb(sk, 50 + len, gfp)) == NULL) return; msg = (struct nsp_conn_init_msg *)skb_put(skb, sizeof(*msg)); diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index 3e0c882c90bf..590e0a72495c 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c @@ -124,8 +124,8 @@ static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = { static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) { struct dn_fib_rule *r = (struct dn_fib_rule *)rule; - u16 daddr = fl->fld_dst; - u16 saddr = fl->fld_src; + __le16 daddr = fl->fld_dst; + __le16 saddr = fl->fld_src; if (((saddr ^ r->src) & r->srcmask) || ((daddr ^ r->dst) & r->dstmask))