diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-03-23 02:25:38 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-03-23 02:25:38 +0000 |
commit | 16b5d462f73eb29d1f67fa01cc1ea66afdc72569 (patch) | |
tree | 5407bd573f4840e473ea27cbe61e5c7a07131fcd /net/core | |
parent | ce8a076e11e7e5ee36007f9a3eee5bb3744cb8f6 (diff) |
Merge with Linux 2.3.99-pre2.
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/netfilter.c | 63 | ||||
-rw-r--r-- | net/core/skbuff.c | 5 |
2 files changed, 54 insertions, 14 deletions
diff --git a/net/core/netfilter.c b/net/core/netfilter.c index 18f697755..02c3bc989 100644 --- a/net/core/netfilter.c +++ b/net/core/netfilter.c @@ -4,9 +4,10 @@ * Thanks to Rob `CmdrTaco' Malda for not influencing this code in any * way. * - * Rusty Russell (C)1998 -- This code is GPL. + * Rusty Russell (C)2000 -- This code is GPL. * * February 2000: Modified by James Morris to have 1 queue per protocol. + * 15-Mar-2000: Added NF_REPEAT --RR. */ #include <linux/config.h> #include <linux/netfilter.h> @@ -56,8 +57,6 @@ int nf_register_hook(struct nf_hook_ops *reg) { struct list_head *i; - NFDEBUG("nf_register_hook: pf=%i hook=%u.\n", reg->pf, reg->hooknum); - br_write_lock_bh(BR_NETPROTO_LOCK); for (i = nf_hooks[reg->pf][reg->hooknum].next; i != &nf_hooks[reg->pf][reg->hooknum]; @@ -119,7 +118,16 @@ out: void nf_unregister_sockopt(struct nf_sockopt_ops *reg) { /* No point being interruptible: we're probably in cleanup_module() */ + restart: down(&nf_sockopt_mutex); + if (reg->use != 0) { + /* To be woken by nf_sockopt call... */ + reg->cleanup_task = current; + up(&nf_sockopt_mutex); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule(); + goto restart; + } list_del(®->list); up(&nf_sockopt_mutex); } @@ -178,7 +186,7 @@ void nf_dump_skb(int pf, struct sk_buff *skb) dst_port = ntohs(tcp->dest); } - printk("PROTO=%d %ld.%ld.%ld.%ld:%hu %ld.%ld.%ld.%ld:%hu" + printk("PROTO=%d %d.%d.%d.%d:%hu %d.%d.%d.%d:%hu" " L=%hu S=0x%2.2hX I=%hu F=0x%4.4hX T=%hu", ip->protocol, (ntohl(ip->saddr)>>24)&0xFF, @@ -261,9 +269,16 @@ void nf_debug_ip_finish_output2(struct sk_buff *skb) if (skb->nf_debug != ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_FORWARD) | (1 << NF_IP_POST_ROUTING))) { - printk("ip_finish_output: bad unowned skb = %p: ",skb); - debug_print_hooks_ip(skb->nf_debug); - nf_dump_skb(PF_INET, skb); + /* Fragments will have no owners, but still + may be local */ + if (!(skb->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) + || skb->nf_debug != ((1 << NF_IP_LOCAL_OUT) + | (1 << NF_IP_POST_ROUTING))){ + printk("ip_finish_output:" + " bad unowned skb = %p: ",skb); + debug_print_hooks_ip(skb->nf_debug); + nf_dump_skb(PF_INET, skb); + } } } } @@ -274,31 +289,42 @@ static int nf_sockopt(struct sock *sk, int pf, int val, char *opt, int *len, int get) { struct list_head *i; + struct nf_sockopt_ops *ops; int ret; if (down_interruptible(&nf_sockopt_mutex) != 0) return -EINTR; for (i = nf_sockopts.next; i != &nf_sockopts; i = i->next) { - struct nf_sockopt_ops *ops = (struct nf_sockopt_ops *)i; + ops = (struct nf_sockopt_ops *)i; if (ops->pf == pf) { if (get) { if (val >= ops->get_optmin && val < ops->get_optmax) { + ops->use++; + up(&nf_sockopt_mutex); ret = ops->get(sk, val, opt, len); goto out; } } else { if (val >= ops->set_optmin && val < ops->set_optmax) { + ops->use++; + up(&nf_sockopt_mutex); ret = ops->set(sk, val, opt, *len); goto out; } } } } - ret = -ENOPROTOOPT; + up(&nf_sockopt_mutex); + return -ENOPROTOOPT; + out: + down(&nf_sockopt_mutex); + ops->use--; + if (ops->cleanup_task) + wake_up_process(ops->cleanup_task); up(&nf_sockopt_mutex); return ret; } @@ -334,6 +360,10 @@ static unsigned int nf_iterate(struct list_head *head, case NF_DROP: return NF_DROP; + case NF_REPEAT: + *i = (*i)->prev; + break; + #ifdef CONFIG_NETFILTER_DEBUG case NF_ACCEPT: break; @@ -367,7 +397,6 @@ int nf_register_queue_handler(int pf, nf_queue_outfn_t outfn, void *data) /* The caller must flush their queue before this */ int nf_unregister_queue_handler(int pf) { - NFDEBUG("Unregistering Netfilter queue handler for pf=%d\n", pf); br_write_lock_bh(BR_NETPROTO_LOCK); queue_handler[pf].outfn = NULL; queue_handler[pf].data = NULL; @@ -390,7 +419,6 @@ static void nf_queue(struct sk_buff *skb, struct nf_info *info; if (!queue_handler[pf].outfn) { - NFDEBUG("nf_queue: noone wants the packet, dropping it.\n"); kfree_skb(skb); return; } @@ -432,6 +460,14 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb, unsigned int verdict; int ret = 0; +#ifdef CONFIG_NETFILTER_DEBUG + if (skb->nf_debug & (1 << hook)) { + printk("nf_hook: hook %i already set.\n", hook); + nf_dump_skb(pf, skb); + } + skb->nf_debug |= (1 << hook); +#endif + elem = &nf_hooks[pf][hook]; verdict = nf_iterate(&nf_hooks[pf][hook], &skb, hook, indev, outdev, &elem, okfn); @@ -473,6 +509,11 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info, } /* Continue traversal iff userspace said ok... */ + if (verdict == NF_REPEAT) { + elem = elem->prev; + verdict = NF_ACCEPT; + } + if (verdict == NF_ACCEPT) { verdict = nf_iterate(&nf_hooks[info->pf][info->hook], &skb, info->hook, diff --git a/net/core/skbuff.c b/net/core/skbuff.c index ecda47d7a..dad1f3925 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -4,7 +4,7 @@ * Authors: Alan Cox <iiitac@pyr.swan.ac.uk> * Florian La Roche <rzsfl@rz.uni-sb.de> * - * Version: $Id: skbuff.c,v 1.69 2000/03/06 03:47:58 davem Exp $ + * Version: $Id: skbuff.c,v 1.70 2000/03/17 14:41:39 davem Exp $ * * Fixes: * Alan Cox : Fixed the worst of the load balancer bugs. @@ -203,7 +203,7 @@ static inline void skb_headerinit(void *p, kmem_cache_t *cache, skb->dst = NULL; skb->rx_dev = NULL; #ifdef CONFIG_NETFILTER - skb->nfmark = skb->nfreason = skb->nfcache = 0; + skb->nfmark = skb->nfcache = 0; skb->nfct = NULL; #ifdef CONFIG_NETFILTER_DEBUG skb->nf_debug = 0; @@ -319,7 +319,6 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) new->security=old->security; #ifdef CONFIG_NETFILTER new->nfmark=old->nfmark; - new->nfreason=old->nfreason; new->nfcache=old->nfcache; new->nfct=old->nfct; nf_conntrack_get(new->nfct); |