1 /* Code to take an ip6tables-style command line and do it. */
4 * Author: Paul.Russell@rustcorp.com.au and mneuling@radlogic.com.au
6 * (C) 2000-2002 by the netfilter coreteam <coreteam@netfilter.org>:
7 * Paul 'Rusty' Russell <rusty@rustcorp.com.au>
8 * Marc Boucher <marc+nf@mbsi.ca>
9 * James Morris <jmorris@intercode.com.au>
10 * Harald Welte <laforge@gnumonks.org>
11 * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
38 #include <ip6tables.h>
40 #include <arpa/inet.h>
43 #include <sys/types.h>
44 #include <sys/socket.h>
45 #include "ip6tables-multi.h"
48 static const char unsupported_rev
[] = " [unsupported revision]";
50 static struct option original_opts
[] = {
51 {.name
= "append", .has_arg
= 1, .val
= 'A'},
52 {.name
= "delete", .has_arg
= 1, .val
= 'D'},
53 {.name
= "check" , .has_arg
= 1, .val
= 'C'},
54 {.name
= "insert", .has_arg
= 1, .val
= 'I'},
55 {.name
= "replace", .has_arg
= 1, .val
= 'R'},
56 {.name
= "list", .has_arg
= 2, .val
= 'L'},
57 {.name
= "list-rules", .has_arg
= 2, .val
= 'S'},
58 {.name
= "flush", .has_arg
= 2, .val
= 'F'},
59 {.name
= "zero", .has_arg
= 2, .val
= 'Z'},
60 {.name
= "new-chain", .has_arg
= 1, .val
= 'N'},
61 {.name
= "delete-chain", .has_arg
= 2, .val
= 'X'},
62 {.name
= "rename-chain", .has_arg
= 1, .val
= 'E'},
63 {.name
= "policy", .has_arg
= 1, .val
= 'P'},
64 {.name
= "source", .has_arg
= 1, .val
= 's'},
65 {.name
= "destination", .has_arg
= 1, .val
= 'd'},
66 {.name
= "src", .has_arg
= 1, .val
= 's'}, /* synonym */
67 {.name
= "dst", .has_arg
= 1, .val
= 'd'}, /* synonym */
68 {.name
= "protocol", .has_arg
= 1, .val
= 'p'},
69 {.name
= "in-interface", .has_arg
= 1, .val
= 'i'},
70 {.name
= "jump", .has_arg
= 1, .val
= 'j'},
71 {.name
= "table", .has_arg
= 1, .val
= 't'},
72 {.name
= "match", .has_arg
= 1, .val
= 'm'},
73 {.name
= "numeric", .has_arg
= 0, .val
= 'n'},
74 {.name
= "out-interface", .has_arg
= 1, .val
= 'o'},
75 {.name
= "verbose", .has_arg
= 0, .val
= 'v'},
76 {.name
= "wait", .has_arg
= 2, .val
= 'w'},
77 {.name
= "wait-interval", .has_arg
= 2, .val
= 'W'},
78 {.name
= "exact", .has_arg
= 0, .val
= 'x'},
79 {.name
= "version", .has_arg
= 0, .val
= 'V'},
80 {.name
= "help", .has_arg
= 2, .val
= 'h'},
81 {.name
= "line-numbers", .has_arg
= 0, .val
= '0'},
82 {.name
= "modprobe", .has_arg
= 1, .val
= 'M'},
83 {.name
= "set-counters", .has_arg
= 1, .val
= 'c'},
84 {.name
= "goto", .has_arg
= 1, .val
= 'g'},
85 {.name
= "ipv4", .has_arg
= 0, .val
= '4'},
86 {.name
= "ipv6", .has_arg
= 0, .val
= '6'},
90 struct xtables_globals ip6tables_globals
= {
92 .program_version
= PACKAGE_VERSION
" (legacy)",
93 .orig_opts
= original_opts
,
94 .compat_rev
= xtables_compatible_revision
,
98 * All functions starting with "parse" should succeed, otherwise
100 * Most routines return pointers to static data that may change
101 * between calls to the same or other routines with a few exceptions:
102 * "host_to_addr", "parse_hostnetwork", and "parse_hostnetworkmask"
103 * return global static data.
107 print_match(const struct xt_entry_match
*m
,
108 const struct ip6t_ip6
*ip
,
111 const char *name
= m
->u
.user
.name
;
112 const int revision
= m
->u
.user
.revision
;
113 struct xtables_match
*match
, *mt
;
115 match
= xtables_find_match(name
, XTF_TRY_LOAD
, NULL
);
117 mt
= xtables_find_match_revision(name
, XTF_TRY_LOAD
,
120 mt
->print(ip
, m
, numeric
);
121 else if (match
->print
)
122 printf("%s%s ", match
->name
, unsupported_rev
);
124 printf("%s ", match
->name
);
126 if (match
->next
== match
)
130 printf("UNKNOWN match `%s' ", name
);
132 /* Don't stop iterating. */
136 /* e is called `fw' here for historical reasons */
138 print_firewall(const struct ip6t_entry
*fw
,
139 const char *targname
,
142 struct xtc_handle
*const handle
)
144 struct xtables_target
*target
, *tg
;
145 const struct xt_entry_target
*t
;
147 if (!ip6tc_is_chain(targname
, handle
))
148 target
= xtables_find_target(targname
, XTF_TRY_LOAD
);
150 target
= xtables_find_target(XT_STANDARD_TARGET
,
151 XTF_LOAD_MUST_SUCCEED
);
153 t
= ip6t_get_target((struct ip6t_entry
*)fw
);
155 print_rule_details(num
, &fw
->counters
, targname
, fw
->ipv6
.proto
,
156 fw
->ipv6
.flags
, fw
->ipv6
.invflags
, format
);
158 print_fragment(fw
->ipv6
.flags
, fw
->ipv6
.invflags
, format
, true);
160 print_ifaces(fw
->ipv6
.iniface
, fw
->ipv6
.outiface
,
161 fw
->ipv6
.invflags
, format
);
163 print_ipv6_addresses(fw
, format
);
165 if (format
& FMT_NOTABLE
)
169 if(fw
->ipv6
.flags
& IP6T_F_GOTO
)
173 IP6T_MATCH_ITERATE(fw
, print_match
, &fw
->ipv6
, format
& FMT_NUMERIC
);
176 const int revision
= t
->u
.user
.revision
;
178 tg
= xtables_find_target_revision(targname
, XTF_TRY_LOAD
,
181 /* Print the target information. */
182 tg
->print(&fw
->ipv6
, t
, format
& FMT_NUMERIC
);
183 else if (target
->print
)
184 printf(" %s%s", target
->name
, unsupported_rev
);
186 if (target
->next
== target
)
188 } else if (t
->u
.target_size
!= sizeof(*t
))
189 printf("[%u bytes of unknown target data] ",
190 (unsigned int)(t
->u
.target_size
- sizeof(*t
)));
192 if (!(format
& FMT_NONEWLINE
))
197 print_firewall_line(const struct ip6t_entry
*fw
,
198 struct xtc_handle
*const h
)
200 struct xt_entry_target
*t
;
202 t
= ip6t_get_target((struct ip6t_entry
*)fw
);
203 print_firewall(fw
, t
->u
.user
.name
, 0, FMT_PRINT_RULE
, h
);
207 append_entry(const xt_chainlabel chain
,
208 struct ip6t_entry
*fw
,
209 unsigned int nsaddrs
,
210 const struct in6_addr saddrs
[],
211 const struct in6_addr smasks
[],
212 unsigned int ndaddrs
,
213 const struct in6_addr daddrs
[],
214 const struct in6_addr dmasks
[],
216 struct xtc_handle
*handle
)
221 for (i
= 0; i
< nsaddrs
; i
++) {
222 fw
->ipv6
.src
= saddrs
[i
];
223 fw
->ipv6
.smsk
= smasks
[i
];
224 for (j
= 0; j
< ndaddrs
; j
++) {
225 fw
->ipv6
.dst
= daddrs
[j
];
226 fw
->ipv6
.dmsk
= dmasks
[j
];
228 print_firewall_line(fw
, handle
);
229 ret
&= ip6tc_append_entry(chain
, fw
, handle
);
237 replace_entry(const xt_chainlabel chain
,
238 struct ip6t_entry
*fw
,
239 unsigned int rulenum
,
240 const struct in6_addr
*saddr
, const struct in6_addr
*smask
,
241 const struct in6_addr
*daddr
, const struct in6_addr
*dmask
,
243 struct xtc_handle
*handle
)
245 fw
->ipv6
.src
= *saddr
;
246 fw
->ipv6
.dst
= *daddr
;
247 fw
->ipv6
.smsk
= *smask
;
248 fw
->ipv6
.dmsk
= *dmask
;
251 print_firewall_line(fw
, handle
);
252 return ip6tc_replace_entry(chain
, fw
, rulenum
, handle
);
256 insert_entry(const xt_chainlabel chain
,
257 struct ip6t_entry
*fw
,
258 unsigned int rulenum
,
259 unsigned int nsaddrs
,
260 const struct in6_addr saddrs
[],
261 const struct in6_addr smasks
[],
262 unsigned int ndaddrs
,
263 const struct in6_addr daddrs
[],
264 const struct in6_addr dmasks
[],
266 struct xtc_handle
*handle
)
271 for (i
= 0; i
< nsaddrs
; i
++) {
272 fw
->ipv6
.src
= saddrs
[i
];
273 fw
->ipv6
.smsk
= smasks
[i
];
274 for (j
= 0; j
< ndaddrs
; j
++) {
275 fw
->ipv6
.dst
= daddrs
[j
];
276 fw
->ipv6
.dmsk
= dmasks
[j
];
278 print_firewall_line(fw
, handle
);
279 ret
&= ip6tc_insert_entry(chain
, fw
, rulenum
, handle
);
287 delete_entry(const xt_chainlabel chain
,
288 struct ip6t_entry
*fw
,
289 unsigned int nsaddrs
,
290 const struct in6_addr saddrs
[],
291 const struct in6_addr smasks
[],
292 unsigned int ndaddrs
,
293 const struct in6_addr daddrs
[],
294 const struct in6_addr dmasks
[],
296 struct xtc_handle
*handle
,
297 struct xtables_rule_match
*matches
,
298 const struct xtables_target
*target
)
304 mask
= make_delete_mask(matches
, target
, sizeof(*fw
));
305 for (i
= 0; i
< nsaddrs
; i
++) {
306 fw
->ipv6
.src
= saddrs
[i
];
307 fw
->ipv6
.smsk
= smasks
[i
];
308 for (j
= 0; j
< ndaddrs
; j
++) {
309 fw
->ipv6
.dst
= daddrs
[j
];
310 fw
->ipv6
.dmsk
= dmasks
[j
];
312 print_firewall_line(fw
, handle
);
313 ret
&= ip6tc_delete_entry(chain
, fw
, mask
, handle
);
322 check_entry(const xt_chainlabel chain
, struct ip6t_entry
*fw
,
323 unsigned int nsaddrs
, const struct in6_addr
*saddrs
,
324 const struct in6_addr
*smasks
, unsigned int ndaddrs
,
325 const struct in6_addr
*daddrs
, const struct in6_addr
*dmasks
,
326 bool verbose
, struct xtc_handle
*handle
,
327 struct xtables_rule_match
*matches
,
328 const struct xtables_target
*target
)
334 mask
= make_delete_mask(matches
, target
, sizeof(*fw
));
335 for (i
= 0; i
< nsaddrs
; i
++) {
336 fw
->ipv6
.src
= saddrs
[i
];
337 fw
->ipv6
.smsk
= smasks
[i
];
338 for (j
= 0; j
< ndaddrs
; j
++) {
339 fw
->ipv6
.dst
= daddrs
[j
];
340 fw
->ipv6
.dmsk
= dmasks
[j
];
342 print_firewall_line(fw
, handle
);
343 ret
&= ip6tc_check_entry(chain
, fw
, mask
, handle
);
352 for_each_chain6(int (*fn
)(const xt_chainlabel
, int, struct xtc_handle
*),
353 int verbose
, int builtinstoo
, struct xtc_handle
*handle
)
358 unsigned int i
, chaincount
= 0;
360 chain
= ip6tc_first_chain(handle
);
363 chain
= ip6tc_next_chain(handle
);
366 chains
= xtables_malloc(sizeof(xt_chainlabel
) * chaincount
);
368 chain
= ip6tc_first_chain(handle
);
370 strcpy(chains
+ i
*sizeof(xt_chainlabel
), chain
);
372 chain
= ip6tc_next_chain(handle
);
375 for (i
= 0; i
< chaincount
; i
++) {
377 && ip6tc_builtin(chains
+ i
*sizeof(xt_chainlabel
),
380 ret
&= fn(chains
+ i
*sizeof(xt_chainlabel
), verbose
, handle
);
388 flush_entries6(const xt_chainlabel chain
, int verbose
,
389 struct xtc_handle
*handle
)
392 return for_each_chain6(flush_entries6
, verbose
, 1, handle
);
395 fprintf(stdout
, "Flushing chain `%s'\n", chain
);
396 return ip6tc_flush_entries(chain
, handle
);
400 zero_entries(const xt_chainlabel chain
, int verbose
,
401 struct xtc_handle
*handle
)
404 return for_each_chain6(zero_entries
, verbose
, 1, handle
);
407 fprintf(stdout
, "Zeroing chain `%s'\n", chain
);
408 return ip6tc_zero_entries(chain
, handle
);
412 delete_chain6(const xt_chainlabel chain
, int verbose
,
413 struct xtc_handle
*handle
)
416 return for_each_chain6(delete_chain6
, verbose
, 0, handle
);
419 fprintf(stdout
, "Deleting chain `%s'\n", chain
);
420 return ip6tc_delete_chain(chain
, handle
);
424 list_entries(const xt_chainlabel chain
, int rulenum
, int verbose
, int numeric
,
425 int expanded
, int linenumbers
, struct xtc_handle
*handle
)
431 format
= FMT_OPTIONS
;
433 format
|= FMT_NOCOUNTS
;
438 format
|= FMT_NUMERIC
;
441 format
|= FMT_KILOMEGAGIGA
;
444 format
|= FMT_LINENUMBERS
;
446 for (this = ip6tc_first_chain(handle
);
448 this = ip6tc_next_chain(handle
)) {
449 const struct ip6t_entry
*i
;
452 if (chain
&& strcmp(chain
, this) != 0)
455 if (found
) printf("\n");
458 struct xt_counters counters
;
463 pol
= ip6tc_get_policy(this, &counters
, handle
);
464 if (!pol
&& ip6tc_get_references(&urefs
, this, handle
))
467 print_header(format
, this, pol
, &counters
, refs
, 0);
469 i
= ip6tc_first_rule(this, handle
);
474 if (!rulenum
|| num
== rulenum
)
476 ip6tc_get_target(i
, handle
),
480 i
= ip6tc_next_rule(i
, handle
);
489 /* We want this to be readable, so only print out necessary fields.
490 * Because that's the kind of world I want to live in.
492 void print_rule6(const struct ip6t_entry
*e
,
493 struct xtc_handle
*h
, const char *chain
, int counters
)
495 const struct xt_entry_target
*t
;
496 const char *target_name
;
498 /* print counters for iptables-save */
500 printf("[%llu:%llu] ", (unsigned long long)e
->counters
.pcnt
, (unsigned long long)e
->counters
.bcnt
);
502 /* print chain name */
503 printf("-A %s", chain
);
506 save_ipv6_addr('s', &e
->ipv6
.src
, &e
->ipv6
.smsk
,
507 e
->ipv6
.invflags
& IP6T_INV_SRCIP
);
509 save_ipv6_addr('d', &e
->ipv6
.dst
, &e
->ipv6
.dmsk
,
510 e
->ipv6
.invflags
& IP6T_INV_DSTIP
);
512 save_rule_details(e
->ipv6
.iniface
, e
->ipv6
.outiface
,
513 e
->ipv6
.proto
, 0, e
->ipv6
.invflags
);
516 /* not definied in ipv6
517 * FIXME: linux/netfilter_ipv6/ip6_tables: IP6T_INV_FRAG why definied? */
518 if (e
->ipv6
.flags
& IPT_F_FRAG
)
520 e
->ipv6
.invflags
& IP6T_INV_FRAG
? " !" : "");
523 if (e
->ipv6
.flags
& IP6T_F_TOS
)
525 e
->ipv6
.invflags
& IP6T_INV_TOS
? " !" : "",
528 /* Print matchinfo part */
529 if (e
->target_offset
) {
530 IP6T_MATCH_ITERATE(e
, print_match_save
, &e
->ipv6
);
533 /* print counters for iptables -R */
535 printf(" -c %llu %llu", (unsigned long long)e
->counters
.pcnt
, (unsigned long long)e
->counters
.bcnt
);
537 /* Print target name and targinfo part */
538 target_name
= ip6tc_get_target(e
, h
);
539 t
= ip6t_get_target((struct ip6t_entry
*)e
);
540 if (t
->u
.user
.name
[0]) {
541 const char *name
= t
->u
.user
.name
;
542 const int revision
= t
->u
.user
.revision
;
543 struct xtables_target
*target
, *tg
, *tg2
;
545 target
= xtables_find_target(name
, XTF_TRY_LOAD
);
547 fprintf(stderr
, "Can't find library for target `%s'\n",
552 tg
= tg2
= xtables_find_target_revision(name
, XTF_TRY_LOAD
,
556 printf(" -j %s", tg2
->alias
? tg2
->alias(t
) : target_name
);
559 tg
->save(&e
->ipv6
, t
);
560 else if (target
->save
)
561 printf(unsupported_rev
);
563 /* If the target size is greater than xt_entry_target
564 * there is something to be saved, we just don't know
566 if (t
->u
.target_size
!=
567 sizeof(struct xt_entry_target
)) {
568 fprintf(stderr
, "Target `%s' is missing "
574 } else if (target_name
&& (*target_name
!= '\0'))
576 printf(" -%c %s", e
->ipv6
.flags
& IP6T_F_GOTO
? 'g' : 'j', target_name
);
578 printf(" -j %s", target_name
);
585 list_rules(const xt_chainlabel chain
, int rulenum
, int counters
,
586 struct xtc_handle
*handle
)
588 const char *this = NULL
;
592 counters
= -1; /* iptables -c format */
594 /* Dump out chain names first,
595 * thereby preventing dependency conflicts */
596 if (!rulenum
) for (this = ip6tc_first_chain(handle
);
598 this = ip6tc_next_chain(handle
)) {
599 if (chain
&& strcmp(this, chain
) != 0)
602 if (ip6tc_builtin(this, handle
)) {
603 struct xt_counters count
;
604 printf("-P %s %s", this, ip6tc_get_policy(this, &count
, handle
));
606 printf(" -c %llu %llu", (unsigned long long)count
.pcnt
, (unsigned long long)count
.bcnt
);
609 printf("-N %s\n", this);
613 for (this = ip6tc_first_chain(handle
);
615 this = ip6tc_next_chain(handle
)) {
616 const struct ip6t_entry
*e
;
619 if (chain
&& strcmp(this, chain
) != 0)
623 e
= ip6tc_first_rule(this, handle
);
626 if (!rulenum
|| num
== rulenum
)
627 print_rule6(e
, handle
, this, counters
);
628 e
= ip6tc_next_rule(e
, handle
);
637 static struct ip6t_entry
*
638 generate_entry(const struct ip6t_entry
*fw
,
639 struct xtables_rule_match
*matches
,
640 struct xt_entry_target
*target
)
643 struct xtables_rule_match
*matchp
;
644 struct ip6t_entry
*e
;
646 size
= sizeof(struct ip6t_entry
);
647 for (matchp
= matches
; matchp
; matchp
= matchp
->next
)
648 size
+= matchp
->match
->m
->u
.match_size
;
650 e
= xtables_malloc(size
+ target
->u
.target_size
);
652 e
->target_offset
= size
;
653 e
->next_offset
= size
+ target
->u
.target_size
;
656 for (matchp
= matches
; matchp
; matchp
= matchp
->next
) {
657 memcpy(e
->elems
+ size
, matchp
->match
->m
, matchp
->match
->m
->u
.match_size
);
658 size
+= matchp
->match
->m
->u
.match_size
;
660 memcpy(e
->elems
+ size
, target
, target
->u
.target_size
);
665 int do_command6(int argc
, char *argv
[], char **table
,
666 struct xtc_handle
**handle
, bool restore
)
668 struct xt_cmd_parse_ops cmd_parse_ops
= {
669 .proto_parse
= ipv6_proto_parse
,
670 .post_parse
= ipv6_post_parse
,
671 .option_name
= ip46t_option_name
,
672 .option_invert
= ip46t_option_invert
,
673 .command_default
= command_default
,
674 .print_help
= xtables_printhelp
,
676 struct xt_cmd_parse p
= {
680 .ops
= &cmd_parse_ops
,
682 struct iptables_command_state cs
= {
686 struct xtables_args args
= {
689 struct ip6t_entry
*e
= NULL
;
690 unsigned int nsaddrs
= 0, ndaddrs
= 0;
691 struct in6_addr
*saddrs
= NULL
, *daddrs
= NULL
;
692 struct in6_addr
*smasks
= NULL
, *dmasks
= NULL
;
696 const char *chain
= NULL
;
697 const char *policy
= NULL
, *newname
= NULL
;
698 unsigned int rulenum
= 0, command
= 0;
701 do_parse(argc
, argv
, &p
, &cs
, &args
);
711 nsaddrs
= args
.s
.naddrs
;
712 ndaddrs
= args
.d
.naddrs
;
713 saddrs
= args
.s
.addr
.v6
;
714 daddrs
= args
.d
.addr
.v6
;
715 smasks
= args
.s
.mask
.v6
;
716 dmasks
= args
.d
.mask
.v6
;
718 iface_to_mask(cs
.fw6
.ipv6
.iniface
, cs
.fw6
.ipv6
.iniface_mask
);
719 iface_to_mask(cs
.fw6
.ipv6
.outiface
, cs
.fw6
.ipv6
.outiface_mask
);
721 /* Attempt to acquire the xtables lock */
723 xtables_lock_or_exit(wait
);
725 /* only allocate handle if we weren't called with a handle */
727 *handle
= ip6tc_init(*table
);
729 /* try to insmod the module if iptc_init failed */
730 if (!*handle
&& xtables_load_ko(xtables_modprobe_program
, false) != -1)
731 *handle
= ip6tc_init(*table
);
734 xtables_error(VERSION_PROBLEM
,
735 "can't initialize ip6tables table `%s': %s",
736 *table
, ip6tc_strerror(errno
));
738 if (command
== CMD_APPEND
739 || command
== CMD_DELETE
740 || command
== CMD_CHECK
741 || command
== CMD_INSERT
742 || command
== CMD_REPLACE
) {
743 if (cs
.target
&& ip6tc_is_chain(cs
.jumpto
, *handle
)) {
745 "Warning: using chain %s, not extension\n",
754 /* If they didn't specify a target, or it's a chain
755 name, use standard. */
757 && (strlen(cs
.jumpto
) == 0
758 || ip6tc_is_chain(cs
.jumpto
, *handle
))) {
761 cs
.target
= xtables_find_target(XT_STANDARD_TARGET
,
762 XTF_LOAD_MUST_SUCCEED
);
764 size
= sizeof(struct xt_entry_target
)
766 cs
.target
->t
= xtables_calloc(1, size
);
767 cs
.target
->t
->u
.target_size
= size
;
768 strcpy(cs
.target
->t
->u
.user
.name
, cs
.jumpto
);
769 xs_init_target(cs
.target
);
773 /* It is no chain, and we can't load a plugin.
774 * We cannot know if the plugin is corrupt, non
775 * existent OR if the user just misspelled a
779 if (cs
.fw6
.ipv6
.flags
& IP6T_F_GOTO
)
780 xtables_error(PARAMETER_PROBLEM
,
781 "goto '%s' is not a chain",
784 xtables_find_target(cs
.jumpto
, XTF_LOAD_MUST_SUCCEED
);
786 e
= generate_entry(&cs
.fw6
, cs
.matches
, cs
.target
->t
);
792 ret
= append_entry(chain
, e
,
793 nsaddrs
, saddrs
, smasks
,
794 ndaddrs
, daddrs
, dmasks
,
795 cs
.options
&OPT_VERBOSE
,
799 ret
= delete_entry(chain
, e
,
800 nsaddrs
, saddrs
, smasks
,
801 ndaddrs
, daddrs
, dmasks
,
802 cs
.options
&OPT_VERBOSE
,
803 *handle
, cs
.matches
, cs
.target
);
806 ret
= ip6tc_delete_num_entry(chain
, rulenum
- 1, *handle
);
809 ret
= check_entry(chain
, e
,
810 nsaddrs
, saddrs
, smasks
,
811 ndaddrs
, daddrs
, dmasks
,
812 cs
.options
&OPT_VERBOSE
,
813 *handle
, cs
.matches
, cs
.target
);
816 ret
= replace_entry(chain
, e
, rulenum
- 1,
817 saddrs
, smasks
, daddrs
, dmasks
,
818 cs
.options
&OPT_VERBOSE
, *handle
);
821 ret
= insert_entry(chain
, e
, rulenum
- 1,
822 nsaddrs
, saddrs
, smasks
,
823 ndaddrs
, daddrs
, dmasks
,
824 cs
.options
&OPT_VERBOSE
,
828 ret
= flush_entries6(chain
, cs
.options
&OPT_VERBOSE
, *handle
);
831 ret
= zero_entries(chain
, cs
.options
&OPT_VERBOSE
, *handle
);
834 ret
= ip6tc_zero_counter(chain
, rulenum
, *handle
);
837 case CMD_LIST
|CMD_ZERO
:
838 case CMD_LIST
|CMD_ZERO_NUM
:
839 ret
= list_entries(chain
,
841 cs
.options
&OPT_VERBOSE
,
842 cs
.options
&OPT_NUMERIC
,
843 cs
.options
&OPT_EXPANDED
,
844 cs
.options
&OPT_LINENUMBERS
,
846 if (ret
&& (command
& CMD_ZERO
))
847 ret
= zero_entries(chain
,
848 cs
.options
&OPT_VERBOSE
, *handle
);
849 if (ret
&& (command
& CMD_ZERO_NUM
))
850 ret
= ip6tc_zero_counter(chain
, rulenum
, *handle
);
853 case CMD_LIST_RULES
|CMD_ZERO
:
854 case CMD_LIST_RULES
|CMD_ZERO_NUM
:
855 ret
= list_rules(chain
,
857 cs
.options
&OPT_VERBOSE
,
859 if (ret
&& (command
& CMD_ZERO
))
860 ret
= zero_entries(chain
,
861 cs
.options
&OPT_VERBOSE
, *handle
);
862 if (ret
&& (command
& CMD_ZERO_NUM
))
863 ret
= ip6tc_zero_counter(chain
, rulenum
, *handle
);
866 ret
= ip6tc_create_chain(chain
, *handle
);
868 case CMD_DELETE_CHAIN
:
869 ret
= delete_chain6(chain
, cs
.options
&OPT_VERBOSE
, *handle
);
871 case CMD_RENAME_CHAIN
:
872 ret
= ip6tc_rename_chain(chain
, newname
, *handle
);
875 ret
= ip6tc_set_policy(chain
, policy
, cs
.options
&OPT_COUNTERS
? &cs
.fw6
.counters
: NULL
, *handle
);
878 /* do_parse ignored the line (eg: -4 with ip6tables-restore) */
881 /* We should never reach this... */
882 exit_tryhelp(2, line
);
886 dump_entries6(*handle
);
888 xtables_clear_iptables_command_state(&cs
);
895 xtables_clear_args(&args
);
896 xtables_free_opts(1);