File: /usr/src/linux/net/ipv4/netfilter/ipchains_core.c

1     /* Minor modifications to fit on compatibility framework:
2        Rusty.Russell@rustcorp.com.au
3     */
4     
5     /*
6      * This code is heavily based on the code on the old ip_fw.c code; see below for
7      * copyrights and attributions of the old code.  This code is basically GPL.
8      *
9      * 15-Aug-1997: Major changes to allow graphs for firewall rules.
10      *              Paul Russell <Paul.Russell@rustcorp.com.au> and
11      *		Michael Neuling <Michael.Neuling@rustcorp.com.au>
12      * 24-Aug-1997: Generalised protocol handling (not just TCP/UDP/ICMP).
13      *              Added explicit RETURN from chains.
14      *              Removed TOS mangling (done in ipchains 1.0.1).
15      *              Fixed read & reset bug by reworking proc handling.
16      *              Paul Russell <Paul.Russell@rustcorp.com.au>
17      * 28-Sep-1997: Added packet marking for net sched code.
18      *              Removed fw_via comparisons: all done on device name now,
19      *              similar to changes in ip_fw.c in DaveM's CVS970924 tree.
20      *              Paul Russell <Paul.Russell@rustcorp.com.au>
21      * 2-Nov-1997:  Moved types across to __u16, etc.
22      *              Added inverse flags.
23      *              Fixed fragment bug (in args to port_match).
24      *              Changed mark to only one flag (MARKABS).
25      * 21-Nov-1997: Added ability to test ICMP code.
26      * 19-Jan-1998: Added wildcard interfaces.
27      * 6-Feb-1998:  Merged 2.0 and 2.1 versions.
28      *              Initialised ip_masq for 2.0.x version.
29      *              Added explicit NETLINK option for 2.1.x version.
30      *              Added packet and byte counters for policy matches.
31      * 26-Feb-1998: Fixed race conditions, added SMP support.
32      * 18-Mar-1998: Fix SMP, fix race condition fix.
33      * 1-May-1998:  Remove caching of device pointer.
34      * 12-May-1998: Allow tiny fragment case for TCP/UDP.
35      * 15-May-1998: Treat short packets as fragments, don't just block.
36      * 3-Jan-1999:  Fixed serious procfs security hole -- users should never
37      *              be allowed to view the chains!
38      *              Marc Santoro <ultima@snicker.emoti.com>
39      * 29-Jan-1999: Locally generated bogus IPs dealt with, rather than crash
40      *              during dump_packet. --RR.
41      * 19-May-1999: Star Wars: The Phantom Menace opened.  Rule num
42      *		printed in log (modified from Michael Hasenstein's patch).
43      *		Added SYN in log message. --RR
44      * 23-Jul-1999: Fixed small fragment security exposure opened on 15-May-1998.
45      *              John McDonald <jm@dataprotect.com>
46      *              Thomas Lopatic <tl@dataprotect.com>
47      */
48     
49     /*
50      *
51      * The origina Linux port was done Alan Cox, with changes/fixes from
52      * Pauline Middlelink, Jos Vos, Thomas Quinot, Wouter Gadeyne, Juan
53      * Jose Ciarlante, Bernd Eckenfels, Keith Owens and others.
54      *
55      * Copyright from the original FreeBSD version follows:
56      *
57      * Copyright (c) 1993 Daniel Boulet
58      * Copyright (c) 1994 Ugen J.S.Antsilevich
59      *
60      * Redistribution and use in source forms, with and without modification,
61      * are permitted provided that this entire comment appears intact.
62      *
63      * Redistribution in binary form may occur without any restrictions.
64      * Obviously, it would be nice if you gave credit where credit is due
65      * but requiring it would be too onerous.
66      *
67      * This software is provided ``AS IS'' without any warranties of any kind.  */
68     
69     #include <linux/config.h>
70     
71     #include <asm/uaccess.h>
72     #include <asm/system.h>
73     #include <linux/types.h>
74     #include <linux/sched.h>
75     #include <linux/string.h>
76     #include <linux/errno.h>
77     #include <linux/module.h>
78     
79     #include <linux/socket.h>
80     #include <linux/sockios.h>
81     #include <linux/in.h>
82     #include <linux/inet.h>
83     #include <linux/netdevice.h>
84     #include <linux/icmp.h>
85     #include <linux/udp.h>
86     #include <net/ip.h>
87     #include <net/protocol.h>
88     #include <net/route.h>
89     #include <net/tcp.h>
90     #include <net/udp.h>
91     #include <net/sock.h>
92     #include <net/icmp.h>
93     #include <linux/netlink.h>
94     #include <linux/netfilter.h>
95     #include <linux/netfilter_ipv4/compat_firewall.h>
96     #include <linux/netfilter_ipv4/ipchains_core.h>
97     
98     #include <net/checksum.h>
99     #include <linux/proc_fs.h>
100     #include <linux/stat.h>
101     
102     /* Understanding locking in this code: (thanks to Alan Cox for using
103      * little words to explain this to me). -- PR
104      *
105      * In UP, there can be two packets traversing the chains:
106      * 1) A packet from the current userspace context
107      * 2) A packet off the bh handlers (timer or net).
108      *
109      * For SMP (kernel v2.1+), multiply this by # CPUs.
110      *
111      * [Note that this in not correct for 2.2 - because the socket code always
112      *  uses lock_kernel() to serialize, and bottom halves (timers and net_bhs)
113      *  only run on one CPU at a time.  This will probably change for 2.3.
114      *  It is still good to use spinlocks because that avoids the global cli()
115      *  for updating the tables, which is rather costly in SMP kernels -AK]
116      *
117      * This means counters and backchains can get corrupted if no precautions
118      * are taken.
119      *
120      * To actually alter a chain on UP, we need only do a cli(), as this will
121      * stop a bh handler firing, as we are in the current userspace context
122      * (coming from a setsockopt()).
123      *
124      * On SMP, we need a write_lock_irqsave(), which is a simple cli() in
125      * UP.
126      *
127      * For backchains and counters, we use an array, indexed by
128      * [cpu_number_map[smp_processor_id()]*2 + !in_interrupt()]; the array is of
129      * size [smp_num_cpus*2].  For v2.0, smp_num_cpus is effectively 1.  So,
130      * confident of uniqueness, we modify counters even though we only
131      * have a read lock (to read the counters, you need a write lock,
132      * though).  */
133     
134     /* Why I didn't use straight locking... -- PR
135      *
136      * The backchains can be separated out of the ip_chains structure, and
137      * allocated as needed inside ip_fw_check().
138      *
139      * The counters, however, can't.  Trying to lock these means blocking
140      * interrupts every time we want to access them.  This would suck HARD
141      * performance-wise.  Not locking them leads to possible corruption,
142      * made worse on 32-bit machines (counters are 64-bit).  */
143     
144     /*#define DEBUG_IP_FIREWALL*/
145     /*#define DEBUG_ALLOW_ALL*/ /* Useful for remote debugging */
146     /*#define DEBUG_IP_FIREWALL_USER*/
147     /*#define DEBUG_IP_FIREWALL_LOCKING*/
148     
149     #if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
150     static struct sock *ipfwsk;
151     #endif
152     
153     #ifdef CONFIG_SMP
154     #define SLOT_NUMBER() (cpu_number_map(smp_processor_id())*2 + !in_interrupt())
155     #else /* !SMP */
156     #define SLOT_NUMBER() (!in_interrupt())
157     #endif /* CONFIG_SMP */
158     #define NUM_SLOTS (smp_num_cpus*2)
159     
160     #define SIZEOF_STRUCT_IP_CHAIN (sizeof(struct ip_chain) \
161     				+ NUM_SLOTS*sizeof(struct ip_reent))
162     #define SIZEOF_STRUCT_IP_FW_KERNEL (sizeof(struct ip_fwkernel) \
163     				    + NUM_SLOTS*sizeof(struct ip_counters))
164     
165     #ifdef DEBUG_IP_FIREWALL_LOCKING
166     static unsigned int fwc_rlocks, fwc_wlocks;
167     #define FWC_DEBUG_LOCK(d)			\
168     do {						\
169     	FWC_DONT_HAVE_LOCK(d);			\
170     	d |= (1 << SLOT_NUMBER());		\
171     } while (0)
172     
173     #define FWC_DEBUG_UNLOCK(d)			\
174     do {						\
175     	FWC_HAVE_LOCK(d);			\
176     	d &= ~(1 << SLOT_NUMBER());		\
177     } while (0)
178     
179     #define FWC_DONT_HAVE_LOCK(d)					\
180     do {								\
181     	if ((d) & (1 << SLOT_NUMBER()))				\
182     		printk("%s:%i: Got lock on %i already!\n", 	\
183     		       __FILE__, __LINE__, SLOT_NUMBER());	\
184     } while(0)
185     
186     #define FWC_HAVE_LOCK(d)				\
187     do {							\
188     	if (!((d) & (1 << SLOT_NUMBER())))		\
189     	printk("%s:%i:No lock on %i!\n", 		\
190     	       __FILE__, __LINE__, SLOT_NUMBER());	\
191     } while (0)
192     
193     #else
194     #define FWC_DEBUG_LOCK(d) do { } while(0)
195     #define FWC_DEBUG_UNLOCK(d) do { } while(0)
196     #define FWC_DONT_HAVE_LOCK(d) do { } while(0)
197     #define FWC_HAVE_LOCK(d) do { } while(0)
198     #endif /*DEBUG_IP_FIRWALL_LOCKING*/
199     
200     #define FWC_READ_LOCK(l) do { FWC_DEBUG_LOCK(fwc_rlocks); read_lock(l); } while (0)
201     #define FWC_WRITE_LOCK(l) do { FWC_DEBUG_LOCK(fwc_wlocks); write_lock(l); } while (0)
202     #define FWC_READ_LOCK_IRQ(l,f) do { FWC_DEBUG_LOCK(fwc_rlocks); read_lock_irqsave(l,f); } while (0)
203     #define FWC_WRITE_LOCK_IRQ(l,f) do { FWC_DEBUG_LOCK(fwc_wlocks); write_lock_irqsave(l,f); } while (0)
204     #define FWC_READ_UNLOCK(l) do { FWC_DEBUG_UNLOCK(fwc_rlocks); read_unlock(l); } while (0)
205     #define FWC_WRITE_UNLOCK(l) do { FWC_DEBUG_UNLOCK(fwc_wlocks); write_unlock(l); } while (0)
206     #define FWC_READ_UNLOCK_IRQ(l,f) do { FWC_DEBUG_UNLOCK(fwc_rlocks); read_unlock_irqrestore(l,f); } while (0)
207     #define FWC_WRITE_UNLOCK_IRQ(l,f) do { FWC_DEBUG_UNLOCK(fwc_wlocks); write_unlock_irqrestore(l,f); } while (0)
208     
209     struct ip_chain;
210     
211     struct ip_counters
212     {
213     	__u64 pcnt, bcnt;			/* Packet and byte counters */
214     };
215     
216     struct ip_fwkernel
217     {
218     	struct ip_fw ipfw;
219     	struct ip_fwkernel *next;	/* where to go next if current
220     					 * rule doesn't match */
221     	struct ip_chain *branch;	/* which branch to jump to if
222     					 * current rule matches */
223     	int simplebranch;		/* Use this if branch == NULL */
224     	struct ip_counters counters[0]; /* Actually several of these */
225     };
226     
227     struct ip_reent
228     {
229     	struct ip_chain *prevchain;	/* Pointer to referencing chain */
230     	struct ip_fwkernel *prevrule;	/* Pointer to referencing rule */
231     	struct ip_counters counters;
232     };
233     
234     struct ip_chain
235     {
236     	ip_chainlabel label;	    /* Defines the label for each block */
237      	struct ip_chain *next;	    /* Pointer to next block */
238     	struct ip_fwkernel *chain;  /* Pointer to first rule in block */
239     	__u32 refcount; 	    /* Number of refernces to block */
240     	int policy;		    /* Default rule for chain.  Only *
241     				     * used in built in chains */
242     	struct ip_reent reent[0];   /* Actually several of these */
243     };
244     
245     /*
246      *	Implement IP packet firewall
247      */
248     
249     #ifdef DEBUG_IP_FIREWALL
250     #define dprintf(format, args...)  printk(format , ## args)
251     #else
252     #define dprintf(format, args...)
253     #endif
254     
255     #ifdef DEBUG_IP_FIREWALL_USER
256     #define duprintf(format, args...) printk(format , ## args)
257     #else
258     #define duprintf(format, args...)
259     #endif
260     
261     /* Lock around ip_fw_chains linked list structure */
262     rwlock_t ip_fw_lock = RW_LOCK_UNLOCKED;
263     
264     /* Head of linked list of fw rules */
265     static struct ip_chain *ip_fw_chains;
266     
267     #define IP_FW_INPUT_CHAIN ip_fw_chains
268     #define IP_FW_FORWARD_CHAIN (ip_fw_chains->next)
269     #define IP_FW_OUTPUT_CHAIN (ip_fw_chains->next->next)
270     
271     /* Returns 1 if the port is matched by the range, 0 otherwise */
272     extern inline int port_match(__u16 min, __u16 max, __u16 port,
273     			     int frag, int invert)
274     {
275     	if (frag) /* Fragments fail ANY port test. */
276     		return (min == 0 && max == 0xFFFF);
277     	else return (port >= min && port <= max) ^ invert;
278     }
279     
280     /* Returns whether matches rule or not. */
281     static int ip_rule_match(struct ip_fwkernel *f,
282     			 const char *ifname,
283     			 struct iphdr *ip,
284     			 char tcpsyn,
285     			 __u16 src_port, __u16 dst_port,
286     			 char isfrag)
287     {
288     #define FWINV(bool,invflg) ((bool) ^ !!(f->ipfw.fw_invflg & invflg))
289     	/*
290     	 *	This is a bit simpler as we don't have to walk
291     	 *	an interface chain as you do in BSD - same logic
292     	 *	however.
293     	 */
294     
295     	if (FWINV((ip->saddr&f->ipfw.fw_smsk.s_addr) != f->ipfw.fw_src.s_addr,
296     		  IP_FW_INV_SRCIP)
297     	    || FWINV((ip->daddr&f->ipfw.fw_dmsk.s_addr)!=f->ipfw.fw_dst.s_addr,
298     		     IP_FW_INV_DSTIP)) {
299     		dprintf("Source or dest mismatch.\n");
300     
301     		dprintf("SRC: %u. Mask: %u. Target: %u.%s\n", ip->saddr,
302     			f->ipfw.fw_smsk.s_addr, f->ipfw.fw_src.s_addr,
303     			f->ipfw.fw_invflg & IP_FW_INV_SRCIP ? " (INV)" : "");
304     		dprintf("DST: %u. Mask: %u. Target: %u.%s\n", ip->daddr,
305     			f->ipfw.fw_dmsk.s_addr, f->ipfw.fw_dst.s_addr,
306     			f->ipfw.fw_invflg & IP_FW_INV_DSTIP ? " (INV)" : "");
307     		return 0;
308     	}
309     
310     	/*
311     	 *	Look for a VIA device match
312     	 */
313     	if (f->ipfw.fw_flg & IP_FW_F_WILDIF) {
314     	    if (FWINV(strncmp(ifname, f->ipfw.fw_vianame,
315     			      strlen(f->ipfw.fw_vianame)) != 0,
316     		      IP_FW_INV_VIA)) {
317     		dprintf("Wildcard interface mismatch.%s\n",
318     			f->ipfw.fw_invflg & IP_FW_INV_VIA ? " (INV)" : "");
319     		return 0;	/* Mismatch */
320     	    }
321     	}
322     	else if (FWINV(strcmp(ifname, f->ipfw.fw_vianame) != 0,
323     		       IP_FW_INV_VIA)) {
324     	    dprintf("Interface name does not match.%s\n",
325     		    f->ipfw.fw_invflg & IP_FW_INV_VIA
326     		    ? " (INV)" : "");
327     	    return 0;	/* Mismatch */
328     	}
329     
330     	/*
331     	 *	Ok the chain addresses match.
332     	 */
333     
334     	/* If we have a fragment rule but the packet is not a fragment
335     	 * the we return zero */
336     	if (FWINV((f->ipfw.fw_flg&IP_FW_F_FRAG) && !isfrag, IP_FW_INV_FRAG)) {
337     		dprintf("Fragment rule but not fragment.%s\n",
338     			f->ipfw.fw_invflg & IP_FW_INV_FRAG ? " (INV)" : "");
339     		return 0;
340     	}
341     
342     	/* Fragment NEVER passes a SYN test, even an inverted one. */
343     	if (FWINV((f->ipfw.fw_flg&IP_FW_F_TCPSYN) && !tcpsyn, IP_FW_INV_SYN)
344     	    || (isfrag && (f->ipfw.fw_flg&IP_FW_F_TCPSYN))) {
345     		dprintf("Rule requires SYN and packet has no SYN.%s\n",
346     			f->ipfw.fw_invflg & IP_FW_INV_SYN ? " (INV)" : "");
347     		return 0;
348     	}
349     
350     	if (f->ipfw.fw_proto) {
351     		/*
352     		 *	Specific firewall - packet's protocol
353     		 *	must match firewall's.
354     		 */
355     
356     		if (FWINV(ip->protocol!=f->ipfw.fw_proto, IP_FW_INV_PROTO)) {
357     			dprintf("Packet protocol %hi does not match %hi.%s\n",
358     				ip->protocol, f->ipfw.fw_proto,
359     				f->ipfw.fw_invflg&IP_FW_INV_PROTO ? " (INV)":"");
360     			return 0;
361     		}
362     
363     		/* For non TCP/UDP/ICMP, port range is max anyway. */
364     		if (!port_match(f->ipfw.fw_spts[0],
365     				f->ipfw.fw_spts[1],
366     				src_port, isfrag,
367     				!!(f->ipfw.fw_invflg&IP_FW_INV_SRCPT))
368     		    || !port_match(f->ipfw.fw_dpts[0],
369     				   f->ipfw.fw_dpts[1],
370     				   dst_port, isfrag,
371     				   !!(f->ipfw.fw_invflg
372     				      &IP_FW_INV_DSTPT))) {
373     		    dprintf("Port match failed.\n");
374     		    return 0;
375     		}
376     	}
377     
378     	dprintf("Match succeeded.\n");
379     	return 1;
380     }
381     
382     static const char *branchname(struct ip_chain *branch,int simplebranch)
383     {
384     	if (branch)
385     		return branch->label;
386     	switch (simplebranch)
387     	{
388     	case FW_BLOCK: return IP_FW_LABEL_BLOCK;
389     	case FW_ACCEPT: return IP_FW_LABEL_ACCEPT;
390     	case FW_REJECT: return IP_FW_LABEL_REJECT;
391     	case FW_REDIRECT: return IP_FW_LABEL_REDIRECT;
392     	case FW_MASQUERADE: return IP_FW_LABEL_MASQUERADE;
393     	case FW_SKIP: return "-";
394     	case FW_SKIP+1: return IP_FW_LABEL_RETURN;
395     	default:
396     		return "UNKNOWN";
397     	}
398     }
399     
400     /*
401      * VERY ugly piece of code which actually
402      * makes kernel printf for matching packets...
403      */
404     static void dump_packet(const struct iphdr *ip,
405     			const char *ifname,
406     			struct ip_fwkernel *f,
407     			const ip_chainlabel chainlabel,
408     			__u16 src_port,
409     			__u16 dst_port,
410     			unsigned int count,
411     			int syn)
412     {
413     	__u32 *opt = (__u32 *) (ip + 1);
414     	int opti;
415     
416     	if (f) {
417     		printk(KERN_INFO "Packet log: %s ",chainlabel);
418     		printk("%s ",branchname(f->branch,f->simplebranch));
419     		if (f->simplebranch==FW_REDIRECT)
420     			printk("%d ",f->ipfw.fw_redirpt);
421     	}
422     
423     	printk("%s PROTO=%d %u.%u.%u.%u:%hu %u.%u.%u.%u:%hu"
424     	       " L=%hu S=0x%2.2hX I=%hu F=0x%4.4hX T=%hu",
425     	       ifname, ip->protocol, NIPQUAD(ip->saddr),
426     	       src_port, NIPQUAD(ip->daddr),
427     	       dst_port,
428     	       ntohs(ip->tot_len), ip->tos, ntohs(ip->id),
429     	       ntohs(ip->frag_off), ip->ttl);
430     
431     	for (opti = 0; opti < (ip->ihl - sizeof(struct iphdr) / 4); opti++)
432     		printk(" O=0x%8.8X", *opt++);
433     	printk(" %s(#%d)\n", syn ? "SYN " : /* "PENANCE" */ "", count);
434     }
435     
436     /* function for checking chain labels for user space. */
437     static int check_label(ip_chainlabel label)
438     {
439     	unsigned int i;
440     	/* strlen must be < IP_FW_MAX_LABEL_LENGTH. */
441     	for (i = 0; i < IP_FW_MAX_LABEL_LENGTH + 1; i++)
442     		if (label[i] == '\0') return 1;
443     
444     	return 0;
445     }
446     
447     /*	This function returns a pointer to the first chain with a label
448      *	that matches the one given. */
449     static struct ip_chain *find_label(ip_chainlabel label)
450     {
451     	struct ip_chain *tmp;
452     	FWC_HAVE_LOCK(fwc_rlocks | fwc_wlocks);
453     	for (tmp = ip_fw_chains; tmp; tmp = tmp->next)
454     		if (strcmp(tmp->label,label) == 0)
455     			break;
456     	return tmp;
457     }
458     
459     /* This function returns a boolean which when true sets answer to one
460        of the FW_*. */
461     static int find_special(ip_chainlabel label, int *answer)
462     {
463     	if (label[0] == '\0') {
464     		*answer = FW_SKIP; /* => pass-through rule */
465     		return 1;
466     	} else if (strcmp(label,IP_FW_LABEL_ACCEPT) == 0) {
467     		*answer = FW_ACCEPT;
468     		return 1;
469     	} else if (strcmp(label,IP_FW_LABEL_BLOCK) == 0) {
470     		*answer = FW_BLOCK;
471     		return 1;
472     	} else if (strcmp(label,IP_FW_LABEL_REJECT) == 0) {
473     		*answer = FW_REJECT;
474     		return 1;
475     	} else if (strcmp(label,IP_FW_LABEL_REDIRECT) == 0) {
476     		*answer = FW_REDIRECT;
477     		return 1;
478     	} else if (strcmp(label,IP_FW_LABEL_MASQUERADE) == 0) {
479     		*answer = FW_MASQUERADE;
480     		return 1;
481     	} else if (strcmp(label, IP_FW_LABEL_RETURN) == 0) {
482     		*answer = FW_SKIP+1;
483     		return 1;
484     	} else {
485     		return 0;
486     	}
487     }
488     
489     /* This function cleans up the prevchain and prevrule.  If the verbose
490      * flag is set then he names of the chains will be printed as it
491      * cleans up.  */
492     static void cleanup(struct ip_chain *chain,
493     		    const int verbose,
494     		    unsigned int slot)
495     {
496     	struct ip_chain *tmpchain = chain->reent[slot].prevchain;
497     	if (verbose)
498     		printk(KERN_ERR "Chain backtrace: ");
499     	while (tmpchain) {
500     		if (verbose)
501     			printk("%s<-",chain->label);
502     		chain->reent[slot].prevchain = NULL;
503     		chain = tmpchain;
504     		tmpchain = chain->reent[slot].prevchain;
505     	}
506     	if (verbose)
507     		printk("%s\n",chain->label);
508     }
509     
510     static inline int
511     ip_fw_domatch(struct ip_fwkernel *f,
512     	      struct iphdr *ip,
513     	      const char *rif,
514     	      const ip_chainlabel label,
515     	      struct sk_buff *skb,
516     	      unsigned int slot,
517     	      __u16 src_port, __u16 dst_port,
518     	      unsigned int count,
519     	      int tcpsyn)
520     {
521     	f->counters[slot].bcnt+=ntohs(ip->tot_len);
522     	f->counters[slot].pcnt++;
523     	if (f->ipfw.fw_flg & IP_FW_F_PRN) {
524     		dump_packet(ip,rif,f,label,src_port,dst_port,count,tcpsyn);
525     	}
526     	ip->tos = (ip->tos & f->ipfw.fw_tosand) ^ f->ipfw.fw_tosxor;
527     
528     /* This functionality is useless in stock 2.0.x series, but we don't
529      * discard the mark thing altogether, to avoid breaking ipchains (and,
530      * more importantly, the ipfwadm wrapper) --PR */
531     	if (f->ipfw.fw_flg & IP_FW_F_MARKABS) {
532     		skb->nfmark = f->ipfw.fw_mark;
533     	} else {
534     		skb->nfmark += f->ipfw.fw_mark;
535     	}
536     	if (f->ipfw.fw_flg & IP_FW_F_NETLINK) {
537     #if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
538     		size_t len = min_t(unsigned int, f->ipfw.fw_outputsize, ntohs(ip->tot_len))
539     			+ sizeof(__u32) + sizeof(skb->nfmark) + IFNAMSIZ;
540     		struct sk_buff *outskb=alloc_skb(len, GFP_ATOMIC);
541     
542     		duprintf("Sending packet out NETLINK (length = %u).\n",
543     			 (unsigned int)len);
544     		if (outskb) {
545     			/* Prepend length, mark & interface */
546     			skb_put(outskb, len);
547     			*((__u32 *)outskb->data) = (__u32)len;
548     			*((__u32 *)(outskb->data+sizeof(__u32))) = skb->nfmark;
549     			strcpy(outskb->data+sizeof(__u32)*2, rif);
550     			memcpy(outskb->data+sizeof(__u32)*2+IFNAMSIZ, ip,
551     			       len-(sizeof(__u32)*2+IFNAMSIZ));
552     			netlink_broadcast(ipfwsk, outskb, 0, ~0, GFP_KERNEL);
553     		}
554     		else {
555     #endif
556     			if (net_ratelimit())
557     				printk(KERN_WARNING "ip_fw: packet drop due to "
558     				       "netlink failure\n");
559     			return 0;
560     #if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
561     		}
562     #endif
563     	}
564     	return 1;
565     }
566     
567     /*
568      *	Returns one of the generic firewall policies, like FW_ACCEPT.
569      *
570      *	The testing is either false for normal firewall mode or true for
571      *	user checking mode (counters are not updated, TOS & mark not done).
572      */
573     static int
574     ip_fw_check(struct iphdr *ip,
575     	    const char *rif,
576     	    __u16 *redirport,
577     	    struct ip_chain *chain,
578     	    struct sk_buff *skb,
579     	    unsigned int slot,
580     	    int testing)
581     {
582     	struct tcphdr		*tcp=(struct tcphdr *)((__u32 *)ip+ip->ihl);
583     	struct udphdr		*udp=(struct udphdr *)((__u32 *)ip+ip->ihl);
584     	struct icmphdr		*icmp=(struct icmphdr *)((__u32 *)ip+ip->ihl);
585     	__u32			src, dst;
586     	__u16			src_port = 0xFFFF, dst_port = 0xFFFF;
587     	char			tcpsyn=0;
588     	__u16			offset;
589     	unsigned char		oldtos;
590     	struct ip_fwkernel	*f;
591     	int			ret = FW_SKIP+2;
592     	unsigned int		count;
593     
594     	/* We handle fragments by dealing with the first fragment as
595     	 * if it was a normal packet.  All other fragments are treated
596     	 * normally, except that they will NEVER match rules that ask
597     	 * things we don't know, ie. tcp syn flag or ports).  If the
598     	 * rule is also a fragment-specific rule, non-fragments won't
599     	 * match it. */
600     
601     	offset = ntohs(ip->frag_off) & IP_OFFSET;
602     
603     	/*
604     	 *	Don't allow a fragment of TCP 8 bytes in. Nobody
605     	 *	normal causes this. Its a cracker trying to break
606     	 *	in by doing a flag overwrite to pass the direction
607     	 *	checks.
608     	 */
609     	if (offset == 1 && ip->protocol == IPPROTO_TCP)	{
610     		if (!testing && net_ratelimit()) {
611     			printk("Suspect TCP fragment.\n");
612     			dump_packet(ip,rif,NULL,NULL,0,0,0,0);
613     		}
614     		return FW_BLOCK;
615     	}
616     
617     	/* If we can't investigate ports, treat as fragment.  It's
618     	 * either a trucated whole packet, or a truncated first
619     	 * fragment, or a TCP first fragment of length 8-15, in which
620     	 * case the above rule stops reassembly.
621     	 */
622     	if (offset == 0) {
623     		unsigned int size_req;
624     		switch (ip->protocol) {
625     		case IPPROTO_TCP:
626     			/* Don't care about things past flags word */
627     			size_req = 16;
628     			break;
629     
630     		case IPPROTO_UDP:
631     		case IPPROTO_ICMP:
632     			size_req = 8;
633     			break;
634     
635     		default:
636     			size_req = 0;
637     		}
638     
639     		/* If it is a truncated first fragment then it can be
640     		 * used to rewrite port information, and thus should
641     		 * be blocked.
642     		 */
643     		if (ntohs(ip->tot_len) < (ip->ihl<<2)+size_req) {
644     			if (!testing && net_ratelimit()) {
645     				printk("Suspect short first fragment.\n");
646     				dump_packet(ip,rif,NULL,NULL,0,0,0,0);
647     			}
648     			return FW_BLOCK;
649     		}
650     	}
651     
652     	src = ip->saddr;
653     	dst = ip->daddr;
654     	oldtos = ip->tos;
655     
656     	/*
657     	 *	If we got interface from which packet came
658     	 *	we can use the address directly. Linux 2.1 now uses address
659     	 *	chains per device too, but unlike BSD we first check if the
660     	 *	incoming packet matches a device address and the routing
661     	 *	table before calling the firewall.
662     	 */
663     
664     	dprintf("Packet ");
665     	switch(ip->protocol)
666     	{
667     		case IPPROTO_TCP:
668     			dprintf("TCP ");
669     			if (!offset) {
670     				src_port=ntohs(tcp->source);
671     				dst_port=ntohs(tcp->dest);
672     
673     				/* Connection initilisation can only
674     				 * be made when the syn bit is set and
675     				 * neither of the ack or reset is
676     				 * set. */
677     				if(tcp->syn && !(tcp->ack || tcp->rst))
678     					tcpsyn=1;
679     			}
680     			break;
681     		case IPPROTO_UDP:
682     			dprintf("UDP ");
683     			if (!offset) {
684     				src_port=ntohs(udp->source);
685     				dst_port=ntohs(udp->dest);
686     			}
687     			break;
688     		case IPPROTO_ICMP:
689     			if (!offset) {
690     				src_port=(__u16)icmp->type;
691     				dst_port=(__u16)icmp->code;
692     			}
693     			dprintf("ICMP ");
694     			break;
695     		default:
696     			dprintf("p=%d ",ip->protocol);
697     			break;
698     	}
699     #ifdef DEBUG_IP_FIREWALL
700     	print_ip(ip->saddr);
701     
702     	if (offset)
703     		dprintf(":fragment (%i) ", ((int)offset)<<2);
704     	else if (ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP
705     		 || ip->protocol==IPPROTO_ICMP)
706     		dprintf(":%hu:%hu", src_port, dst_port);
707     	dprintf("\n");
708     #endif
709     
710     	if (!testing) FWC_READ_LOCK(&ip_fw_lock);
711     	else FWC_HAVE_LOCK(fwc_rlocks);
712     
713     	f = chain->chain;
714     	do {
715     		count = 0;
716     		for (; f; f = f->next) {
717     			count++;
718     			if (ip_rule_match(f,rif,ip,
719     					  tcpsyn,src_port,dst_port,offset)) {
720     				if (!testing
721     				    && !ip_fw_domatch(f, ip, rif, chain->label,
722     						      skb, slot,
723     						      src_port, dst_port,
724     						      count, tcpsyn)) {
725     					ret = FW_BLOCK;
726     					goto out;
727     				}
728     				break;
729     			}
730     		}
731     		if (f) {
732     			if (f->branch) {
733     				/* Do sanity check to see if we have
734                                      * already set prevchain and if so we
735                                      * must be in a loop */
736     				if (f->branch->reent[slot].prevchain) {
737     					if (!testing) {
738     						printk(KERN_ERR
739     						       "IP firewall: "
740     						       "Loop detected "
741     						       "at `%s'.\n",
742     						       f->branch->label);
743     						cleanup(chain, 1, slot);
744     						ret = FW_BLOCK;
745     					} else {
746     						cleanup(chain, 0, slot);
747     						ret = FW_SKIP+1;
748     					}
749     				}
750     				else {
751     					f->branch->reent[slot].prevchain
752     						= chain;
753     					f->branch->reent[slot].prevrule
754     						= f->next;
755     					chain = f->branch;
756     					f = chain->chain;
757     				}
758     			}
759     			else if (f->simplebranch == FW_SKIP)
760     				f = f->next;
761     			else if (f->simplebranch == FW_SKIP+1) {
762     				/* Just like falling off the chain */
763     				goto fall_off_chain;
764     			} else {
765     				cleanup(chain, 0, slot);
766     				ret = f->simplebranch;
767     			}
768     		} /* f == NULL */
769     		else {
770     		fall_off_chain:
771     			if (chain->reent[slot].prevchain) {
772     				struct ip_chain *tmp = chain;
773     				f = chain->reent[slot].prevrule;
774     				chain = chain->reent[slot].prevchain;
775     				tmp->reent[slot].prevchain = NULL;
776     			}
777     			else {
778     				ret = chain->policy;
779     				if (!testing) {
780     					chain->reent[slot].counters.pcnt++;
781     					chain->reent[slot].counters.bcnt
782     						+= ntohs(ip->tot_len);
783     				}
784     			}
785     		}
786     	} while (ret == FW_SKIP+2);
787     
788      out:
789     	if (!testing) FWC_READ_UNLOCK(&ip_fw_lock);
790     
791     	/* Recalculate checksum if not going to reject, and TOS changed. */
792     	if (ip->tos != oldtos
793     	    && ret != FW_REJECT && ret != FW_BLOCK
794     	    && !testing)
795     		ip_send_check(ip);
796     
797     	if (ret == FW_REDIRECT && redirport) {
798     		if ((*redirport = htons(f->ipfw.fw_redirpt)) == 0) {
799     			/* Wildcard redirection.
800     			 * Note that redirport will become
801     			 * 0xFFFF for non-TCP/UDP packets.
802     			 */
803     			*redirport = htons(dst_port);
804     		}
805     	}
806     
807     #ifdef DEBUG_ALLOW_ALL
808     	return (testing ? ret : FW_ACCEPT);
809     #else
810     	return ret;
811     #endif
812     }
813     
814     /* Must have write lock & interrupts off for any of these */
815     
816     /* This function sets all the byte counters in a chain to zero.  The
817      * input is a pointer to the chain required for zeroing */
818     static int zero_fw_chain(struct ip_chain *chainptr)
819     {
820     	struct ip_fwkernel *i;
821     
822     	FWC_HAVE_LOCK(fwc_wlocks);
823     	for (i = chainptr->chain; i; i = i->next)
824     		memset(i->counters, 0, sizeof(struct ip_counters)*NUM_SLOTS);
825     	return 0;
826     }
827     
828     static int clear_fw_chain(struct ip_chain *chainptr)
829     {
830     	struct ip_fwkernel *i= chainptr->chain;
831     
832     	FWC_HAVE_LOCK(fwc_wlocks);
833     	chainptr->chain=NULL;
834     
835     	while (i) {
836     		struct ip_fwkernel *tmp = i->next;
837     		if (i->branch)
838     			i->branch->refcount--;
839     		kfree(i);
840     		i = tmp;
841     	}
842     	return 0;
843     }
844     
845     static int replace_in_chain(struct ip_chain *chainptr,
846     			    struct ip_fwkernel *frwl,
847     			    __u32 position)
848     {
849     	struct ip_fwkernel *f = chainptr->chain;
850     
851     	FWC_HAVE_LOCK(fwc_wlocks);
852     
853     	while (--position && f != NULL) f = f->next;
854     	if (f == NULL)
855     		return EINVAL;
856     
857     	if (f->branch) f->branch->refcount--;
858     	if (frwl->branch) frwl->branch->refcount++;
859     
860     	frwl->next = f->next;
861     	memcpy(f,frwl,sizeof(struct ip_fwkernel));
862     	kfree(frwl);
863     	return 0;
864     }
865     
866     static int append_to_chain(struct ip_chain *chainptr, struct ip_fwkernel *rule)
867     {
868     	struct ip_fwkernel *i;
869     
870     	FWC_HAVE_LOCK(fwc_wlocks);
871     	/* Special case if no rules already present */
872     	if (chainptr->chain == NULL) {
873     
874     		/* If pointer writes are atomic then turning off
875     		 * interrupts is not necessary. */
876     		chainptr->chain = rule;
877     		if (rule->branch) rule->branch->refcount++;
878     		return 0;
879     	}
880     
881     	/* Find the rule before the end of the chain */
882     	for (i = chainptr->chain; i->next; i = i->next);
883     	i->next = rule;
884     	if (rule->branch) rule->branch->refcount++;
885     	return 0;
886     }
887     
888     /* This function inserts a rule at the position of position in the
889      * chain refenced by chainptr.  If position is 1 then this rule will
890      * become the new rule one. */
891     static int insert_in_chain(struct ip_chain *chainptr,
892     			   struct ip_fwkernel *frwl,
893     			   __u32 position)
894     {
895     	struct ip_fwkernel *f = chainptr->chain;
896     
897     	FWC_HAVE_LOCK(fwc_wlocks);
898     	/* special case if the position is number 1 */
899     	if (position == 1) {
900     		frwl->next = chainptr->chain;
901     		if (frwl->branch) frwl->branch->refcount++;
902     		chainptr->chain = frwl;
903     		return 0;
904     	}
905     	position--;
906     	while (--position && f != NULL) f = f->next;
907     	if (f == NULL)
908     		return EINVAL;
909     	if (frwl->branch) frwl->branch->refcount++;
910     	frwl->next = f->next;
911     
912     	f->next = frwl;
913     	return 0;
914     }
915     
916     /* This function deletes the a rule from a given rulenum and chain.
917      * With rulenum = 1 is the first rule is deleted. */
918     
919     static int del_num_from_chain(struct ip_chain *chainptr, __u32 rulenum)
920     {
921     	struct ip_fwkernel *i=chainptr->chain,*tmp;
922     
923     	FWC_HAVE_LOCK(fwc_wlocks);
924     
925     	if (!chainptr->chain)
926     		return ENOENT;
927     
928     	/* Need a special case for the first rule */
929     	if (rulenum == 1) {
930     		/* store temp to allow for freeing up of memory */
931     		tmp = chainptr->chain;
932     	        if (chainptr->chain->branch) chainptr->chain->branch->refcount--;
933     		chainptr->chain = chainptr->chain->next;
934     		kfree(tmp); /* free memory that is now unused */
935     	} else {
936     		rulenum--;
937     		while (--rulenum && i->next ) i = i->next;
938     		if (!i->next)
939     			return ENOENT;
940     		tmp = i->next;
941     		if (i->next->branch)
942     			i->next->branch->refcount--;
943     		i->next = i->next->next;
944     		kfree(tmp);
945     	}
946     	return 0;
947     }
948     
949     
950     /* This function deletes the a rule from a given rule and chain.
951      * The rule that is deleted is the first occursance of that rule. */
952     static int del_rule_from_chain(struct ip_chain *chainptr,
953     			       struct ip_fwkernel *frwl)
954     {
955     	struct ip_fwkernel *ltmp,*ftmp = chainptr->chain ;
956     	int was_found;
957     
958     	FWC_HAVE_LOCK(fwc_wlocks);
959     
960     	/* Sure, we should compare marks, but since the `ipfwadm'
961     	 * script uses it for an unholy hack... well, life is easier
962     	 * this way.  We also mask it out of the flags word. --PR */
963     	for (ltmp=NULL, was_found=0;
964     	     !was_found && ftmp != NULL;
965     	     ltmp = ftmp,ftmp = ftmp->next) {
966     		if (ftmp->ipfw.fw_src.s_addr!=frwl->ipfw.fw_src.s_addr
967     		    || ftmp->ipfw.fw_dst.s_addr!=frwl->ipfw.fw_dst.s_addr
968     		    || ftmp->ipfw.fw_smsk.s_addr!=frwl->ipfw.fw_smsk.s_addr
969     		    || ftmp->ipfw.fw_dmsk.s_addr!=frwl->ipfw.fw_dmsk.s_addr
970     #if 0
971     		    || ftmp->ipfw.fw_flg!=frwl->ipfw.fw_flg
972     #else
973     		    || ((ftmp->ipfw.fw_flg & ~IP_FW_F_MARKABS)
974     			!= (frwl->ipfw.fw_flg & ~IP_FW_F_MARKABS))
975     #endif
976     		    || ftmp->ipfw.fw_invflg!=frwl->ipfw.fw_invflg
977     		    || ftmp->ipfw.fw_proto!=frwl->ipfw.fw_proto
978     #if 0
979     		    || ftmp->ipfw.fw_mark!=frwl->ipfw.fw_mark
980     #endif
981     		    || ftmp->ipfw.fw_redirpt!=frwl->ipfw.fw_redirpt
982     		    || ftmp->ipfw.fw_spts[0]!=frwl->ipfw.fw_spts[0]
983     		    || ftmp->ipfw.fw_spts[1]!=frwl->ipfw.fw_spts[1]
984     		    || ftmp->ipfw.fw_dpts[0]!=frwl->ipfw.fw_dpts[0]
985     		    || ftmp->ipfw.fw_dpts[1]!=frwl->ipfw.fw_dpts[1]
986     		    || ftmp->ipfw.fw_outputsize!=frwl->ipfw.fw_outputsize) {
987     			duprintf("del_rule_from_chain: mismatch:"
988     				 "src:%u/%u dst:%u/%u smsk:%u/%u dmsk:%u/%u "
989     				 "flg:%hX/%hX invflg:%hX/%hX proto:%u/%u "
990     				 "mark:%u/%u "
991     				 "ports:%hu-%hu/%hu-%hu %hu-%hu/%hu-%hu "
992     				 "outputsize:%hu-%hu\n",
993     				 ftmp->ipfw.fw_src.s_addr,
994     				 frwl->ipfw.fw_src.s_addr,
995     				 ftmp->ipfw.fw_dst.s_addr,
996     				 frwl->ipfw.fw_dst.s_addr,
997     				 ftmp->ipfw.fw_smsk.s_addr,
998     				 frwl->ipfw.fw_smsk.s_addr,
999     				 ftmp->ipfw.fw_dmsk.s_addr,
1000     				 frwl->ipfw.fw_dmsk.s_addr,
1001     				 ftmp->ipfw.fw_flg,
1002     				 frwl->ipfw.fw_flg,
1003     				 ftmp->ipfw.fw_invflg,
1004     				 frwl->ipfw.fw_invflg,
1005     				 ftmp->ipfw.fw_proto,
1006     				 frwl->ipfw.fw_proto,
1007     				 ftmp->ipfw.fw_mark,
1008     				 frwl->ipfw.fw_mark,
1009     				 ftmp->ipfw.fw_spts[0],
1010     				 frwl->ipfw.fw_spts[0],
1011     				 ftmp->ipfw.fw_spts[1],
1012     				 frwl->ipfw.fw_spts[1],
1013     				 ftmp->ipfw.fw_dpts[0],
1014     				 frwl->ipfw.fw_dpts[0],
1015     				 ftmp->ipfw.fw_dpts[1],
1016     				 frwl->ipfw.fw_dpts[1],
1017     				 ftmp->ipfw.fw_outputsize,
1018     				 frwl->ipfw.fw_outputsize);
1019     			continue;
1020     		}
1021     
1022     		if (strncmp(ftmp->ipfw.fw_vianame,
1023     			    frwl->ipfw.fw_vianame,
1024     			    IFNAMSIZ)) {
1025     			duprintf("del_rule_from_chain: if mismatch: %s/%s\n",
1026     				 ftmp->ipfw.fw_vianame,
1027     				 frwl->ipfw.fw_vianame);
1028     		        continue;
1029     		}
1030     		if (ftmp->branch != frwl->branch) {
1031     			duprintf("del_rule_from_chain: branch mismatch: "
1032     				 "%s/%s\n",
1033     				 ftmp->branch?ftmp->branch->label:"(null)",
1034     				 frwl->branch?frwl->branch->label:"(null)");
1035     			continue;
1036     		}
1037     		if (ftmp->branch == NULL
1038     		    && ftmp->simplebranch != frwl->simplebranch) {
1039     			duprintf("del_rule_from_chain: simplebranch mismatch: "
1040     				 "%i/%i\n",
1041     				 ftmp->simplebranch, frwl->simplebranch);
1042     			continue;
1043     		}
1044     		was_found = 1;
1045     		if (ftmp->branch)
1046     			ftmp->branch->refcount--;
1047     		if (ltmp)
1048     			ltmp->next = ftmp->next;
1049     		else
1050     			chainptr->chain = ftmp->next;
1051     		kfree(ftmp);
1052     		break;
1053     	}
1054     
1055     	if (was_found)
1056     		return 0;
1057     	else {
1058     		duprintf("del_rule_from_chain: no matching rule found\n");
1059     		return EINVAL;
1060     	}
1061     }
1062     
1063     /* This function takes the label of a chain and deletes the first
1064      * chain with that name.  No special cases required for the built in
1065      * chains as they have their refcount initilised to 1 so that they are
1066      * never deleted.  */
1067     static int del_chain(ip_chainlabel label)
1068     {
1069     	struct ip_chain *tmp,*tmp2;
1070     
1071     	FWC_HAVE_LOCK(fwc_wlocks);
1072     	/* Corner case: return EBUSY not ENOENT for first elem ("input") */
1073     	if (strcmp(label, ip_fw_chains->label) == 0)
1074     		return EBUSY;
1075     
1076     	for (tmp = ip_fw_chains; tmp->next; tmp = tmp->next)
1077     		if(strcmp(tmp->next->label,label) == 0)
1078     			break;
1079     
1080     	tmp2 = tmp->next;
1081     	if (!tmp2)
1082     		return ENOENT;
1083     
1084     	if (tmp2->refcount)
1085     		return EBUSY;
1086     
1087     	if (tmp2->chain)
1088     		return ENOTEMPTY;
1089     
1090     	tmp->next = tmp2->next;
1091     	kfree(tmp2);
1092     	return 0;
1093     }
1094     
1095     /* This is a function to initilise a chain.  Built in rules start with
1096      * refcount = 1 so that they cannot be deleted.  User defined rules
1097      * start with refcount = 0 so they can be deleted. */
1098     static struct ip_chain *ip_init_chain(ip_chainlabel name,
1099     				      __u32 ref,
1100     				      int policy)
1101     {
1102     	unsigned int i;
1103     	struct ip_chain *label
1104     		= kmalloc(SIZEOF_STRUCT_IP_CHAIN, GFP_KERNEL);
1105     	if (label == NULL)
1106     		panic("Can't kmalloc for firewall chains.\n");
1107     	strcpy(label->label,name);
1108     	label->next = NULL;
1109     	label->chain = NULL;
1110     	label->refcount = ref;
1111     	label->policy = policy;
1112     	for (i = 0; i < smp_num_cpus*2; i++) {
1113     		label->reent[i].counters.pcnt = label->reent[i].counters.bcnt
1114     			= 0;
1115     		label->reent[i].prevchain = NULL;
1116     		label->reent[i].prevrule = NULL;
1117     	}
1118     
1119     	return label;
1120     }
1121     
1122     /* This is a function for reating a new chain.  The chains is not
1123      * created if a chain of the same name already exists */
1124     static int create_chain(ip_chainlabel label)
1125     {
1126     	struct ip_chain *tmp;
1127     
1128     	if (!check_label(label))
1129     		return EINVAL;
1130     
1131     	FWC_HAVE_LOCK(fwc_wlocks);
1132     	for (tmp = ip_fw_chains; tmp->next; tmp = tmp->next)
1133     		if (strcmp(tmp->label,label) == 0)
1134     			return EEXIST;
1135     
1136     	if (strcmp(tmp->label,label) == 0)
1137     		return EEXIST;
1138     
1139     	tmp->next = ip_init_chain(label, 0, FW_SKIP); /* refcount is
1140     					      * zero since this is a
1141     					      * user defined chain *
1142     					      * and therefore can be
1143     					      * deleted */
1144     	return 0;
1145     }
1146     
1147     /* This function simply changes the policy on one of the built in
1148      * chains.  checking must be done before this is call to ensure that
1149      * chainptr is pointing to one of the three possible chains */
1150     static int change_policy(struct ip_chain *chainptr, int policy)
1151     {
1152     	FWC_HAVE_LOCK(fwc_wlocks);
1153     	chainptr->policy = policy;
1154     	return 0;
1155     }
1156     
1157     /* This function takes an ip_fwuser and converts it to a ip_fwkernel.  It also
1158      * performs some checks in the structure. */
1159     static struct ip_fwkernel *convert_ipfw(struct ip_fwuser *fwuser, int *errno)
1160     {
1161     	struct ip_fwkernel *fwkern;
1162     
1163     	if ( (fwuser->ipfw.fw_flg & ~IP_FW_F_MASK) != 0 ) {
1164     		duprintf("convert_ipfw: undefined flag bits set (flags=%x)\n",
1165     			 fwuser->ipfw.fw_flg);
1166     		*errno = EINVAL;
1167     		return NULL;
1168     	}
1169     
1170     #ifdef DEBUG_IP_FIREWALL_USER
1171     	/* These are sanity checks that don't really matter.
1172     	 * We can get rid of these once testing is complete.
1173     	 */
1174     	if ((fwuser->ipfw.fw_flg & IP_FW_F_TCPSYN)
1175     	    && ((fwuser->ipfw.fw_invflg & IP_FW_INV_PROTO)
1176     		|| fwuser->ipfw.fw_proto != IPPROTO_TCP)) {
1177     		duprintf("convert_ipfw: TCP SYN flag set but proto != TCP!\n");
1178     		*errno = EINVAL;
1179     		return NULL;
1180     	}
1181     
1182     	if (strcmp(fwuser->label, IP_FW_LABEL_REDIRECT) != 0
1183     	    && fwuser->ipfw.fw_redirpt != 0) {
1184     		duprintf("convert_ipfw: Target not REDIR but redirpt != 0!\n");
1185     		*errno = EINVAL;
1186     		return NULL;
1187     	}
1188     
1189     	if ((!(fwuser->ipfw.fw_flg & IP_FW_F_FRAG)
1190     	     && (fwuser->ipfw.fw_invflg & IP_FW_INV_FRAG))
1191     	    || (!(fwuser->ipfw.fw_flg & IP_FW_F_TCPSYN)
1192     		&& (fwuser->ipfw.fw_invflg & IP_FW_INV_SYN))) {
1193     		duprintf("convert_ipfw: Can't have INV flag if flag unset!\n");
1194     		*errno = EINVAL;
1195     		return NULL;
1196     	}
1197     
1198     	if (((fwuser->ipfw.fw_invflg & IP_FW_INV_SRCPT)
1199     	     && fwuser->ipfw.fw_spts[0] == 0
1200     	     && fwuser->ipfw.fw_spts[1] == 0xFFFF)
1201     	    || ((fwuser->ipfw.fw_invflg & IP_FW_INV_DSTPT)
1202     		&& fwuser->ipfw.fw_dpts[0] == 0
1203     		&& fwuser->ipfw.fw_dpts[1] == 0xFFFF)
1204     	    || ((fwuser->ipfw.fw_invflg & IP_FW_INV_VIA)
1205     		&& (fwuser->ipfw.fw_vianame)[0] == '\0')
1206     	    || ((fwuser->ipfw.fw_invflg & IP_FW_INV_SRCIP)
1207     		&& fwuser->ipfw.fw_smsk.s_addr == 0)
1208     	    || ((fwuser->ipfw.fw_invflg & IP_FW_INV_DSTIP)
1209     		&& fwuser->ipfw.fw_dmsk.s_addr == 0)) {
1210     		duprintf("convert_ipfw: INV flag makes rule unmatchable!\n");
1211     		*errno = EINVAL;
1212     		return NULL;
1213     	}
1214     
1215     	if ((fwuser->ipfw.fw_flg & IP_FW_F_FRAG)
1216     	    && !(fwuser->ipfw.fw_invflg & IP_FW_INV_FRAG)
1217     	    && (fwuser->ipfw.fw_spts[0] != 0
1218     		|| fwuser->ipfw.fw_spts[1] != 0xFFFF
1219     		|| fwuser->ipfw.fw_dpts[0] != 0
1220     		|| fwuser->ipfw.fw_dpts[1] != 0xFFFF
1221     		|| (fwuser->ipfw.fw_flg & IP_FW_F_TCPSYN))) {
1222     		duprintf("convert_ipfw: Can't test ports or SYN with frag!\n");
1223     		*errno = EINVAL;
1224     		return NULL;
1225     	}
1226     #endif
1227     
1228     	if ((fwuser->ipfw.fw_spts[0] != 0
1229     	     || fwuser->ipfw.fw_spts[1] != 0xFFFF
1230     	     || fwuser->ipfw.fw_dpts[0] != 0
1231     	     || fwuser->ipfw.fw_dpts[1] != 0xFFFF)
1232     	    && ((fwuser->ipfw.fw_invflg & IP_FW_INV_PROTO)
1233     		|| (fwuser->ipfw.fw_proto != IPPROTO_TCP
1234     		    && fwuser->ipfw.fw_proto != IPPROTO_UDP
1235     		    && fwuser->ipfw.fw_proto != IPPROTO_ICMP))) {
1236     		duprintf("convert_ipfw: Can only test ports for TCP/UDP/ICMP!\n");
1237     		*errno = EINVAL;
1238     		return NULL;
1239     	}
1240     
1241     	fwkern = kmalloc(SIZEOF_STRUCT_IP_FW_KERNEL, GFP_KERNEL);
1242     	if (!fwkern) {
1243     		duprintf("convert_ipfw: kmalloc failed!\n");
1244     		*errno = ENOMEM;
1245     		return NULL;
1246     	}
1247     	memcpy(&fwkern->ipfw,&fwuser->ipfw,sizeof(struct ip_fw));
1248     
1249     	if (!find_special(fwuser->label, &fwkern->simplebranch)) {
1250     		fwkern->branch = find_label(fwuser->label);
1251     		if (!fwkern->branch) {
1252     			duprintf("convert_ipfw: chain doesn't exist `%s'.\n",
1253     				 fwuser->label);
1254     			kfree(fwkern);
1255     			*errno = ENOENT;
1256     			return NULL;
1257     		} else if (fwkern->branch == IP_FW_INPUT_CHAIN
1258     			   || fwkern->branch == IP_FW_FORWARD_CHAIN
1259     			   || fwkern->branch == IP_FW_OUTPUT_CHAIN) {
1260     			duprintf("convert_ipfw: Can't branch to builtin chain `%s'.\n",
1261     				 fwuser->label);
1262     			kfree(fwkern);
1263     			*errno = ENOENT;
1264     			return NULL;
1265     		}
1266     	} else
1267     		fwkern->branch = NULL;
1268     	memset(fwkern->counters, 0, sizeof(struct ip_counters)*NUM_SLOTS);
1269     
1270     	/* Handle empty vianame by making it a wildcard */
1271     	if ((fwkern->ipfw.fw_vianame)[0] == '\0')
1272     	    fwkern->ipfw.fw_flg |= IP_FW_F_WILDIF;
1273     
1274     	fwkern->next = NULL;
1275     	return fwkern;
1276     }
1277     
1278     int ip_fw_ctl(int cmd, void *m, int len)
1279     {
1280     	int ret;
1281     	struct ip_chain *chain;
1282     	unsigned long flags;
1283     
1284     	FWC_WRITE_LOCK_IRQ(&ip_fw_lock, flags);
1285     
1286     	switch (cmd) {
1287     	case IP_FW_FLUSH:
1288     		if (len != sizeof(ip_chainlabel) || !check_label(m))
1289     			ret = EINVAL;
1290     		else if ((chain = find_label(m)) == NULL)
1291     			ret = ENOENT;
1292     		else ret = clear_fw_chain(chain);
1293     		break;
1294     
1295     	case IP_FW_ZERO:
1296     		if (len != sizeof(ip_chainlabel) || !check_label(m))
1297     			ret = EINVAL;
1298     		else if ((chain = find_label(m)) == NULL)
1299     			ret = ENOENT;
1300     		else ret = zero_fw_chain(chain);
1301     		break;
1302     
1303     	case IP_FW_CHECK: {
1304     		struct ip_fwtest *new = m;
1305     		struct iphdr *ip;
1306     
1307     		/* Don't need write lock. */
1308     		FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);
1309     
1310     		if (len != sizeof(struct ip_fwtest) || !check_label(m))
1311     			return EINVAL;
1312     
1313     		/* Need readlock to do find_label */
1314     		FWC_READ_LOCK(&ip_fw_lock);
1315     
1316     		if ((chain = find_label(new->fwt_label)) == NULL)
1317     			ret = ENOENT;
1318     		else {
1319     			ip = &(new->fwt_packet.fwp_iph);
1320     
1321     			if (ip->ihl != sizeof(struct iphdr) / sizeof(int)) {
1322     			    duprintf("ip_fw_ctl: ip->ihl=%d, want %d\n",
1323     				     ip->ihl,
1324     				     sizeof(struct iphdr) / sizeof(int));
1325     			    ret = EINVAL;
1326     			}
1327     			else {
1328     				ret = ip_fw_check(ip, new->fwt_packet.fwp_vianame,
1329     						  NULL, chain,
1330     						  NULL, SLOT_NUMBER(), 1);
1331     				switch (ret) {
1332     				case FW_ACCEPT:
1333     					ret = 0; break;
1334     				case FW_REDIRECT:
1335     					ret = ECONNABORTED; break;
1336     				case FW_MASQUERADE:
1337     					ret = ECONNRESET; break;
1338     				case FW_REJECT:
1339     					ret = ECONNREFUSED; break;
1340     					/* Hack to help diag; these only get
1341     					   returned when testing. */
1342     				case FW_SKIP+1:
1343     					ret = ELOOP; break;
1344     				case FW_SKIP:
1345     					ret = ENFILE; break;
1346     				default: /* FW_BLOCK */
1347     					ret = ETIMEDOUT; break;
1348     				}
1349     			}
1350     		}
1351     		FWC_READ_UNLOCK(&ip_fw_lock);
1352     		return ret;
1353     	}
1354     
1355     	case IP_FW_MASQ_TIMEOUTS: {
1356     		ret = ip_fw_masq_timeouts(m, len);
1357     	}
1358     	break;
1359     
1360     	case IP_FW_REPLACE: {
1361     		struct ip_fwkernel *ip_fwkern;
1362     		struct ip_fwnew *new = m;
1363     
1364     		if (len != sizeof(struct ip_fwnew)
1365     		    || !check_label(new->fwn_label))
1366     			ret = EINVAL;
1367     		else if ((chain = find_label(new->fwn_label)) == NULL)
1368     			ret = ENOENT;
1369     		else if ((ip_fwkern = convert_ipfw(&new->fwn_rule, &ret))
1370     			 != NULL)
1371     			ret = replace_in_chain(chain, ip_fwkern,
1372     					       new->fwn_rulenum);
1373     	}
1374     	break;
1375     
1376     	case IP_FW_APPEND: {
1377     		struct ip_fwchange *new = m;
1378     		struct ip_fwkernel *ip_fwkern;
1379     
1380     		if (len != sizeof(struct ip_fwchange)
1381     		    || !check_label(new->fwc_label))
1382     			ret = EINVAL;
1383     		else if ((chain = find_label(new->fwc_label)) == NULL)
1384     			ret = ENOENT;
1385     		else if ((ip_fwkern = convert_ipfw(&new->fwc_rule, &ret))
1386     			 != NULL)
1387     			ret = append_to_chain(chain, ip_fwkern);
1388     	}
1389     	break;
1390     
1391     	case IP_FW_INSERT: {
1392     		struct ip_fwkernel *ip_fwkern;
1393     		struct ip_fwnew *new = m;
1394     
1395     		if (len != sizeof(struct ip_fwnew)
1396     		    || !check_label(new->fwn_label))
1397     			ret = EINVAL;
1398     		else if ((chain = find_label(new->fwn_label)) == NULL)
1399     			ret = ENOENT;
1400     		else if ((ip_fwkern = convert_ipfw(&new->fwn_rule, &ret))
1401     			 != NULL)
1402     			ret = insert_in_chain(chain, ip_fwkern,
1403     					      new->fwn_rulenum);
1404     	}
1405     	break;
1406     
1407     	case IP_FW_DELETE: {
1408     		struct ip_fwchange *new = m;
1409     		struct ip_fwkernel *ip_fwkern;
1410     
1411     		if (len != sizeof(struct ip_fwchange)
1412     		    || !check_label(new->fwc_label))
1413     			ret = EINVAL;
1414     		else if ((chain = find_label(new->fwc_label)) == NULL)
1415     			ret = ENOENT;
1416     		else if ((ip_fwkern = convert_ipfw(&new->fwc_rule, &ret))
1417     			 != NULL) {
1418     			ret = del_rule_from_chain(chain, ip_fwkern);
1419     			kfree(ip_fwkern);
1420     		}
1421     	}
1422     	break;
1423     
1424     	case IP_FW_DELETE_NUM: {
1425     		struct ip_fwdelnum *new = m;
1426     
1427     		if (len != sizeof(struct ip_fwdelnum)
1428     		    || !check_label(new->fwd_label))
1429     			ret = EINVAL;
1430     		else if ((chain = find_label(new->fwd_label)) == NULL)
1431     			ret = ENOENT;
1432     		else ret = del_num_from_chain(chain, new->fwd_rulenum);
1433     	}
1434     	break;
1435     
1436     	case IP_FW_CREATECHAIN: {
1437     		if (len != sizeof(ip_chainlabel)) {
1438     			duprintf("create_chain: bad size %i\n", len);
1439     			ret = EINVAL;
1440     		}
1441     		else ret = create_chain(m);
1442     	}
1443     	break;
1444     
1445     	case IP_FW_DELETECHAIN: {
1446     		if (len != sizeof(ip_chainlabel)) {
1447     			duprintf("delete_chain: bad size %i\n", len);
1448     			ret = EINVAL;
1449     		}
1450     		else ret = del_chain(m);
1451     	}
1452     	break;
1453     
1454     	case IP_FW_POLICY: {
1455     		struct ip_fwpolicy *new = m;
1456     
1457     		if (len != sizeof(struct ip_fwpolicy)
1458     		    || !check_label(new->fwp_label))
1459     			ret = EINVAL;
1460     		else if ((chain = find_label(new->fwp_label)) == NULL)
1461     			ret = ENOENT;
1462     		else if (chain != IP_FW_INPUT_CHAIN
1463     			 && chain != IP_FW_FORWARD_CHAIN
1464     			 && chain != IP_FW_OUTPUT_CHAIN) {
1465     			duprintf("change_policy: can't change policy on user"
1466     				 " defined chain.\n");
1467     			ret = EINVAL;
1468     		}
1469     		else {
1470     		        int pol = FW_SKIP;
1471     			find_special(new->fwp_policy, &pol);
1472     
1473     			switch(pol) {
1474     			case FW_MASQUERADE:
1475     				if (chain != IP_FW_FORWARD_CHAIN) {
1476     					ret = EINVAL;
1477     					break;
1478     				}
1479     				/* Fall thru... */
1480     			case FW_BLOCK:
1481     			case FW_ACCEPT:
1482     			case FW_REJECT:
1483     				ret = change_policy(chain, pol);
1484     				break;
1485     			default:
1486     			        duprintf("change_policy: bad policy `%s'\n",
1487     					 new->fwp_policy);
1488     				ret = EINVAL;
1489     			}
1490     		}
1491     		break;
1492     	}
1493     	default:
1494     		duprintf("ip_fw_ctl:  unknown request %d\n",cmd);
1495     		ret = ENOPROTOOPT;
1496     	}
1497     
1498     	FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);
1499     	return ret;
1500     }
1501     
1502     /* Returns bytes used - doesn't NUL terminate */
1503     static int dump_rule(char *buffer,
1504     		     const char *chainlabel,
1505     		     const struct ip_fwkernel *rule)
1506     {
1507     	int len;
1508     	unsigned int i;
1509     	__u64 packets = 0, bytes = 0;
1510     
1511     	FWC_HAVE_LOCK(fwc_wlocks);
1512     	for (i = 0; i < NUM_SLOTS; i++) {
1513     		packets += rule->counters[i].pcnt;
1514     		bytes += rule->counters[i].bcnt;
1515     	}
1516     
1517     	len=sprintf(buffer,
1518     		    "%9s "			/* Chain name */
1519     		    "%08X/%08X->%08X/%08X "	/* Source & Destination IPs */
1520     		    "%.16s "			/* Interface */
1521     		    "%X %X "			/* fw_flg and fw_invflg fields */
1522     		    "%u "			/* Protocol */
1523     		    "%-9u %-9u %-9u %-9u "	/* Packet & byte counters */
1524     		    "%u-%u %u-%u "		/* Source & Dest port ranges */
1525     		    "A%02X X%02X "		/* TOS and and xor masks */
1526     		    "%08X "			/* Redirection port */
1527     		    "%u "			/* fw_mark field */
1528     		    "%u "			/* output size */
1529     		    "%9s\n",			/* Target */
1530     		    chainlabel,
1531     		    ntohl(rule->ipfw.fw_src.s_addr),
1532     		    ntohl(rule->ipfw.fw_smsk.s_addr),
1533     		    ntohl(rule->ipfw.fw_dst.s_addr),
1534     		    ntohl(rule->ipfw.fw_dmsk.s_addr),
1535     		    (rule->ipfw.fw_vianame)[0] ? rule->ipfw.fw_vianame : "-",
1536     		    rule->ipfw.fw_flg,
1537     		    rule->ipfw.fw_invflg,
1538     		    rule->ipfw.fw_proto,
1539     		    (__u32)(packets >> 32), (__u32)packets,
1540     		    (__u32)(bytes >> 32), (__u32)bytes,
1541     		    rule->ipfw.fw_spts[0], rule->ipfw.fw_spts[1],
1542     		    rule->ipfw.fw_dpts[0], rule->ipfw.fw_dpts[1],
1543     		    rule->ipfw.fw_tosand, rule->ipfw.fw_tosxor,
1544     		    rule->ipfw.fw_redirpt,
1545     		    rule->ipfw.fw_mark,
1546     		    rule->ipfw.fw_outputsize,
1547     		    branchname(rule->branch,rule->simplebranch));
1548     
1549     	duprintf("dump_rule: %i bytes done.\n", len);
1550     	return len;
1551     }
1552     
1553     /* File offset is actually in records, not bytes. */
1554     static int ip_chain_procinfo(char *buffer, char **start,
1555     			     off_t offset, int length
1556     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,29)
1557     			     , int reset
1558     #endif
1559     	)
1560     {
1561     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29)
1562     	/* FIXME: No more `atomic' read and reset.  Wonderful 8-( --RR */
1563     	int reset = 0;
1564     #endif
1565     	struct ip_chain *i;
1566     	struct ip_fwkernel *j = ip_fw_chains->chain;
1567     	unsigned long flags;
1568     	int len = 0;
1569     	int last_len = 0;
1570     	off_t upto = 0;
1571     
1572     	duprintf("Offset starts at %lu\n", offset);
1573     	duprintf("ip_fw_chains is 0x%0lX\n", (unsigned long int)ip_fw_chains);
1574     
1575     	/* Need a write lock to lock out ``readers'' which update counters. */
1576     	FWC_WRITE_LOCK_IRQ(&ip_fw_lock, flags);
1577     
1578     	for (i = ip_fw_chains; i; i = i->next) {
1579     	    for (j = i->chain; j; j = j->next) {
1580     		if (upto == offset) break;
1581     		duprintf("Skipping rule in chain `%s'\n",
1582     			 i->label);
1583     		upto++;
1584     	    }
1585     	    if (upto == offset) break;
1586     	}
1587     
1588     	/* Don't init j first time, or once i = NULL */
1589     	for (; i; (void)((i = i->next) && (j = i->chain))) {
1590     		duprintf("Dumping chain `%s'\n", i->label);
1591     		for (; j; j = j->next, upto++, last_len = len)
1592     		{
1593     			len += dump_rule(buffer+len, i->label, j);
1594     			if (len > length) {
1595     				duprintf("Dumped to %i (past %i).  "
1596     					 "Moving back to %i.\n",
1597     					 len, length, last_len);
1598     				len = last_len;
1599     				goto outside;
1600     			}
1601     			else if (reset)
1602     				memset(j->counters, 0,
1603     				       sizeof(struct ip_counters)*NUM_SLOTS);
1604     		}
1605     	}
1606     outside:
1607     	FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);
1608     	buffer[len] = '\0';
1609     
1610     	duprintf("ip_chain_procinfo: Length = %i (of %i).  Offset = %li.\n",
1611     		 len, length, upto);
1612     	/* `start' hack - see fs/proc/generic.c line ~165 */
1613     	*start=(char *)((unsigned int)upto-offset);
1614     	return len;
1615     }
1616     
1617     static int ip_chain_name_procinfo(char *buffer, char **start,
1618     				  off_t offset, int length)
1619     {
1620     	struct ip_chain *i;
1621     	int len = 0,last_len = 0;
1622     	off_t pos = 0,begin = 0;
1623     	unsigned long flags;
1624     
1625     	/* Need a write lock to lock out ``readers'' which update counters. */
1626     	FWC_WRITE_LOCK_IRQ(&ip_fw_lock, flags);
1627     
1628     	for (i = ip_fw_chains; i; i = i->next)
1629     	{
1630     		unsigned int j;
1631     		__u32 packetsHi = 0, packetsLo = 0, bytesHi = 0, bytesLo = 0;
1632     
1633     		for (j = 0; j < NUM_SLOTS; j++) {
1634     			packetsLo += i->reent[j].counters.pcnt & 0xFFFFFFFF;
1635     			packetsHi += ((i->reent[j].counters.pcnt >> 32)
1636     				      & 0xFFFFFFFF);
1637     			bytesLo += i->reent[j].counters.bcnt & 0xFFFFFFFF;
1638     			bytesHi += ((i->reent[j].counters.bcnt >> 32)
1639     				    & 0xFFFFFFFF);
1640     		}
1641     
1642     		/* print the label and the policy */
1643     		len+=sprintf(buffer+len,"%s %s %i %u %u %u %u\n",
1644     			     i->label,branchname(NULL, i->policy),i->refcount,
1645     			     packetsHi, packetsLo, bytesHi, bytesLo);
1646     		pos=begin+len;
1647     		if(pos<offset) {
1648     			len=0;
1649     			begin=pos;
1650     		}
1651     		else if(pos>offset+length) {
1652     			len = last_len;
1653     			break;
1654     		}
1655     
1656     		last_len = len;
1657     	}
1658     	FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);
1659     
1660     	*start = buffer+(offset-begin);
1661     	len-=(offset-begin);
1662     	if(len>length)
1663     		len=length;
1664     	return len;
1665     }
1666     
1667     /*
1668      *	Interface to the generic firewall chains.
1669      */
1670     int ipfw_input_check(struct firewall_ops *this, int pf,
1671     		     struct net_device *dev, void *phdr, void *arg,
1672     		     struct sk_buff **pskb)
1673     {
1674     	return ip_fw_check(phdr, dev->name,
1675     			   arg, IP_FW_INPUT_CHAIN, *pskb, SLOT_NUMBER(), 0);
1676     }
1677     
1678     int ipfw_output_check(struct firewall_ops *this, int pf,
1679     		      struct net_device *dev, void *phdr, void *arg,
1680     		      struct sk_buff **pskb)
1681     {
1682     	/* Locally generated bogus packets by root. <SIGH>. */
1683     	if (((struct iphdr *)phdr)->ihl * 4 < sizeof(struct iphdr)
1684     	    || (*pskb)->len < sizeof(struct iphdr))
1685     		return FW_ACCEPT;
1686     	return ip_fw_check(phdr, dev->name,
1687     			   arg, IP_FW_OUTPUT_CHAIN, *pskb, SLOT_NUMBER(), 0);
1688     }
1689     
1690     int ipfw_forward_check(struct firewall_ops *this, int pf,
1691     		       struct net_device *dev, void *phdr, void *arg,
1692     		       struct sk_buff **pskb)
1693     {
1694     	return ip_fw_check(phdr, dev->name,
1695     			   arg, IP_FW_FORWARD_CHAIN, *pskb, SLOT_NUMBER(), 0);
1696     }
1697     
1698     struct firewall_ops ipfw_ops=
1699     {
1700     	NULL,
1701     	ipfw_forward_check,
1702     	ipfw_input_check,
1703     	ipfw_output_check,
1704     	NULL,
1705     	NULL
1706     };
1707     
1708     int ipfw_init_or_cleanup(int init)
1709     {
1710     	struct proc_dir_entry *proc;
1711     	int ret = 0;
1712     	unsigned long flags;
1713     
1714     	if (!init) goto cleanup;
1715     
1716     #ifdef DEBUG_IP_FIREWALL_LOCKING
1717     	fwc_wlocks = fwc_rlocks = 0;
1718     #endif
1719     
1720     #if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
1721     	ipfwsk = netlink_kernel_create(NETLINK_FIREWALL, NULL);
1722     	if (ipfwsk == NULL)
1723     		goto cleanup_nothing;
1724     #endif
1725     
1726     	ret = register_firewall(PF_INET, &ipfw_ops);
1727     	if (ret < 0)
1728     		goto cleanup_netlink;
1729     
1730     	proc = proc_net_create(IP_FW_PROC_CHAINS, S_IFREG | S_IRUSR | S_IWUSR,
1731     			       ip_chain_procinfo);
1732     	if (proc) proc->owner = THIS_MODULE;
1733     	proc = proc_net_create(IP_FW_PROC_CHAIN_NAMES,
1734     			       S_IFREG | S_IRUSR | S_IWUSR,
1735     			       ip_chain_name_procinfo);
1736     	if (proc) proc->owner = THIS_MODULE;
1737     
1738     	IP_FW_INPUT_CHAIN = ip_init_chain(IP_FW_LABEL_INPUT, 1, FW_ACCEPT);
1739     	IP_FW_FORWARD_CHAIN = ip_init_chain(IP_FW_LABEL_FORWARD, 1, FW_ACCEPT);
1740     	IP_FW_OUTPUT_CHAIN = ip_init_chain(IP_FW_LABEL_OUTPUT, 1, FW_ACCEPT);
1741     
1742     	return ret;
1743     
1744      cleanup:
1745     	unregister_firewall(PF_INET, &ipfw_ops);
1746     
1747     	FWC_WRITE_LOCK_IRQ(&ip_fw_lock, flags);
1748     	while (ip_fw_chains) {
1749     		struct ip_chain *next = ip_fw_chains->next;
1750     
1751     		clear_fw_chain(ip_fw_chains);
1752     		kfree(ip_fw_chains);
1753     		ip_fw_chains = next;
1754     	}
1755     	FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);
1756     
1757     	proc_net_remove(IP_FW_PROC_CHAINS);
1758     	proc_net_remove(IP_FW_PROC_CHAIN_NAMES);
1759     
1760      cleanup_netlink:
1761     #if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
1762     	sock_release(ipfwsk->socket);
1763     
1764      cleanup_nothing:
1765     #endif
1766     	return ret;
1767     }
1768