From 2f1622620b3b79e054c21fb5b1fe7594eefcdd4d Mon Sep 17 00:00:00 2001 From: Hideaki Yoshifuji Date: Wed, 26 Nov 2003 01:24:51 -0800 Subject: [IPV6]: Fix ipv4 mapped address calculation in udpv6_sendmsg(). --- net/ipv6/udp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 5b2f64efc8d1..103ab5d59923 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -825,7 +825,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = sin6 ? sin6->sin6_port : inet->dport; - sin.sin_addr.s_addr = daddr->s6_addr[3]; + sin.sin_addr.s_addr = daddr->s6_addr32[3]; msg->msg_name = &sin; msg->msg_namelen = sizeof(sin); do_udp_sendmsg: -- cgit v1.2.3 From 1f6dc81c1ed49b16e21723a708f530b2af44ad02 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 26 Nov 2003 01:31:26 -0800 Subject: [XFRM]: Handle device down/unregister events. This patch makes us prune all bundles containing devices being shut down or removed. It also merges two existing functions that walk bundles looking for things to delete. --- net/xfrm/xfrm_policy.c | 81 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 32 deletions(-) diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 85f626d20c4a..2564d6dfa7f3 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include @@ -1022,7 +1024,8 @@ static struct dst_entry *xfrm_negative_advice(struct dst_entry *dst) return dst; } -static void __xfrm_garbage_collect(void) +static void xfrm_prune_bundles(int (*func)(struct dst_entry *, void *), + void *data) { int i; struct xfrm_policy *pol; @@ -1034,7 +1037,7 @@ static void __xfrm_garbage_collect(void) write_lock(&pol->lock); dstp = &pol->bundles; while ((dst=*dstp) != NULL) { - if (atomic_read(&dst->__refcnt) == 0) { + if (func(dst, data)) { *dstp = dst->next; dst->next = gc_list; gc_list = dst; @@ -1054,8 +1057,20 @@ static void __xfrm_garbage_collect(void) } } -static int bundle_depends_on(struct dst_entry *dst, struct xfrm_state *x) +static int unused_dst(struct dst_entry *dst, void *data) { + return !atomic_read(&dst->__refcnt); +} + +static void __xfrm_garbage_collect(void) +{ + xfrm_prune_bundles(unused_dst, NULL); +} + +static int bundle_depends_on(struct dst_entry *dst, void *data) +{ + struct xfrm_state *x = data; + do { if (dst->xfrm == x) return 1; @@ -1065,35 +1080,7 @@ static int bundle_depends_on(struct dst_entry *dst, struct xfrm_state *x) int xfrm_flush_bundles(struct xfrm_state *x) { - int i; - struct xfrm_policy *pol; - struct dst_entry *dst, **dstp, *gc_list = NULL; - - read_lock_bh(&xfrm_policy_lock); - for (i=0; i<2*XFRM_POLICY_MAX; i++) { - for (pol = xfrm_policy_list[i]; pol; pol = pol->next) { - write_lock(&pol->lock); - dstp = &pol->bundles; - while ((dst=*dstp) != NULL) { - if (bundle_depends_on(dst, x)) { - *dstp = dst->next; - dst->next = gc_list; - gc_list = dst; - } else { - dstp = &dst->next; - } - } - write_unlock(&pol->lock); - } - } - read_unlock_bh(&xfrm_policy_lock); - - while (gc_list) { - dst = gc_list; - gc_list = dst->next; - dst_free(dst); - } - + xfrm_prune_bundles(bundle_depends_on, x); return 0; } @@ -1216,6 +1203,35 @@ void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo) read_unlock(&afinfo->lock); } +static int bundle_has_dev(struct dst_entry *dst, void *data) +{ + struct net_device *dev = data; + + do { + if (dst->dev == dev) + return 1; + } while ((dst = dst->child) != NULL); + return 0; +} + +static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr) +{ + struct net_device *dev = ptr; + + switch (event) { + case NETDEV_UNREGISTER: + case NETDEV_DOWN: + xfrm_prune_bundles(bundle_has_dev, dev); + } + return NOTIFY_DONE; +} + +struct notifier_block xfrm_dev_notifier = { + xfrm_dev_event, + NULL, + 0 +}; + void __init xfrm_policy_init(void) { xfrm_dst_cache = kmem_cache_create("xfrm_dst_cache", @@ -1226,6 +1242,7 @@ void __init xfrm_policy_init(void) panic("XFRM: failed to allocate xfrm_dst_cache\n"); INIT_WORK(&xfrm_policy_gc_work, xfrm_policy_gc_task, NULL); + register_netdevice_notifier(&xfrm_dev_notifier); } void __init xfrm_init(void) -- cgit v1.2.3 From 33bb7ddaa0f0eb90b79850f367419f05c021507b Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sat, 29 Nov 2003 04:24:48 -0800 Subject: [XFRM]: Check whether a dst is still valid before adding it to a bundle. --- include/net/xfrm.h | 2 +- net/xfrm/xfrm_policy.c | 60 +++++++++++++++++++------------------------------- net/xfrm/xfrm_state.c | 2 +- 3 files changed, 25 insertions(+), 39 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 2ae391720d4d..67072071aec1 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -860,7 +860,7 @@ extern void xfrm_policy_flush(void); extern void xfrm_policy_kill(struct xfrm_policy *); extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); extern struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl); -extern int xfrm_flush_bundles(struct xfrm_state *x); +extern int xfrm_flush_bundles(void); extern wait_queue_head_t km_waitq; extern void km_state_expired(struct xfrm_state *x, int hard); diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 2564d6dfa7f3..0f970906c9ef 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -692,6 +692,8 @@ static inline int policy_to_flow_dir(int dir) }; } +static int stale_bundle(struct dst_entry *dst); + /* Main function: finds/creates a bundle for given flow. * * At the moment we eat a raw IP route. Mostly to speed up lookups @@ -816,10 +818,11 @@ restart: } write_lock_bh(&policy->lock); - if (unlikely(policy->dead)) { + if (unlikely(policy->dead || stale_bundle(dst))) { /* Wow! While we worked on resolving, this * policy has gone. Retry. It is not paranoia, * we just cannot enlist new bundle to dead object. + * We can't enlist stable bundles either. */ write_unlock_bh(&policy->lock); @@ -986,19 +989,28 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family) /* Optimize later using cookies and generation ids. */ static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie) +{ + if (!stale_bundle(dst)) + return dst; + + dst_release(dst); + return NULL; +} + +static int stale_bundle(struct dst_entry *dst) { struct dst_entry *child = dst; while (child) { if (child->obsolete > 0 || + (child->dev && !netif_running(child->dev)) || (child->xfrm && child->xfrm->km.state != XFRM_STATE_VALID)) { - dst_release(dst); - return NULL; + return 1; } child = child->child; } - return dst; + return 0; } static void xfrm_dst_destroy(struct dst_entry *dst) @@ -1024,8 +1036,7 @@ static struct dst_entry *xfrm_negative_advice(struct dst_entry *dst) return dst; } -static void xfrm_prune_bundles(int (*func)(struct dst_entry *, void *), - void *data) +static void xfrm_prune_bundles(int (*func)(struct dst_entry *)) { int i; struct xfrm_policy *pol; @@ -1037,7 +1048,7 @@ static void xfrm_prune_bundles(int (*func)(struct dst_entry *, void *), write_lock(&pol->lock); dstp = &pol->bundles; while ((dst=*dstp) != NULL) { - if (func(dst, data)) { + if (func(dst)) { *dstp = dst->next; dst->next = gc_list; gc_list = dst; @@ -1057,30 +1068,19 @@ static void xfrm_prune_bundles(int (*func)(struct dst_entry *, void *), } } -static int unused_dst(struct dst_entry *dst, void *data) +static int unused_bundle(struct dst_entry *dst) { return !atomic_read(&dst->__refcnt); } static void __xfrm_garbage_collect(void) { - xfrm_prune_bundles(unused_dst, NULL); + xfrm_prune_bundles(unused_bundle); } -static int bundle_depends_on(struct dst_entry *dst, void *data) +int xfrm_flush_bundles(void) { - struct xfrm_state *x = data; - - do { - if (dst->xfrm == x) - return 1; - } while ((dst = dst->child) != NULL); - return 0; -} - -int xfrm_flush_bundles(struct xfrm_state *x) -{ - xfrm_prune_bundles(bundle_depends_on, x); + xfrm_prune_bundles(stale_bundle); return 0; } @@ -1203,25 +1203,11 @@ void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo) read_unlock(&afinfo->lock); } -static int bundle_has_dev(struct dst_entry *dst, void *data) -{ - struct net_device *dev = data; - - do { - if (dst->dev == dev) - return 1; - } while ((dst = dst->child) != NULL); - return 0; -} - static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr) { - struct net_device *dev = ptr; - switch (event) { - case NETDEV_UNREGISTER: case NETDEV_DOWN: - xfrm_prune_bundles(bundle_has_dev, dev); + xfrm_flush_bundles(); } return NOTIFY_DONE; } diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index ab1c1ec1aa12..dc70df79f9cb 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -219,7 +219,7 @@ static void __xfrm_state_delete(struct xfrm_state *x) * there are DSTs attached to this xfrm_state. */ if (atomic_read(&x->refcnt) > 2) - xfrm_flush_bundles(x); + xfrm_flush_bundles(); /* All xfrm_state objects are created by one of two possible * paths: -- cgit v1.2.3 From 7e693e32414241474a420fa18138d1f1e3130dfd Mon Sep 17 00:00:00 2001 From: Hirofumi Ogawa Date: Sat, 29 Nov 2003 04:40:06 -0800 Subject: [TCP]: Fix OOPS when seeking in /proc/net/tcp. Forgotten initialization of st->state in tcp_seq_start(). --- net/ipv4/tcp_ipv4.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 558fe618276a..7ea3ed719344 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2356,6 +2356,7 @@ static void *tcp_get_idx(struct seq_file *seq, loff_t pos) static void *tcp_seq_start(struct seq_file *seq, loff_t *pos) { struct tcp_iter_state* st = seq->private; + st->state = TCP_SEQ_STATE_LISTENING; st->num = 0; return *pos ? tcp_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; } -- cgit v1.2.3 From 202ca737b132b513e2112e48e6361c6eaa52e549 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sat, 29 Nov 2003 04:42:29 -0800 Subject: [NETFILTER]: Sanitize ip_ct_tcp_timeout_close_wait value, from 2.4.x --- net/ipv4/netfilter/ip_conntrack_proto_tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c index 0e76daa586a5..ec5727de8f3b 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c @@ -53,7 +53,7 @@ unsigned long ip_ct_tcp_timeout_syn_sent = 2 MINS; unsigned long ip_ct_tcp_timeout_syn_recv = 60 SECS; unsigned long ip_ct_tcp_timeout_established = 5 DAYS; unsigned long ip_ct_tcp_timeout_fin_wait = 2 MINS; -unsigned long ip_ct_tcp_timeout_close_wait = 3 DAYS; +unsigned long ip_ct_tcp_timeout_close_wait = 60 SECS; unsigned long ip_ct_tcp_timeout_last_ack = 30 SECS; unsigned long ip_ct_tcp_timeout_time_wait = 2 MINS; unsigned long ip_ct_tcp_timeout_close = 10 SECS; -- cgit v1.2.3 From 60b95251032ff12ce322231a8165e8176078832e Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sat, 29 Nov 2003 04:46:30 -0800 Subject: [SCTP]: Fix sm.h/sctp.h header include loop. --- include/net/sctp/sctp.h | 1 - net/sctp/associola.c | 1 + net/sctp/outqueue.c | 1 + net/sctp/socket.c | 1 + net/sctp/transport.c | 1 + 5 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index bf33562cd101..7edb15d6561a 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -90,7 +90,6 @@ #include #include #include -#include /* Set SCTP_DEBUG flag via config if not already set. */ diff --git a/net/sctp/associola.c b/net/sctp/associola.c index dba3d149e499..44b30efb17a9 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -58,6 +58,7 @@ #include #include #include +#include /* Forward declarations for internal functions. */ static void sctp_assoc_bh_rcv(struct sctp_association *asoc); diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index d26292af9ff1..dc4cb1a5a739 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -53,6 +53,7 @@ #include /* For skb_set_owner_w */ #include +#include /* Declare internal functions here. */ static int sctp_acked(struct sctp_sackhdr *sack, __u32 tsn); diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 0ac8c9bf5363..36b2ec11a3a8 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -77,6 +77,7 @@ #include /* for sa_family_t */ #include #include +#include /* WARNING: Please do not remove the SCTP_STATIC attribute to * any of the functions below as they are used to export functions diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 485d77015399..026ffebb61d4 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -50,6 +50,7 @@ #include #include +#include /* 1st Level Abstractions. */ -- cgit v1.2.3 From 54dd6c88f80e2faa33d9a1d0658684201e9acbce Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Dec 2003 09:32:03 -0800 Subject: [NETFILTER]: Trivial -- Get rid of warnings in netfilter if /proc is not configured on. --- net/ipv4/netfilter/ipt_recent.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c index 3e03fe295529..eda86a22accd 100644 --- a/net/ipv4/netfilter/ipt_recent.c +++ b/net/ipv4/netfilter/ipt_recent.c @@ -91,8 +91,10 @@ static struct recent_ip_tables *r_tables = NULL; */ static spinlock_t recent_lock = SPIN_LOCK_UNLOCKED; +#ifdef CONFIG_PROC_FS /* Our /proc/net/ipt_recent entry */ static struct proc_dir_entry *proc_net_ipt_recent = NULL; +#endif /* Function declaration for later. */ static int @@ -959,8 +961,10 @@ static int __init init(void) int count; printk(version); +#ifdef CONFIG_PROC_FS proc_net_ipt_recent = proc_mkdir("ipt_recent",proc_net); if(!proc_net_ipt_recent) return -ENOMEM; +#endif if(ip_list_hash_size && ip_list_hash_size <= ip_list_tot) { printk(KERN_WARNING RECENT_NAME ": ip_list_hash_size too small, resetting to default.\n"); -- cgit v1.2.3 From 8662a8291af8db959a9358d6b705cac117f373ca Mon Sep 17 00:00:00 2001 From: Pavlin Radoslavov Date: Tue, 2 Dec 2003 00:28:17 -0800 Subject: [RTNETLINK]: Add RTPROT_XORP. --- include/linux/rtnetlink.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index aadba39502cc..4a26f207b5d7 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -138,6 +138,7 @@ enum #define RTPROT_ZEBRA 11 /* Zebra */ #define RTPROT_BIRD 12 /* BIRD */ #define RTPROT_DNROUTED 13 /* DECnet routing daemon */ +#define RTPROT_XORP 14 /* XORP */ /* rtm_scope -- cgit v1.2.3 From 32b71296b247fb444467a00b4c653bfab2200b7f Mon Sep 17 00:00:00 2001 From: "jlut@cs.hut.fi" Date: Tue, 2 Dec 2003 00:38:42 -0800 Subject: [IPV6]: Neighbour discovery bypasses netfilter. --- net/ipv6/ndisc.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 7ce6138bdd13..d683c92fdc3a 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -75,6 +75,9 @@ #include #include +#include +#include + static struct socket *ndisc_socket; static u32 ndisc_hash(const void *pkey, const struct net_device *dev); @@ -498,10 +501,11 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, skb->dst = dst; idev = in6_dev_get(dst->dev); - dst_output(skb); - - ICMP6_INC_STATS(idev, Icmp6OutNeighborAdvertisements); - ICMP6_INC_STATS(idev, Icmp6OutMsgs); + err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output); + if (!err) { + ICMP6_INC_STATS(idev, Icmp6OutNeighborAdvertisements); + ICMP6_INC_STATS(idev, Icmp6OutMsgs); + } if (likely(idev != NULL)) in6_dev_put(idev); @@ -577,10 +581,11 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, /* send it! */ skb->dst = dst; idev = in6_dev_get(dst->dev); - dst_output(skb); - - ICMP6_INC_STATS(idev, Icmp6OutNeighborSolicits); - ICMP6_INC_STATS(idev, Icmp6OutMsgs); + err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output); + if (!err) { + ICMP6_INC_STATS(idev, Icmp6OutNeighborSolicits); + ICMP6_INC_STATS(idev, Icmp6OutMsgs); + } if (likely(idev != NULL)) in6_dev_put(idev); @@ -644,10 +649,11 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr, /* send it! */ skb->dst = dst; idev = in6_dev_get(dst->dev); - dst_output(skb); - - ICMP6_INC_STATS(idev, Icmp6OutRouterSolicits); - ICMP6_INC_STATS(idev, Icmp6OutMsgs); + err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output); + if (!err) { + ICMP6_INC_STATS(idev, Icmp6OutRouterSolicits); + ICMP6_INC_STATS(idev, Icmp6OutMsgs); + } if (likely(idev != NULL)) in6_dev_put(idev); @@ -1406,10 +1412,11 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, buff->dst = dst; idev = in6_dev_get(dst->dev); - dst_output(buff); - - ICMP6_INC_STATS(idev, Icmp6OutRedirects); - ICMP6_INC_STATS(idev, Icmp6OutMsgs); + err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output); + if (!err) { + ICMP6_INC_STATS(idev, Icmp6OutRedirects); + ICMP6_INC_STATS(idev, Icmp6OutMsgs); + } if (likely(idev != NULL)) in6_dev_put(idev); -- cgit v1.2.3 From 2831834d0a34da8fe9a2f9ede28b1b2338ecc21c Mon Sep 17 00:00:00 2001 From: Bart De Schuymer Date: Mon, 29 Dec 2003 01:47:00 -0800 Subject: [BRIDGE]: Fix loopback over bridge port. When sending a broadcast from a Linux bridge over a bridge port, net/ipv4/ip_output.c::ip_dev_loopback_xmit() will send the packet back to the bridge port. Currently, the bridge code will intercept this loopback packet and try to bridge it. This is not right, the loopback packet doesn't even have an Ethernet header. This loopback packet is intended for the bridge port and should not be stolen by the bridge code. The patch below fixes this by adding a check in __handle_bridge(). It also changes br_netfilter.c by only doing the paranoid checks of br_nf_post_routing() when CONFIG_NETFILTER_DEBUG is set. I think the loopback fix will get rid of any skbuffs matching those paranoid checks. The patch also introduces/removes some whitespace in br_netfilter.c. --- net/bridge/br_netfilter.c | 40 ++++++++++++++++++++++++++-------------- net/core/dev.c | 2 +- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 932f3ae2bbea..359555cd35b6 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -356,6 +356,7 @@ static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff **pskb, return NF_ACCEPT; } + /* PF_BRIDGE/FORWARD *************************************************/ static int br_nf_forward_finish(struct sk_buff *skb) { @@ -466,6 +467,7 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb, return NF_STOLEN; } + /* PF_BRIDGE/LOCAL_OUT ***********************************************/ static int br_nf_local_out_finish(struct sk_buff *skb) { @@ -531,9 +533,7 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb, return NF_ACCEPT; nf_bridge = skb->nf_bridge; - nf_bridge->physoutdev = skb->dev; - realindev = nf_bridge->physindev; /* Bridged, take PF_BRIDGE/FORWARD. @@ -601,18 +601,15 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet); struct net_device *realoutdev = bridge_parent(skb->dev); - /* Be very paranoid. Must be a device driver bug. */ +#ifdef CONFIG_NETFILTER_DEBUG + /* Be very paranoid. This probably won't happen anymore, but let's + * keep the check just to be sure... */ if (skb->mac.raw < skb->head || skb->mac.raw + ETH_HLEN > skb->data) { printk(KERN_CRIT "br_netfilter: Argh!! br_nf_post_routing: " "bad mac.raw pointer."); - if (skb->dev != NULL) { - printk("[%s]", skb->dev->name); - if (has_bridge_parent(skb->dev)) - printk("[%s]", bridge_parent(skb->dev)->name); - } - printk(" head:%p, raw:%p\n", skb->head, skb->mac.raw); - return NF_ACCEPT; + goto print_error; } +#endif #ifdef CONFIG_SYSCTL if (!nf_bridge) @@ -622,13 +619,16 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, if (skb->protocol != __constant_htons(ETH_P_IP) && !IS_VLAN_IP) return NF_ACCEPT; +#ifdef CONFIG_NETFILTER_DEBUG /* Sometimes we get packets with NULL ->dst here (for example, - * running a dhcp client daemon triggers this). + * running a dhcp client daemon triggers this). This should now + * be fixed, but let's keep the check around. */ - if (skb->dst == NULL) - return NF_ACCEPT; + if (skb->dst == NULL) { + printk(KERN_CRIT "br_netfilter: skb->dst == NULL."); + goto print_error; + } -#ifdef CONFIG_NETFILTER_DEBUG skb->nf_debug ^= (1 << NF_IP_POST_ROUTING); #endif @@ -655,6 +655,18 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, realoutdev, br_dev_queue_push_xmit); return NF_STOLEN; + +#ifdef CONFIG_NETFILTER_DEBUG +print_error: + if (skb->dev != NULL) { + printk("[%s]", skb->dev->name); + if (has_bridge_parent(skb->dev)) + printk("[%s]", bridge_parent(skb->dev)->name); + } + printk(" head:%p, raw:%p, data:%p\n", skb->head, skb->mac.raw, + skb->data); + return NF_ACCEPT; +#endif } diff --git a/net/core/dev.c b/net/core/dev.c index 47fff21ea3b2..30cba1e1c633 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1543,7 +1543,7 @@ static inline int __handle_bridge(struct sk_buff *skb, struct packet_type **pt_prev, int *ret) { #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) - if (skb->dev->br_port) { + if (skb->dev->br_port && skb->pkt_type != PACKET_LOOPBACK) { *ret = handle_bridge(skb, *pt_prev); if (br_handle_frame_hook(skb) == 0) return 1; -- cgit v1.2.3 From dd7862a29f567b9447cd6198cc643fc94f4f388c Mon Sep 17 00:00:00 2001 From: Bart De Schuymer Date: Mon, 29 Dec 2003 01:52:28 -0800 Subject: [BRIDGE]: Always copy and save the vlan header in bridge-nf. --- include/linux/netfilter_bridge.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h index 88cc98af2dce..a6531bb097ca 100644 --- a/include/linux/netfilter_bridge.h +++ b/include/linux/netfilter_bridge.h @@ -71,12 +71,10 @@ static inline void nf_bridge_maybe_copy_header(struct sk_buff *skb) { if (skb->nf_bridge) { -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) if (skb->protocol == __constant_htons(ETH_P_8021Q)) { memcpy(skb->data - 18, skb->nf_bridge->hh, 18); skb_push(skb, 4); } else -#endif memcpy(skb->data - 16, skb->nf_bridge->hh, 16); } } @@ -86,10 +84,9 @@ void nf_bridge_save_header(struct sk_buff *skb) { int header_size = 16; -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) if (skb->protocol == __constant_htons(ETH_P_8021Q)) header_size = 18; -#endif + memcpy(skb->nf_bridge->hh, skb->data - header_size, header_size); } -- cgit v1.2.3 From a632875f1d94a901fe026191935c5b4337e51e1c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 29 Dec 2003 22:41:42 -0800 Subject: [NET]: Uninline {lock,release}_sock(). --- include/net/sock.h | 19 ++----------------- net/core/sock.c | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index ac2eccb7ff9a..1d85a3e5a3cc 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -542,24 +542,9 @@ static inline struct inode *SOCK_INODE(struct socket *socket) extern void __lock_sock(struct sock *sk); extern void __release_sock(struct sock *sk); #define sock_owned_by_user(sk) ((sk)->sk_lock.owner) -#define lock_sock(__sk) \ -do { might_sleep(); \ - spin_lock_bh(&((__sk)->sk_lock.slock)); \ - if ((__sk)->sk_lock.owner) \ - __lock_sock(__sk); \ - (__sk)->sk_lock.owner = (void *)1; \ - spin_unlock_bh(&((__sk)->sk_lock.slock)); \ -} while(0) -#define release_sock(__sk) \ -do { spin_lock_bh(&((__sk)->sk_lock.slock)); \ - if ((__sk)->sk_backlog.tail) \ - __release_sock(__sk); \ - (__sk)->sk_lock.owner = NULL; \ - if (waitqueue_active(&((__sk)->sk_lock.wq))) \ - wake_up(&((__sk)->sk_lock.wq)); \ - spin_unlock_bh(&((__sk)->sk_lock.slock)); \ -} while(0) +extern void lock_sock(struct sock *sk); +extern void release_sock(struct sock *sk); /* BH context may only use the following locking interface. */ #define bh_lock_sock(__sk) spin_lock(&((__sk)->sk_lock.slock)) diff --git a/net/core/sock.c b/net/core/sock.c index 9d51516eaa56..d549d519482d 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1119,6 +1119,31 @@ void sock_init_data(struct socket *sock, struct sock *sk) atomic_set(&sk->sk_refcnt, 1); } +void lock_sock(struct sock *sk) +{ + might_sleep(); + spin_lock_bh(&(sk->sk_lock.slock)); + if (sk->sk_lock.owner) + __lock_sock(sk); + sk->sk_lock.owner = (void *)1; + spin_unlock_bh(&(sk->sk_lock.slock)); +} + +EXPORT_SYMBOL(lock_sock); + +void release_sock(struct sock *sk) +{ + spin_lock_bh(&(sk->sk_lock.slock)); + if (sk->sk_backlog.tail) + __release_sock(sk); + sk->sk_lock.owner = NULL; + if (waitqueue_active(&(sk->sk_lock.wq))) + wake_up(&(sk->sk_lock.wq)); + spin_unlock_bh(&(sk->sk_lock.slock)); +} + +EXPORT_SYMBOL(release_sock); + EXPORT_SYMBOL(__lock_sock); EXPORT_SYMBOL(__release_sock); EXPORT_SYMBOL(sk_alloc); -- cgit v1.2.3 From 7f43e27277168f1eb4bf08ce326afb357dccfcc9 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 29 Dec 2003 22:46:55 -0800 Subject: [TCP]: Make tcp_sk() do type checking. --- include/linux/tcp.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 3a2e7bf3c44a..d25e5bd21c4d 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -386,7 +386,10 @@ struct tcp_sock { struct tcp_opt tcp; }; -#define tcp_sk(__sk) (&((struct tcp_sock *)__sk)->tcp) +static inline struct tcp_opt * tcp_sk(const struct sock *__sk) +{ + return &((struct tcp_sock *)__sk)->tcp; +} #endif -- cgit v1.2.3 From 09fa6bcea48db8d55e9789585773cf367a899a75 Mon Sep 17 00:00:00 2001 From: Hideaki Yoshifuji Date: Mon, 29 Dec 2003 23:43:58 -0800 Subject: [NET]: Missing sysctl strategy entries in net/{core,ipv6,appletalk} --- net/appletalk/sysctl_net_atalk.c | 3 +++ net/core/neighbour.c | 4 ++++ net/core/sysctl_net_core.c | 6 ++++-- net/ipv6/addrconf.c | 2 ++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/net/appletalk/sysctl_net_atalk.c b/net/appletalk/sysctl_net_atalk.c index edddd3291f70..25b33f670499 100644 --- a/net/appletalk/sysctl_net_atalk.c +++ b/net/appletalk/sysctl_net_atalk.c @@ -23,6 +23,7 @@ static struct ctl_table atalk_table[] = { .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies, }, { .ctl_name = NET_ATALK_AARP_TICK_TIME, @@ -31,6 +32,7 @@ static struct ctl_table atalk_table[] = { .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies, }, { .ctl_name = NET_ATALK_AARP_RETRANSMIT_LIMIT, @@ -47,6 +49,7 @@ static struct ctl_table atalk_table[] = { .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies, }, { 0 }, }; diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 247b6d6e661d..4b194b6be05a 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1518,6 +1518,7 @@ struct neigh_sysctl_table { .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies, }, { .ctl_name = NET_NEIGH_DELAY_PROBE_TIME, @@ -1525,6 +1526,7 @@ struct neigh_sysctl_table { .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies, }, { .ctl_name = NET_NEIGH_GC_STALE_TIME, @@ -1532,6 +1534,7 @@ struct neigh_sysctl_table { .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies, }, { .ctl_name = NET_NEIGH_UNRES_QLEN, @@ -1574,6 +1577,7 @@ struct neigh_sysctl_table { .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies, }, { .ctl_name = NET_NEIGH_GC_THRESH1, diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index 46c0c78b196d..642ef77a2824 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c @@ -146,7 +146,8 @@ ctl_table core_table[] = { .data = &net_msg_cost, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = &proc_dointvec_jiffies + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies, }, { .ctl_name = NET_CORE_MSG_BURST, @@ -154,7 +155,8 @@ ctl_table core_table[] = { .data = &net_msg_burst, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = &proc_dointvec_jiffies + .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies, }, { .ctl_name = NET_CORE_OPTMEM_MAX, diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index b08ba41c5356..0d4b1688a801 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2946,6 +2946,7 @@ static struct addrconf_sysctl_table .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies, }, { .ctl_name = NET_IPV6_RTR_SOLICIT_DELAY, @@ -2954,6 +2955,7 @@ static struct addrconf_sysctl_table .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, + .strategy = &sysctl_jiffies, }, #ifdef CONFIG_IPV6_PRIVACY { -- cgit v1.2.3