From 42c5e15f18d63c1ecf79d52bdaf4ea31cd22416d Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 2 Feb 2006 16:53:26 -0800 Subject: [NET] snap: needs hardware checksum fix The SNAP code pops off it's 5 byte header, but doesn't adjust the checksum. This would cause problems when using device that does IP over SNAP and hardware receive checksums. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/802/psnap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'net') diff --git a/net/802/psnap.c b/net/802/psnap.c index 4d638944d933bf..34e42968b477d9 100644 --- a/net/802/psnap.c +++ b/net/802/psnap.c @@ -59,8 +59,10 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev, proto = find_snap_client(skb->h.raw); if (proto) { /* Pass the frame on. */ + u8 *hdr = skb->data; skb->h.raw += 5; skb_pull(skb, 5); + skb_postpull_rcsum(skb, hdr, 5); rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev); } else { skb->sk = NULL; -- cgit 1.2.3-korg From 4641e7a334adf6856300a98e7296dfc886c446af Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 2 Feb 2006 16:55:45 -0800 Subject: [IPV6]: Don't hold extra ref count in ipv6_ifa_notify Currently the logic in ipv6_ifa_notify is to hold an extra reference count for addrconf dst's that get added to the routing table. Thus, when addrconf dst entries are taken out of the routing table, we need to drop that dst. However, addrconf dst entries may be removed from the routing table by means other than __ipv6_ifa_notify. So we're faced with the choice of either fixing up all places where addrconf dst entries are removed, or dropping the extra reference count altogether. I chose the latter because the ifp itself always holds a dst reference count of 1 while it's alive. This is dropped just before we kfree the ifp object. Therefore we know that in __ipv6_ifa_notify we will always hold that count. This bug was found by Eric W. Biederman. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'net') diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d328d59861438a..1db50487916bf0 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3321,9 +3321,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) switch (event) { case RTM_NEWADDR: - dst_hold(&ifp->rt->u.dst); - if (ip6_ins_rt(ifp->rt, NULL, NULL, NULL)) - dst_release(&ifp->rt->u.dst); + ip6_ins_rt(ifp->rt, NULL, NULL, NULL); if (ifp->idev->cnf.forwarding) addrconf_join_anycast(ifp); break; @@ -3334,8 +3332,6 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) dst_hold(&ifp->rt->u.dst); if (ip6_del_rt(ifp->rt, NULL, NULL, NULL)) dst_free(&ifp->rt->u.dst); - else - dst_release(&ifp->rt->u.dst); break; } } -- cgit 1.2.3-korg From 27852c26baab8b95fc9a2b3e8a18770ecd553f10 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Thu, 2 Feb 2006 16:57:31 -0800 Subject: [SCTP]: Fix 'fast retransmit' to send a TSN only once. SCTP used to "fast retransmit" a TSN every time we hit the number of missing reports for the TSN. However the Implementers Guide specifies that we should only "fast retransmit" a given TSN once. Subsequent retransmits should be timeouts only. Also change the number of missing reports to 3 as per the latest IG(similar to TCP). Signed-off-by: Vlad Yasevich Signed-off-by: Sridhar Samudrala Signed-off-by: David S. Miller --- include/net/sctp/structs.h | 2 +- net/sctp/output.c | 2 +- net/sctp/outqueue.c | 12 +++++++----- 3 files changed, 9 insertions(+), 7 deletions(-) (limited to 'net') diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 8c522ae031bbf5..072f407848a6fe 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -700,7 +700,7 @@ struct sctp_chunk { __u8 ecn_ce_done; /* Have we processed the ECN CE bit? */ __u8 pdiscard; /* Discard the whole packet now? */ __u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */ - __u8 fast_retransmit; /* Is this chunk fast retransmitted? */ + __s8 fast_retransmit; /* Is this chunk fast retransmitted? */ __u8 tsn_missing_report; /* Data chunk missing counter. */ }; diff --git a/net/sctp/output.c b/net/sctp/output.c index a40991ef72c92b..437cba7260a4a1 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -608,7 +608,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet, * When a Fast Retransmit is being performed the sender SHOULD * ignore the value of cwnd and SHOULD NOT delay retransmission. */ - if (!chunk->fast_retransmit) + if (chunk->fast_retransmit <= 0) if (transport->flight_size >= transport->cwnd) { retval = SCTP_XMIT_RWND_FULL; goto finish; diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index efb72faba20cd5..f148f9576dd226 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -406,7 +406,7 @@ void sctp_retransmit_mark(struct sctp_outq *q, * chunks that are not yet acked should be added to the * retransmit queue. */ - if ((fast_retransmit && chunk->fast_retransmit) || + if ((fast_retransmit && (chunk->fast_retransmit > 0)) || (!fast_retransmit && !chunk->tsn_gap_acked)) { /* RFC 2960 6.2.1 Processing a Received SACK * @@ -603,7 +603,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, /* Mark the chunk as ineligible for fast retransmit * after it is retransmitted. */ - chunk->fast_retransmit = 0; + if (chunk->fast_retransmit > 0) + chunk->fast_retransmit = -1; *start_timer = 1; q->empty = 0; @@ -621,7 +622,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, list_for_each(lchunk1, lqueue) { chunk1 = list_entry(lchunk1, struct sctp_chunk, transmitted_list); - chunk1->fast_retransmit = 0; + if (chunk1->fast_retransmit > 0) + chunk1->fast_retransmit = -1; } } } @@ -1562,11 +1564,11 @@ static void sctp_mark_missing(struct sctp_outq *q, /* * M4) If any DATA chunk is found to have a * 'TSN.Missing.Report' - * value larger than or equal to 4, mark that chunk for + * value larger than or equal to 3, mark that chunk for * retransmission and start the fast retransmit procedure. */ - if (chunk->tsn_missing_report >= 4) { + if (chunk->tsn_missing_report >= 3) { chunk->fast_retransmit = 1; do_fast_retransmit = 1; } -- cgit 1.2.3-korg From f8addb3215bf58154f189017d934dfc06b62c75e Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 2 Feb 2006 16:59:16 -0800 Subject: [IPV4] multipath_wrandom: Fix softirq-unsafe spin lock usage The spin locks in multipath_wrandom may be obtained from either process context or softirq context depending on whether the packet is locally or remotely generated. Therefore we need to disable BH processing when taking these locks. This bug was found by Ingo's lock validator. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/ipv4/multipath_wrandom.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c index d34a9fa608e0b8..342d0b9098f5f8 100644 --- a/net/ipv4/multipath_wrandom.c +++ b/net/ipv4/multipath_wrandom.c @@ -228,7 +228,7 @@ static void wrandom_set_nhinfo(__u32 network, struct multipath_dest *d, *target_dest = NULL; /* store the weight information for a certain route */ - spin_lock(&state[state_idx].lock); + spin_lock_bh(&state[state_idx].lock); /* find state entry for gateway or add one if necessary */ list_for_each_entry_rcu(r, &state[state_idx].head, list) { @@ -276,7 +276,7 @@ static void wrandom_set_nhinfo(__u32 network, * we are finished */ - spin_unlock(&state[state_idx].lock); + spin_unlock_bh(&state[state_idx].lock); } static void __multipath_free(struct rcu_head *head) @@ -302,7 +302,7 @@ static void wrandom_flush(void) for (i = 0; i < MULTIPATH_STATE_SIZE; ++i) { struct multipath_route *r; - spin_lock(&state[i].lock); + spin_lock_bh(&state[i].lock); list_for_each_entry_rcu(r, &state[i].head, list) { struct multipath_dest *d; list_for_each_entry_rcu(d, &r->dests, list) { @@ -315,7 +315,7 @@ static void wrandom_flush(void) __multipath_free); } - spin_unlock(&state[i].lock); + spin_unlock_bh(&state[i].lock); } } -- cgit 1.2.3-korg From 6f4b6ec1cffcbb12cc47244381496d59b6a5a790 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 2 Feb 2006 17:01:13 -0800 Subject: [IPV6]: Fix illegal dst locking in softirq context. On Tue, Jan 31, 2006 at 10:24:32PM +0100, Ingo Molnar wrote: > > [] _write_lock+0x8/0x10 > [] inet6_destroy_sock+0x25/0x100 > [] tcp_v6_destroy_sock+0x12/0x20 > [] inet_csk_destroy_sock+0x4a/0x150 > [] tcp_rcv_state_process+0xd4c/0xdd0 > [] tcp_v4_do_rcv+0xa9/0x340 > [] tcp_v4_rcv+0x8eb/0x9d0 OK this is definitely broken. We should never touch the dst lock in softirq context. Since inet6_destroy_sock may be called from that context due to the asynchronous nature of sockets, we can't take the lock there. In fact this sk_dst_reset is totally redundant since all IPv6 sockets use inet_sock_destruct as their socket destructor which always cleans up the dst anyway. So the solution is to simply remove the call. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/ipv6/af_inet6.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'net') diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 064ffab82a9fe5..6c9711ac1c0324 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -369,12 +369,6 @@ int inet6_destroy_sock(struct sock *sk) struct sk_buff *skb; struct ipv6_txoptions *opt; - /* - * Release destination entry - */ - - sk_dst_reset(sk); - /* Release rx options */ if ((skb = xchg(&np->pktoptions, NULL)) != NULL) -- cgit 1.2.3-korg From f00c401b9b5f0a90e2eb05705f5988fbda0b082b Mon Sep 17 00:00:00 2001 From: Horms Date: Thu, 2 Feb 2006 17:03:18 -0800 Subject: [IPV4]: Remove suprious use of goto out: in icmp_reply This seems to be an artifact of the follwoing commit in February '02. e7e173af42dbf37b1d946f9ee00219cb3b2bea6a In a nutshell, goto out and return actually do the same thing, and both are called in this function. This patch removes out. Signed-Off-By: Horms Signed-off-by: David S. Miller --- net/ipv4/icmp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'net') diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 105039eb762935..6bc0887b0834ff 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -385,7 +385,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) u32 daddr; if (ip_options_echo(&icmp_param->replyopts, skb)) - goto out; + return; if (icmp_xmit_lock()) return; @@ -416,7 +416,6 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) ip_rt_put(rt); out_unlock: icmp_xmit_unlock(); -out:; } -- cgit 1.2.3-korg From 0dec456d1fe73e0539625f0973ee8ef8fb805943 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 2 Feb 2006 20:40:09 -0800 Subject: [NET]: Add CONFIG_NETDEBUG to suppress bad packet messages. If you are on a hostile network, or are running protocol tests, you can easily get the logged swamped by messages about bad UDP and ICMP packets. This turns those messages off unless a config option is enabled. Signed-off-by: Stephen Hemminger Acked-by: Dave Jones Signed-off-by: David S. Miller --- include/net/sock.h | 8 ++++---- net/Kconfig | 7 +++++++ 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/include/net/sock.h b/include/net/sock.h index 1806e5b6141936..30758035d6161b 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1354,12 +1354,12 @@ extern int sock_get_timestamp(struct sock *, struct timeval __user *); * Enable debug/info messages */ -#if 0 -#define NETDEBUG(fmt, args...) do { } while (0) -#define LIMIT_NETDEBUG(fmt, args...) do { } while(0) -#else +#ifdef CONFIG_NETDEBUG #define NETDEBUG(fmt, args...) printk(fmt,##args) #define LIMIT_NETDEBUG(fmt, args...) do { if (net_ratelimit()) printk(fmt,##args); } while(0) +#else +#define NETDEBUG(fmt, args...) do { } while (0) +#define LIMIT_NETDEBUG(fmt, args...) do { } while(0) #endif /* diff --git a/net/Kconfig b/net/Kconfig index bc603d9aea56c1..5126f58d9c44fb 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -27,6 +27,13 @@ if NET menu "Networking options" +config NETDEBUG + bool "Network packet debugging" + help + You can say Y here if you want to get additional messages useful in + debugging bad packets, but can overwhelm logs under denial of service + attacks. + source "net/packet/Kconfig" source "net/unix/Kconfig" source "net/xfrm/Kconfig" -- cgit 1.2.3-korg