Merge branch 'master' of git://1984.lsi.us.es/net-next-2.6
[pandora-kernel.git] / net / ipv4 / netfilter / ip_tables.c
1 /*
2  * Packet matching code.
3  *
4  * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
5  * Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.org>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12 #include <linux/cache.h>
13 #include <linux/capability.h>
14 #include <linux/skbuff.h>
15 #include <linux/kmod.h>
16 #include <linux/vmalloc.h>
17 #include <linux/netdevice.h>
18 #include <linux/module.h>
19 #include <linux/icmp.h>
20 #include <net/ip.h>
21 #include <net/compat.h>
22 #include <asm/uaccess.h>
23 #include <linux/mutex.h>
24 #include <linux/proc_fs.h>
25 #include <linux/err.h>
26 #include <linux/cpumask.h>
27
28 #include <linux/netfilter/x_tables.h>
29 #include <linux/netfilter_ipv4/ip_tables.h>
30 #include <net/netfilter/nf_log.h>
31 #include "../../netfilter/xt_repldata.h"
32
33 MODULE_LICENSE("GPL");
34 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
35 MODULE_DESCRIPTION("IPv4 packet filter");
36
37 /*#define DEBUG_IP_FIREWALL*/
38 /*#define DEBUG_ALLOW_ALL*/ /* Useful for remote debugging */
39 /*#define DEBUG_IP_FIREWALL_USER*/
40
41 #ifdef DEBUG_IP_FIREWALL
42 #define dprintf(format, args...) pr_info(format , ## args)
43 #else
44 #define dprintf(format, args...)
45 #endif
46
47 #ifdef DEBUG_IP_FIREWALL_USER
48 #define duprintf(format, args...) pr_info(format , ## args)
49 #else
50 #define duprintf(format, args...)
51 #endif
52
53 #ifdef CONFIG_NETFILTER_DEBUG
54 #define IP_NF_ASSERT(x)         WARN_ON(!(x))
55 #else
56 #define IP_NF_ASSERT(x)
57 #endif
58
59 #if 0
60 /* All the better to debug you with... */
61 #define static
62 #define inline
63 #endif
64
65 void *ipt_alloc_initial_table(const struct xt_table *info)
66 {
67         return xt_alloc_initial_table(ipt, IPT);
68 }
69 EXPORT_SYMBOL_GPL(ipt_alloc_initial_table);
70
71 /*
72    We keep a set of rules for each CPU, so we can avoid write-locking
73    them in the softirq when updating the counters and therefore
74    only need to read-lock in the softirq; doing a write_lock_bh() in user
75    context stops packets coming through and allows user context to read
76    the counters or update the rules.
77
78    Hence the start of any table is given by get_table() below.  */
79
80 /* Returns whether matches rule or not. */
81 /* Performance critical - called for every packet */
82 static inline bool
83 ip_packet_match(const struct iphdr *ip,
84                 const char *indev,
85                 const char *outdev,
86                 const struct ipt_ip *ipinfo,
87                 int isfrag)
88 {
89         unsigned long ret;
90
91 #define FWINV(bool, invflg) ((bool) ^ !!(ipinfo->invflags & (invflg)))
92
93         if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
94                   IPT_INV_SRCIP) ||
95             FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
96                   IPT_INV_DSTIP)) {
97                 dprintf("Source or dest mismatch.\n");
98
99                 dprintf("SRC: %pI4. Mask: %pI4. Target: %pI4.%s\n",
100                         &ip->saddr, &ipinfo->smsk.s_addr, &ipinfo->src.s_addr,
101                         ipinfo->invflags & IPT_INV_SRCIP ? " (INV)" : "");
102                 dprintf("DST: %pI4 Mask: %pI4 Target: %pI4.%s\n",
103                         &ip->daddr, &ipinfo->dmsk.s_addr, &ipinfo->dst.s_addr,
104                         ipinfo->invflags & IPT_INV_DSTIP ? " (INV)" : "");
105                 return false;
106         }
107
108         ret = ifname_compare_aligned(indev, ipinfo->iniface, ipinfo->iniface_mask);
109
110         if (FWINV(ret != 0, IPT_INV_VIA_IN)) {
111                 dprintf("VIA in mismatch (%s vs %s).%s\n",
112                         indev, ipinfo->iniface,
113                         ipinfo->invflags&IPT_INV_VIA_IN ?" (INV)":"");
114                 return false;
115         }
116
117         ret = ifname_compare_aligned(outdev, ipinfo->outiface, ipinfo->outiface_mask);
118
119         if (FWINV(ret != 0, IPT_INV_VIA_OUT)) {
120                 dprintf("VIA out mismatch (%s vs %s).%s\n",
121                         outdev, ipinfo->outiface,
122                         ipinfo->invflags&IPT_INV_VIA_OUT ?" (INV)":"");
123                 return false;
124         }
125
126         /* Check specific protocol */
127         if (ipinfo->proto &&
128             FWINV(ip->protocol != ipinfo->proto, IPT_INV_PROTO)) {
129                 dprintf("Packet protocol %hi does not match %hi.%s\n",
130                         ip->protocol, ipinfo->proto,
131                         ipinfo->invflags&IPT_INV_PROTO ? " (INV)":"");
132                 return false;
133         }
134
135         /* If we have a fragment rule but the packet is not a fragment
136          * then we return zero */
137         if (FWINV((ipinfo->flags&IPT_F_FRAG) && !isfrag, IPT_INV_FRAG)) {
138                 dprintf("Fragment rule but not fragment.%s\n",
139                         ipinfo->invflags & IPT_INV_FRAG ? " (INV)" : "");
140                 return false;
141         }
142
143         return true;
144 }
145
146 static bool
147 ip_checkentry(const struct ipt_ip *ip)
148 {
149         if (ip->flags & ~IPT_F_MASK) {
150                 duprintf("Unknown flag bits set: %08X\n",
151                          ip->flags & ~IPT_F_MASK);
152                 return false;
153         }
154         if (ip->invflags & ~IPT_INV_MASK) {
155                 duprintf("Unknown invflag bits set: %08X\n",
156                          ip->invflags & ~IPT_INV_MASK);
157                 return false;
158         }
159         return true;
160 }
161
162 static unsigned int
163 ipt_error(struct sk_buff *skb, const struct xt_action_param *par)
164 {
165         if (net_ratelimit())
166                 pr_info("error: `%s'\n", (const char *)par->targinfo);
167
168         return NF_DROP;
169 }
170
171 /* Performance critical */
172 static inline struct ipt_entry *
173 get_entry(const void *base, unsigned int offset)
174 {
175         return (struct ipt_entry *)(base + offset);
176 }
177
178 /* All zeroes == unconditional rule. */
179 /* Mildly perf critical (only if packet tracing is on) */
180 static inline bool unconditional(const struct ipt_ip *ip)
181 {
182         static const struct ipt_ip uncond;
183
184         return memcmp(ip, &uncond, sizeof(uncond)) == 0;
185 #undef FWINV
186 }
187
188 /* for const-correctness */
189 static inline const struct xt_entry_target *
190 ipt_get_target_c(const struct ipt_entry *e)
191 {
192         return ipt_get_target((struct ipt_entry *)e);
193 }
194
195 #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
196     defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
197 static const char *const hooknames[] = {
198         [NF_INET_PRE_ROUTING]           = "PREROUTING",
199         [NF_INET_LOCAL_IN]              = "INPUT",
200         [NF_INET_FORWARD]               = "FORWARD",
201         [NF_INET_LOCAL_OUT]             = "OUTPUT",
202         [NF_INET_POST_ROUTING]          = "POSTROUTING",
203 };
204
205 enum nf_ip_trace_comments {
206         NF_IP_TRACE_COMMENT_RULE,
207         NF_IP_TRACE_COMMENT_RETURN,
208         NF_IP_TRACE_COMMENT_POLICY,
209 };
210
211 static const char *const comments[] = {
212         [NF_IP_TRACE_COMMENT_RULE]      = "rule",
213         [NF_IP_TRACE_COMMENT_RETURN]    = "return",
214         [NF_IP_TRACE_COMMENT_POLICY]    = "policy",
215 };
216
217 static struct nf_loginfo trace_loginfo = {
218         .type = NF_LOG_TYPE_LOG,
219         .u = {
220                 .log = {
221                         .level = 4,
222                         .logflags = NF_LOG_MASK,
223                 },
224         },
225 };
226
227 /* Mildly perf critical (only if packet tracing is on) */
228 static inline int
229 get_chainname_rulenum(const struct ipt_entry *s, const struct ipt_entry *e,
230                       const char *hookname, const char **chainname,
231                       const char **comment, unsigned int *rulenum)
232 {
233         const struct xt_standard_target *t = (void *)ipt_get_target_c(s);
234
235         if (strcmp(t->target.u.kernel.target->name, XT_ERROR_TARGET) == 0) {
236                 /* Head of user chain: ERROR target with chainname */
237                 *chainname = t->target.data;
238                 (*rulenum) = 0;
239         } else if (s == e) {
240                 (*rulenum)++;
241
242                 if (s->target_offset == sizeof(struct ipt_entry) &&
243                     strcmp(t->target.u.kernel.target->name,
244                            XT_STANDARD_TARGET) == 0 &&
245                    t->verdict < 0 &&
246                    unconditional(&s->ip)) {
247                         /* Tail of chains: STANDARD target (return/policy) */
248                         *comment = *chainname == hookname
249                                 ? comments[NF_IP_TRACE_COMMENT_POLICY]
250                                 : comments[NF_IP_TRACE_COMMENT_RETURN];
251                 }
252                 return 1;
253         } else
254                 (*rulenum)++;
255
256         return 0;
257 }
258
259 static void trace_packet(const struct sk_buff *skb,
260                          unsigned int hook,
261                          const struct net_device *in,
262                          const struct net_device *out,
263                          const char *tablename,
264                          const struct xt_table_info *private,
265                          const struct ipt_entry *e)
266 {
267         const void *table_base;
268         const struct ipt_entry *root;
269         const char *hookname, *chainname, *comment;
270         const struct ipt_entry *iter;
271         unsigned int rulenum = 0;
272
273         table_base = private->entries[smp_processor_id()];
274         root = get_entry(table_base, private->hook_entry[hook]);
275
276         hookname = chainname = hooknames[hook];
277         comment = comments[NF_IP_TRACE_COMMENT_RULE];
278
279         xt_entry_foreach(iter, root, private->size - private->hook_entry[hook])
280                 if (get_chainname_rulenum(iter, e, hookname,
281                     &chainname, &comment, &rulenum) != 0)
282                         break;
283
284         nf_log_packet(AF_INET, hook, skb, in, out, &trace_loginfo,
285                       "TRACE: %s:%s:%s:%u ",
286                       tablename, chainname, comment, rulenum);
287 }
288 #endif
289
290 static inline __pure
291 struct ipt_entry *ipt_next_entry(const struct ipt_entry *entry)
292 {
293         return (void *)entry + entry->next_offset;
294 }
295
296 /* Returns one of the generic firewall policies, like NF_ACCEPT. */
297 unsigned int
298 ipt_do_table(struct sk_buff *skb,
299              unsigned int hook,
300              const struct net_device *in,
301              const struct net_device *out,
302              struct xt_table *table)
303 {
304         static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
305         const struct iphdr *ip;
306         /* Initializing verdict to NF_DROP keeps gcc happy. */
307         unsigned int verdict = NF_DROP;
308         const char *indev, *outdev;
309         const void *table_base;
310         struct ipt_entry *e, **jumpstack;
311         unsigned int *stackptr, origptr, cpu;
312         const struct xt_table_info *private;
313         struct xt_action_param acpar;
314
315         /* Initialization */
316         ip = ip_hdr(skb);
317         indev = in ? in->name : nulldevname;
318         outdev = out ? out->name : nulldevname;
319         /* We handle fragments by dealing with the first fragment as
320          * if it was a normal packet.  All other fragments are treated
321          * normally, except that they will NEVER match rules that ask
322          * things we don't know, ie. tcp syn flag or ports).  If the
323          * rule is also a fragment-specific rule, non-fragments won't
324          * match it. */
325         acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
326         acpar.thoff   = ip_hdrlen(skb);
327         acpar.hotdrop = false;
328         acpar.in      = in;
329         acpar.out     = out;
330         acpar.family  = NFPROTO_IPV4;
331         acpar.hooknum = hook;
332
333         IP_NF_ASSERT(table->valid_hooks & (1 << hook));
334         xt_info_rdlock_bh();
335         private = table->private;
336         cpu        = smp_processor_id();
337         table_base = private->entries[cpu];
338         jumpstack  = (struct ipt_entry **)private->jumpstack[cpu];
339         stackptr   = per_cpu_ptr(private->stackptr, cpu);
340         origptr    = *stackptr;
341
342         e = get_entry(table_base, private->hook_entry[hook]);
343
344         pr_debug("Entering %s(hook %u); sp at %u (UF %p)\n",
345                  table->name, hook, origptr,
346                  get_entry(table_base, private->underflow[hook]));
347
348         do {
349                 const struct xt_entry_target *t;
350                 const struct xt_entry_match *ematch;
351
352                 IP_NF_ASSERT(e);
353                 if (!ip_packet_match(ip, indev, outdev,
354                     &e->ip, acpar.fragoff)) {
355  no_match:
356                         e = ipt_next_entry(e);
357                         continue;
358                 }
359
360                 xt_ematch_foreach(ematch, e) {
361                         acpar.match     = ematch->u.kernel.match;
362                         acpar.matchinfo = ematch->data;
363                         if (!acpar.match->match(skb, &acpar))
364                                 goto no_match;
365                 }
366
367                 ADD_COUNTER(e->counters, skb->len, 1);
368
369                 t = ipt_get_target(e);
370                 IP_NF_ASSERT(t->u.kernel.target);
371
372 #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
373     defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
374                 /* The packet is traced: log it */
375                 if (unlikely(skb->nf_trace))
376                         trace_packet(skb, hook, in, out,
377                                      table->name, private, e);
378 #endif
379                 /* Standard target? */
380                 if (!t->u.kernel.target->target) {
381                         int v;
382
383                         v = ((struct xt_standard_target *)t)->verdict;
384                         if (v < 0) {
385                                 /* Pop from stack? */
386                                 if (v != XT_RETURN) {
387                                         verdict = (unsigned)(-v) - 1;
388                                         break;
389                                 }
390                                 if (*stackptr == 0) {
391                                         e = get_entry(table_base,
392                                             private->underflow[hook]);
393                                         pr_debug("Underflow (this is normal) "
394                                                  "to %p\n", e);
395                                 } else {
396                                         e = jumpstack[--*stackptr];
397                                         pr_debug("Pulled %p out from pos %u\n",
398                                                  e, *stackptr);
399                                         e = ipt_next_entry(e);
400                                 }
401                                 continue;
402                         }
403                         if (table_base + v != ipt_next_entry(e) &&
404                             !(e->ip.flags & IPT_F_GOTO)) {
405                                 if (*stackptr >= private->stacksize) {
406                                         verdict = NF_DROP;
407                                         break;
408                                 }
409                                 jumpstack[(*stackptr)++] = e;
410                                 pr_debug("Pushed %p into pos %u\n",
411                                          e, *stackptr - 1);
412                         }
413
414                         e = get_entry(table_base, v);
415                         continue;
416                 }
417
418                 acpar.target   = t->u.kernel.target;
419                 acpar.targinfo = t->data;
420
421                 verdict = t->u.kernel.target->target(skb, &acpar);
422                 /* Target might have changed stuff. */
423                 ip = ip_hdr(skb);
424                 if (verdict == XT_CONTINUE)
425                         e = ipt_next_entry(e);
426                 else
427                         /* Verdict */
428                         break;
429         } while (!acpar.hotdrop);
430         xt_info_rdunlock_bh();
431         pr_debug("Exiting %s; resetting sp from %u to %u\n",
432                  __func__, *stackptr, origptr);
433         *stackptr = origptr;
434 #ifdef DEBUG_ALLOW_ALL
435         return NF_ACCEPT;
436 #else
437         if (acpar.hotdrop)
438                 return NF_DROP;
439         else return verdict;
440 #endif
441 }
442
443 /* Figures out from what hook each rule can be called: returns 0 if
444    there are loops.  Puts hook bitmask in comefrom. */
445 static int
446 mark_source_chains(const struct xt_table_info *newinfo,
447                    unsigned int valid_hooks, void *entry0)
448 {
449         unsigned int hook;
450
451         /* No recursion; use packet counter to save back ptrs (reset
452            to 0 as we leave), and comefrom to save source hook bitmask */
453         for (hook = 0; hook < NF_INET_NUMHOOKS; hook++) {
454                 unsigned int pos = newinfo->hook_entry[hook];
455                 struct ipt_entry *e = (struct ipt_entry *)(entry0 + pos);
456
457                 if (!(valid_hooks & (1 << hook)))
458                         continue;
459
460                 /* Set initial back pointer. */
461                 e->counters.pcnt = pos;
462
463                 for (;;) {
464                         const struct xt_standard_target *t
465                                 = (void *)ipt_get_target_c(e);
466                         int visited = e->comefrom & (1 << hook);
467
468                         if (e->comefrom & (1 << NF_INET_NUMHOOKS)) {
469                                 pr_err("iptables: loop hook %u pos %u %08X.\n",
470                                        hook, pos, e->comefrom);
471                                 return 0;
472                         }
473                         e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS));
474
475                         /* Unconditional return/END. */
476                         if ((e->target_offset == sizeof(struct ipt_entry) &&
477                              (strcmp(t->target.u.user.name,
478                                      XT_STANDARD_TARGET) == 0) &&
479                              t->verdict < 0 && unconditional(&e->ip)) ||
480                             visited) {
481                                 unsigned int oldpos, size;
482
483                                 if ((strcmp(t->target.u.user.name,
484                                             XT_STANDARD_TARGET) == 0) &&
485                                     t->verdict < -NF_MAX_VERDICT - 1) {
486                                         duprintf("mark_source_chains: bad "
487                                                 "negative verdict (%i)\n",
488                                                                 t->verdict);
489                                         return 0;
490                                 }
491
492                                 /* Return: backtrack through the last
493                                    big jump. */
494                                 do {
495                                         e->comefrom ^= (1<<NF_INET_NUMHOOKS);
496 #ifdef DEBUG_IP_FIREWALL_USER
497                                         if (e->comefrom
498                                             & (1 << NF_INET_NUMHOOKS)) {
499                                                 duprintf("Back unset "
500                                                          "on hook %u "
501                                                          "rule %u\n",
502                                                          hook, pos);
503                                         }
504 #endif
505                                         oldpos = pos;
506                                         pos = e->counters.pcnt;
507                                         e->counters.pcnt = 0;
508
509                                         /* We're at the start. */
510                                         if (pos == oldpos)
511                                                 goto next;
512
513                                         e = (struct ipt_entry *)
514                                                 (entry0 + pos);
515                                 } while (oldpos == pos + e->next_offset);
516
517                                 /* Move along one */
518                                 size = e->next_offset;
519                                 e = (struct ipt_entry *)
520                                         (entry0 + pos + size);
521                                 e->counters.pcnt = pos;
522                                 pos += size;
523                         } else {
524                                 int newpos = t->verdict;
525
526                                 if (strcmp(t->target.u.user.name,
527                                            XT_STANDARD_TARGET) == 0 &&
528                                     newpos >= 0) {
529                                         if (newpos > newinfo->size -
530                                                 sizeof(struct ipt_entry)) {
531                                                 duprintf("mark_source_chains: "
532                                                         "bad verdict (%i)\n",
533                                                                 newpos);
534                                                 return 0;
535                                         }
536                                         /* This a jump; chase it. */
537                                         duprintf("Jump rule %u -> %u\n",
538                                                  pos, newpos);
539                                 } else {
540                                         /* ... this is a fallthru */
541                                         newpos = pos + e->next_offset;
542                                 }
543                                 e = (struct ipt_entry *)
544                                         (entry0 + newpos);
545                                 e->counters.pcnt = pos;
546                                 pos = newpos;
547                         }
548                 }
549                 next:
550                 duprintf("Finished chain %u\n", hook);
551         }
552         return 1;
553 }
554
555 static void cleanup_match(struct xt_entry_match *m, struct net *net)
556 {
557         struct xt_mtdtor_param par;
558
559         par.net       = net;
560         par.match     = m->u.kernel.match;
561         par.matchinfo = m->data;
562         par.family    = NFPROTO_IPV4;
563         if (par.match->destroy != NULL)
564                 par.match->destroy(&par);
565         module_put(par.match->me);
566 }
567
568 static int
569 check_entry(const struct ipt_entry *e, const char *name)
570 {
571         const struct xt_entry_target *t;
572
573         if (!ip_checkentry(&e->ip)) {
574                 duprintf("ip check failed %p %s.\n", e, par->match->name);
575                 return -EINVAL;
576         }
577
578         if (e->target_offset + sizeof(struct xt_entry_target) >
579             e->next_offset)
580                 return -EINVAL;
581
582         t = ipt_get_target_c(e);
583         if (e->target_offset + t->u.target_size > e->next_offset)
584                 return -EINVAL;
585
586         return 0;
587 }
588
589 static int
590 check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
591 {
592         const struct ipt_ip *ip = par->entryinfo;
593         int ret;
594
595         par->match     = m->u.kernel.match;
596         par->matchinfo = m->data;
597
598         ret = xt_check_match(par, m->u.match_size - sizeof(*m),
599               ip->proto, ip->invflags & IPT_INV_PROTO);
600         if (ret < 0) {
601                 duprintf("check failed for `%s'.\n", par->match->name);
602                 return ret;
603         }
604         return 0;
605 }
606
607 static int
608 find_check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
609 {
610         struct xt_match *match;
611         int ret;
612
613         match = xt_request_find_match(NFPROTO_IPV4, m->u.user.name,
614                                       m->u.user.revision);
615         if (IS_ERR(match)) {
616                 duprintf("find_check_match: `%s' not found\n", m->u.user.name);
617                 return PTR_ERR(match);
618         }
619         m->u.kernel.match = match;
620
621         ret = check_match(m, par);
622         if (ret)
623                 goto err;
624
625         return 0;
626 err:
627         module_put(m->u.kernel.match->me);
628         return ret;
629 }
630
631 static int check_target(struct ipt_entry *e, struct net *net, const char *name)
632 {
633         struct xt_entry_target *t = ipt_get_target(e);
634         struct xt_tgchk_param par = {
635                 .net       = net,
636                 .table     = name,
637                 .entryinfo = e,
638                 .target    = t->u.kernel.target,
639                 .targinfo  = t->data,
640                 .hook_mask = e->comefrom,
641                 .family    = NFPROTO_IPV4,
642         };
643         int ret;
644
645         ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
646               e->ip.proto, e->ip.invflags & IPT_INV_PROTO);
647         if (ret < 0) {
648                 duprintf("check failed for `%s'.\n",
649                          t->u.kernel.target->name);
650                 return ret;
651         }
652         return 0;
653 }
654
655 static int
656 find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
657                  unsigned int size)
658 {
659         struct xt_entry_target *t;
660         struct xt_target *target;
661         int ret;
662         unsigned int j;
663         struct xt_mtchk_param mtpar;
664         struct xt_entry_match *ematch;
665
666         ret = check_entry(e, name);
667         if (ret)
668                 return ret;
669
670         j = 0;
671         mtpar.net       = net;
672         mtpar.table     = name;
673         mtpar.entryinfo = &e->ip;
674         mtpar.hook_mask = e->comefrom;
675         mtpar.family    = NFPROTO_IPV4;
676         xt_ematch_foreach(ematch, e) {
677                 ret = find_check_match(ematch, &mtpar);
678                 if (ret != 0)
679                         goto cleanup_matches;
680                 ++j;
681         }
682
683         t = ipt_get_target(e);
684         target = xt_request_find_target(NFPROTO_IPV4, t->u.user.name,
685                                         t->u.user.revision);
686         if (IS_ERR(target)) {
687                 duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
688                 ret = PTR_ERR(target);
689                 goto cleanup_matches;
690         }
691         t->u.kernel.target = target;
692
693         ret = check_target(e, net, name);
694         if (ret)
695                 goto err;
696         return 0;
697  err:
698         module_put(t->u.kernel.target->me);
699  cleanup_matches:
700         xt_ematch_foreach(ematch, e) {
701                 if (j-- == 0)
702                         break;
703                 cleanup_match(ematch, net);
704         }
705         return ret;
706 }
707
708 static bool check_underflow(const struct ipt_entry *e)
709 {
710         const struct xt_entry_target *t;
711         unsigned int verdict;
712
713         if (!unconditional(&e->ip))
714                 return false;
715         t = ipt_get_target_c(e);
716         if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
717                 return false;
718         verdict = ((struct xt_standard_target *)t)->verdict;
719         verdict = -verdict - 1;
720         return verdict == NF_DROP || verdict == NF_ACCEPT;
721 }
722
723 static int
724 check_entry_size_and_hooks(struct ipt_entry *e,
725                            struct xt_table_info *newinfo,
726                            const unsigned char *base,
727                            const unsigned char *limit,
728                            const unsigned int *hook_entries,
729                            const unsigned int *underflows,
730                            unsigned int valid_hooks)
731 {
732         unsigned int h;
733
734         if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 ||
735             (unsigned char *)e + sizeof(struct ipt_entry) >= limit) {
736                 duprintf("Bad offset %p\n", e);
737                 return -EINVAL;
738         }
739
740         if (e->next_offset
741             < sizeof(struct ipt_entry) + sizeof(struct xt_entry_target)) {
742                 duprintf("checking: element %p size %u\n",
743                          e, e->next_offset);
744                 return -EINVAL;
745         }
746
747         /* Check hooks & underflows */
748         for (h = 0; h < NF_INET_NUMHOOKS; h++) {
749                 if (!(valid_hooks & (1 << h)))
750                         continue;
751                 if ((unsigned char *)e - base == hook_entries[h])
752                         newinfo->hook_entry[h] = hook_entries[h];
753                 if ((unsigned char *)e - base == underflows[h]) {
754                         if (!check_underflow(e)) {
755                                 pr_err("Underflows must be unconditional and "
756                                        "use the STANDARD target with "
757                                        "ACCEPT/DROP\n");
758                                 return -EINVAL;
759                         }
760                         newinfo->underflow[h] = underflows[h];
761                 }
762         }
763
764         /* Clear counters and comefrom */
765         e->counters = ((struct xt_counters) { 0, 0 });
766         e->comefrom = 0;
767         return 0;
768 }
769
770 static void
771 cleanup_entry(struct ipt_entry *e, struct net *net)
772 {
773         struct xt_tgdtor_param par;
774         struct xt_entry_target *t;
775         struct xt_entry_match *ematch;
776
777         /* Cleanup all matches */
778         xt_ematch_foreach(ematch, e)
779                 cleanup_match(ematch, net);
780         t = ipt_get_target(e);
781
782         par.net      = net;
783         par.target   = t->u.kernel.target;
784         par.targinfo = t->data;
785         par.family   = NFPROTO_IPV4;
786         if (par.target->destroy != NULL)
787                 par.target->destroy(&par);
788         module_put(par.target->me);
789 }
790
791 /* Checks and translates the user-supplied table segment (held in
792    newinfo) */
793 static int
794 translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
795                 const struct ipt_replace *repl)
796 {
797         struct ipt_entry *iter;
798         unsigned int i;
799         int ret = 0;
800
801         newinfo->size = repl->size;
802         newinfo->number = repl->num_entries;
803
804         /* Init all hooks to impossible value. */
805         for (i = 0; i < NF_INET_NUMHOOKS; i++) {
806                 newinfo->hook_entry[i] = 0xFFFFFFFF;
807                 newinfo->underflow[i] = 0xFFFFFFFF;
808         }
809
810         duprintf("translate_table: size %u\n", newinfo->size);
811         i = 0;
812         /* Walk through entries, checking offsets. */
813         xt_entry_foreach(iter, entry0, newinfo->size) {
814                 ret = check_entry_size_and_hooks(iter, newinfo, entry0,
815                                                  entry0 + repl->size,
816                                                  repl->hook_entry,
817                                                  repl->underflow,
818                                                  repl->valid_hooks);
819                 if (ret != 0)
820                         return ret;
821                 ++i;
822                 if (strcmp(ipt_get_target(iter)->u.user.name,
823                     XT_ERROR_TARGET) == 0)
824                         ++newinfo->stacksize;
825         }
826
827         if (i != repl->num_entries) {
828                 duprintf("translate_table: %u not %u entries\n",
829                          i, repl->num_entries);
830                 return -EINVAL;
831         }
832
833         /* Check hooks all assigned */
834         for (i = 0; i < NF_INET_NUMHOOKS; i++) {
835                 /* Only hooks which are valid */
836                 if (!(repl->valid_hooks & (1 << i)))
837                         continue;
838                 if (newinfo->hook_entry[i] == 0xFFFFFFFF) {
839                         duprintf("Invalid hook entry %u %u\n",
840                                  i, repl->hook_entry[i]);
841                         return -EINVAL;
842                 }
843                 if (newinfo->underflow[i] == 0xFFFFFFFF) {
844                         duprintf("Invalid underflow %u %u\n",
845                                  i, repl->underflow[i]);
846                         return -EINVAL;
847                 }
848         }
849
850         if (!mark_source_chains(newinfo, repl->valid_hooks, entry0))
851                 return -ELOOP;
852
853         /* Finally, each sanity check must pass */
854         i = 0;
855         xt_entry_foreach(iter, entry0, newinfo->size) {
856                 ret = find_check_entry(iter, net, repl->name, repl->size);
857                 if (ret != 0)
858                         break;
859                 ++i;
860         }
861
862         if (ret != 0) {
863                 xt_entry_foreach(iter, entry0, newinfo->size) {
864                         if (i-- == 0)
865                                 break;
866                         cleanup_entry(iter, net);
867                 }
868                 return ret;
869         }
870
871         /* And one copy for every other CPU */
872         for_each_possible_cpu(i) {
873                 if (newinfo->entries[i] && newinfo->entries[i] != entry0)
874                         memcpy(newinfo->entries[i], entry0, newinfo->size);
875         }
876
877         return ret;
878 }
879
880 static void
881 get_counters(const struct xt_table_info *t,
882              struct xt_counters counters[])
883 {
884         struct ipt_entry *iter;
885         unsigned int cpu;
886         unsigned int i;
887         unsigned int curcpu = get_cpu();
888
889         /* Instead of clearing (by a previous call to memset())
890          * the counters and using adds, we set the counters
891          * with data used by 'current' CPU.
892          *
893          * Bottom half has to be disabled to prevent deadlock
894          * if new softirq were to run and call ipt_do_table
895          */
896         local_bh_disable();
897         i = 0;
898         xt_entry_foreach(iter, t->entries[curcpu], t->size) {
899                 SET_COUNTER(counters[i], iter->counters.bcnt,
900                             iter->counters.pcnt);
901                 ++i;
902         }
903         local_bh_enable();
904         /* Processing counters from other cpus, we can let bottom half enabled,
905          * (preemption is disabled)
906          */
907
908         for_each_possible_cpu(cpu) {
909                 if (cpu == curcpu)
910                         continue;
911                 i = 0;
912                 local_bh_disable();
913                 xt_info_wrlock(cpu);
914                 xt_entry_foreach(iter, t->entries[cpu], t->size) {
915                         ADD_COUNTER(counters[i], iter->counters.bcnt,
916                                     iter->counters.pcnt);
917                         ++i; /* macro does multi eval of i */
918                 }
919                 xt_info_wrunlock(cpu);
920                 local_bh_enable();
921         }
922         put_cpu();
923 }
924
925 static struct xt_counters *alloc_counters(const struct xt_table *table)
926 {
927         unsigned int countersize;
928         struct xt_counters *counters;
929         const struct xt_table_info *private = table->private;
930
931         /* We need atomic snapshot of counters: rest doesn't change
932            (other than comefrom, which userspace doesn't care
933            about). */
934         countersize = sizeof(struct xt_counters) * private->number;
935         counters = vmalloc(countersize);
936
937         if (counters == NULL)
938                 return ERR_PTR(-ENOMEM);
939
940         get_counters(private, counters);
941
942         return counters;
943 }
944
945 static int
946 copy_entries_to_user(unsigned int total_size,
947                      const struct xt_table *table,
948                      void __user *userptr)
949 {
950         unsigned int off, num;
951         const struct ipt_entry *e;
952         struct xt_counters *counters;
953         const struct xt_table_info *private = table->private;
954         int ret = 0;
955         const void *loc_cpu_entry;
956
957         counters = alloc_counters(table);
958         if (IS_ERR(counters))
959                 return PTR_ERR(counters);
960
961         /* choose the copy that is on our node/cpu, ...
962          * This choice is lazy (because current thread is
963          * allowed to migrate to another cpu)
964          */
965         loc_cpu_entry = private->entries[raw_smp_processor_id()];
966         if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
967                 ret = -EFAULT;
968                 goto free_counters;
969         }
970
971         /* FIXME: use iterator macros --RR */
972         /* ... then go back and fix counters and names */
973         for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){
974                 unsigned int i;
975                 const struct xt_entry_match *m;
976                 const struct xt_entry_target *t;
977
978                 e = (struct ipt_entry *)(loc_cpu_entry + off);
979                 if (copy_to_user(userptr + off
980                                  + offsetof(struct ipt_entry, counters),
981                                  &counters[num],
982                                  sizeof(counters[num])) != 0) {
983                         ret = -EFAULT;
984                         goto free_counters;
985                 }
986
987                 for (i = sizeof(struct ipt_entry);
988                      i < e->target_offset;
989                      i += m->u.match_size) {
990                         m = (void *)e + i;
991
992                         if (copy_to_user(userptr + off + i
993                                          + offsetof(struct xt_entry_match,
994                                                     u.user.name),
995                                          m->u.kernel.match->name,
996                                          strlen(m->u.kernel.match->name)+1)
997                             != 0) {
998                                 ret = -EFAULT;
999                                 goto free_counters;
1000                         }
1001                 }
1002
1003                 t = ipt_get_target_c(e);
1004                 if (copy_to_user(userptr + off + e->target_offset
1005                                  + offsetof(struct xt_entry_target,
1006                                             u.user.name),
1007                                  t->u.kernel.target->name,
1008                                  strlen(t->u.kernel.target->name)+1) != 0) {
1009                         ret = -EFAULT;
1010                         goto free_counters;
1011                 }
1012         }
1013
1014  free_counters:
1015         vfree(counters);
1016         return ret;
1017 }
1018
1019 #ifdef CONFIG_COMPAT
1020 static void compat_standard_from_user(void *dst, const void *src)
1021 {
1022         int v = *(compat_int_t *)src;
1023
1024         if (v > 0)
1025                 v += xt_compat_calc_jump(AF_INET, v);
1026         memcpy(dst, &v, sizeof(v));
1027 }
1028
1029 static int compat_standard_to_user(void __user *dst, const void *src)
1030 {
1031         compat_int_t cv = *(int *)src;
1032
1033         if (cv > 0)
1034                 cv -= xt_compat_calc_jump(AF_INET, cv);
1035         return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0;
1036 }
1037
1038 static int compat_calc_entry(const struct ipt_entry *e,
1039                              const struct xt_table_info *info,
1040                              const void *base, struct xt_table_info *newinfo)
1041 {
1042         const struct xt_entry_match *ematch;
1043         const struct xt_entry_target *t;
1044         unsigned int entry_offset;
1045         int off, i, ret;
1046
1047         off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
1048         entry_offset = (void *)e - base;
1049         xt_ematch_foreach(ematch, e)
1050                 off += xt_compat_match_offset(ematch->u.kernel.match);
1051         t = ipt_get_target_c(e);
1052         off += xt_compat_target_offset(t->u.kernel.target);
1053         newinfo->size -= off;
1054         ret = xt_compat_add_offset(AF_INET, entry_offset, off);
1055         if (ret)
1056                 return ret;
1057
1058         for (i = 0; i < NF_INET_NUMHOOKS; i++) {
1059                 if (info->hook_entry[i] &&
1060                     (e < (struct ipt_entry *)(base + info->hook_entry[i])))
1061                         newinfo->hook_entry[i] -= off;
1062                 if (info->underflow[i] &&
1063                     (e < (struct ipt_entry *)(base + info->underflow[i])))
1064                         newinfo->underflow[i] -= off;
1065         }
1066         return 0;
1067 }
1068
1069 static int compat_table_info(const struct xt_table_info *info,
1070                              struct xt_table_info *newinfo)
1071 {
1072         struct ipt_entry *iter;
1073         void *loc_cpu_entry;
1074         int ret;
1075
1076         if (!newinfo || !info)
1077                 return -EINVAL;
1078
1079         /* we dont care about newinfo->entries[] */
1080         memcpy(newinfo, info, offsetof(struct xt_table_info, entries));
1081         newinfo->initial_entries = 0;
1082         loc_cpu_entry = info->entries[raw_smp_processor_id()];
1083         xt_compat_init_offsets(AF_INET, info->number);
1084         xt_entry_foreach(iter, loc_cpu_entry, info->size) {
1085                 ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo);
1086                 if (ret != 0)
1087                         return ret;
1088         }
1089         return 0;
1090 }
1091 #endif
1092
1093 static int get_info(struct net *net, void __user *user,
1094                     const int *len, int compat)
1095 {
1096         char name[XT_TABLE_MAXNAMELEN];
1097         struct xt_table *t;
1098         int ret;
1099
1100         if (*len != sizeof(struct ipt_getinfo)) {
1101                 duprintf("length %u != %zu\n", *len,
1102                          sizeof(struct ipt_getinfo));
1103                 return -EINVAL;
1104         }
1105
1106         if (copy_from_user(name, user, sizeof(name)) != 0)
1107                 return -EFAULT;
1108
1109         name[XT_TABLE_MAXNAMELEN-1] = '\0';
1110 #ifdef CONFIG_COMPAT
1111         if (compat)
1112                 xt_compat_lock(AF_INET);
1113 #endif
1114         t = try_then_request_module(xt_find_table_lock(net, AF_INET, name),
1115                                     "iptable_%s", name);
1116         if (t && !IS_ERR(t)) {
1117                 struct ipt_getinfo info;
1118                 const struct xt_table_info *private = t->private;
1119 #ifdef CONFIG_COMPAT
1120                 struct xt_table_info tmp;
1121
1122                 if (compat) {
1123                         ret = compat_table_info(private, &tmp);
1124                         xt_compat_flush_offsets(AF_INET);
1125                         private = &tmp;
1126                 }
1127 #endif
1128                 memset(&info, 0, sizeof(info));
1129                 info.valid_hooks = t->valid_hooks;
1130                 memcpy(info.hook_entry, private->hook_entry,
1131                        sizeof(info.hook_entry));
1132                 memcpy(info.underflow, private->underflow,
1133                        sizeof(info.underflow));
1134                 info.num_entries = private->number;
1135                 info.size = private->size;
1136                 strcpy(info.name, name);
1137
1138                 if (copy_to_user(user, &info, *len) != 0)
1139                         ret = -EFAULT;
1140                 else
1141                         ret = 0;
1142
1143                 xt_table_unlock(t);
1144                 module_put(t->me);
1145         } else
1146                 ret = t ? PTR_ERR(t) : -ENOENT;
1147 #ifdef CONFIG_COMPAT
1148         if (compat)
1149                 xt_compat_unlock(AF_INET);
1150 #endif
1151         return ret;
1152 }
1153
1154 static int
1155 get_entries(struct net *net, struct ipt_get_entries __user *uptr,
1156             const int *len)
1157 {
1158         int ret;
1159         struct ipt_get_entries get;
1160         struct xt_table *t;
1161
1162         if (*len < sizeof(get)) {
1163                 duprintf("get_entries: %u < %zu\n", *len, sizeof(get));
1164                 return -EINVAL;
1165         }
1166         if (copy_from_user(&get, uptr, sizeof(get)) != 0)
1167                 return -EFAULT;
1168         if (*len != sizeof(struct ipt_get_entries) + get.size) {
1169                 duprintf("get_entries: %u != %zu\n",
1170                          *len, sizeof(get) + get.size);
1171                 return -EINVAL;
1172         }
1173
1174         t = xt_find_table_lock(net, AF_INET, get.name);
1175         if (t && !IS_ERR(t)) {
1176                 const struct xt_table_info *private = t->private;
1177                 duprintf("t->private->number = %u\n", private->number);
1178                 if (get.size == private->size)
1179                         ret = copy_entries_to_user(private->size,
1180                                                    t, uptr->entrytable);
1181                 else {
1182                         duprintf("get_entries: I've got %u not %u!\n",
1183                                  private->size, get.size);
1184                         ret = -EAGAIN;
1185                 }
1186                 module_put(t->me);
1187                 xt_table_unlock(t);
1188         } else
1189                 ret = t ? PTR_ERR(t) : -ENOENT;
1190
1191         return ret;
1192 }
1193
1194 static int
1195 __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
1196              struct xt_table_info *newinfo, unsigned int num_counters,
1197              void __user *counters_ptr)
1198 {
1199         int ret;
1200         struct xt_table *t;
1201         struct xt_table_info *oldinfo;
1202         struct xt_counters *counters;
1203         void *loc_cpu_old_entry;
1204         struct ipt_entry *iter;
1205
1206         ret = 0;
1207         counters = vmalloc(num_counters * sizeof(struct xt_counters));
1208         if (!counters) {
1209                 ret = -ENOMEM;
1210                 goto out;
1211         }
1212
1213         t = try_then_request_module(xt_find_table_lock(net, AF_INET, name),
1214                                     "iptable_%s", name);
1215         if (!t || IS_ERR(t)) {
1216                 ret = t ? PTR_ERR(t) : -ENOENT;
1217                 goto free_newinfo_counters_untrans;
1218         }
1219
1220         /* You lied! */
1221         if (valid_hooks != t->valid_hooks) {
1222                 duprintf("Valid hook crap: %08X vs %08X\n",
1223                          valid_hooks, t->valid_hooks);
1224                 ret = -EINVAL;
1225                 goto put_module;
1226         }
1227
1228         oldinfo = xt_replace_table(t, num_counters, newinfo, &ret);
1229         if (!oldinfo)
1230                 goto put_module;
1231
1232         /* Update module usage count based on number of rules */
1233         duprintf("do_replace: oldnum=%u, initnum=%u, newnum=%u\n",
1234                 oldinfo->number, oldinfo->initial_entries, newinfo->number);
1235         if ((oldinfo->number > oldinfo->initial_entries) ||
1236             (newinfo->number <= oldinfo->initial_entries))
1237                 module_put(t->me);
1238         if ((oldinfo->number > oldinfo->initial_entries) &&
1239             (newinfo->number <= oldinfo->initial_entries))
1240                 module_put(t->me);
1241
1242         /* Get the old counters, and synchronize with replace */
1243         get_counters(oldinfo, counters);
1244
1245         /* Decrease module usage counts and free resource */
1246         loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
1247         xt_entry_foreach(iter, loc_cpu_old_entry, oldinfo->size)
1248                 cleanup_entry(iter, net);
1249
1250         xt_free_table_info(oldinfo);
1251         if (copy_to_user(counters_ptr, counters,
1252                          sizeof(struct xt_counters) * num_counters) != 0)
1253                 ret = -EFAULT;
1254         vfree(counters);
1255         xt_table_unlock(t);
1256         return ret;
1257
1258  put_module:
1259         module_put(t->me);
1260         xt_table_unlock(t);
1261  free_newinfo_counters_untrans:
1262         vfree(counters);
1263  out:
1264         return ret;
1265 }
1266
1267 static int
1268 do_replace(struct net *net, const void __user *user, unsigned int len)
1269 {
1270         int ret;
1271         struct ipt_replace tmp;
1272         struct xt_table_info *newinfo;
1273         void *loc_cpu_entry;
1274         struct ipt_entry *iter;
1275
1276         if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
1277                 return -EFAULT;
1278
1279         /* overflow check */
1280         if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
1281                 return -ENOMEM;
1282
1283         newinfo = xt_alloc_table_info(tmp.size);
1284         if (!newinfo)
1285                 return -ENOMEM;
1286
1287         /* choose the copy that is on our node/cpu */
1288         loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
1289         if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
1290                            tmp.size) != 0) {
1291                 ret = -EFAULT;
1292                 goto free_newinfo;
1293         }
1294
1295         ret = translate_table(net, newinfo, loc_cpu_entry, &tmp);
1296         if (ret != 0)
1297                 goto free_newinfo;
1298
1299         duprintf("Translated table\n");
1300
1301         ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
1302                            tmp.num_counters, tmp.counters);
1303         if (ret)
1304                 goto free_newinfo_untrans;
1305         return 0;
1306
1307  free_newinfo_untrans:
1308         xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
1309                 cleanup_entry(iter, net);
1310  free_newinfo:
1311         xt_free_table_info(newinfo);
1312         return ret;
1313 }
1314
1315 static int
1316 do_add_counters(struct net *net, const void __user *user,
1317                 unsigned int len, int compat)
1318 {
1319         unsigned int i, curcpu;
1320         struct xt_counters_info tmp;
1321         struct xt_counters *paddc;
1322         unsigned int num_counters;
1323         const char *name;
1324         int size;
1325         void *ptmp;
1326         struct xt_table *t;
1327         const struct xt_table_info *private;
1328         int ret = 0;
1329         void *loc_cpu_entry;
1330         struct ipt_entry *iter;
1331 #ifdef CONFIG_COMPAT
1332         struct compat_xt_counters_info compat_tmp;
1333
1334         if (compat) {
1335                 ptmp = &compat_tmp;
1336                 size = sizeof(struct compat_xt_counters_info);
1337         } else
1338 #endif
1339         {
1340                 ptmp = &tmp;
1341                 size = sizeof(struct xt_counters_info);
1342         }
1343
1344         if (copy_from_user(ptmp, user, size) != 0)
1345                 return -EFAULT;
1346
1347 #ifdef CONFIG_COMPAT
1348         if (compat) {
1349                 num_counters = compat_tmp.num_counters;
1350                 name = compat_tmp.name;
1351         } else
1352 #endif
1353         {
1354                 num_counters = tmp.num_counters;
1355                 name = tmp.name;
1356         }
1357
1358         if (len != size + num_counters * sizeof(struct xt_counters))
1359                 return -EINVAL;
1360
1361         paddc = vmalloc(len - size);
1362         if (!paddc)
1363                 return -ENOMEM;
1364
1365         if (copy_from_user(paddc, user + size, len - size) != 0) {
1366                 ret = -EFAULT;
1367                 goto free;
1368         }
1369
1370         t = xt_find_table_lock(net, AF_INET, name);
1371         if (!t || IS_ERR(t)) {
1372                 ret = t ? PTR_ERR(t) : -ENOENT;
1373                 goto free;
1374         }
1375
1376         local_bh_disable();
1377         private = t->private;
1378         if (private->number != num_counters) {
1379                 ret = -EINVAL;
1380                 goto unlock_up_free;
1381         }
1382
1383         i = 0;
1384         /* Choose the copy that is on our node */
1385         curcpu = smp_processor_id();
1386         loc_cpu_entry = private->entries[curcpu];
1387         xt_info_wrlock(curcpu);
1388         xt_entry_foreach(iter, loc_cpu_entry, private->size) {
1389                 ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt);
1390                 ++i;
1391         }
1392         xt_info_wrunlock(curcpu);
1393  unlock_up_free:
1394         local_bh_enable();
1395         xt_table_unlock(t);
1396         module_put(t->me);
1397  free:
1398         vfree(paddc);
1399
1400         return ret;
1401 }
1402
1403 #ifdef CONFIG_COMPAT
1404 struct compat_ipt_replace {
1405         char                    name[XT_TABLE_MAXNAMELEN];
1406         u32                     valid_hooks;
1407         u32                     num_entries;
1408         u32                     size;
1409         u32                     hook_entry[NF_INET_NUMHOOKS];
1410         u32                     underflow[NF_INET_NUMHOOKS];
1411         u32                     num_counters;
1412         compat_uptr_t           counters;       /* struct xt_counters * */
1413         struct compat_ipt_entry entries[0];
1414 };
1415
1416 static int
1417 compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
1418                           unsigned int *size, struct xt_counters *counters,
1419                           unsigned int i)
1420 {
1421         struct xt_entry_target *t;
1422         struct compat_ipt_entry __user *ce;
1423         u_int16_t target_offset, next_offset;
1424         compat_uint_t origsize;
1425         const struct xt_entry_match *ematch;
1426         int ret = 0;
1427
1428         origsize = *size;
1429         ce = (struct compat_ipt_entry __user *)*dstptr;
1430         if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 ||
1431             copy_to_user(&ce->counters, &counters[i],
1432             sizeof(counters[i])) != 0)
1433                 return -EFAULT;
1434
1435         *dstptr += sizeof(struct compat_ipt_entry);
1436         *size -= sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
1437
1438         xt_ematch_foreach(ematch, e) {
1439                 ret = xt_compat_match_to_user(ematch, dstptr, size);
1440                 if (ret != 0)
1441                         return ret;
1442         }
1443         target_offset = e->target_offset - (origsize - *size);
1444         t = ipt_get_target(e);
1445         ret = xt_compat_target_to_user(t, dstptr, size);
1446         if (ret)
1447                 return ret;
1448         next_offset = e->next_offset - (origsize - *size);
1449         if (put_user(target_offset, &ce->target_offset) != 0 ||
1450             put_user(next_offset, &ce->next_offset) != 0)
1451                 return -EFAULT;
1452         return 0;
1453 }
1454
1455 static int
1456 compat_find_calc_match(struct xt_entry_match *m,
1457                        const char *name,
1458                        const struct ipt_ip *ip,
1459                        unsigned int hookmask,
1460                        int *size)
1461 {
1462         struct xt_match *match;
1463
1464         match = xt_request_find_match(NFPROTO_IPV4, m->u.user.name,
1465                                       m->u.user.revision);
1466         if (IS_ERR(match)) {
1467                 duprintf("compat_check_calc_match: `%s' not found\n",
1468                          m->u.user.name);
1469                 return PTR_ERR(match);
1470         }
1471         m->u.kernel.match = match;
1472         *size += xt_compat_match_offset(match);
1473         return 0;
1474 }
1475
1476 static void compat_release_entry(struct compat_ipt_entry *e)
1477 {
1478         struct xt_entry_target *t;
1479         struct xt_entry_match *ematch;
1480
1481         /* Cleanup all matches */
1482         xt_ematch_foreach(ematch, e)
1483                 module_put(ematch->u.kernel.match->me);
1484         t = compat_ipt_get_target(e);
1485         module_put(t->u.kernel.target->me);
1486 }
1487
1488 static int
1489 check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
1490                                   struct xt_table_info *newinfo,
1491                                   unsigned int *size,
1492                                   const unsigned char *base,
1493                                   const unsigned char *limit,
1494                                   const unsigned int *hook_entries,
1495                                   const unsigned int *underflows,
1496                                   const char *name)
1497 {
1498         struct xt_entry_match *ematch;
1499         struct xt_entry_target *t;
1500         struct xt_target *target;
1501         unsigned int entry_offset;
1502         unsigned int j;
1503         int ret, off, h;
1504
1505         duprintf("check_compat_entry_size_and_hooks %p\n", e);
1506         if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 ||
1507             (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit) {
1508                 duprintf("Bad offset %p, limit = %p\n", e, limit);
1509                 return -EINVAL;
1510         }
1511
1512         if (e->next_offset < sizeof(struct compat_ipt_entry) +
1513                              sizeof(struct compat_xt_entry_target)) {
1514                 duprintf("checking: element %p size %u\n",
1515                          e, e->next_offset);
1516                 return -EINVAL;
1517         }
1518
1519         /* For purposes of check_entry casting the compat entry is fine */
1520         ret = check_entry((struct ipt_entry *)e, name);
1521         if (ret)
1522                 return ret;
1523
1524         off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
1525         entry_offset = (void *)e - (void *)base;
1526         j = 0;
1527         xt_ematch_foreach(ematch, e) {
1528                 ret = compat_find_calc_match(ematch, name,
1529                                              &e->ip, e->comefrom, &off);
1530                 if (ret != 0)
1531                         goto release_matches;
1532                 ++j;
1533         }
1534
1535         t = compat_ipt_get_target(e);
1536         target = xt_request_find_target(NFPROTO_IPV4, t->u.user.name,
1537                                         t->u.user.revision);
1538         if (IS_ERR(target)) {
1539                 duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
1540                          t->u.user.name);
1541                 ret = PTR_ERR(target);
1542                 goto release_matches;
1543         }
1544         t->u.kernel.target = target;
1545
1546         off += xt_compat_target_offset(target);
1547         *size += off;
1548         ret = xt_compat_add_offset(AF_INET, entry_offset, off);
1549         if (ret)
1550                 goto out;
1551
1552         /* Check hooks & underflows */
1553         for (h = 0; h < NF_INET_NUMHOOKS; h++) {
1554                 if ((unsigned char *)e - base == hook_entries[h])
1555                         newinfo->hook_entry[h] = hook_entries[h];
1556                 if ((unsigned char *)e - base == underflows[h])
1557                         newinfo->underflow[h] = underflows[h];
1558         }
1559
1560         /* Clear counters and comefrom */
1561         memset(&e->counters, 0, sizeof(e->counters));
1562         e->comefrom = 0;
1563         return 0;
1564
1565 out:
1566         module_put(t->u.kernel.target->me);
1567 release_matches:
1568         xt_ematch_foreach(ematch, e) {
1569                 if (j-- == 0)
1570                         break;
1571                 module_put(ematch->u.kernel.match->me);
1572         }
1573         return ret;
1574 }
1575
1576 static int
1577 compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
1578                             unsigned int *size, const char *name,
1579                             struct xt_table_info *newinfo, unsigned char *base)
1580 {
1581         struct xt_entry_target *t;
1582         struct xt_target *target;
1583         struct ipt_entry *de;
1584         unsigned int origsize;
1585         int ret, h;
1586         struct xt_entry_match *ematch;
1587
1588         ret = 0;
1589         origsize = *size;
1590         de = (struct ipt_entry *)*dstptr;
1591         memcpy(de, e, sizeof(struct ipt_entry));
1592         memcpy(&de->counters, &e->counters, sizeof(e->counters));
1593
1594         *dstptr += sizeof(struct ipt_entry);
1595         *size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
1596
1597         xt_ematch_foreach(ematch, e) {
1598                 ret = xt_compat_match_from_user(ematch, dstptr, size);
1599                 if (ret != 0)
1600                         return ret;
1601         }
1602         de->target_offset = e->target_offset - (origsize - *size);
1603         t = compat_ipt_get_target(e);
1604         target = t->u.kernel.target;
1605         xt_compat_target_from_user(t, dstptr, size);
1606
1607         de->next_offset = e->next_offset - (origsize - *size);
1608         for (h = 0; h < NF_INET_NUMHOOKS; h++) {
1609                 if ((unsigned char *)de - base < newinfo->hook_entry[h])
1610                         newinfo->hook_entry[h] -= origsize - *size;
1611                 if ((unsigned char *)de - base < newinfo->underflow[h])
1612                         newinfo->underflow[h] -= origsize - *size;
1613         }
1614         return ret;
1615 }
1616
1617 static int
1618 compat_check_entry(struct ipt_entry *e, struct net *net, const char *name)
1619 {
1620         struct xt_entry_match *ematch;
1621         struct xt_mtchk_param mtpar;
1622         unsigned int j;
1623         int ret = 0;
1624
1625         j = 0;
1626         mtpar.net       = net;
1627         mtpar.table     = name;
1628         mtpar.entryinfo = &e->ip;
1629         mtpar.hook_mask = e->comefrom;
1630         mtpar.family    = NFPROTO_IPV4;
1631         xt_ematch_foreach(ematch, e) {
1632                 ret = check_match(ematch, &mtpar);
1633                 if (ret != 0)
1634                         goto cleanup_matches;
1635                 ++j;
1636         }
1637
1638         ret = check_target(e, net, name);
1639         if (ret)
1640                 goto cleanup_matches;
1641         return 0;
1642
1643  cleanup_matches:
1644         xt_ematch_foreach(ematch, e) {
1645                 if (j-- == 0)
1646                         break;
1647                 cleanup_match(ematch, net);
1648         }
1649         return ret;
1650 }
1651
1652 static int
1653 translate_compat_table(struct net *net,
1654                        const char *name,
1655                        unsigned int valid_hooks,
1656                        struct xt_table_info **pinfo,
1657                        void **pentry0,
1658                        unsigned int total_size,
1659                        unsigned int number,
1660                        unsigned int *hook_entries,
1661                        unsigned int *underflows)
1662 {
1663         unsigned int i, j;
1664         struct xt_table_info *newinfo, *info;
1665         void *pos, *entry0, *entry1;
1666         struct compat_ipt_entry *iter0;
1667         struct ipt_entry *iter1;
1668         unsigned int size;
1669         int ret;
1670
1671         info = *pinfo;
1672         entry0 = *pentry0;
1673         size = total_size;
1674         info->number = number;
1675
1676         /* Init all hooks to impossible value. */
1677         for (i = 0; i < NF_INET_NUMHOOKS; i++) {
1678                 info->hook_entry[i] = 0xFFFFFFFF;
1679                 info->underflow[i] = 0xFFFFFFFF;
1680         }
1681
1682         duprintf("translate_compat_table: size %u\n", info->size);
1683         j = 0;
1684         xt_compat_lock(AF_INET);
1685         xt_compat_init_offsets(AF_INET, number);
1686         /* Walk through entries, checking offsets. */
1687         xt_entry_foreach(iter0, entry0, total_size) {
1688                 ret = check_compat_entry_size_and_hooks(iter0, info, &size,
1689                                                         entry0,
1690                                                         entry0 + total_size,
1691                                                         hook_entries,
1692                                                         underflows,
1693                                                         name);
1694                 if (ret != 0)
1695                         goto out_unlock;
1696                 ++j;
1697         }
1698
1699         ret = -EINVAL;
1700         if (j != number) {
1701                 duprintf("translate_compat_table: %u not %u entries\n",
1702                          j, number);
1703                 goto out_unlock;
1704         }
1705
1706         /* Check hooks all assigned */
1707         for (i = 0; i < NF_INET_NUMHOOKS; i++) {
1708                 /* Only hooks which are valid */
1709                 if (!(valid_hooks & (1 << i)))
1710                         continue;
1711                 if (info->hook_entry[i] == 0xFFFFFFFF) {
1712                         duprintf("Invalid hook entry %u %u\n",
1713                                  i, hook_entries[i]);
1714                         goto out_unlock;
1715                 }
1716                 if (info->underflow[i] == 0xFFFFFFFF) {
1717                         duprintf("Invalid underflow %u %u\n",
1718                                  i, underflows[i]);
1719                         goto out_unlock;
1720                 }
1721         }
1722
1723         ret = -ENOMEM;
1724         newinfo = xt_alloc_table_info(size);
1725         if (!newinfo)
1726                 goto out_unlock;
1727
1728         newinfo->number = number;
1729         for (i = 0; i < NF_INET_NUMHOOKS; i++) {
1730                 newinfo->hook_entry[i] = info->hook_entry[i];
1731                 newinfo->underflow[i] = info->underflow[i];
1732         }
1733         entry1 = newinfo->entries[raw_smp_processor_id()];
1734         pos = entry1;
1735         size = total_size;
1736         xt_entry_foreach(iter0, entry0, total_size) {
1737                 ret = compat_copy_entry_from_user(iter0, &pos, &size,
1738                                                   name, newinfo, entry1);
1739                 if (ret != 0)
1740                         break;
1741         }
1742         xt_compat_flush_offsets(AF_INET);
1743         xt_compat_unlock(AF_INET);
1744         if (ret)
1745                 goto free_newinfo;
1746
1747         ret = -ELOOP;
1748         if (!mark_source_chains(newinfo, valid_hooks, entry1))
1749                 goto free_newinfo;
1750
1751         i = 0;
1752         xt_entry_foreach(iter1, entry1, newinfo->size) {
1753                 ret = compat_check_entry(iter1, net, name);
1754                 if (ret != 0)
1755                         break;
1756                 ++i;
1757                 if (strcmp(ipt_get_target(iter1)->u.user.name,
1758                     XT_ERROR_TARGET) == 0)
1759                         ++newinfo->stacksize;
1760         }
1761         if (ret) {
1762                 /*
1763                  * The first i matches need cleanup_entry (calls ->destroy)
1764                  * because they had called ->check already. The other j-i
1765                  * entries need only release.
1766                  */
1767                 int skip = i;
1768                 j -= i;
1769                 xt_entry_foreach(iter0, entry0, newinfo->size) {
1770                         if (skip-- > 0)
1771                                 continue;
1772                         if (j-- == 0)
1773                                 break;
1774                         compat_release_entry(iter0);
1775                 }
1776                 xt_entry_foreach(iter1, entry1, newinfo->size) {
1777                         if (i-- == 0)
1778                                 break;
1779                         cleanup_entry(iter1, net);
1780                 }
1781                 xt_free_table_info(newinfo);
1782                 return ret;
1783         }
1784
1785         /* And one copy for every other CPU */
1786         for_each_possible_cpu(i)
1787                 if (newinfo->entries[i] && newinfo->entries[i] != entry1)
1788                         memcpy(newinfo->entries[i], entry1, newinfo->size);
1789
1790         *pinfo = newinfo;
1791         *pentry0 = entry1;
1792         xt_free_table_info(info);
1793         return 0;
1794
1795 free_newinfo:
1796         xt_free_table_info(newinfo);
1797 out:
1798         xt_entry_foreach(iter0, entry0, total_size) {
1799                 if (j-- == 0)
1800                         break;
1801                 compat_release_entry(iter0);
1802         }
1803         return ret;
1804 out_unlock:
1805         xt_compat_flush_offsets(AF_INET);
1806         xt_compat_unlock(AF_INET);
1807         goto out;
1808 }
1809
1810 static int
1811 compat_do_replace(struct net *net, void __user *user, unsigned int len)
1812 {
1813         int ret;
1814         struct compat_ipt_replace tmp;
1815         struct xt_table_info *newinfo;
1816         void *loc_cpu_entry;
1817         struct ipt_entry *iter;
1818
1819         if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
1820                 return -EFAULT;
1821
1822         /* overflow check */
1823         if (tmp.size >= INT_MAX / num_possible_cpus())
1824                 return -ENOMEM;
1825         if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
1826                 return -ENOMEM;
1827
1828         newinfo = xt_alloc_table_info(tmp.size);
1829         if (!newinfo)
1830                 return -ENOMEM;
1831
1832         /* choose the copy that is on our node/cpu */
1833         loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
1834         if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
1835                            tmp.size) != 0) {
1836                 ret = -EFAULT;
1837                 goto free_newinfo;
1838         }
1839
1840         ret = translate_compat_table(net, tmp.name, tmp.valid_hooks,
1841                                      &newinfo, &loc_cpu_entry, tmp.size,
1842                                      tmp.num_entries, tmp.hook_entry,
1843                                      tmp.underflow);
1844         if (ret != 0)
1845                 goto free_newinfo;
1846
1847         duprintf("compat_do_replace: Translated table\n");
1848
1849         ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
1850                            tmp.num_counters, compat_ptr(tmp.counters));
1851         if (ret)
1852                 goto free_newinfo_untrans;
1853         return 0;
1854
1855  free_newinfo_untrans:
1856         xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
1857                 cleanup_entry(iter, net);
1858  free_newinfo:
1859         xt_free_table_info(newinfo);
1860         return ret;
1861 }
1862
1863 static int
1864 compat_do_ipt_set_ctl(struct sock *sk,  int cmd, void __user *user,
1865                       unsigned int len)
1866 {
1867         int ret;
1868
1869         if (!capable(CAP_NET_ADMIN))
1870                 return -EPERM;
1871
1872         switch (cmd) {
1873         case IPT_SO_SET_REPLACE:
1874                 ret = compat_do_replace(sock_net(sk), user, len);
1875                 break;
1876
1877         case IPT_SO_SET_ADD_COUNTERS:
1878                 ret = do_add_counters(sock_net(sk), user, len, 1);
1879                 break;
1880
1881         default:
1882                 duprintf("do_ipt_set_ctl:  unknown request %i\n", cmd);
1883                 ret = -EINVAL;
1884         }
1885
1886         return ret;
1887 }
1888
1889 struct compat_ipt_get_entries {
1890         char name[XT_TABLE_MAXNAMELEN];
1891         compat_uint_t size;
1892         struct compat_ipt_entry entrytable[0];
1893 };
1894
1895 static int
1896 compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table,
1897                             void __user *userptr)
1898 {
1899         struct xt_counters *counters;
1900         const struct xt_table_info *private = table->private;
1901         void __user *pos;
1902         unsigned int size;
1903         int ret = 0;
1904         const void *loc_cpu_entry;
1905         unsigned int i = 0;
1906         struct ipt_entry *iter;
1907
1908         counters = alloc_counters(table);
1909         if (IS_ERR(counters))
1910                 return PTR_ERR(counters);
1911
1912         /* choose the copy that is on our node/cpu, ...
1913          * This choice is lazy (because current thread is
1914          * allowed to migrate to another cpu)
1915          */
1916         loc_cpu_entry = private->entries[raw_smp_processor_id()];
1917         pos = userptr;
1918         size = total_size;
1919         xt_entry_foreach(iter, loc_cpu_entry, total_size) {
1920                 ret = compat_copy_entry_to_user(iter, &pos,
1921                                                 &size, counters, i++);
1922                 if (ret != 0)
1923                         break;
1924         }
1925
1926         vfree(counters);
1927         return ret;
1928 }
1929
1930 static int
1931 compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr,
1932                    int *len)
1933 {
1934         int ret;
1935         struct compat_ipt_get_entries get;
1936         struct xt_table *t;
1937
1938         if (*len < sizeof(get)) {
1939                 duprintf("compat_get_entries: %u < %zu\n", *len, sizeof(get));
1940                 return -EINVAL;
1941         }
1942
1943         if (copy_from_user(&get, uptr, sizeof(get)) != 0)
1944                 return -EFAULT;
1945
1946         if (*len != sizeof(struct compat_ipt_get_entries) + get.size) {
1947                 duprintf("compat_get_entries: %u != %zu\n",
1948                          *len, sizeof(get) + get.size);
1949                 return -EINVAL;
1950         }
1951
1952         xt_compat_lock(AF_INET);
1953         t = xt_find_table_lock(net, AF_INET, get.name);
1954         if (t && !IS_ERR(t)) {
1955                 const struct xt_table_info *private = t->private;
1956                 struct xt_table_info info;
1957                 duprintf("t->private->number = %u\n", private->number);
1958                 ret = compat_table_info(private, &info);
1959                 if (!ret && get.size == info.size) {
1960                         ret = compat_copy_entries_to_user(private->size,
1961                                                           t, uptr->entrytable);
1962                 } else if (!ret) {
1963                         duprintf("compat_get_entries: I've got %u not %u!\n",
1964                                  private->size, get.size);
1965                         ret = -EAGAIN;
1966                 }
1967                 xt_compat_flush_offsets(AF_INET);
1968                 module_put(t->me);
1969                 xt_table_unlock(t);
1970         } else
1971                 ret = t ? PTR_ERR(t) : -ENOENT;
1972
1973         xt_compat_unlock(AF_INET);
1974         return ret;
1975 }
1976
1977 static int do_ipt_get_ctl(struct sock *, int, void __user *, int *);
1978
1979 static int
1980 compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
1981 {
1982         int ret;
1983
1984         if (!capable(CAP_NET_ADMIN))
1985                 return -EPERM;
1986
1987         switch (cmd) {
1988         case IPT_SO_GET_INFO:
1989                 ret = get_info(sock_net(sk), user, len, 1);
1990                 break;
1991         case IPT_SO_GET_ENTRIES:
1992                 ret = compat_get_entries(sock_net(sk), user, len);
1993                 break;
1994         default:
1995                 ret = do_ipt_get_ctl(sk, cmd, user, len);
1996         }
1997         return ret;
1998 }
1999 #endif
2000
2001 static int
2002 do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
2003 {
2004         int ret;
2005
2006         if (!capable(CAP_NET_ADMIN))
2007                 return -EPERM;
2008
2009         switch (cmd) {
2010         case IPT_SO_SET_REPLACE:
2011                 ret = do_replace(sock_net(sk), user, len);
2012                 break;
2013
2014         case IPT_SO_SET_ADD_COUNTERS:
2015                 ret = do_add_counters(sock_net(sk), user, len, 0);
2016                 break;
2017
2018         default:
2019                 duprintf("do_ipt_set_ctl:  unknown request %i\n", cmd);
2020                 ret = -EINVAL;
2021         }
2022
2023         return ret;
2024 }
2025
2026 static int
2027 do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
2028 {
2029         int ret;
2030
2031         if (!capable(CAP_NET_ADMIN))
2032                 return -EPERM;
2033
2034         switch (cmd) {
2035         case IPT_SO_GET_INFO:
2036                 ret = get_info(sock_net(sk), user, len, 0);
2037                 break;
2038
2039         case IPT_SO_GET_ENTRIES:
2040                 ret = get_entries(sock_net(sk), user, len);
2041                 break;
2042
2043         case IPT_SO_GET_REVISION_MATCH:
2044         case IPT_SO_GET_REVISION_TARGET: {
2045                 struct xt_get_revision rev;
2046                 int target;
2047
2048                 if (*len != sizeof(rev)) {
2049                         ret = -EINVAL;
2050                         break;
2051                 }
2052                 if (copy_from_user(&rev, user, sizeof(rev)) != 0) {
2053                         ret = -EFAULT;
2054                         break;
2055                 }
2056
2057                 if (cmd == IPT_SO_GET_REVISION_TARGET)
2058                         target = 1;
2059                 else
2060                         target = 0;
2061
2062                 try_then_request_module(xt_find_revision(AF_INET, rev.name,
2063                                                          rev.revision,
2064                                                          target, &ret),
2065                                         "ipt_%s", rev.name);
2066                 break;
2067         }
2068
2069         default:
2070                 duprintf("do_ipt_get_ctl: unknown request %i\n", cmd);
2071                 ret = -EINVAL;
2072         }
2073
2074         return ret;
2075 }
2076
2077 struct xt_table *ipt_register_table(struct net *net,
2078                                     const struct xt_table *table,
2079                                     const struct ipt_replace *repl)
2080 {
2081         int ret;
2082         struct xt_table_info *newinfo;
2083         struct xt_table_info bootstrap = {0};
2084         void *loc_cpu_entry;
2085         struct xt_table *new_table;
2086
2087         newinfo = xt_alloc_table_info(repl->size);
2088         if (!newinfo) {
2089                 ret = -ENOMEM;
2090                 goto out;
2091         }
2092
2093         /* choose the copy on our node/cpu, but dont care about preemption */
2094         loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
2095         memcpy(loc_cpu_entry, repl->entries, repl->size);
2096
2097         ret = translate_table(net, newinfo, loc_cpu_entry, repl);
2098         if (ret != 0)
2099                 goto out_free;
2100
2101         new_table = xt_register_table(net, table, &bootstrap, newinfo);
2102         if (IS_ERR(new_table)) {
2103                 ret = PTR_ERR(new_table);
2104                 goto out_free;
2105         }
2106
2107         return new_table;
2108
2109 out_free:
2110         xt_free_table_info(newinfo);
2111 out:
2112         return ERR_PTR(ret);
2113 }
2114
2115 void ipt_unregister_table(struct net *net, struct xt_table *table)
2116 {
2117         struct xt_table_info *private;
2118         void *loc_cpu_entry;
2119         struct module *table_owner = table->me;
2120         struct ipt_entry *iter;
2121
2122         private = xt_unregister_table(table);
2123
2124         /* Decrease module usage counts and free resources */
2125         loc_cpu_entry = private->entries[raw_smp_processor_id()];
2126         xt_entry_foreach(iter, loc_cpu_entry, private->size)
2127                 cleanup_entry(iter, net);
2128         if (private->number > private->initial_entries)
2129                 module_put(table_owner);
2130         xt_free_table_info(private);
2131 }
2132
2133 /* Returns 1 if the type and code is matched by the range, 0 otherwise */
2134 static inline bool
2135 icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
2136                      u_int8_t type, u_int8_t code,
2137                      bool invert)
2138 {
2139         return ((test_type == 0xFF) ||
2140                 (type == test_type && code >= min_code && code <= max_code))
2141                 ^ invert;
2142 }
2143
2144 static bool
2145 icmp_match(const struct sk_buff *skb, struct xt_action_param *par)
2146 {
2147         const struct icmphdr *ic;
2148         struct icmphdr _icmph;
2149         const struct ipt_icmp *icmpinfo = par->matchinfo;
2150
2151         /* Must not be a fragment. */
2152         if (par->fragoff != 0)
2153                 return false;
2154
2155         ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph);
2156         if (ic == NULL) {
2157                 /* We've been asked to examine this packet, and we
2158                  * can't.  Hence, no choice but to drop.
2159                  */
2160                 duprintf("Dropping evil ICMP tinygram.\n");
2161                 par->hotdrop = true;
2162                 return false;
2163         }
2164
2165         return icmp_type_code_match(icmpinfo->type,
2166                                     icmpinfo->code[0],
2167                                     icmpinfo->code[1],
2168                                     ic->type, ic->code,
2169                                     !!(icmpinfo->invflags&IPT_ICMP_INV));
2170 }
2171
2172 static int icmp_checkentry(const struct xt_mtchk_param *par)
2173 {
2174         const struct ipt_icmp *icmpinfo = par->matchinfo;
2175
2176         /* Must specify no unknown invflags */
2177         return (icmpinfo->invflags & ~IPT_ICMP_INV) ? -EINVAL : 0;
2178 }
2179
2180 static struct xt_target ipt_builtin_tg[] __read_mostly = {
2181         {
2182                 .name             = XT_STANDARD_TARGET,
2183                 .targetsize       = sizeof(int),
2184                 .family           = NFPROTO_IPV4,
2185 #ifdef CONFIG_COMPAT
2186                 .compatsize       = sizeof(compat_int_t),
2187                 .compat_from_user = compat_standard_from_user,
2188                 .compat_to_user   = compat_standard_to_user,
2189 #endif
2190         },
2191         {
2192                 .name             = XT_ERROR_TARGET,
2193                 .target           = ipt_error,
2194                 .targetsize       = XT_FUNCTION_MAXNAMELEN,
2195                 .family           = NFPROTO_IPV4,
2196         },
2197 };
2198
2199 static struct nf_sockopt_ops ipt_sockopts = {
2200         .pf             = PF_INET,
2201         .set_optmin     = IPT_BASE_CTL,
2202         .set_optmax     = IPT_SO_SET_MAX+1,
2203         .set            = do_ipt_set_ctl,
2204 #ifdef CONFIG_COMPAT
2205         .compat_set     = compat_do_ipt_set_ctl,
2206 #endif
2207         .get_optmin     = IPT_BASE_CTL,
2208         .get_optmax     = IPT_SO_GET_MAX+1,
2209         .get            = do_ipt_get_ctl,
2210 #ifdef CONFIG_COMPAT
2211         .compat_get     = compat_do_ipt_get_ctl,
2212 #endif
2213         .owner          = THIS_MODULE,
2214 };
2215
2216 static struct xt_match ipt_builtin_mt[] __read_mostly = {
2217         {
2218                 .name       = "icmp",
2219                 .match      = icmp_match,
2220                 .matchsize  = sizeof(struct ipt_icmp),
2221                 .checkentry = icmp_checkentry,
2222                 .proto      = IPPROTO_ICMP,
2223                 .family     = NFPROTO_IPV4,
2224         },
2225 };
2226
2227 static int __net_init ip_tables_net_init(struct net *net)
2228 {
2229         return xt_proto_init(net, NFPROTO_IPV4);
2230 }
2231
2232 static void __net_exit ip_tables_net_exit(struct net *net)
2233 {
2234         xt_proto_fini(net, NFPROTO_IPV4);
2235 }
2236
2237 static struct pernet_operations ip_tables_net_ops = {
2238         .init = ip_tables_net_init,
2239         .exit = ip_tables_net_exit,
2240 };
2241
2242 static int __init ip_tables_init(void)
2243 {
2244         int ret;
2245
2246         ret = register_pernet_subsys(&ip_tables_net_ops);
2247         if (ret < 0)
2248                 goto err1;
2249
2250         /* Noone else will be downing sem now, so we won't sleep */
2251         ret = xt_register_targets(ipt_builtin_tg, ARRAY_SIZE(ipt_builtin_tg));
2252         if (ret < 0)
2253                 goto err2;
2254         ret = xt_register_matches(ipt_builtin_mt, ARRAY_SIZE(ipt_builtin_mt));
2255         if (ret < 0)
2256                 goto err4;
2257
2258         /* Register setsockopt */
2259         ret = nf_register_sockopt(&ipt_sockopts);
2260         if (ret < 0)
2261                 goto err5;
2262
2263         pr_info("(C) 2000-2006 Netfilter Core Team\n");
2264         return 0;
2265
2266 err5:
2267         xt_unregister_matches(ipt_builtin_mt, ARRAY_SIZE(ipt_builtin_mt));
2268 err4:
2269         xt_unregister_targets(ipt_builtin_tg, ARRAY_SIZE(ipt_builtin_tg));
2270 err2:
2271         unregister_pernet_subsys(&ip_tables_net_ops);
2272 err1:
2273         return ret;
2274 }
2275
2276 static void __exit ip_tables_fini(void)
2277 {
2278         nf_unregister_sockopt(&ipt_sockopts);
2279
2280         xt_unregister_matches(ipt_builtin_mt, ARRAY_SIZE(ipt_builtin_mt));
2281         xt_unregister_targets(ipt_builtin_tg, ARRAY_SIZE(ipt_builtin_tg));
2282         unregister_pernet_subsys(&ip_tables_net_ops);
2283 }
2284
2285 EXPORT_SYMBOL(ipt_register_table);
2286 EXPORT_SYMBOL(ipt_unregister_table);
2287 EXPORT_SYMBOL(ipt_do_table);
2288 module_init(ip_tables_init);
2289 module_exit(ip_tables_fini);