Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Pkg Iptables
Commits
eb1d7c5f
Commit
eb1d7c5f
authored
Jun 04, 2020
by
Arturo Borrero Gonzalez
Browse files
New upstream version 1.8.5
parent
290749d4
Changes
125
Hide whitespace changes
Inline
Side-by-side
iptables/iptables-apply
View file @
eb1d7c5f
#!/bin/bash
#
# iptables-apply -- a safer way to update iptables remotely
#
# Copyright © Martin F. Krafft <madduck@madduck.net>
# Usage:
# iptables-apply [-hV] [-t timeout] [-w savefile] {[rulesfile]|-c [runcmd]}
#
# Versions:
# * 1.0 Copyright 2006 Martin F. Krafft <madduck@madduck.net>
# Original version
# * 1.1 Copyright 2010 GW <gw.2010@tnode.com or http://gw.tnode.com/>
# Added parameter -c (run command)
# Added parameter -w (save successfully applied rules to file)
# Major code cleanup
#
# Released under the terms of the Artistic Licence 2.0
#
set
-eu
PROGNAME
=
"
${
0
##*/
}
"
;
VERSION
=
1.0
PROGNAME
=
"
${
0
##*/
}
"
VERSION
=
1.1
### Default settings
DEF_TIMEOUT
=
10
MODE
=
0
# apply rulesfile mode
# MODE=1 # run command mode
case
"
$PROGNAME
"
in
(
*
6
*
)
SAVE
=
ip6tables-save
RESTORE
=
ip6tables-restore
DEF_RULESFILE
=
"/etc/network/ip6tables.up.rules"
DEF_SAVEFILE
=
"
$DEF_RULESFILE
"
DEF_RUNCMD
=
"/etc/network/ip6tables.up.run"
;;
(
*
)
SAVE
=
iptables-save
RESTORE
=
iptables-restore
DEF_RULESFILE
=
"/etc/network/iptables.up.rules"
DEF_SAVEFILE
=
"
$DEF_RULESFILE
"
DEF_RUNCMD
=
"/etc/network/iptables.up.run"
;;
esac
TIMEOUT
=
10
### Functions
function
blurb
()
{
cat
<<-
_eof
function
blurb
()
{
cat
<<-
__EOF__
$PROGNAME
$VERSION
-- a safer way to update iptables remotely
_
eof
_
_EOF__
}
function
copyright
()
{
cat
<<-
_eof
$PROGNAME
is C Martin F. Krafft <madduck@madduck.net>.
function
copyright
()
{
cat
<<-
__EOF__
$PROGNAME
has been published under the terms of the Artistic Licence 2.0.
The program has been published under the terms of the Artistic Licence 2.0
_eof
Original version - Copyright 2006 Martin F. Krafft <madduck@madduck.net>.
Version 1.1 - Copyright 2010 GW <gw.2010@tnode.com or http://gw.tnode.com/>.
__EOF__
}
function
about
()
{
function
about
()
{
blurb
echo
copyright
}
function
usage
()
{
cat
<<-
_eof
Usage:
$PROGNAME
[options] ruleset
function
usage
()
{
blurb
echo
cat
<<-
__EOF__
Usage:
$PROGNAME
[-hV] [-t timeout] [-w savefile] {[rulesfile]|-c [runcmd]}
The script will try to apply a new rulesfile (as output by iptables-save,
read by iptables-restore) or run a command to configure iptables and then
prompt the user whether the changes are okay. If the new iptables rules cut
the existing connection, the user will not be able to answer affirmatively.
In this case, the script rolls back to the previous working iptables rules
after the timeout expires.
Successfully applied rules can also be written to savefile and later used
to roll back to this state. This can be used to implement a store last good
configuration mechanism when experimenting with an iptables setup script:
$PROGNAME
-w
$DEF_SAVEFILE
-c
$DEF_RUNCMD
The script will try to apply a new ruleset (as output by iptables-save/read
by iptables-restore) to iptables, then prompt the user whether the changes
are okay. If the new ruleset cut the existing connection, the user will not
be able to answer affirmatively. In this case, the script rolls back to the
previous ruleset.
When called as ip6tables-apply, the script will use ip6tables-save/-restore
and IPv6 default values instead. Default value for rulesfile is
'
$DEF_RULESFILE
'.
Options:
-t seconds, --timeout seconds
Specify the timeout in seconds (default:
$DEF_TIMEOUT
).
-w savefile, --write savefile
Specify the savefile where successfully applied rules will be written to
(default if empty string is given:
$DEF_SAVEFILE
).
-c runcmd, --command runcmd
Run command runcmd to configure iptables instead of applying a rulesfile
(default:
$DEF_RUNCMD
).
-h, --help
Display this help text.
-V, --version
Display version information.
__EOF__
}
The following options may be specified, using standard conventions:
function
checkcommands
()
{
for
cmd
in
"
${
COMMANDS
[@]
}
"
;
do
if
!
command
-v
"
$cmd
"
>
/dev/null
;
then
echo
"Error: needed command not found:
$cmd
"
>
&2
exit
127
fi
done
}
-t | --timeout Specify the timeout in seconds (default:
$TIMEOUT
)
-V | --version Display version information
-h | --help Display this help text
_eof
function
revertrules
()
{
echo
-n
"Reverting to old iptables rules... "
"
$RESTORE
"
<
"
$TMPFILE
"
echo
"done."
}
SHORTOPTS
=
"t:Vh"
;
LONGOPTS
=
"timeout:,version,help"
;
### Parsing and checking parameters
TIMEOUT
=
"
$DEF_TIMEOUT
"
SAVEFILE
=
""
SHORTOPTS
=
"t:w:chV"
;
LONGOPTS
=
"timeout:,write:,command,help,version"
;
OPTS
=
$(
getopt
-s
bash
-o
"
$SHORTOPTS
"
-l
"
$LONGOPTS
"
-n
"
$PROGNAME
"
--
"
$@
"
)
||
exit
$?
for
opt
in
$OPTS
;
do
case
"
$opt
"
in
(
-
*
)
unset
OPT_STATE
;;
(
-
*
)
unset
OPT_STATE
;;
(
*
)
case
"
${
OPT_STATE
:-}
"
in
(
SET_TIMEOUT
)
eval
TIMEOUT
=
$opt
case
"
$TIMEOUT
"
in
([
0-9]
*
)
:
;;
(
*
)
echo
"E: non-numeric timeout value."
>
&2
exit
1
;;
esac
(
SET_TIMEOUT
)
eval
TIMEOUT
=
$opt
;;
(
SET_SAVEFILE
)
eval
SAVEFILE
=
$opt
[
-z
"
$SAVEFILE
"
]
&&
SAVEFILE
=
"
$DEF_SAVEFILE
"
;;
esac
;;
esac
case
"
$opt
"
in
(
-t
|
--timeout
)
OPT_STATE
=
"SET_TIMEOUT"
;;
(
-w
|
--write
)
OPT_STATE
=
"SET_SAVEFILE"
;;
(
-c
|
--command
)
MODE
=
1
;;
(
-h
|
--help
)
usage
>
&2
;
exit
0
;;
(
-V
|
--version
)
about
>
&2
;
exit
0
;;
(
-t
|
--timeout
)
OPT_STATE
=
SET_TIMEOUT
;;
(
--
)
break
;;
esac
shift
done
case
"
$PROGNAME
"
in
(
*
6
*
)
SAVE
=
ip6tables-save
RESTORE
=
ip6tables-restore
DEFAULT_FILE
=
/etc/network/ip6tables
;;
(
*
)
SAVE
=
iptables-save
RESTORE
=
iptables-restore
DEFAULT_FILE
=
/etc/network/iptables
;;
esac
FILE
=
"
${
1
:-
$DEFAULT_FILE
}
"
;
if
[[
-z
"
$FILE
"
]]
;
then
echo
"E: missing file argument."
>
&2
# Validate parameters
if
[
"
$TIMEOUT
"
-ge
0
]
2>/dev/null
;
then
TIMEOUT
=
$((
$TIMEOUT
))
else
echo
"Error: timeout must be a positive number"
>
&2
exit
1
fi
if
[
[
!
-
r
"
$FILE
"
]
]
;
then
echo
"E
: cannot read
$
FILE
"
>
&2
exit
2
if
[
-n
"
$SAVEFILE
"
-a
-e
"
$SAVEFILE
"
-a
!
-
w
"
$
SAVE
FILE
"
]
;
then
echo
"E
rror: savefile not writable:
$SAVE
FILE
"
>
&2
exit
8
fi
COMMANDS
=(
tempfile
"
$SAVE
"
"
$RESTORE
"
)
case
"
$MODE
"
in
(
1
)
# Treat parameter as runcmd (run command mode)
RUNCMD
=
"
${
1
:-
$DEF_RUNCMD
}
"
if
[
!
-x
"
$RUNCMD
"
]
;
then
echo
"Error: runcmd not executable:
$RUNCMD
"
>
&2
exit
6
fi
# Needed commands
COMMANDS
=(
mktemp
"
$SAVE
"
"
$RESTORE
"
"
$RUNCMD
"
)
checkcommands
;;
(
*
)
# Treat parameter as rulesfile (apply rulesfile mode)
RULESFILE
=
"
${
1
:-
$DEF_RULESFILE
}
"
;
if
[
!
-r
"
$RULESFILE
"
]
;
then
echo
"Error: rulesfile not readable:
$RULESFILE
"
>
&2
exit
2
fi
# Needed commands
COMMANDS
=(
mktemp
"
$SAVE
"
"
$RESTORE
"
)
checkcommands
;;
esac
for
cmd
in
"
${
COMMANDS
[@]
}
"
;
do
if
!
command
-v
$cmd
>
/dev/null
;
then
echo
"E: command not found:
$cmd
"
>
&2
exit
127
fi
done
umask
0700
### Begin work
TMPFILE
=
$(
tempfile
-p
iptap
)
# Store old iptables rules to temporary file
TMPFILE
=
`
mktemp
/tmp/
$PROGNAME
-XXXXXXXX
`
trap
"rm -f
$TMPFILE
"
EXIT HUP INT QUIT ILL TRAP ABRT BUS
\
FPE USR1 SEGV USR2 PIPE ALRM TERM
if
!
"
$SAVE
"
>
"
$TMPFILE
"
;
then
# An error occured
if
!
grep
-q
ipt /proc/modules 2>/dev/null
;
then
echo
"E: iptables support lacking from the kernel
.
"
>
&2
echo
"E
rror
: iptables support lacking from the kernel"
>
&2
exit
3
else
echo
"E: unknown error saving
current
iptables rules
et.
"
>
&2
echo
"E
rror
: unknown error saving
old
iptables rules
:
$TMPFILE
"
>
&2
exit
4
fi
fi
# Legacy to stop the fail2ban daemon if present
[
-x
/etc/init.d/fail2ban
]
&&
/etc/init.d/fail2ban stop
echo
-n
"Applying new ruleset... "
if
!
"
$RESTORE
"
<
"
$FILE
"
;
then
echo
"failed."
echo
"E: unknown error applying new iptables ruleset."
>
&2
exit
5
else
echo
"done."
fi
# Configure iptables
case
"
$MODE
"
in
(
1
)
# Run command in background and kill it if it times out
echo
-n
"Running command '
$RUNCMD
'... "
"
$RUNCMD
"
&
CMD_PID
=
$!
(
sleep
"
$TIMEOUT
"
;
kill
"
$CMD_PID
"
2>/dev/null
;
exit
0
)
&
CMDTIMEOUT_PID
=
$!
if
!
wait
"
$CMD_PID
"
;
then
echo
"failed."
echo
"Error: unknown error running command:
$RUNCMD
"
>
&2
revertrules
exit
7
else
echo
"done."
fi
;;
(
*
)
# Apply iptables rulesfile
echo
-n
"Applying new iptables rules from '
$RULESFILE
'... "
if
!
"
$RESTORE
"
<
"
$RULESFILE
"
;
then
echo
"failed."
echo
"Error: unknown error applying new iptables rules:
$RULESFILE
"
>
&2
revertrules
exit
5
else
echo
"done."
fi
;;
esac
# Prompt user for confirmation
echo
-n
"Can you establish NEW connections to the machine? (y/N) "
read
-n1
-t
"
$
{
TIMEOUT
:-
15
}
"
ret 2>&1
||
:
read
-n1
-t
"
$TIMEOUT
"
ret 2>&1
||
:
case
"
${
ret
:-}
"
in
(
y
*
|
Y
*
)
# Success
echo
if
[
!
-z
"
$SAVEFILE
"
]
;
then
# Write successfully applied rules to the savefile
echo
"Writing successfully applied rules to '
$SAVEFILE
'..."
if
!
"
$SAVE
"
>
"
$SAVEFILE
"
;
then
echo
"Error: unknown error writing successfully applied rules:
$SAVEFILE
"
>
&2
exit
9
fi
fi
echo
"... then my job is done. See you next time."
;;
(
*
)
if
[[
-z
"
${
ret
:-}
"
]]
;
then
echo
"apparently not..."
# Failed
echo
if
[
-z
"
${
ret
:-}
"
]
;
then
echo
"Timeout! Something happened (or did not). Better play it safe..."
else
echo
echo
"No affirmative response! Better play it safe..."
fi
echo
"Timeout. Something happened (or did not). Better play it safe..."
echo
-n
"Reverting to old ruleset... "
"
$RESTORE
"
<
"
$TMPFILE
"
;
echo
"done."
revertrules
exit
255
;;
esac
# Legacy to start the fail2ban daemon again
[
-x
/etc/init.d/fail2ban
]
&&
/etc/init.d/fail2ban start
exit
0
...
...
iptables/iptables-apply.8.in
View file @
eb1d7c5f
.\" Title: iptables-apply
.\" Author: Martin F. Krafft
.\" Date:
Jun 04
, 200
6
.\" Author: Martin F. Krafft
, GW
.\" Date:
May 10
, 20
1
0
.\"
.TH IPTABLES\-APPLY 8 "" "@PACKAGE_STRING@" "@PACKAGE_STRING@"
.\" disable hyphenation
...
...
@@ -8,23 +8,37 @@
.SH NAME
iptables-apply \- a safer way to update iptables remotely
.SH SYNOPSIS
\fBiptables\-apply\fP [\-\fBhV\fP] [\fB-t\fP \fItimeout\fP]
\fIruleset\-file
\fP
\fBiptables\-apply\fP [\-\fBhV\fP] [\fB-t\fP \fItimeout\fP]
[\fB-w\fP \fIsavefile\fP] {[\fIrulesfile]|-c [runcmd]}
\fP
.SH "DESCRIPTION"
.PP
iptables\-apply will try to apply a new rulese
t
(as output by
iptables
\
-save
/
read by iptables
\
-restore)
to iptables, then prompt th
e
user whether the changes are okay. If the
new ruleset cut the existing
connection, the user will not be able to answer affirmatively. In this
case, the script rolls back to the previous ruleset after the timeout
expired. The timeout can be set with \fB\-t\fP
.
iptables\-apply will try to apply a new rules
fil
e (as output by
iptables-save
,
read by iptables-restore)
or run a command to configur
e
iptables and then prompt the
user whether the changes are okay. If the
new iptables rules cut the existing connection, the user will not be
able to answer affirmatively. In this case, the script rolls back to
the previous working iptables rules after the timeout expires
.
.PP
When called as \fBip6tables\-apply\fP, the script will use
ip6tables\-save/\-restore instead.
Successfully applied rules can also be written to savefile and later used
to roll back to this state. This can be used to implement a store last good
configuration mechanism when experimenting with an iptables setup script:
iptables-apply \-w /etc/network/iptables.up.rules \-c /etc/network/iptables.up.run
.PP
When called as ip6tables\-apply, the script will use
ip6tables\-save/\-restore and IPv6 default values instead. Default
value for rulesfile is '/etc/network/iptables.up.rules'.
.SH OPTIONS
.TP
\fB\-t\fP \fIseconds\fR, \fB\-\-timeout\fP \fIseconds\fR
Sets the timeout after which the script will roll back to the previous
ruleset.
Sets the timeout in seconds after which the script will roll back
to the previous ruleset (default: 10).
.TP
\fB\-w\fP \fIsavefile\fR, \fB\-\-write\fP \fIsavefile\fR
Specify the savefile where successfully applied rules will be written to
(default if empty string is given: /etc/network/iptables.up.rules).
.TP
\fB\-c\fP \fIruncmd\fR, \fB\-\-command\fP \fIruncmd\fR
Run command runcmd to configure iptables instead of applying a rulesfile
(default: /etc/network/iptables.up.run).
.TP
\fB\-h\fP, \fB\-\-help\fP
Display usage information.
...
...
@@ -36,9 +50,11 @@ Display version information.
\fBiptables-restore\fP(8), \fBiptables-save\fP(8), \fBiptables\fR(8).
.SH LEGALESE
.PP
iptables\-apply is copyright by Martin F. Krafft.
Original iptables-apply - Copyright 2006 Martin F. Krafft <madduck@madduck.net>.
Version 1.1 - Copyright 2010 GW <gw.2010@tnode.com or http://gw.tnode.com/>.
.PP
This manual page was written by Martin F. Krafft <madduck@madduck.net>
This manual page was written by Martin F. Krafft <madduck@madduck.net> and
extended by GW <gw.2010@tnode.com or http://gw.tnode.com/>.
.PP
Permission is granted to copy, distribute and/or modify this document
under the terms of the Artistic License 2.0.
iptables/iptables-restore.8.in
View file @
eb1d7c5f
...
...
@@ -87,7 +87,7 @@ from Rusty Russell.
.br
Andras Kis-Szabo <kisza@sch.bme.hu> contributed ip6tables-restore.
.SH SEE ALSO
\fBiptables\-save\fP(8), \fBiptables\fP(8)
\fBiptables\-apply\fP(8),
\fBiptables\-save\fP(8), \fBiptables\fP(8)
.PP
The iptables-HOWTO, which details more iptables usage, the NAT-HOWTO,
which details NAT, and the netfilter-hacking-HOWTO which details the
...
...
iptables/iptables-restore.c
View file @
eb1d7c5f
...
...
@@ -178,8 +178,10 @@ ip46tables_restore_main(const struct iptables_restore_cb *cb,
if
(
buffer
[
0
]
==
'\n'
)
continue
;
else
if
(
buffer
[
0
]
==
'#'
)
{
if
(
verbose
)
if
(
verbose
)
{
fputs
(
buffer
,
stdout
);
fflush
(
stdout
);
}
continue
;
}
else
if
((
strcmp
(
buffer
,
"COMMIT
\n
"
)
==
0
)
&&
(
in_table
))
{
if
(
!
testing
)
{
...
...
@@ -370,7 +372,7 @@ static const struct iptables_restore_cb ipt_restore_cb = {
int
iptables_restore_main
(
int
argc
,
char
*
argv
[])
{
int
c
;
int
c
,
ret
;
iptables_globals
.
program_name
=
"iptables-restore"
;
c
=
xtables_init_all
(
&
iptables_globals
,
NFPROTO_IPV4
);
...
...
@@ -385,7 +387,10 @@ iptables_restore_main(int argc, char *argv[])
init_extensions4
();
#endif
return
ip46tables_restore_main
(
&
ipt_restore_cb
,
argc
,
argv
);
ret
=
ip46tables_restore_main
(
&
ipt_restore_cb
,
argc
,
argv
);
xtables_fini
();
return
ret
;
}
#endif
...
...
@@ -401,7 +406,7 @@ static const struct iptables_restore_cb ip6t_restore_cb = {
int
ip6tables_restore_main
(
int
argc
,
char
*
argv
[])
{
int
c
;
int
c
,
ret
;
ip6tables_globals
.
program_name
=
"ip6tables-restore"
;
c
=
xtables_init_all
(
&
ip6tables_globals
,
NFPROTO_IPV6
);
...
...
@@ -416,6 +421,9 @@ ip6tables_restore_main(int argc, char *argv[])
init_extensions6
();
#endif
return
ip46tables_restore_main
(
&
ip6t_restore_cb
,
argc
,
argv
);
ret
=
ip46tables_restore_main
(
&
ip6t_restore_cb
,
argc
,
argv
);
xtables_fini
();
return
ret
;
}
#endif
iptables/iptables-save.8.in
View file @
eb1d7c5f
...
...
@@ -62,7 +62,7 @@ Rusty Russell <rusty@rustcorp.com.au>
.br
Andras Kis-Szabo <kisza@sch.bme.hu> contributed ip6tables-save.
.SH SEE ALSO
\fBiptables\-restore\fP(8), \fBiptables\fP(8)
\fBiptables\-apply\fP(8),
\fBiptables\-restore\fP(8), \fBiptables\fP(8)
.PP
The iptables-HOWTO, which details more iptables usage, the NAT-HOWTO,
which details NAT, and the netfilter-hacking-HOWTO which details the
...
...
iptables/iptables-save.c
View file @
eb1d7c5f
...
...
@@ -218,6 +218,8 @@ struct iptables_save_cb ipt_save_cb = {
int
iptables_save_main
(
int
argc
,
char
*
argv
[])
{
int
ret
;
iptables_globals
.
program_name
=
"iptables-save"
;
if
(
xtables_init_all
(
&
iptables_globals
,
NFPROTO_IPV4
)
<
0
)
{
fprintf
(
stderr
,
"%s/%s Failed to initialize xtables
\n
"
,
...
...
@@ -230,7 +232,10 @@ iptables_save_main(int argc, char *argv[])
init_extensions4
();
#endif
return
do_iptables_save
(
&
ipt_save_cb
,
argc
,
argv
);
ret
=
do_iptables_save
(
&
ipt_save_cb
,
argc
,
argv
);
xtables_fini
();
return
ret
;
}
#endif
/* ENABLE_IPV4 */
...
...
@@ -259,6 +264,8 @@ struct iptables_save_cb ip6t_save_cb = {
int
ip6tables_save_main
(
int
argc
,
char
*
argv
[])
{
int
ret
;
ip6tables_globals
.
program_name
=
"ip6tables-save"
;
if
(
xtables_init_all
(
&
ip6tables_globals
,
NFPROTO_IPV6
)
<
0
)
{
fprintf
(
stderr
,
"%s/%s Failed to initialize xtables
\n
"
,
...
...
@@ -271,6 +278,9 @@ ip6tables_save_main(int argc, char *argv[])
init_extensions6
();
#endif
return
do_iptables_save
(
&
ip6t_save_cb
,
argc
,
argv
);
ret
=
do_iptables_save
(
&
ip6t_save_cb
,
argc
,
argv
);
xtables_fini
();
return
ret
;
}
#endif
/* ENABLE_IPV6 */
iptables/iptables-standalone.c
View file @
eb1d7c5f
...
...
@@ -64,6 +64,8 @@ iptables_main(int argc, char *argv[])
iptc_free
(
handle
);
}
xtables_fini
();
if
(
!
ret
)
{
if
(
errno
==
EINVAL
)
{
fprintf
(
stderr
,
"iptables: %s. "
...
...
iptables/iptables.8.in
View file @
eb1d7c5f
...
...
@@ -245,13 +245,13 @@ add, delete, insert, replace and append commands).
This option has no effect in iptables and iptables-restore.
If a rule using the \fB\-4\fP option is inserted with (and only with)
ip6tables-restore, it will be silently ignored. Any other uses will throw an
error. This option allows
to put both
IPv4 and IPv6 rules in a single rule file
error. This option allows IPv4 and IPv6 rules in a single rule file
for use with both iptables-restore and ip6tables-restore.
.TP
\fB\-6\fP, \fB\-\-ipv6\fP
If a rule using the \fB\-6\fP option is inserted with (and only with)
iptables-restore, it will be silently ignored. Any other uses will throw an
error. This option allows
to put both
IPv4 and IPv6 rules in a single rule file
error. This option allows IPv4 and IPv6 rules in a single rule file
for use with both iptables-restore and ip6tables-restore.
This option has no effect in ip6tables and ip6tables-restore.
.TP
...
...
iptables/nft-arp.c
View file @
eb1d7c5f
...
...
@@ -604,6 +604,8 @@ nft_arp_print_rule(struct nft_handle *h, struct nftnl_rule *r,
if
(
!
(
format
&
FMT_NONEWLINE
))
fputc
(
'\n'
,
stdout
);
nft_clear_iptables_command_state
(
&
cs
);
}
static
bool
nft_arp_is_same
(
const
void
*
data_a
,
...
...
@@ -633,31 +635,6 @@ static bool nft_arp_is_same(const void *data_a,
(
unsigned
char
*
)
b
->
arp
.
outiface_mask
);
}
static
bool
nft_arp_rule_find
(
struct
nft_handle
*
h
,
struct
nftnl_rule
*
r
,
void
*
data
)
{
const
struct
iptables_command_state
*
cs
=
data
;
struct
iptables_command_state
this
=
{};
bool
ret
=
false
;
/* Delete by matching rule case */
nft_rule_to_iptables_command_state
(
h
,
r
,
&
this
);
if
(
!
nft_arp_is_same
(
&
cs
->
arp
,
&
this
.
arp
))
goto
out
;
if
(
!
compare_targets
(
cs
->
target
,
this
.
target
))
goto
out
;
if
(
this
.
jumpto
&&
strcmp
(
cs
->
jumpto
,
this
.
jumpto
)
!=
0
)
goto
out
;
ret
=
true
;
out:
h
->
ops
->
clear_cs
(
&
this
);
return
ret
;
}
static
void
nft_arp_save_chain
(
const
struct
nftnl_chain
*
c
,
const
char
*
policy
)
{
const
char
*
chain
=
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_NAME
);
...
...
@@ -675,11 +652,9 @@ struct nft_family_ops nft_family_ops_arp = {
.
print_header
=
nft_arp_print_header
,
.
print_rule
=
nft_arp_print_rule
,
.
save_rule
=
nft_arp_save_rule
,
.
save_counters
=
save_counters
,
.
save_chain
=
nft_arp_save_chain
,
.
post_parse
=
NULL
,
.
rule_to_cs
=
nft_rule_to_iptables_command_state
,
.
clear_cs
=
nft_clear_iptables_command_state
,
.
rule_find
=
nft_arp_rule_find
,
.
parse_target
=
nft_ipv46_parse_target
,
};
iptables/nft-bridge.c
View file @
eb1d7c5f
...
...
@@ -421,11 +421,20 @@ static struct nftnl_set *set_from_lookup_expr(struct nft_xt_ctx *ctx,
const
struct
nftnl_expr
*
e
)
{
const
char
*
set_name
=
nftnl_expr_get_str
(
e
,
NFTNL_EXPR_LOOKUP_SET
);
uint32_t
set_id
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_LOOKUP_SET_ID
);
struct
nftnl_set_list
*
slist
;
struct
nftnl_set
*
set
;
slist
=
nft_set_list_get
(
ctx
->
h
,
ctx
->
table
,
set_name
);
if
(
slist
)
return
nftnl_set_list_lookup_byname
(
slist
,
set_name
);
if
(
slist
)
{
set
=
nftnl_set_list_lookup_byname
(
slist
,
set_name
);
if
(
set
)
return
set
;
set
=
nft_set_batch_lookup_byid
(
ctx
->
h
,
set_id
);
if
(
set
)
return
set
;
}
return
NULL
;
}
...
...
@@ -747,41 +756,6 @@ static bool nft_bridge_is_same(const void *data_a, const void *data_b)
return
strcmp
(
a
->
in
,
b
->
in
)
==
0
&&
strcmp
(
a
->
out
,
b
->
out
)
==
0
;
}
static
bool
nft_bridge_rule_find
(
struct
nft_handle
*
h
,
struct
nftnl_rule
*
r
,
void
*
data
)
{
struct
iptables_command_state
*
cs
=
data
;
struct
iptables_command_state
this
=
{};
bool
ret
=
false
;
nft_rule_to_ebtables_command_state
(
h
,
r
,
&
this
);
DEBUGP
(
"comparing with... "
);
if
(
!
nft_bridge_is_same
(
cs
,
&
this
))
goto
out
;
if
(
!
compare_matches
(
cs
->
matches
,
this
.
matches
))
{
DEBUGP
(
"Different matches
\n
"
);
goto
out
;
}
if
(
!
compare_targets
(
cs
->
target
,
this
.
target
))
{
DEBUGP
(
"Different target
\n
"
);
goto
out
;
}
if
(
cs
->
jumpto
!=
NULL
&&
strcmp
(
cs
->
jumpto
,
this
.
jumpto
)
!=
0
)
{
DEBUGP
(
"Different verdict
\n
"
);
goto
out
;
}
ret
=
true
;
out:
h
->
ops
->
clear_cs
(
&
this
);
return
ret
;
}
static
int
xlate_ebmatches
(
const
struct
iptables_command_state
*
cs
,
struct
xt_xlate
*
xl
)
{
int
ret
=
1
,
numeric
=
cs
->
options
&
OPT_NUMERIC
;
...
...
@@ -958,11 +932,9 @@ struct nft_family_ops nft_family_ops_bridge = {
.
print_header
=
nft_bridge_print_header
,
.
print_rule
=
nft_bridge_print_rule
,
.
save_rule
=
nft_bridge_save_rule
,
.
save_counters
=
save_counters
,
.
save_chain
=
nft_bridge_save_chain
,
.
post_parse
=
NULL
,
.
rule_to_cs
=
nft_rule_to_ebtables_command_state
,
.
clear_cs
=
ebt_cs_clean
,
.
rule_find
=
nft_bridge_rule_find
,
.
xlate
=
nft_bridge_xlate
,
};
iptables/nft-cache.c
View file @
eb1d7c5f
...
...
@@ -11,6 +11,7 @@
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <xtables.h>
...
...
@@ -24,6 +25,52 @@
#include "nft.h"
#include "nft-cache.h"
static
void
cache_chain_list_insert
(
struct
list_head
*
list
,
const
char
*
name
)
{
struct
cache_chain
*
pos
=
NULL
,
*
new
;
list_for_each_entry
(
pos
,
list
,
head
)
{
int
cmp
=
strcmp
(
pos
->
name
,
name
);
if
(
!
cmp
)
return
;
if
(
cmp
>
0
)
break
;
}
new
=
xtables_malloc
(
sizeof
(
*
new
));
new
->
name
=
strdup
(
name
);
list_add_tail
(
&
new
->
head
,
pos
?
&
pos
->
head
:
list
);
}
void
nft_cache_level_set
(
struct
nft_handle
*
h
,
int
level
,
const
struct
nft_cmd
*
cmd
)
{
struct
nft_cache_req
*
req
=
&
h
->
cache_req
;
if
(
level
>
req
->
level
)
req
->
level
=
level
;
if
(
!
cmd
||
!
cmd
->
table
||
req
->
all_chains
)
return
;
if
(
!
req
->
table
)
req
->
table
=
strdup
(
cmd
->
table
);
else
assert
(
!
strcmp
(
req
->
table
,
cmd
->
table
));
if
(
!
cmd
->
chain
)
{
req
->
all_chains
=
true
;
return
;
}
cache_chain_list_insert
(
&
req
->
chain_list
,
cmd
->
chain
);
if
(
cmd
->
rename
)
cache_chain_list_insert
(
&
req
->
chain_list
,
cmd
->
rename
);
if
(
cmd
->
jumpto
)
cache_chain_list_insert
(
&
req
->
chain_list
,
cmd
->
jumpto
);
}
static
int
genid_cb
(
const
struct
nlmsghdr
*
nlh
,
void
*
data
)
{
uint32_t
*
genid
=
data
;
...
...
@@ -86,7 +133,7 @@ static int fetch_table_cache(struct nft_handle *h)
char
buf
[
16536
];
struct
nlmsghdr
*
nlh
;
struct
nftnl_table_list
*
list
;
int
ret
;
int
i
,
ret
;
if
(
h
->
cache
->
tables
)
return
0
;
...
...
@@ -104,6 +151,21 @@ static int fetch_table_cache(struct nft_handle *h)
h
->
cache
->
tables
=
list
;
for
(
i
=
0
;
i
<
NFT_TABLE_MAX
;
i
++
)
{
enum
nft_table_type
type
=
h
->
tables
[
i
].
type
;
if
(
!
h
->
tables
[
i
].
name
)
continue
;
h
->
cache
->
table
[
type
].
chains
=
nftnl_chain_list_alloc
();
if
(
!
h
->
cache
->
table
[
type
].
chains
)
return
0
;
h
->
cache
->
table
[
type
].
sets
=
nftnl_set_list_alloc
();
if
(
!
h
->
cache
->
table
[
type
].
sets
)
return
0
;
}
return
1
;
}
...
...
@@ -239,40 +301,31 @@ static int fetch_set_cache(struct nft_handle *h,
.
h
=
h
,
.
t
=
t
,
};
uint16_t
flags
=
NLM_F_DUMP
;
struct
nftnl_set
*
s
=
NULL
;
struct
nlmsghdr
*
nlh
;
char
buf
[
16536
];
int
i
,
ret
;
if
(
!
t
)
{
for
(
i
=
0
;
i
<
NFT_TABLE_MAX
;
i
++
)
{
enum
nft_table_type
type
=
h
->
tables
[
i
].
type
;
if
(
t
)
{
s
=
nftnl_set_alloc
();
if
(
!
s
)
return
-
1
;
if
(
!
h
->
tables
[
i
].
name
)
continue
;
nftnl_set_set_str
(
s
,
NFTNL_SET_TABLE
,
t
->
name
);
h
->
cache
->
table
[
type
].
sets
=
nftnl_set_list_alloc
();
if
(
!
h
->
cache
->
table
[
type
].
sets
)
return
-
1
;
if
(
set
)
{
nftnl_set_set_str
(
s
,
NFTNL_SET_NAME
,
set
);
flags
=
NLM_F_ACK
;
}
}
else
if
(
!
h
->
cache
->
table
[
t
->
type
].
sets
)
{
h
->
cache
->
table
[
t
->
type
].
sets
=
nftnl_set_list_alloc
();
}
if
(
t
&&
set
)
{
struct
nftnl_set
*
s
=
nftnl_set_alloc
();
if
(
!
s
)
return
-
1
;
nlh
=
nftnl_set_nlmsg_build_hdr
(
buf
,
NFT_MSG_GETSET
,
h
->
family
,
flags
,
h
->
seq
);
nlh
=
nftnl_set_nlmsg_build_hdr
(
buf
,
NFT_MSG_GETSET
,
h
->
family
,
NLM_F_ACK
,
h
->
seq
);
nftnl_set_set_str
(
s
,
NFTNL_SET_TABLE
,
t
->
name
);
nftnl_set_set_str
(
s
,
NFTNL_SET_NAME
,
set
);
if
(
s
)
{
nftnl_set_nlmsg_build_payload
(
nlh
,
s
);
nftnl_set_free
(
s
);
}
else
{
nlh
=
nftnl_set_nlmsg_build_hdr
(
buf
,
NFT_MSG_GETSET
,
h
->
family
,
NLM_F_DUMP
,
h
->
seq
);
}
ret
=
mnl_talk
(
h
,
nlh
,
nftnl_set_list_cb
,
&
d
);
...
...
@@ -281,13 +334,7 @@ static int fetch_set_cache(struct nft_handle *h,
return
ret
;
}
if
(
t
&&
set
)
{
struct
nftnl_set
*
s
;
s
=
nftnl_set_list_lookup_byname
(
h
->
cache
->
table
[
t
->
type
].
sets
,
set
);
set_fetch_elem_cb
(
s
,
h
);
}
else
if
(
t
)
{
if
(
t
)
{
nftnl_set_list_foreach
(
h
->
cache
->
table
[
t
->
type
].
sets
,
set_fetch_elem_cb
,
h
);
}
else
{
...
...
@@ -304,9 +351,9 @@ static int fetch_set_cache(struct nft_handle *h,
return
ret
;
}
static
int
fetch_chain_cache
(
struct
nft_handle
*
h
,
const
struct
builtin_table
*
t
,
const
char
*
chain
)
static
int
__
fetch_chain_cache
(
struct
nft_handle
*
h
,
const
struct
builtin_table
*
t
,
const
struct
nftnl_
chain
*
c
)
{
struct
nftnl_chain_list_cb_data
d
=
{
.
h
=
h
,
...
...
@@ -314,51 +361,47 @@ static int fetch_chain_cache(struct nft_handle *h,
};
char
buf
[
16536
];
struct
nlmsghdr
*
nlh
;
int
i
,
ret
;
int
ret
;
if
(
!
t
)
{
for
(
i
=
0
;
i
<
NFT_TABLE_MAX
;
i
++
)
{
enum
nft_table_type
type
=
h
->
tables
[
i
].
type
;
nlh
=
nftnl_chain_nlmsg_build_hdr
(
buf
,
NFT_MSG_GETCHAIN
,
h
->
family
,
c
?
NLM_F_ACK
:
NLM_F_DUMP
,
h
->
seq
);
if
(
c
)
nftnl_chain_nlmsg_build_payload
(
nlh
,
c
);
if
(
!
h
->
tables
[
i
].
name
)
continue
;
ret
=
mnl_talk
(
h
,
nlh
,
nftnl_chain_list_cb
,
&
d
);
if
(
ret
<
0
&&
errno
==
EINTR
)
assert
(
nft_restart
(
h
)
>=
0
);
if
(
h
->
cache
->
table
[
type
].
chains
)
continue
;
return
ret
;
}
h
->
cache
->
table
[
type
].
chains
=
nftnl_chain_list_alloc
();
if
(
!
h
->
cache
->
table
[
type
].
chains
)
return
-
1
;
}
}
else
if
(
!
h
->
cache
->
table
[
t
->
type
].
chains
)
{
h
->
cache
->
table
[
t
->
type
].
chains
=
nftnl_chain_list_alloc
();
if
(
!
h
->
cache
->
table
[
t
->
type
].
chains
)
return
-
1
;
}
static
int
fetch_chain_cache
(
struct
nft_handle
*
h
,
const
struct
builtin_table
*
t
,
struct
list_head
*
chains
)
{
struct
cache_chain
*
cc
;
struct
nftnl_chain
*
c
;
int
rc
,
ret
=
0
;
if
(
t
&&
chain
)
{
struct
nftnl_chain
*
c
=
nftnl_chain_alloc
(
);
if
(
!
chain
s
)
return
__fetch_chain_cache
(
h
,
t
,
NULL
);
if
(
!
c
)
return
-
1
;
assert
(
t
);
nlh
=
nftnl_chain_nlmsg_build_hdr
(
buf
,
NFT_MSG_GETCHAIN
,
h
->
family
,
NLM_F_ACK
,
h
->
seq
);
nftnl_chain_set_str
(
c
,
NFTNL_CHAIN_TABLE
,
t
->
name
);
nftnl_chain_set_str
(
c
,
NFTNL_CHAIN_NAME
,
chain
);
nftnl_chain_nlmsg_build_payload
(
nlh
,
c
);
nftnl_chain_free
(
c
);
}
else
{
nlh
=
nftnl_chain_nlmsg_build_hdr
(
buf
,
NFT_MSG_GETCHAIN
,
h
->
family
,
NLM_F_DUMP
,
h
->
seq
);
}
c
=
nftnl_chain_alloc
();
if
(
!
c
)
return
-
1
;
ret
=
mnl_talk
(
h
,
nlh
,
nftnl_chain_list_cb
,
&
d
);
if
(
ret
<
0
&&
errno
==
EINTR
)
assert
(
nft_restart
(
h
)
>=
0
);
nftnl_chain_set_str
(
c
,
NFTNL_CHAIN_TABLE
,
t
->
name
);
list_for_each_entry
(
cc
,
chains
,
head
)
{
nftnl_chain_set_str
(
c
,
NFTNL_CHAIN_NAME
,
cc
->
name
);
rc
=
__fetch_chain_cache
(
h
,
t
,
c
);
if
(
rc
)
ret
=
rc
;
}
nftnl_chain_free
(
c
);
return
ret
;
}
...
...
@@ -417,20 +460,14 @@ static int nft_rule_list_update(struct nftnl_chain *c, void *data)
}
static
int
fetch_rule_cache
(
struct
nft_handle
*
h
,
const
struct
builtin_table
*
t
,
const
char
*
chain
)
const
struct
builtin_table
*
t
)
{
int
i
;
if
(
t
)
{
struct
nftnl_chain_list
*
list
;
struct
nftnl_chain
*
c
;
list
=
h
->
cache
->
table
[
t
->
type
].
chains
;
struct
nftnl_chain_list
*
list
=
h
->
cache
->
table
[
t
->
type
].
chains
;
if
(
chain
)
{
c
=
nftnl_chain_list_lookup_byname
(
list
,
chain
);
return
nft_rule_list_update
(
c
,
h
);
}
return
nftnl_chain_list_foreach
(
list
,
nft_rule_list_update
,
h
);
}
...
...
@@ -447,89 +484,46 @@ static int fetch_rule_cache(struct nft_handle *h,
return
0
;
}
static
int
flush_cache
(
struct
nft_handle
*
h
,
struct
nft_cache
*
c
,
const
char
*
tablename
);
static
void
__nft_build_cache
(
struct
nft_handle
*
h
,
enum
nft_cache_level
level
,
const
struct
builtin_table
*
t
,
const
char
*
set
,
const
char
*
chain
)
__nft_build_cache
(
struct
nft_handle
*
h
)
{
uint32_t
genid_start
,
genid_stop
;
struct
nft_cache_req
*
req
=
&
h
->
cache_req
;
const
struct
builtin_table
*
t
=
NULL
;
struct
list_head
*
chains
=
NULL
;
uint32_t
genid_check
;
if
(
level
<=
h
->
cache_
level
)
if
(
h
->
cache_
init
)
return
;
retry:
mnl_genid_get
(
h
,
&
genid_start
);
if
(
h
->
cache_level
&&
genid_start
!=
h
->
nft_genid
)
flush_chain_cache
(
h
,
NULL
);
switch
(
h
->
cache_level
)
{
case
NFT_CL_NONE
:
fetch_table_cache
(
h
);
if
(
level
==
NFT_CL_TABLES
)
break
;
/* fall through */
case
NFT_CL_TABLES
:
fetch_chain_cache
(
h
,
t
,
chain
);
if
(
level
==
NFT_CL_CHAINS
)
break
;
/* fall through */
case
NFT_CL_CHAINS
:
fetch_set_cache
(
h
,
t
,
set
);
if
(
level
==
NFT_CL_SETS
)
break
;
/* fall through */
case
NFT_CL_SETS
:
fetch_rule_cache
(
h
,
t
,
chain
);
if
(
level
==
NFT_CL_RULES
)
break
;
/* fall through */
case
NFT_CL_RULES
:
break
;
}
mnl_genid_get
(
h
,
&
genid_stop
);
if
(
genid_start
!=
genid_stop
)
{
flush_chain_cache
(
h
,
NULL
);
goto
retry
;
if
(
req
->
table
)
{
t
=
nft_table_builtin_find
(
h
,
req
->
table
);
if
(
!
req
->
all_chains
)
chains
=
&
req
->
chain_list
;
}
if
(
!
t
&&
!
chain
)
h
->
cache_level
=
level
;
else
if
(
h
->
cache_level
<
NFT_CL_TABLES
)
h
->
cache_level
=
NFT_CL_TABLES
;
h
->
nft_genid
=
genid_start
;
}
void
nft_build_cache
(
struct
nft_handle
*
h
,
struct
nftnl_chain
*
c
)
{
const
struct
builtin_table
*
t
;
const
char
*
table
,
*
chain
;
if
(
!
c
)
return
__nft_build_cache
(
h
,
NFT_CL_RULES
,
NULL
,
NULL
,
NULL
);
table
=
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_TABLE
);
chain
=
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_NAME
);
t
=
nft_table_builtin_find
(
h
,
table
);
__nft_build_cache
(
h
,
NFT_CL_RULES
,
t
,
NULL
,
chain
);
}
void
nft_fake_cache
(
struct
nft_handle
*
h
)
{
int
i
;
fetch_table_cache
(
h
);
for
(
i
=
0
;
i
<
NFT_TABLE_MAX
;
i
++
)
{
enum
nft_table_type
type
=
h
->
tables
[
i
].
type
;
if
(
!
h
->
tables
[
i
].
name
)
continue
;
h
->
cache_init
=
true
;
retry:
mnl_genid_get
(
h
,
&
h
->
nft_genid
);
h
->
cache
->
table
[
type
].
chains
=
nftnl_chain_list_alloc
();
if
(
req
->
level
>=
NFT_CL_TABLES
)
fetch_table_cache
(
h
);
if
(
req
->
level
==
NFT_CL_FAKE
)
return
;
if
(
req
->
level
>=
NFT_CL_CHAINS
)
fetch_chain_cache
(
h
,
t
,
chains
);
if
(
req
->
level
>=
NFT_CL_SETS
)
fetch_set_cache
(
h
,
t
,
NULL
);
if
(
req
->
level
>=
NFT_CL_RULES
)
fetch_rule_cache
(
h
,
t
);
mnl_genid_get
(
h
,
&
genid_check
);
if
(
h
->
nft_genid
!=
genid_check
)
{
flush_cache
(
h
,
h
->
cache
,
NULL
);
goto
retry
;
}
h
->
cache_level
=
NFT_CL_RULES
;
mnl_genid_get
(
h
,
&
h
->
nft_genid
);
}
static
void
__nft_flush_cache
(
struct
nft_handle
*
h
)
...
...
@@ -610,51 +604,93 @@ static int flush_cache(struct nft_handle *h, struct nft_cache *c,
if
(
h
->
tables
[
i
].
name
==
NULL
)
continue
;
if
(
!
c
->
table
[
i
].
chains
)
continue
;
nftnl_chain_list_free
(
c
->
table
[
i
].
chains
);
c
->
table
[
i
].
chains
=
NULL
;
if
(
c
->
table
[
i
].
sets
)
if
(
c
->
table
[
i
].
chains
)
{
nftnl_chain_list_free
(
c
->
table
[
i
].
chains
);
c
->
table
[
i
].
chains
=
NULL
;
}
if
(
c
->
table
[
i
].
sets
)
{
nftnl_set_list_free
(
c
->
table
[
i
].
sets
);
c
->
table
[
i
].
sets
=
NULL
;
c
->
table
[
i
].
sets
=
NULL
;
}
}
if
(
c
->
tables
)
{
nftnl_table_list_free
(
c
->
tables
);
c
->
tables
=
NULL
;
}
nftnl_table_list_free
(
c
->
tables
);
c
->
tables
=
NULL
;
return
1
;
}
void
flush_chain_cache
(
struct
nft_handle
*
h
,
const
char
*
tablename
)
{
if
(
!
h
->
cache_
level
)
if
(
!
h
->
cache_
init
)
return
;
if
(
flush_cache
(
h
,
h
->
cache
,
tablename
))
h
->
cache_
level
=
NFT_CL_NONE
;
h
->
cache_
init
=
false
;
}
void
nft_rebuild_cache
(
struct
nft_handle
*
h
)
{
enum
nft_cache_level
level
=
h
->
cache_level
;
if
(
h
->
cache_level
)
if
(
h
->
cache_init
)
{
__nft_flush_cache
(
h
);
h
->
cache_init
=
false
;
}
__nft_build_cache
(
h
);
}
void
nft_cache_build
(
struct
nft_handle
*
h
)
{
struct
nft_cache_req
*
req
=
&
h
->
cache_req
;
const
struct
builtin_table
*
t
=
NULL
;
int
i
;
if
(
req
->
table
)
t
=
nft_table_builtin_find
(
h
,
req
->
table
);
h
->
cache_level
=
NFT_CL_NONE
;
__nft_build_cache
(
h
,
level
,
NULL
,
NULL
,
NULL
);
/* fetch builtin chains as well (if existing) so nft_xt_builtin_init()
* doesn't override policies by accident */
if
(
t
&&
!
req
->
all_chains
)
{
for
(
i
=
0
;
i
<
NF_INET_NUMHOOKS
;
i
++
)
{
const
char
*
cname
=
t
->
chains
[
i
].
name
;
if
(
!
cname
)
break
;
cache_chain_list_insert
(
&
req
->
chain_list
,
cname
);
}
}
__nft_build_cache
(
h
);
}
void
nft_release_cache
(
struct
nft_handle
*
h
)
{
if
(
h
->
cache_index
)
flush_cache
(
h
,
&
h
->
__cache
[
0
],
NULL
);
struct
nft_cache_req
*
req
=
&
h
->
cache_req
;
struct
cache_chain
*
cc
,
*
cc_tmp
;
while
(
h
->
cache_index
)
flush_cache
(
h
,
&
h
->
__cache
[
h
->
cache_index
--
],
NULL
);
flush_cache
(
h
,
&
h
->
__cache
[
0
],
NULL
);
h
->
cache
=
&
h
->
__cache
[
0
];
h
->
cache_init
=
false
;
if
(
req
->
level
!=
NFT_CL_FAKE
)
req
->
level
=
NFT_CL_TABLES
;
if
(
req
->
table
)
{
free
(
req
->
table
);
req
->
table
=
NULL
;
}
req
->
all_chains
=
false
;
list_for_each_entry_safe
(
cc
,
cc_tmp
,
&
req
->
chain_list
,
head
)
{
list_del
(
&
cc
->
head
);
free
(
cc
->
name
);
free
(
cc
);
}
}
struct
nftnl_table_list
*
nftnl_table_list_get
(
struct
nft_handle
*
h
)
{
__nft_build_cache
(
h
,
NFT_CL_TABLES
,
NULL
,
NULL
,
NULL
);
return
h
->
cache
->
tables
;
}
...
...
@@ -667,8 +703,6 @@ nft_set_list_get(struct nft_handle *h, const char *table, const char *set)
if
(
!
t
)
return
NULL
;
__nft_build_cache
(
h
,
NFT_CL_RULES
,
t
,
set
,
NULL
);
return
h
->
cache
->
table
[
t
->
type
].
sets
;
}
...
...
@@ -681,8 +715,6 @@ nft_chain_list_get(struct nft_handle *h, const char *table, const char *chain)
if
(
!
t
)
return
NULL
;
__nft_build_cache
(
h
,
NFT_CL_CHAINS
,
t
,
NULL
,
chain
);
return
h
->
cache
->
table
[
t
->
type
].
chains
;
}
iptables/nft-cache.h
View file @
eb1d7c5f
...
...
@@ -2,14 +2,16 @@
#define _NFT_CACHE_H_
struct
nft_handle
;
struct
nft_cmd
;
void
nft_
fake_
cache
(
struct
nft_handle
*
h
);
void
nft_build_cache
(
struct
nft_handle
*
h
,
struct
nft
nl_chain
*
c
);
void
nft_cache
_level_set
(
struct
nft_handle
*
h
,
int
level
,
const
struct
nft
_cmd
*
c
md
);
void
nft_rebuild_cache
(
struct
nft_handle
*
h
);
void
nft_release_cache
(
struct
nft_handle
*
h
);
void
flush_chain_cache
(
struct
nft_handle
*
h
,
const
char
*
tablename
);
int
flush_rule_cache
(
struct
nft_handle
*
h
,
const
char
*
table
,
struct
nftnl_chain
*
c
);
void
nft_cache_build
(
struct
nft_handle
*
h
);
struct
nftnl_chain_list
*
nft_chain_list_get
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
);
...
...
iptables/nft-cmd.c
0 → 100644
View file @
eb1d7c5f
/*
* (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code has been sponsored by Sophos Astaro <http://www.sophos.com>
*/
#include <stdlib.h>
#include <string.h>
#include "nft.h"
#include "nft-cmd.h"
struct
nft_cmd
*
nft_cmd_new
(
struct
nft_handle
*
h
,
int
command
,
const
char
*
table
,
const
char
*
chain
,
struct
iptables_command_state
*
state
,
int
rulenum
,
bool
verbose
)
{
struct
nftnl_rule
*
rule
;
struct
nft_cmd
*
cmd
;
cmd
=
calloc
(
1
,
sizeof
(
struct
nft_cmd
));
if
(
!
cmd
)
return
NULL
;
cmd
->
command
=
command
;
cmd
->
table
=
strdup
(
table
);
if
(
chain
)
cmd
->
chain
=
strdup
(
chain
);
cmd
->
rulenum
=
rulenum
;
cmd
->
verbose
=
verbose
;
if
(
state
)
{
rule
=
nft_rule_new
(
h
,
chain
,
table
,
state
);
if
(
!
rule
)
return
NULL
;
cmd
->
obj
.
rule
=
rule
;
if
(
!
state
->
target
&&
strlen
(
state
->
jumpto
)
>
0
)
cmd
->
jumpto
=
strdup
(
state
->
jumpto
);
}
list_add_tail
(
&
cmd
->
head
,
&
h
->
cmd_list
);
return
cmd
;
}
void
nft_cmd_free
(
struct
nft_cmd
*
cmd
)
{
free
((
void
*
)
cmd
->
table
);
free
((
void
*
)
cmd
->
chain
);
free
((
void
*
)
cmd
->
policy
);
free
((
void
*
)
cmd
->
rename
);
free
((
void
*
)
cmd
->
jumpto
);
switch
(
cmd
->
command
)
{
case
NFT_COMPAT_RULE_CHECK
:
case
NFT_COMPAT_RULE_DELETE
:
if
(
cmd
->
obj
.
rule
)
nftnl_rule_free
(
cmd
->
obj
.
rule
);
break
;
default:
break
;
}
list_del
(
&
cmd
->
head
);
free
(
cmd
);
}
static
void
nft_cmd_rule_bridge
(
struct
nft_handle
*
h
,
const
struct
nft_cmd
*
cmd
)
{
const
struct
builtin_table
*
t
;
t
=
nft_table_builtin_find
(
h
,
cmd
->
table
);
if
(
!
t
)
return
;
/* Since ebtables user-defined chain policies are implemented as last
* rule in nftables, rule cache is required here to treat them right.
*/
if
(
h
->
family
==
NFPROTO_BRIDGE
&&
!
nft_chain_builtin_find
(
t
,
cmd
->
chain
))
nft_cache_level_set
(
h
,
NFT_CL_RULES
,
cmd
);
else
nft_cache_level_set
(
h
,
NFT_CL_CHAINS
,
cmd
);
}
int
nft_cmd_rule_append
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
struct
iptables_command_state
*
state
,
void
*
ref
,
bool
verbose
)
{
struct
nft_cmd
*
cmd
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_RULE_APPEND
,
table
,
chain
,
state
,
-
1
,
verbose
);
if
(
!
cmd
)
return
0
;
nft_cmd_rule_bridge
(
h
,
cmd
);
return
1
;
}
int
nft_cmd_rule_insert
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
struct
iptables_command_state
*
state
,
int
rulenum
,
bool
verbose
)
{
struct
nft_cmd
*
cmd
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_RULE_INSERT
,
table
,
chain
,
state
,
rulenum
,
verbose
);
if
(
!
cmd
)
return
0
;
nft_cmd_rule_bridge
(
h
,
cmd
);
if
(
cmd
->
rulenum
>
0
)
nft_cache_level_set
(
h
,
NFT_CL_RULES
,
cmd
);
else
nft_cache_level_set
(
h
,
NFT_CL_CHAINS
,
cmd
);
return
1
;
}
int
nft_cmd_rule_delete
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
struct
iptables_command_state
*
state
,
bool
verbose
)
{
struct
nft_cmd
*
cmd
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_RULE_DELETE
,
table
,
chain
,
state
,
-
1
,
verbose
);
if
(
!
cmd
)
return
0
;
nft_cache_level_set
(
h
,
NFT_CL_RULES
,
cmd
);
return
1
;
}
int
nft_cmd_rule_delete_num
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
int
rulenum
,
bool
verbose
)
{
struct
nft_cmd
*
cmd
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_RULE_DELETE
,
table
,
chain
,
NULL
,
rulenum
,
verbose
);
if
(
!
cmd
)
return
0
;
nft_cache_level_set
(
h
,
NFT_CL_RULES
,
cmd
);
return
1
;
}
int
nft_cmd_rule_flush
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
bool
verbose
)
{
struct
nft_cmd
*
cmd
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_RULE_FLUSH
,
table
,
chain
,
NULL
,
-
1
,
verbose
);
if
(
!
cmd
)
return
0
;
if
(
chain
||
verbose
)
nft_cache_level_set
(
h
,
NFT_CL_CHAINS
,
cmd
);
else
nft_cache_level_set
(
h
,
NFT_CL_TABLES
,
cmd
);
return
1
;
}
int
nft_cmd_chain_zero_counters
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
bool
verbose
)
{
struct
nft_cmd
*
cmd
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_CHAIN_ZERO
,
table
,
chain
,
NULL
,
-
1
,
verbose
);
if
(
!
cmd
)
return
0
;
nft_cache_level_set
(
h
,
NFT_CL_CHAINS
,
cmd
);
return
1
;
}
int
nft_cmd_chain_user_add
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
)
{
struct
nft_cmd
*
cmd
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_CHAIN_USER_ADD
,
table
,
chain
,
NULL
,
-
1
,
false
);
if
(
!
cmd
)
return
0
;
nft_cache_level_set
(
h
,
NFT_CL_CHAINS
,
cmd
);
return
1
;
}
int
nft_cmd_chain_user_del
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
bool
verbose
)
{
struct
nft_cmd
*
cmd
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_CHAIN_USER_DEL
,
table
,
chain
,
NULL
,
-
1
,
verbose
);
if
(
!
cmd
)
return
0
;
/* This triggers nft_bridge_chain_postprocess() when fetching the
* rule cache.
*/
if
(
h
->
family
==
NFPROTO_BRIDGE
)
nft_cache_level_set
(
h
,
NFT_CL_RULES
,
cmd
);
else
nft_cache_level_set
(
h
,
NFT_CL_CHAINS
,
cmd
);
return
1
;
}
int
nft_cmd_chain_user_rename
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
const
char
*
newname
)
{
struct
nft_cmd
*
cmd
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_CHAIN_RENAME
,
table
,
chain
,
NULL
,
-
1
,
false
);
if
(
!
cmd
)
return
0
;
cmd
->
rename
=
strdup
(
newname
);
nft_cache_level_set
(
h
,
NFT_CL_CHAINS
,
cmd
);
return
1
;
}
int
nft_cmd_rule_list
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
int
rulenum
,
unsigned
int
format
)
{
struct
nft_cmd
*
cmd
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_RULE_LIST
,
table
,
chain
,
NULL
,
rulenum
,
false
);
if
(
!
cmd
)
return
0
;
cmd
->
format
=
format
;
nft_cache_level_set
(
h
,
NFT_CL_RULES
,
cmd
);
return
1
;
}
int
nft_cmd_rule_replace
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
,
int
rulenum
,
bool
verbose
)
{
struct
nft_cmd
*
cmd
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_RULE_REPLACE
,
table
,
chain
,
data
,
rulenum
,
verbose
);
if
(
!
cmd
)
return
0
;
nft_cache_level_set
(
h
,
NFT_CL_RULES
,
cmd
);
return
1
;
}
int
nft_cmd_rule_check
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
,
bool
verbose
)
{
struct
nft_cmd
*
cmd
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_RULE_CHECK
,
table
,
chain
,
data
,
-
1
,
verbose
);
if
(
!
cmd
)
return
0
;
nft_cache_level_set
(
h
,
NFT_CL_RULES
,
cmd
);
return
1
;
}
int
nft_cmd_chain_set
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
,
const
char
*
policy
,
const
struct
xt_counters
*
counters
)
{
struct
nft_cmd
*
cmd
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_CHAIN_UPDATE
,
table
,
chain
,
NULL
,
-
1
,
false
);
if
(
!
cmd
)
return
0
;
cmd
->
policy
=
strdup
(
policy
);
if
(
counters
)
cmd
->
counters
=
*
counters
;
nft_cache_level_set
(
h
,
NFT_CL_CHAINS
,
cmd
);
return
1
;
}
int
nft_cmd_table_flush
(
struct
nft_handle
*
h
,
const
char
*
table
)
{
struct
nft_cmd
*
cmd
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_TABLE_FLUSH
,
table
,
NULL
,
NULL
,
-
1
,
false
);
if
(
!
cmd
)
return
0
;
nft_cache_level_set
(
h
,
NFT_CL_TABLES
,
cmd
);
return
1
;
}
int
nft_cmd_chain_restore
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
)
{
struct
nft_cmd
*
cmd
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_CHAIN_RESTORE
,
table
,
chain
,
NULL
,
-
1
,
false
);
if
(
!
cmd
)
return
0
;
nft_cache_level_set
(
h
,
NFT_CL_CHAINS
,
cmd
);
return
1
;
}
int
nft_cmd_rule_zero_counters
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
int
rulenum
)
{
struct
nft_cmd
*
cmd
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_RULE_ZERO
,
table
,
chain
,
NULL
,
rulenum
,
false
);
if
(
!
cmd
)
return
0
;
nft_cache_level_set
(
h
,
NFT_CL_RULES
,
cmd
);
return
1
;
}
int
nft_cmd_rule_list_save
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
int
rulenum
,
int
counters
)
{
struct
nft_cmd
*
cmd
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_RULE_SAVE
,
table
,
chain
,
NULL
,
rulenum
,
false
);
if
(
!
cmd
)
return
0
;
cmd
->
counters_save
=
counters
;
nft_cache_level_set
(
h
,
NFT_CL_RULES
,
cmd
);
return
1
;
}
int
ebt_cmd_user_chain_policy
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
,
const
char
*
policy
)
{
struct
nft_cmd
*
cmd
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE
,
table
,
chain
,
NULL
,
-
1
,
false
);
if
(
!
cmd
)
return
0
;
cmd
->
policy
=
strdup
(
policy
);
nft_cache_level_set
(
h
,
NFT_CL_RULES
,
cmd
);
return
1
;
}
void
nft_cmd_table_new
(
struct
nft_handle
*
h
,
const
char
*
table
)
{
nft_cmd_new
(
h
,
NFT_COMPAT_TABLE_NEW
,
table
,
NULL
,
NULL
,
-
1
,
false
);
}
iptables/nft-cmd.h
0 → 100644
View file @
eb1d7c5f
#ifndef _NFT_CMD_H_
#define _NFT_CMD_H_
#include <libiptc/linux_list.h>
#include <stdbool.h>
#include "nft.h"
struct
nftnl_rule
;
struct
nft_cmd
{
struct
list_head
head
;
int
command
;
const
char
*
table
;
const
char
*
chain
;
const
char
*
jumpto
;
int
rulenum
;
bool
verbose
;
unsigned
int
format
;
struct
{
struct
nftnl_rule
*
rule
;
struct
nftnl_set
*
set
;
}
obj
;
const
char
*
policy
;
struct
xt_counters
counters
;
const
char
*
rename
;
int
counters_save
;
};
struct
nft_cmd
*
nft_cmd_new
(
struct
nft_handle
*
h
,
int
command
,
const
char
*
table
,
const
char
*
chain
,
struct
iptables_command_state
*
state
,
int
rulenum
,
bool
verbose
);
void
nft_cmd_free
(
struct
nft_cmd
*
cmd
);
int
nft_cmd_rule_append
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
struct
iptables_command_state
*
state
,
void
*
ref
,
bool
verbose
);
int
nft_cmd_rule_insert
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
struct
iptables_command_state
*
state
,
int
rulenum
,
bool
verbose
);
int
nft_cmd_rule_delete
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
struct
iptables_command_state
*
state
,
bool
verbose
);
int
nft_cmd_rule_delete_num
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
int
rulenum
,
bool
verbose
);
int
nft_cmd_rule_flush
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
bool
verbose
);
int
nft_cmd_zero_counters
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
bool
verbose
);
int
nft_cmd_chain_user_add
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
);
int
nft_cmd_chain_user_del
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
bool
verbose
);
int
nft_cmd_chain_zero_counters
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
bool
verbose
);
int
nft_cmd_rule_list
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
int
rulenum
,
unsigned
int
format
);
int
nft_cmd_rule_check
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
,
bool
verbose
);
int
nft_cmd_chain_set
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
,
const
char
*
policy
,
const
struct
xt_counters
*
counters
);
int
nft_cmd_chain_user_rename
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
const
char
*
newname
);
int
nft_cmd_rule_replace
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
,
int
rulenum
,
bool
verbose
);
int
nft_cmd_table_flush
(
struct
nft_handle
*
h
,
const
char
*
table
);
int
nft_cmd_chain_restore
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
);
int
nft_cmd_rule_zero_counters
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
int
rulenum
);
int
nft_cmd_rule_list_save
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
int
rulenum
,
int
counters
);
int
ebt_cmd_user_chain_policy
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
,
const
char
*
policy
);
void
nft_cmd_table_new
(
struct
nft_handle
*
h
,
const
char
*
table
);
#endif
/* _NFT_CMD_H_ */
iptables/nft-ipv4.c
View file @
eb1d7c5f
...
...
@@ -288,7 +288,7 @@ static void nft_ipv4_print_rule(struct nft_handle *h, struct nftnl_rule *r,
if
(
!
(
format
&
FMT_NONEWLINE
))
fputc
(
'\n'
,
stdout
);
xtables_rule_matches_free
(
&
cs
.
matche
s
);
nft_clear_iptables_command_state
(
&
c
s
);
}
static
void
save_ipv4_addr
(
char
letter
,
const
struct
in_addr
*
addr
,
...
...
@@ -450,13 +450,11 @@ struct nft_family_ops nft_family_ops_ipv4 = {
.
print_header
=
print_header
,
.
print_rule
=
nft_ipv4_print_rule
,
.
save_rule
=
nft_ipv4_save_rule
,
.
save_counters
=
save_counters
,
.
save_chain
=
nft_ipv46_save_chain
,
.
proto_parse
=
nft_ipv4_proto_parse
,
.
post_parse
=
nft_ipv4_post_parse
,
.
parse_target
=
nft_ipv46_parse_target
,
.
rule_to_cs
=
nft_rule_to_iptables_command_state
,
.
clear_cs
=
nft_clear_iptables_command_state
,
.
rule_find
=
nft_ipv46_rule_find
,
.
xlate
=
nft_ipv4_xlate
,
};
iptables/nft-ipv6.c
View file @
eb1d7c5f
...
...
@@ -217,7 +217,7 @@ static void nft_ipv6_print_rule(struct nft_handle *h, struct nftnl_rule *r,
if
(
!
(
format
&
FMT_NONEWLINE
))
fputc
(
'\n'
,
stdout
);
xtables_rule_matches_free
(
&
cs
.
matche
s
);
nft_clear_iptables_command_state
(
&
c
s
);
}
static
void
save_ipv6_addr
(
char
letter
,
const
struct
in6_addr
*
addr
,
...
...
@@ -402,13 +402,11 @@ struct nft_family_ops nft_family_ops_ipv6 = {
.
print_header
=
print_header
,
.
print_rule
=
nft_ipv6_print_rule
,
.
save_rule
=
nft_ipv6_save_rule
,
.
save_counters
=
save_counters
,
.
save_chain
=
nft_ipv46_save_chain
,
.
proto_parse
=
nft_ipv6_proto_parse
,
.
post_parse
=
nft_ipv6_post_parse
,
.
parse_target
=
nft_ipv46_parse_target
,
.
rule_to_cs
=
nft_rule_to_iptables_command_state
,
.
clear_cs
=
nft_clear_iptables_command_state
,
.
rule_find
=
nft_ipv46_rule_find
,
.
xlate
=
nft_ipv6_xlate
,
};
iptables/nft-shared.c
View file @
eb1d7c5f
...
...
@@ -831,14 +831,6 @@ void save_rule_details(const struct iptables_command_state *cs,
}
}
void
save_counters
(
const
void
*
data
)
{
const
struct
iptables_command_state
*
cs
=
data
;
printf
(
"[%llu:%llu] "
,
(
unsigned
long
long
)
cs
->
counters
.
pcnt
,
(
unsigned
long
long
)
cs
->
counters
.
bcnt
);
}
void
nft_ipv46_save_chain
(
const
struct
nftnl_chain
*
c
,
const
char
*
policy
)
{
const
char
*
chain
=
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_NAME
);
...
...
@@ -989,41 +981,6 @@ void nft_ipv46_parse_target(struct xtables_target *t, void *data)
cs
->
target
=
t
;
}
bool
nft_ipv46_rule_find
(
struct
nft_handle
*
h
,
struct
nftnl_rule
*
r
,
void
*
data
)
{
struct
iptables_command_state
*
cs
=
data
,
this
=
{};
bool
ret
=
false
;
nft_rule_to_iptables_command_state
(
h
,
r
,
&
this
);
DEBUGP
(
"comparing with... "
);
#ifdef DEBUG_DEL
nft_rule_print_save
(
r
,
NFT_RULE_APPEND
,
0
);
#endif
if
(
!
h
->
ops
->
is_same
(
cs
,
&
this
))
goto
out
;
if
(
!
compare_matches
(
cs
->
matches
,
this
.
matches
))
{
DEBUGP
(
"Different matches
\n
"
);
goto
out
;
}
if
(
!
compare_targets
(
cs
->
target
,
this
.
target
))
{
DEBUGP
(
"Different target
\n
"
);
goto
out
;
}
if
(
strcmp
(
cs
->
jumpto
,
this
.
jumpto
)
!=
0
)
{
DEBUGP
(
"Different verdict
\n
"
);
goto
out
;
}
ret
=
true
;
out:
h
->
ops
->
clear_cs
(
&
this
);
return
ret
;
}
void
nft_check_xt_legacy
(
int
family
,
bool
is_ipt_save
)
{
static
const
char
tables6
[]
=
"/proc/net/ip6_tables_names"
;
...
...
iptables/nft-shared.h
View file @
eb1d7c5f
...
...
@@ -98,7 +98,6 @@ struct nft_family_ops {
void
(
*
print_rule
)(
struct
nft_handle
*
h
,
struct
nftnl_rule
*
r
,
unsigned
int
num
,
unsigned
int
format
);
void
(
*
save_rule
)(
const
void
*
data
,
unsigned
int
format
);
void
(
*
save_counters
)(
const
void
*
data
);
void
(
*
save_chain
)(
const
struct
nftnl_chain
*
c
,
const
char
*
policy
);
void
(
*
proto_parse
)(
struct
iptables_command_state
*
cs
,
struct
xtables_args
*
args
);
...
...
@@ -109,8 +108,6 @@ struct nft_family_ops {
void
(
*
rule_to_cs
)(
struct
nft_handle
*
h
,
const
struct
nftnl_rule
*
r
,
struct
iptables_command_state
*
cs
);
void
(
*
clear_cs
)(
struct
iptables_command_state
*
cs
);
bool
(
*
rule_find
)(
struct
nft_handle
*
h
,
struct
nftnl_rule
*
r
,
void
*
data
);
int
(
*
xlate
)(
const
void
*
data
,
struct
xt_xlate
*
xl
);
};
...
...
@@ -162,7 +159,6 @@ void save_rule_details(const struct iptables_command_state *cs,
unsigned
const
char
*
iniface_mask
,
const
char
*
outiface
,
unsigned
const
char
*
outiface_mask
);
void
save_counters
(
const
void
*
data
);
void
nft_ipv46_save_chain
(
const
struct
nftnl_chain
*
c
,
const
char
*
policy
);
void
save_matches_and_target
(
const
struct
iptables_command_state
*
cs
,
bool
goto_flag
,
const
void
*
fw
,
...
...
@@ -171,8 +167,6 @@ void save_matches_and_target(const struct iptables_command_state *cs,
struct
nft_family_ops
*
nft_family_ops_lookup
(
int
family
);
void
nft_ipv46_parse_target
(
struct
xtables_target
*
t
,
void
*
data
);
bool
nft_ipv46_rule_find
(
struct
nft_handle
*
h
,
struct
nftnl_rule
*
r
,
void
*
data
);
bool
compare_matches
(
struct
xtables_rule_match
*
mt1
,
struct
xtables_rule_match
*
mt2
);
bool
compare_targets
(
struct
xtables_target
*
tg1
,
struct
xtables_target
*
tg2
);
...
...
iptables/nft.c
View file @
eb1d7c5f
...
...
@@ -256,24 +256,6 @@ static int mnl_batch_talk(struct nft_handle *h, int numcmds)
return
err
;
}
enum
obj_update_type
{
NFT_COMPAT_TABLE_ADD
,
NFT_COMPAT_TABLE_FLUSH
,
NFT_COMPAT_CHAIN_ADD
,
NFT_COMPAT_CHAIN_USER_ADD
,
NFT_COMPAT_CHAIN_USER_DEL
,
NFT_COMPAT_CHAIN_USER_FLUSH
,
NFT_COMPAT_CHAIN_UPDATE
,
NFT_COMPAT_CHAIN_RENAME
,
NFT_COMPAT_CHAIN_ZERO
,
NFT_COMPAT_RULE_APPEND
,
NFT_COMPAT_RULE_INSERT
,
NFT_COMPAT_RULE_REPLACE
,
NFT_COMPAT_RULE_DELETE
,
NFT_COMPAT_RULE_FLUSH
,
NFT_COMPAT_SET_ADD
,
};
enum
obj_action
{
NFT_COMPAT_COMMIT
,
NFT_COMPAT_ABORT
,
...
...
@@ -362,6 +344,15 @@ static int mnl_append_error(const struct nft_handle *h,
snprintf
(
tcr
,
sizeof
(
tcr
),
"set %s"
,
nftnl_set_get_str
(
o
->
set
,
NFTNL_SET_NAME
));
break
;
case
NFT_COMPAT_RULE_LIST
:
case
NFT_COMPAT_RULE_CHECK
:
case
NFT_COMPAT_CHAIN_RESTORE
:
case
NFT_COMPAT_RULE_SAVE
:
case
NFT_COMPAT_RULE_ZERO
:
case
NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE
:
case
NFT_COMPAT_TABLE_NEW
:
assert
(
0
);
break
;
}
return
snprintf
(
buf
,
len
,
"%s: %s"
,
errmsg
,
tcr
);
...
...
@@ -411,6 +402,38 @@ batch_rule_add(struct nft_handle *h, enum obj_update_type type,
return
batch_add
(
h
,
type
,
r
);
}
static
void
batch_obj_del
(
struct
nft_handle
*
h
,
struct
obj_update
*
o
);
static
void
batch_chain_flush
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
)
{
struct
obj_update
*
obj
,
*
tmp
;
list_for_each_entry_safe
(
obj
,
tmp
,
&
h
->
obj_list
,
head
)
{
struct
nftnl_rule
*
r
=
obj
->
ptr
;
switch
(
obj
->
type
)
{
case
NFT_COMPAT_RULE_APPEND
:
case
NFT_COMPAT_RULE_INSERT
:
case
NFT_COMPAT_RULE_REPLACE
:
case
NFT_COMPAT_RULE_DELETE
:
break
;
default:
continue
;
}
if
(
table
&&
strcmp
(
table
,
nftnl_rule_get_str
(
r
,
NFTNL_RULE_TABLE
)))
continue
;
if
(
chain
&&
strcmp
(
chain
,
nftnl_rule_get_str
(
r
,
NFTNL_RULE_CHAIN
)))
continue
;
batch_obj_del
(
h
,
obj
);
}
}
const
struct
builtin_table
xtables_ipv4
[
NFT_TABLE_MAX
]
=
{
[
NFT_TABLE_RAW
]
=
{
.
name
=
"raw"
,
...
...
@@ -746,6 +769,9 @@ static int nft_xt_builtin_init(struct nft_handle *h, const char *table)
{
const
struct
builtin_table
*
t
;
if
(
!
h
->
cache_init
)
return
0
;
t
=
nft_table_builtin_find
(
h
,
table
);
if
(
t
==
NULL
)
return
-
1
;
...
...
@@ -756,6 +782,9 @@ static int nft_xt_builtin_init(struct nft_handle *h, const char *table)
if
(
nft_table_builtin_add
(
h
,
t
)
<
0
)
return
-
1
;
if
(
h
->
cache_req
.
level
<
NFT_CL_CHAINS
)
return
0
;
nft_chain_builtin_init
(
h
,
t
);
h
->
cache
->
table
[
t
->
type
].
initialized
=
true
;
...
...
@@ -789,8 +818,10 @@ int nft_restart(struct nft_handle *h)
return
0
;
}
int
nft_init
(
struct
nft_handle
*
h
,
const
struct
builtin_table
*
t
)
int
nft_init
(
struct
nft_handle
*
h
,
int
family
,
const
struct
builtin_table
*
t
)
{
memset
(
h
,
0
,
sizeof
(
*
h
));
h
->
nl
=
mnl_socket_open
(
NETLINK_NETFILTER
);
if
(
h
->
nl
==
NULL
)
return
-
1
;
...
...
@@ -800,19 +831,37 @@ int nft_init(struct nft_handle *h, const struct builtin_table *t)
return
-
1
;
}
h
->
ops
=
nft_family_ops_lookup
(
family
);
if
(
!
h
->
ops
)
xtables_error
(
PARAMETER_PROBLEM
,
"Unknown family"
);
h
->
portid
=
mnl_socket_get_portid
(
h
->
nl
);
h
->
tables
=
t
;
h
->
cache
=
&
h
->
__cache
[
0
];
h
->
family
=
family
;
INIT_LIST_HEAD
(
&
h
->
obj_list
);
INIT_LIST_HEAD
(
&
h
->
err_list
);
INIT_LIST_HEAD
(
&
h
->
cmd_list
);
INIT_LIST_HEAD
(
&
h
->
cache_req
.
chain_list
);
return
0
;
}
void
nft_fini
(
struct
nft_handle
*
h
)
{
flush_chain_cache
(
h
,
NULL
);
struct
list_head
*
pos
,
*
n
;
list_for_each_safe
(
pos
,
n
,
&
h
->
cmd_list
)
nft_cmd_free
(
list_entry
(
pos
,
struct
nft_cmd
,
head
));
list_for_each_safe
(
pos
,
n
,
&
h
->
obj_list
)
batch_obj_del
(
h
,
list_entry
(
pos
,
struct
obj_update
,
head
));
list_for_each_safe
(
pos
,
n
,
&
h
->
err_list
)
mnl_err_list_free
(
list_entry
(
pos
,
struct
mnl_err
,
head
));
nft_release_cache
(
h
);
mnl_socket_close
(
h
->
nl
);
}
...
...
@@ -950,6 +999,7 @@ static struct nftnl_set *add_anon_set(struct nft_handle *h, const char *table,
{
static
uint32_t
set_id
=
0
;
struct
nftnl_set
*
s
;
struct
nft_cmd
*
cmd
;
s
=
nftnl_set_alloc
();
if
(
!
s
)
...
...
@@ -965,7 +1015,14 @@ static struct nftnl_set *add_anon_set(struct nft_handle *h, const char *table,
nftnl_set_set_u32
(
s
,
NFTNL_SET_KEY_LEN
,
key_len
);
nftnl_set_set_u32
(
s
,
NFTNL_SET_DESC_SIZE
,
size
);
return
batch_set_add
(
h
,
NFT_COMPAT_SET_ADD
,
s
)
?
s
:
NULL
;
cmd
=
nft_cmd_new
(
h
,
NFT_COMPAT_SET_ADD
,
table
,
NULL
,
NULL
,
-
1
,
false
);
if
(
!
cmd
)
{
nftnl_set_free
(
s
);
return
NULL
;
}
cmd
->
obj
.
set
=
s
;
return
s
;
}
static
struct
nftnl_expr
*
...
...
@@ -1022,19 +1079,28 @@ static int __add_nft_among(struct nft_handle *h, const char *table,
};
struct
nftnl_expr
*
e
;
struct
nftnl_set
*
s
;
uint32_t
flags
=
0
;
int
idx
=
0
;
if
(
ip
)
{
type
=
type
<<
CONCAT_TYPE_BITS
|
NFT_DATATYPE_IPADDR
;
len
+=
sizeof
(
struct
in_addr
)
+
NETLINK_ALIGN
-
1
;
len
&=
~
(
NETLINK_ALIGN
-
1
);
flags
=
NFT_SET_INTERVAL
;
}
s
=
add_anon_set
(
h
,
table
,
0
,
type
,
len
,
cnt
);
s
=
add_anon_set
(
h
,
table
,
flags
,
type
,
len
,
cnt
);
if
(
!
s
)
return
-
ENOMEM
;
set_id
=
nftnl_set_get_u32
(
s
,
NFTNL_SET_ID
);
if
(
ip
)
{
uint8_t
field_len
[
2
]
=
{
ETH_ALEN
,
sizeof
(
struct
in_addr
)
};
nftnl_set_set_data
(
s
,
NFTNL_SET_DESC_CONCAT
,
field_len
,
sizeof
(
field_len
));
}
for
(
idx
=
0
;
idx
<
cnt
;
idx
++
)
{
struct
nftnl_set_elem
*
elem
=
nftnl_set_elem_alloc
();
...
...
@@ -1042,6 +1108,15 @@ static int __add_nft_among(struct nft_handle *h, const char *table,
return
-
ENOMEM
;
nftnl_set_elem_set
(
elem
,
NFTNL_SET_ELEM_KEY
,
&
pairs
[
idx
],
len
);
if
(
ip
)
{
struct
in_addr
tmp
=
pairs
[
idx
].
in
;
if
(
tmp
.
s_addr
==
INADDR_ANY
)
pairs
[
idx
].
in
.
s_addr
=
INADDR_BROADCAST
;
nftnl_set_elem_set
(
elem
,
NFTNL_SET_ELEM_KEY_END
,
&
pairs
[
idx
],
len
);
pairs
[
idx
].
in
=
tmp
;
}
nftnl_set_elem_add
(
s
,
elem
);
}
...
...
@@ -1302,7 +1377,7 @@ void add_compat(struct nftnl_rule *r, uint32_t proto, bool inv)
inv
?
NFT_RULE_COMPAT_F_INV
:
0
);
}
static
struct
nftnl_rule
*
struct
nftnl_rule
*
nft_rule_new
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
)
{
...
...
@@ -1330,28 +1405,15 @@ nft_chain_find(struct nft_handle *h, const char *table, const char *chain);
int
nft_rule_append
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
,
struct
nftnl_rule
*
ref
,
bool
verbose
)
struct
nftnl_rule
*
r
,
struct
nftnl_rule
*
ref
,
bool
verbose
)
{
struct
nftnl_chain
*
c
;
struct
nftnl_rule
*
r
;
int
type
;
nft_xt_builtin_init
(
h
,
table
);
/* Since ebtables user-defined chain policies are implemented as last
* rule in nftables, rule cache is required here to treat them right. */
if
(
h
->
family
==
NFPROTO_BRIDGE
)
{
c
=
nft_chain_find
(
h
,
table
,
chain
);
if
(
c
&&
!
nft_chain_builtin
(
c
))
nft_build_cache
(
h
,
c
);
}
nft_fn
=
nft_rule_append
;
r
=
nft_rule_new
(
h
,
chain
,
table
,
data
);
if
(
r
==
NULL
)
return
0
;
if
(
ref
)
{
nftnl_rule_set_u64
(
r
,
NFTNL_RULE_HANDLE
,
nftnl_rule_get_u64
(
ref
,
NFTNL_RULE_HANDLE
));
...
...
@@ -1359,17 +1421,16 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
}
else
type
=
NFT_COMPAT_RULE_APPEND
;
if
(
batch_rule_add
(
h
,
type
,
r
)
==
NULL
)
{
nftnl_rule_free
(
r
);
if
(
batch_rule_add
(
h
,
type
,
r
)
==
NULL
)
return
0
;
}
if
(
verbose
)
h
->
ops
->
print_rule
(
h
,
r
,
0
,
FMT_PRINT_RULE
);
if
(
ref
)
{
nftnl_chain_rule_insert_at
(
r
,
ref
);
nftnl_chain_rule_del
(
r
);
nftnl_chain_rule_del
(
ref
);
nftnl_rule_free
(
ref
);
}
else
{
c
=
nft_chain_find
(
h
,
table
,
chain
);
if
(
!
c
)
{
...
...
@@ -1392,8 +1453,9 @@ nft_rule_print_save(struct nft_handle *h, const struct nftnl_rule *r,
ops
->
rule_to_cs
(
h
,
r
,
&
cs
);
if
(
!
(
format
&
(
FMT_NOCOUNTS
|
FMT_C_COUNTS
))
&&
ops
->
save_counters
)
ops
->
save_counters
(
&
cs
);
if
(
!
(
format
&
(
FMT_NOCOUNTS
|
FMT_C_COUNTS
)))
printf
(
"[%llu:%llu] "
,
(
unsigned
long
long
)
cs
.
counters
.
pcnt
,
(
unsigned
long
long
)
cs
.
counters
.
bcnt
);
/* print chain name */
switch
(
type
)
{
...
...
@@ -1576,7 +1638,6 @@ int nft_rule_save(struct nft_handle *h, const char *table, unsigned int format)
c
=
nftnl_chain_list_iter_next
(
iter
);
while
(
c
)
{
nft_build_cache
(
h
,
c
);
ret
=
nft_chain_save_rules
(
h
,
c
,
format
);
if
(
ret
!=
0
)
break
;
...
...
@@ -1590,6 +1651,20 @@ int nft_rule_save(struct nft_handle *h, const char *table, unsigned int format)
return
ret
==
0
?
1
:
0
;
}
struct
nftnl_set
*
nft_set_batch_lookup_byid
(
struct
nft_handle
*
h
,
uint32_t
set_id
)
{
struct
obj_update
*
n
;
list_for_each_entry
(
n
,
&
h
->
obj_list
,
head
)
{
if
(
n
->
type
==
NFT_COMPAT_SET_ADD
&&
nftnl_set_get_u32
(
n
->
set
,
NFTNL_SET_ID
)
==
set_id
)
return
n
->
set
;
}
return
NULL
;
}
static
void
__nft_rule_flush
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
,
bool
verbose
,
bool
implicit
)
...
...
@@ -1646,6 +1721,7 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table,
}
if
(
chain
||
!
verbose
)
{
batch_chain_flush
(
h
,
table
,
chain
);
__nft_rule_flush
(
h
,
table
,
chain
,
verbose
,
false
);
flush_rule_cache
(
h
,
table
,
c
);
return
1
;
...
...
@@ -1661,6 +1737,7 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table,
while
(
c
!=
NULL
)
{
chain
=
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_NAME
);
batch_chain_flush
(
h
,
table
,
chain
);
__nft_rule_flush
(
h
,
table
,
chain
,
verbose
,
false
);
flush_rule_cache
(
h
,
table
,
c
);
c
=
nftnl_chain_list_iter_next
(
iter
);
...
...
@@ -1722,7 +1799,7 @@ int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table
}
else
{
c
=
nftnl_chain_alloc
();
if
(
!
c
)
return
-
1
;
return
0
;
nftnl_chain_set_str
(
c
,
NFTNL_CHAIN_TABLE
,
table
);
nftnl_chain_set_str
(
c
,
NFTNL_CHAIN_NAME
,
chain
);
...
...
@@ -1733,7 +1810,7 @@ int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table
nftnl_chain_set_u32
(
c
,
NFTNL_CHAIN_POLICY
,
NF_ACCEPT
);
if
(
!
created
)
return
0
;
return
1
;
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_USER_ADD
,
c
);
...
...
@@ -1741,7 +1818,8 @@ int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table
if
(
list
)
nftnl_chain_list_add
(
c
,
list
);
return
ret
;
/* the core expects 1 for success and 0 for error */
return
ret
==
0
?
1
:
0
;
}
/* From linux/netlink.h */
...
...
@@ -1769,10 +1847,6 @@ static int __nft_chain_user_del(struct nftnl_chain *c, void *data)
fprintf
(
stdout
,
"Deleting chain `%s'
\n
"
,
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_NAME
));
/* This triggers required policy rule deletion. */
if
(
h
->
family
==
NFPROTO_BRIDGE
)
nft_build_cache
(
h
,
c
);
/* XXX This triggers a fast lookup from the kernel. */
nftnl_chain_unset
(
c
,
NFTNL_CHAIN_HANDLE
);
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_USER_DEL
,
c
);
...
...
@@ -2047,15 +2121,53 @@ static int __nft_rule_del(struct nft_handle *h, struct nftnl_rule *r)
return
1
;
}
static
bool
nft_rule_cmp
(
struct
nft_handle
*
h
,
struct
nftnl_rule
*
r
,
struct
nftnl_rule
*
rule
)
{
struct
iptables_command_state
_cs
=
{},
this
=
{},
*
cs
=
&
_cs
;
bool
ret
=
false
;
h
->
ops
->
rule_to_cs
(
h
,
r
,
&
this
);
h
->
ops
->
rule_to_cs
(
h
,
rule
,
cs
);
DEBUGP
(
"comparing with... "
);
#ifdef DEBUG_DEL
nft_rule_print_save
(
h
,
r
,
NFT_RULE_APPEND
,
0
);
#endif
if
(
!
h
->
ops
->
is_same
(
cs
,
&
this
))
goto
out
;
if
(
!
compare_matches
(
cs
->
matches
,
this
.
matches
))
{
DEBUGP
(
"Different matches
\n
"
);
goto
out
;
}
if
(
!
compare_targets
(
cs
->
target
,
this
.
target
))
{
DEBUGP
(
"Different target
\n
"
);
goto
out
;
}
if
((
!
cs
->
target
||
!
this
.
target
)
&&
strcmp
(
cs
->
jumpto
,
this
.
jumpto
)
!=
0
)
{
DEBUGP
(
"Different verdict
\n
"
);
goto
out
;
}
ret
=
true
;
out:
h
->
ops
->
clear_cs
(
&
this
);
h
->
ops
->
clear_cs
(
cs
);
return
ret
;
}
static
struct
nftnl_rule
*
nft_rule_find
(
struct
nft_handle
*
h
,
struct
nftnl_chain
*
c
,
void
*
data
,
int
rulenum
)
nft_rule_find
(
struct
nft_handle
*
h
,
struct
nftnl_chain
*
c
,
struct
nftnl_rule
*
rule
,
int
rulenum
)
{
struct
nftnl_rule
*
r
;
struct
nftnl_rule_iter
*
iter
;
bool
found
=
false
;
nft_build_cache
(
h
,
c
);
if
(
rulenum
>=
0
)
/* Delete by rule number case */
return
nftnl_rule_lookup_byindex
(
c
,
rulenum
);
...
...
@@ -2066,7 +2178,7 @@ nft_rule_find(struct nft_handle *h, struct nftnl_chain *c, void *data, int rulen
r
=
nftnl_rule_iter_next
(
iter
);
while
(
r
!=
NULL
)
{
found
=
h
->
ops
->
rule_
find
(
h
,
r
,
data
);
found
=
nft_
rule_
cmp
(
h
,
r
,
rule
);
if
(
found
)
break
;
r
=
nftnl_rule_iter_next
(
iter
);
...
...
@@ -2078,7 +2190,7 @@ nft_rule_find(struct nft_handle *h, struct nftnl_chain *c, void *data, int rulen
}
int
nft_rule_check
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
,
bool
verbose
)
const
char
*
table
,
struct
nftnl_rule
*
rule
,
bool
verbose
)
{
struct
nftnl_chain
*
c
;
struct
nftnl_rule
*
r
;
...
...
@@ -2089,7 +2201,7 @@ int nft_rule_check(struct nft_handle *h, const char *chain,
if
(
!
c
)
goto
fail_enoent
;
r
=
nft_rule_find
(
h
,
c
,
data
,
-
1
);
r
=
nft_rule_find
(
h
,
c
,
rule
,
-
1
);
if
(
r
==
NULL
)
goto
fail_enoent
;
...
...
@@ -2103,7 +2215,7 @@ fail_enoent:
}
int
nft_rule_delete
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
,
bool
verbose
)
const
char
*
table
,
struct
nftnl_rule
*
rule
,
bool
verbose
)
{
int
ret
=
0
;
struct
nftnl_chain
*
c
;
...
...
@@ -2117,7 +2229,7 @@ int nft_rule_delete(struct nft_handle *h, const char *chain,
return
0
;
}
r
=
nft_rule_find
(
h
,
c
,
data
,
-
1
);
r
=
nft_rule_find
(
h
,
c
,
rule
,
-
1
);
if
(
r
!=
NULL
)
{
ret
=
__nft_rule_del
(
h
,
r
);
if
(
ret
<
0
)
...
...
@@ -2132,16 +2244,11 @@ int nft_rule_delete(struct nft_handle *h, const char *chain,
static
struct
nftnl_rule
*
nft_rule_add
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
struct
iptables_command_stat
e
*
cs
,
const
char
*
table
,
struct
nftnl_rul
e
*
r
,
struct
nftnl_rule
*
ref
,
bool
verbose
)
{
struct
nftnl_rule
*
r
;
uint64_t
ref_id
;
r
=
nft_rule_new
(
h
,
chain
,
table
,
cs
);
if
(
r
==
NULL
)
return
NULL
;
if
(
ref
)
{
ref_id
=
nftnl_rule_get_u64
(
ref
,
NFTNL_RULE_HANDLE
);
if
(
ref_id
>
0
)
{
...
...
@@ -2158,10 +2265,8 @@ nft_rule_add(struct nft_handle *h, const char *chain,
}
}
if
(
!
batch_rule_add
(
h
,
NFT_COMPAT_RULE_INSERT
,
r
))
{
nftnl_rule_free
(
r
);
if
(
!
batch_rule_add
(
h
,
NFT_COMPAT_RULE_INSERT
,
r
))
return
NULL
;
}
if
(
verbose
)
h
->
ops
->
print_rule
(
h
,
r
,
0
,
FMT_PRINT_RULE
);
...
...
@@ -2170,9 +2275,10 @@ nft_rule_add(struct nft_handle *h, const char *chain,
}
int
nft_rule_insert
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
,
int
rulenum
,
bool
verbose
)
const
char
*
table
,
struct
nftnl_rule
*
new_rule
,
int
rulenum
,
bool
verbose
)
{
struct
nftnl_rule
*
r
=
NULL
,
*
new_rule
;
struct
nftnl_rule
*
r
=
NULL
;
struct
nftnl_chain
*
c
;
nft_xt_builtin_init
(
h
,
table
);
...
...
@@ -2186,22 +2292,22 @@ int nft_rule_insert(struct nft_handle *h, const char *chain,
}
if
(
rulenum
>
0
)
{
r
=
nft_rule_find
(
h
,
c
,
data
,
rulenum
);
r
=
nft_rule_find
(
h
,
c
,
new_rule
,
rulenum
);
if
(
r
==
NULL
)
{
/* special case: iptables allows to insert into
* rule_count + 1 position.
*/
r
=
nft_rule_find
(
h
,
c
,
data
,
rulenum
-
1
);
r
=
nft_rule_find
(
h
,
c
,
new_rule
,
rulenum
-
1
);
if
(
r
!=
NULL
)
return
nft_rule_append
(
h
,
chain
,
table
,
data
,
NULL
,
verbose
);
return
nft_rule_append
(
h
,
chain
,
table
,
new_rule
,
NULL
,
verbose
);
errno
=
E2BIG
;
goto
err
;
}
}
new_rule
=
nft_rule_add
(
h
,
chain
,
table
,
data
,
r
,
verbose
);
new_rule
=
nft_rule_add
(
h
,
chain
,
table
,
new_rule
,
r
,
verbose
);
if
(
!
new_rule
)
goto
err
;
...
...
@@ -2243,7 +2349,8 @@ int nft_rule_delete_num(struct nft_handle *h, const char *chain,
}
int
nft_rule_replace
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
,
int
rulenum
,
bool
verbose
)
const
char
*
table
,
struct
nftnl_rule
*
rule
,
int
rulenum
,
bool
verbose
)
{
int
ret
=
0
;
struct
nftnl_chain
*
c
;
...
...
@@ -2257,13 +2364,13 @@ int nft_rule_replace(struct nft_handle *h, const char *chain,
return
0
;
}
r
=
nft_rule_find
(
h
,
c
,
data
,
rulenum
);
r
=
nft_rule_find
(
h
,
c
,
rule
,
rulenum
);
if
(
r
!=
NULL
)
{
DEBUGP
(
"replacing rule with handle=%llu
\n
"
,
(
unsigned
long
long
)
nftnl_rule_get_u64
(
r
,
NFTNL_RULE_HANDLE
));
ret
=
nft_rule_append
(
h
,
chain
,
table
,
data
,
r
,
verbose
);
ret
=
nft_rule_append
(
h
,
chain
,
table
,
rule
,
r
,
verbose
);
}
else
errno
=
E2BIG
;
...
...
@@ -2496,8 +2603,8 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain,
const
char
*
table
,
int
rulenum
)
{
struct
iptables_command_state
cs
=
{};
struct
nftnl_rule
*
r
,
*
new_rule
;
struct
nftnl_chain
*
c
;
struct
nftnl_rule
*
r
;
int
ret
=
0
;
nft_fn
=
nft_rule_delete
;
...
...
@@ -2516,8 +2623,11 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain,
nft_rule_to_iptables_command_state
(
h
,
r
,
&
cs
);
cs
.
counters
.
pcnt
=
cs
.
counters
.
bcnt
=
0
;
new_rule
=
nft_rule_new
(
h
,
chain
,
table
,
&
cs
);
if
(
!
new_rule
)
return
1
;
ret
=
nft_rule_append
(
h
,
chain
,
table
,
&
cs
,
r
,
false
);
ret
=
nft_rule_append
(
h
,
chain
,
table
,
new_rule
,
r
,
false
);
error:
return
ret
;
...
...
@@ -2611,14 +2721,23 @@ static void batch_obj_del(struct nft_handle *h, struct obj_update *o)
case
NFT_COMPAT_RULE_APPEND
:
case
NFT_COMPAT_RULE_INSERT
:
case
NFT_COMPAT_RULE_REPLACE
:
case
NFT_COMPAT_RULE_DELETE
:
break
;
case
NFT_COMPAT_RULE_DELETE
:
case
NFT_COMPAT_RULE_FLUSH
:
nftnl_rule_free
(
o
->
rule
);
break
;
case
NFT_COMPAT_SET_ADD
:
nftnl_set_free
(
o
->
set
);
break
;
case
NFT_COMPAT_RULE_LIST
:
case
NFT_COMPAT_RULE_CHECK
:
case
NFT_COMPAT_CHAIN_RESTORE
:
case
NFT_COMPAT_RULE_SAVE
:
case
NFT_COMPAT_RULE_ZERO
:
case
NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE
:
case
NFT_COMPAT_TABLE_NEW
:
assert
(
0
);
break
;
}
h
->
obj_list_num
--
;
list_del
(
&
o
->
head
);
...
...
@@ -2686,6 +2805,13 @@ static void nft_refresh_transaction(struct nft_handle *h)
case
NFT_COMPAT_RULE_DELETE
:
case
NFT_COMPAT_RULE_FLUSH
:
case
NFT_COMPAT_SET_ADD
:
case
NFT_COMPAT_RULE_LIST
:
case
NFT_COMPAT_RULE_CHECK
:
case
NFT_COMPAT_CHAIN_RESTORE
:
case
NFT_COMPAT_RULE_SAVE
:
case
NFT_COMPAT_RULE_ZERO
:
case
NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE
:
case
NFT_COMPAT_TABLE_NEW
:
break
;
}
}
...
...
@@ -2783,6 +2909,14 @@ retry:
NLM_F_CREATE
,
&
n
->
seq
,
n
->
set
);
seq
=
n
->
seq
;
break
;
case
NFT_COMPAT_RULE_LIST
:
case
NFT_COMPAT_RULE_CHECK
:
case
NFT_COMPAT_CHAIN_RESTORE
:
case
NFT_COMPAT_RULE_SAVE
:
case
NFT_COMPAT_RULE_ZERO
:
case
NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE
:
case
NFT_COMPAT_TABLE_NEW
:
assert
(
0
);
}
mnl_nft_batch_continue
(
h
->
batch
);
...
...
@@ -2803,7 +2937,6 @@ retry:
nft_refresh_transaction
(
h
);
i
=
0
;
list_for_each_entry_safe
(
err
,
ne
,
&
h
->
err_list
,
head
)
mnl_err_list_free
(
err
);
...
...
@@ -2878,27 +3011,33 @@ static int ebt_add_policy_rule(struct nftnl_chain *c, void *data)
r
=
nft_rule_new
(
h
,
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_NAME
),
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_TABLE
),
&
cs
);
ebt_cs_clean
(
&
cs
);
if
(
!
r
)
return
-
1
;
udata
=
nftnl_udata_buf_alloc
(
NFT_USERDATA_MAXLEN
);
if
(
!
udata
)
return
-
1
;
goto
err_free_rule
;
if
(
!
nftnl_udata_put_u32
(
udata
,
UDATA_TYPE_EBTABLES_POLICY
,
1
))
return
-
1
;
goto
err_free_rule
;
nftnl_rule_set_data
(
r
,
NFTNL_RULE_USERDATA
,
nftnl_udata_buf_data
(
udata
),
nftnl_udata_buf_len
(
udata
));
nftnl_udata_buf_free
(
udata
);
if
(
!
batch_rule_add
(
h
,
NFT_COMPAT_RULE_APPEND
,
r
))
{
nftnl_rule_free
(
r
);
return
-
1
;
}
if
(
!
batch_rule_add
(
h
,
NFT_COMPAT_RULE_APPEND
,
r
))
goto
err_free_rule
;
/* add the rule to chain so it is freed later */
nftnl_chain_rule_add_tail
(
r
,
c
);
return
0
;
err_free_rule:
nftnl_rule_free
(
r
);
return
-
1
;
}
int
ebt_set_user_chain_policy
(
struct
nft_handle
*
h
,
const
char
*
table
,
...
...
@@ -2919,8 +3058,6 @@ int ebt_set_user_chain_policy(struct nft_handle *h, const char *table,
else
return
0
;
nft_build_cache
(
h
,
c
);
nftnl_chain_set_u32
(
c
,
NFTNL_CHAIN_POLICY
,
pval
);
return
1
;
}
...
...
@@ -2945,41 +3082,152 @@ static void nft_bridge_commit_prepare(struct nft_handle *h)
}
}
int
nft_commit
(
struct
nft_handle
*
h
)
static
void
assert_chain_exists
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
)
{
return
nft_action
(
h
,
NFT_COMPAT_COMMIT
);
if
(
chain
&&
!
nft_chain_exists
(
h
,
table
,
chain
))
xtables_error
(
PARAMETER_PROBLEM
,
"Chain '%s' does not exist"
,
chain
);
}
int
nft_
bridge_commit
(
struct
nft_handle
*
h
)
static
int
nft_
prepare
(
struct
nft_handle
*
h
)
{
nft_bridge_commit_prepare
(
h
);
return
nft_commit
(
h
);
struct
nft_cmd
*
cmd
,
*
next
;
int
ret
=
1
;
nft_cache_build
(
h
);
list_for_each_entry_safe
(
cmd
,
next
,
&
h
->
cmd_list
,
head
)
{
switch
(
cmd
->
command
)
{
case
NFT_COMPAT_TABLE_FLUSH
:
ret
=
nft_table_flush
(
h
,
cmd
->
table
);
break
;
case
NFT_COMPAT_CHAIN_USER_ADD
:
ret
=
nft_chain_user_add
(
h
,
cmd
->
chain
,
cmd
->
table
);
break
;
case
NFT_COMPAT_CHAIN_USER_DEL
:
ret
=
nft_chain_user_del
(
h
,
cmd
->
chain
,
cmd
->
table
,
cmd
->
verbose
);
break
;
case
NFT_COMPAT_CHAIN_RESTORE
:
ret
=
nft_chain_restore
(
h
,
cmd
->
chain
,
cmd
->
table
);
break
;
case
NFT_COMPAT_CHAIN_UPDATE
:
ret
=
nft_chain_set
(
h
,
cmd
->
table
,
cmd
->
chain
,
cmd
->
policy
,
&
cmd
->
counters
);
break
;
case
NFT_COMPAT_CHAIN_RENAME
:
ret
=
nft_chain_user_rename
(
h
,
cmd
->
chain
,
cmd
->
table
,
cmd
->
rename
);
break
;
case
NFT_COMPAT_CHAIN_ZERO
:
ret
=
nft_chain_zero_counters
(
h
,
cmd
->
chain
,
cmd
->
table
,
cmd
->
verbose
);
break
;
case
NFT_COMPAT_RULE_APPEND
:
assert_chain_exists
(
h
,
cmd
->
table
,
cmd
->
jumpto
);
ret
=
nft_rule_append
(
h
,
cmd
->
chain
,
cmd
->
table
,
cmd
->
obj
.
rule
,
NULL
,
cmd
->
verbose
);
break
;
case
NFT_COMPAT_RULE_INSERT
:
assert_chain_exists
(
h
,
cmd
->
table
,
cmd
->
jumpto
);
ret
=
nft_rule_insert
(
h
,
cmd
->
chain
,
cmd
->
table
,
cmd
->
obj
.
rule
,
cmd
->
rulenum
,
cmd
->
verbose
);
break
;
case
NFT_COMPAT_RULE_REPLACE
:
assert_chain_exists
(
h
,
cmd
->
table
,
cmd
->
jumpto
);
ret
=
nft_rule_replace
(
h
,
cmd
->
chain
,
cmd
->
table
,
cmd
->
obj
.
rule
,
cmd
->
rulenum
,
cmd
->
verbose
);
break
;
case
NFT_COMPAT_RULE_DELETE
:
assert_chain_exists
(
h
,
cmd
->
table
,
cmd
->
jumpto
);
if
(
cmd
->
rulenum
>=
0
)
ret
=
nft_rule_delete_num
(
h
,
cmd
->
chain
,
cmd
->
table
,
cmd
->
rulenum
,
cmd
->
verbose
);
else
ret
=
nft_rule_delete
(
h
,
cmd
->
chain
,
cmd
->
table
,
cmd
->
obj
.
rule
,
cmd
->
verbose
);
break
;
case
NFT_COMPAT_RULE_FLUSH
:
ret
=
nft_rule_flush
(
h
,
cmd
->
chain
,
cmd
->
table
,
cmd
->
verbose
);
break
;
case
NFT_COMPAT_RULE_LIST
:
ret
=
nft_rule_list
(
h
,
cmd
->
chain
,
cmd
->
table
,
cmd
->
rulenum
,
cmd
->
format
);
break
;
case
NFT_COMPAT_RULE_CHECK
:
assert_chain_exists
(
h
,
cmd
->
table
,
cmd
->
jumpto
);
ret
=
nft_rule_check
(
h
,
cmd
->
chain
,
cmd
->
table
,
cmd
->
obj
.
rule
,
cmd
->
rulenum
);
break
;
case
NFT_COMPAT_RULE_ZERO
:
ret
=
nft_rule_zero_counters
(
h
,
cmd
->
chain
,
cmd
->
table
,
cmd
->
rulenum
);
break
;
case
NFT_COMPAT_RULE_SAVE
:
ret
=
nft_rule_list_save
(
h
,
cmd
->
chain
,
cmd
->
table
,
cmd
->
rulenum
,
cmd
->
counters_save
);
break
;
case
NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE
:
ret
=
ebt_set_user_chain_policy
(
h
,
cmd
->
table
,
cmd
->
chain
,
cmd
->
policy
);
break
;
case
NFT_COMPAT_TABLE_NEW
:
nft_xt_builtin_init
(
h
,
cmd
->
table
);
ret
=
1
;
break
;
case
NFT_COMPAT_SET_ADD
:
nft_xt_builtin_init
(
h
,
cmd
->
table
);
batch_set_add
(
h
,
NFT_COMPAT_SET_ADD
,
cmd
->
obj
.
set
);
ret
=
1
;
break
;
case
NFT_COMPAT_TABLE_ADD
:
case
NFT_COMPAT_CHAIN_ADD
:
assert
(
0
);
break
;
}
nft_cmd_free
(
cmd
);
if
(
ret
==
0
)
return
0
;
}
return
1
;
}
int
nft_
abor
t
(
struct
nft_handle
*
h
)
int
nft_
commi
t
(
struct
nft_handle
*
h
)
{
return
nft_action
(
h
,
NFT_COMPAT_ABORT
);
if
(
!
nft_prepare
(
h
))
return
0
;
return
nft_action
(
h
,
NFT_COMPAT_COMMIT
);
}
int
nft_
abort_policy_rule
(
struct
nft_handle
*
h
,
const
char
*
table
)
int
nft_
bridge_commit
(
struct
nft_handle
*
h
)
{
struct
obj_update
*
n
,
*
tmp
;
if
(
!
nft_prepare
(
h
))
return
0
;
list_for_each_entry_safe
(
n
,
tmp
,
&
h
->
obj_list
,
head
)
{
if
(
n
->
type
!=
NFT_COMPAT_RULE_APPEND
&&
n
->
type
!=
NFT_COMPAT_RULE_DELETE
)
continue
;
nft_bridge_commit_prepare
(
h
);
if
(
strcmp
(
table
,
nftnl_rule_get_str
(
n
->
rule
,
NFTNL_RULE_TABLE
)))
continue
;
return
nft_action
(
h
,
NFT_COMPAT_COMMIT
);
}
if
(
!
nft_rule_is_policy_rule
(
n
->
rule
))
continue
;
int
nft_abort
(
struct
nft_handle
*
h
)
{
struct
nft_cmd
*
cmd
,
*
next
;
batch_obj_del
(
h
,
n
);
}
return
0
;
list_for_each_entry_safe
(
cmd
,
next
,
&
h
->
cmd_list
,
head
)
nft_cmd_free
(
cmd
);
return
nft_action
(
h
,
NFT_COMPAT_ABORT
);
}
int
nft_compatible_revision
(
const
char
*
name
,
uint8_t
rev
,
int
opt
)
...
...
@@ -3162,8 +3410,6 @@ static int __nft_chain_zero_counters(struct nftnl_chain *c, void *data)
return
-
1
;
}
nft_build_cache
(
h
,
c
);
iter
=
nftnl_rule_iter_create
(
c
);
if
(
iter
==
NULL
)
return
-
1
;
...
...
@@ -3300,8 +3546,6 @@ static int nft_is_chain_compatible(struct nftnl_chain *c, void *data)
enum
nf_inet_hooks
hook
;
int
prio
;
nft_build_cache
(
h
,
c
);
if
(
nftnl_rule_foreach
(
c
,
nft_is_rule_compatible
,
NULL
))
return
-
1
;
...
...
iptables/nft.h
View file @
eb1d7c5f
...
...
@@ -3,6 +3,8 @@
#include "xshared.h"
#include "nft-shared.h"
#include "nft-cache.h"
#include "nft-cmd.h"
#include <libiptc/linux_list.h>
enum
nft_table_type
{
...
...
@@ -28,11 +30,11 @@ struct builtin_table {
};
enum
nft_cache_level
{
NFT_CL_NONE
,
NFT_CL_TABLES
,
NFT_CL_CHAINS
,
NFT_CL_SETS
,
NFT_CL_RULES
NFT_CL_RULES
,
NFT_CL_FAKE
/* must be last entry */
};
struct
nft_cache
{
...
...
@@ -44,6 +46,43 @@ struct nft_cache {
}
table
[
NFT_TABLE_MAX
];
};
enum
obj_update_type
{
NFT_COMPAT_TABLE_ADD
,
NFT_COMPAT_TABLE_FLUSH
,
NFT_COMPAT_CHAIN_ADD
,
NFT_COMPAT_CHAIN_USER_ADD
,
NFT_COMPAT_CHAIN_USER_DEL
,
NFT_COMPAT_CHAIN_USER_FLUSH
,
NFT_COMPAT_CHAIN_UPDATE
,
NFT_COMPAT_CHAIN_RENAME
,
NFT_COMPAT_CHAIN_ZERO
,
NFT_COMPAT_RULE_APPEND
,
NFT_COMPAT_RULE_INSERT
,
NFT_COMPAT_RULE_REPLACE
,
NFT_COMPAT_RULE_DELETE
,
NFT_COMPAT_RULE_FLUSH
,
NFT_COMPAT_SET_ADD
,
NFT_COMPAT_RULE_LIST
,
NFT_COMPAT_RULE_CHECK
,
NFT_COMPAT_CHAIN_RESTORE
,
NFT_COMPAT_RULE_SAVE
,
NFT_COMPAT_RULE_ZERO
,
NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE
,
NFT_COMPAT_TABLE_NEW
,
};
struct
cache_chain
{
struct
list_head
head
;
char
*
name
;
};
struct
nft_cache_req
{
enum
nft_cache_level
level
;
char
*
table
;
bool
all_chains
;
struct
list_head
chain_list
;
};
struct
nft_handle
{
int
family
;
struct
mnl_socket
*
nl
;
...
...
@@ -62,10 +101,12 @@ struct nft_handle {
unsigned
int
cache_index
;
struct
nft_cache
__cache
[
2
];
struct
nft_cache
*
cache
;
enum
nft_cache_
level
cache_
level
;
struct
nft_cache_
req
cache_
req
;
bool
restore
;
bool
noflush
;
int8_t
config_done
;
struct
list_head
cmd_list
;
bool
cache_init
;
/* meta data, for error reporting */
struct
{
...
...
@@ -80,7 +121,7 @@ extern const struct builtin_table xtables_bridge[NFT_TABLE_MAX];
int
mnl_talk
(
struct
nft_handle
*
h
,
struct
nlmsghdr
*
nlh
,
int
(
*
cb
)(
const
struct
nlmsghdr
*
nlh
,
void
*
data
),
void
*
data
);
int
nft_init
(
struct
nft_handle
*
h
,
const
struct
builtin_table
*
t
);
int
nft_init
(
struct
nft_handle
*
h
,
int
family
,
const
struct
builtin_table
*
t
);
void
nft_fini
(
struct
nft_handle
*
h
);
int
nft_restart
(
struct
nft_handle
*
h
);
...
...
@@ -115,17 +156,24 @@ void nft_bridge_chain_postprocess(struct nft_handle *h,
struct
nftnl_chain
*
c
);
/*
* Operations with sets.
*/
struct
nftnl_set
*
nft_set_batch_lookup_byid
(
struct
nft_handle
*
h
,
uint32_t
set_id
);
/*
* Operations with rule-set.
*/
struct
nftnl_rule
;
int
nft_rule_append
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
,
struct
nftnl_rule
*
ref
,
bool
verbose
);
int
nft_rule_insert
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
,
int
rulenum
,
bool
verbose
);
int
nft_rule_check
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
,
bool
verbose
);
int
nft_rule_delete
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
,
bool
verbose
);
struct
nftnl_rule
*
nft_rule_new
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
);
int
nft_rule_append
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
struct
nftnl_rule
*
r
,
struct
nftnl_rule
*
ref
,
bool
verbose
);
int
nft_rule_insert
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
struct
nftnl_rule
*
r
,
int
rulenum
,
bool
verbose
);
int
nft_rule_check
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
struct
nftnl_rule
*
r
,
bool
verbose
);
int
nft_rule_delete
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
struct
nftnl_rule
*
r
,
bool
verbose
);
int
nft_rule_delete_num
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
int
rulenum
,
bool
verbose
);
int
nft_rule_replace
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
,
int
rulenum
,
bool
verbose
);
int
nft_rule_replace
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
struct
nftnl_rule
*
r
,
int
rulenum
,
bool
verbose
);
int
nft_rule_list
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
int
rulenum
,
unsigned
int
format
);
int
nft_rule_list_save
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
int
rulenum
,
int
counters
);
int
nft_rule_save
(
struct
nft_handle
*
h
,
const
char
*
table
,
unsigned
int
format
);
...
...
@@ -159,7 +207,6 @@ uint32_t nft_invflags2cmp(uint32_t invflags, uint32_t flag);
int
nft_commit
(
struct
nft_handle
*
h
);
int
nft_bridge_commit
(
struct
nft_handle
*
h
);
int
nft_abort
(
struct
nft_handle
*
h
);
int
nft_abort_policy_rule
(
struct
nft_handle
*
h
,
const
char
*
table
);
/*
* revision compatibility.
...
...
@@ -178,6 +225,7 @@ int nft_init_arp(struct nft_handle *h, const char *pname);
int
do_commandarp
(
struct
nft_handle
*
h
,
int
argc
,
char
*
argv
[],
char
**
table
,
bool
restore
);
/* For xtables-eb.c */
int
nft_init_eb
(
struct
nft_handle
*
h
,
const
char
*
pname
);
void
nft_fini_eb
(
struct
nft_handle
*
h
);
int
ebt_get_current_chain
(
const
char
*
chain
);
int
do_commandeb
(
struct
nft_handle
*
h
,
int
argc
,
char
*
argv
[],
char
**
table
,
bool
restore
);
...
...
Prev
1
2
3
4
5
6
7
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment