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
3bc9369c
"vscode:/vscode.git/clone" did not exist on "22003482b7b98851d61bf7e2c3b6d214730ec6c7"
Commit
3bc9369c
authored
Oct 24, 2018
by
Arturo Borrero Gonzalez
Browse files
New upstream version 1.8.1
parent
278668fa
Changes
98
Hide whitespace changes
Inline
Side-by-side
iptables/iptables.c
View file @
3bc9369c
...
@@ -405,27 +405,6 @@ parse_chain(const char *chainname)
...
@@ -405,27 +405,6 @@ parse_chain(const char *chainname)
"Invalid chain name `%s'"
,
chainname
);
"Invalid chain name `%s'"
,
chainname
);
}
}
static
const
char
*
parse_target
(
const
char
*
targetname
)
{
const
char
*
ptr
;
if
(
strlen
(
targetname
)
<
1
)
xtables_error
(
PARAMETER_PROBLEM
,
"Invalid target name (too short)"
);
if
(
strlen
(
targetname
)
>=
XT_EXTENSION_MAXNAMELEN
)
xtables_error
(
PARAMETER_PROBLEM
,
"Invalid target name `%s' (%u chars max)"
,
targetname
,
XT_EXTENSION_MAXNAMELEN
-
1
);
for
(
ptr
=
targetname
;
*
ptr
;
ptr
++
)
if
(
isspace
(
*
ptr
))
xtables_error
(
PARAMETER_PROBLEM
,
"Invalid target name `%s'"
,
targetname
);
return
targetname
;
}
static
void
static
void
set_option
(
unsigned
int
*
options
,
unsigned
int
option
,
uint8_t
*
invflg
,
set_option
(
unsigned
int
*
options
,
unsigned
int
option
,
uint8_t
*
invflg
,
int
invert
)
int
invert
)
...
@@ -535,7 +514,6 @@ print_firewall(const struct ipt_entry *fw,
...
@@ -535,7 +514,6 @@ print_firewall(const struct ipt_entry *fw,
struct
xtables_target
*
target
,
*
tg
;
struct
xtables_target
*
target
,
*
tg
;
const
struct
xt_entry_target
*
t
;
const
struct
xt_entry_target
*
t
;
uint8_t
flags
;
uint8_t
flags
;
char
buf
[
BUFSIZ
];
if
(
!
iptc_is_chain
(
targname
,
handle
))
if
(
!
iptc_is_chain
(
targname
,
handle
))
target
=
xtables_find_target
(
targname
,
XTF_TRY_LOAD
);
target
=
xtables_find_target
(
targname
,
XTF_TRY_LOAD
);
...
@@ -574,59 +552,9 @@ print_firewall(const struct ipt_entry *fw,
...
@@ -574,59 +552,9 @@ print_firewall(const struct ipt_entry *fw,
fputc
(
' '
,
stdout
);
fputc
(
' '
,
stdout
);
}
}
if
(
format
&
FMT_VIA
)
{
print_ifaces
(
fw
->
ip
.
iniface
,
fw
->
ip
.
outiface
,
fw
->
ip
.
invflags
,
format
);
char
iface
[
IFNAMSIZ
+
2
];
if
(
fw
->
ip
.
invflags
&
IPT_INV_VIA_IN
)
{
print_ipv4_addresses
(
fw
,
format
);
iface
[
0
]
=
'!'
;
iface
[
1
]
=
'\0'
;
}
else
iface
[
0
]
=
'\0'
;
if
(
fw
->
ip
.
iniface
[
0
]
!=
'\0'
)
{
strcat
(
iface
,
fw
->
ip
.
iniface
);
}
else
if
(
format
&
FMT_NUMERIC
)
strcat
(
iface
,
"*"
);
else
strcat
(
iface
,
"any"
);
printf
(
FMT
(
" %-6s "
,
"in %s "
),
iface
);
if
(
fw
->
ip
.
invflags
&
IPT_INV_VIA_OUT
)
{
iface
[
0
]
=
'!'
;
iface
[
1
]
=
'\0'
;
}
else
iface
[
0
]
=
'\0'
;
if
(
fw
->
ip
.
outiface
[
0
]
!=
'\0'
)
{
strcat
(
iface
,
fw
->
ip
.
outiface
);
}
else
if
(
format
&
FMT_NUMERIC
)
strcat
(
iface
,
"*"
);
else
strcat
(
iface
,
"any"
);
printf
(
FMT
(
"%-6s "
,
"out %s "
),
iface
);
}
fputc
(
fw
->
ip
.
invflags
&
IPT_INV_SRCIP
?
'!'
:
' '
,
stdout
);
if
(
fw
->
ip
.
smsk
.
s_addr
==
0L
&&
!
(
format
&
FMT_NUMERIC
))
printf
(
FMT
(
"%-19s "
,
"%s "
),
"anywhere"
);
else
{
if
(
format
&
FMT_NUMERIC
)
strcpy
(
buf
,
xtables_ipaddr_to_numeric
(
&
fw
->
ip
.
src
));
else
strcpy
(
buf
,
xtables_ipaddr_to_anyname
(
&
fw
->
ip
.
src
));
strcat
(
buf
,
xtables_ipmask_to_numeric
(
&
fw
->
ip
.
smsk
));
printf
(
FMT
(
"%-19s "
,
"%s "
),
buf
);
}
fputc
(
fw
->
ip
.
invflags
&
IPT_INV_DSTIP
?
'!'
:
' '
,
stdout
);
if
(
fw
->
ip
.
dmsk
.
s_addr
==
0L
&&
!
(
format
&
FMT_NUMERIC
))
printf
(
FMT
(
"%-19s "
,
"-> %s"
),
"anywhere"
);
else
{
if
(
format
&
FMT_NUMERIC
)
strcpy
(
buf
,
xtables_ipaddr_to_numeric
(
&
fw
->
ip
.
dst
));
else
strcpy
(
buf
,
xtables_ipaddr_to_anyname
(
&
fw
->
ip
.
dst
));
strcat
(
buf
,
xtables_ipmask_to_numeric
(
&
fw
->
ip
.
dmsk
));
printf
(
FMT
(
"%-19s "
,
"-> %s"
),
buf
);
}
if
(
format
&
FMT_NOTABLE
)
if
(
format
&
FMT_NOTABLE
)
fputs
(
" "
,
stdout
);
fputs
(
" "
,
stdout
);
...
@@ -1262,90 +1190,13 @@ generate_entry(const struct ipt_entry *fw,
...
@@ -1262,90 +1190,13 @@ generate_entry(const struct ipt_entry *fw,
return
e
;
return
e
;
}
}
static
void
command_jump
(
struct
iptables_command_state
*
cs
)
{
size_t
size
;
set_option
(
&
cs
->
options
,
OPT_JUMP
,
&
cs
->
fw
.
ip
.
invflags
,
cs
->
invert
);
cs
->
jumpto
=
parse_target
(
optarg
);
/* TRY_LOAD (may be chain name) */
cs
->
target
=
xtables_find_target
(
cs
->
jumpto
,
XTF_TRY_LOAD
);
if
(
cs
->
target
==
NULL
)
return
;
size
=
XT_ALIGN
(
sizeof
(
struct
xt_entry_target
))
+
cs
->
target
->
size
;
cs
->
target
->
t
=
xtables_calloc
(
1
,
size
);
cs
->
target
->
t
->
u
.
target_size
=
size
;
if
(
cs
->
target
->
real_name
==
NULL
)
{
strcpy
(
cs
->
target
->
t
->
u
.
user
.
name
,
cs
->
jumpto
);
}
else
{
/* Alias support for userspace side */
strcpy
(
cs
->
target
->
t
->
u
.
user
.
name
,
cs
->
target
->
real_name
);
if
(
!
(
cs
->
target
->
ext_flags
&
XTABLES_EXT_ALIAS
))
fprintf
(
stderr
,
"Notice: The %s target is converted into %s target "
"in rule listing and saving.
\n
"
,
cs
->
jumpto
,
cs
->
target
->
real_name
);
}
cs
->
target
->
t
->
u
.
user
.
revision
=
cs
->
target
->
revision
;
xs_init_target
(
cs
->
target
);
if
(
cs
->
target
->
x6_options
!=
NULL
)
opts
=
xtables_options_xfrm
(
iptables_globals
.
orig_opts
,
opts
,
cs
->
target
->
x6_options
,
&
cs
->
target
->
option_offset
);
else
opts
=
xtables_merge_options
(
iptables_globals
.
orig_opts
,
opts
,
cs
->
target
->
extra_opts
,
&
cs
->
target
->
option_offset
);
if
(
opts
==
NULL
)
xtables_error
(
OTHER_PROBLEM
,
"can't alloc memory!"
);
}
static
void
command_match
(
struct
iptables_command_state
*
cs
)
{
struct
xtables_match
*
m
;
size_t
size
;
if
(
cs
->
invert
)
xtables_error
(
PARAMETER_PROBLEM
,
"unexpected ! flag before --match"
);
m
=
xtables_find_match
(
optarg
,
XTF_LOAD_MUST_SUCCEED
,
&
cs
->
matches
);
size
=
XT_ALIGN
(
sizeof
(
struct
xt_entry_match
))
+
m
->
size
;
m
->
m
=
xtables_calloc
(
1
,
size
);
m
->
m
->
u
.
match_size
=
size
;
if
(
m
->
real_name
==
NULL
)
{
strcpy
(
m
->
m
->
u
.
user
.
name
,
m
->
name
);
}
else
{
strcpy
(
m
->
m
->
u
.
user
.
name
,
m
->
real_name
);
if
(
!
(
m
->
ext_flags
&
XTABLES_EXT_ALIAS
))
fprintf
(
stderr
,
"Notice: the %s match is converted into %s match "
"in rule listing and saving.
\n
"
,
m
->
name
,
m
->
real_name
);
}
m
->
m
->
u
.
user
.
revision
=
m
->
revision
;
xs_init_match
(
m
);
if
(
m
==
m
->
next
)
return
;
/* Merge options for non-cloned matches */
if
(
m
->
x6_options
!=
NULL
)
opts
=
xtables_options_xfrm
(
iptables_globals
.
orig_opts
,
opts
,
m
->
x6_options
,
&
m
->
option_offset
);
else
if
(
m
->
extra_opts
!=
NULL
)
opts
=
xtables_merge_options
(
iptables_globals
.
orig_opts
,
opts
,
m
->
extra_opts
,
&
m
->
option_offset
);
if
(
opts
==
NULL
)
xtables_error
(
OTHER_PROBLEM
,
"can't alloc memory!"
);
}
int
do_command4
(
int
argc
,
char
*
argv
[],
char
**
table
,
int
do_command4
(
int
argc
,
char
*
argv
[],
char
**
table
,
struct
xtc_handle
**
handle
,
bool
restore
)
struct
xtc_handle
**
handle
,
bool
restore
)
{
{
struct
iptables_command_state
cs
;
struct
iptables_command_state
cs
=
{
.
jumpto
=
""
,
.
argv
=
argv
,
};
struct
ipt_entry
*
e
=
NULL
;
struct
ipt_entry
*
e
=
NULL
;
unsigned
int
nsaddrs
=
0
,
ndaddrs
=
0
;
unsigned
int
nsaddrs
=
0
,
ndaddrs
=
0
;
struct
in_addr
*
saddrs
=
NULL
,
*
smasks
=
NULL
;
struct
in_addr
*
saddrs
=
NULL
,
*
smasks
=
NULL
;
...
@@ -1367,10 +1218,6 @@ int do_command4(int argc, char *argv[], char **table,
...
@@ -1367,10 +1218,6 @@ int do_command4(int argc, char *argv[], char **table,
struct
xtables_target
*
t
;
struct
xtables_target
*
t
;
unsigned
long
long
cnt
;
unsigned
long
long
cnt
;
memset
(
&
cs
,
0
,
sizeof
(
cs
));
cs
.
jumpto
=
""
;
cs
.
argv
=
argv
;
/* re-set optind to 0 in case do_command4 gets called
/* re-set optind to 0 in case do_command4 gets called
* a second time */
* a second time */
optind
=
0
;
optind
=
0
;
...
@@ -1567,11 +1414,13 @@ int do_command4(int argc, char *argv[], char **table,
...
@@ -1567,11 +1414,13 @@ int do_command4(int argc, char *argv[], char **table,
set_option
(
&
cs
.
options
,
OPT_JUMP
,
&
cs
.
fw
.
ip
.
invflags
,
set_option
(
&
cs
.
options
,
OPT_JUMP
,
&
cs
.
fw
.
ip
.
invflags
,
cs
.
invert
);
cs
.
invert
);
cs
.
fw
.
ip
.
flags
|=
IPT_F_GOTO
;
cs
.
fw
.
ip
.
flags
|=
IPT_F_GOTO
;
cs
.
jumpto
=
parse_target
(
optarg
);
cs
.
jumpto
=
xt_
parse_target
(
optarg
);
break
;
break
;
#endif
#endif
case
'j'
:
case
'j'
:
set_option
(
&
cs
.
options
,
OPT_JUMP
,
&
cs
.
fw
.
ip
.
invflags
,
cs
.
invert
);
command_jump
(
&
cs
);
command_jump
(
&
cs
);
break
;
break
;
...
...
iptables/nft-arp.c
View file @
3bc9369c
...
@@ -139,8 +139,8 @@ static void print_mac_and_mask(const unsigned char *mac, const unsigned char *ma
...
@@ -139,8 +139,8 @@ static void print_mac_and_mask(const unsigned char *mac, const unsigned char *ma
static
int
nft_arp_add
(
struct
nftnl_rule
*
r
,
void
*
data
)
static
int
nft_arp_add
(
struct
nftnl_rule
*
r
,
void
*
data
)
{
{
struct
ar
ptables_command_state
*
cs
=
data
;
struct
i
ptables_command_state
*
cs
=
data
;
struct
arpt_entry
*
fw
=
&
cs
->
fw
;
struct
arpt_entry
*
fw
=
&
cs
->
arp
;
uint32_t
op
;
uint32_t
op
;
int
ret
=
0
;
int
ret
=
0
;
...
@@ -260,8 +260,8 @@ static uint16_t ipt_to_arpt_flags(uint8_t invflags)
...
@@ -260,8 +260,8 @@ static uint16_t ipt_to_arpt_flags(uint8_t invflags)
static
void
nft_arp_parse_meta
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
,
static
void
nft_arp_parse_meta
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
,
void
*
data
)
void
*
data
)
{
{
struct
ar
ptables_command_state
*
cs
=
data
;
struct
i
ptables_command_state
*
cs
=
data
;
struct
arpt_entry
*
fw
=
&
cs
->
fw
;
struct
arpt_entry
*
fw
=
&
cs
->
arp
;
uint8_t
flags
=
0
;
uint8_t
flags
=
0
;
parse_meta
(
e
,
ctx
->
meta
.
key
,
fw
->
arp
.
iniface
,
fw
->
arp
.
iniface_mask
,
parse_meta
(
e
,
ctx
->
meta
.
key
,
fw
->
arp
.
iniface
,
fw
->
arp
.
iniface_mask
,
...
@@ -271,17 +271,10 @@ static void nft_arp_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e,
...
@@ -271,17 +271,10 @@ static void nft_arp_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e,
fw
->
arp
.
invflags
|=
ipt_to_arpt_flags
(
flags
);
fw
->
arp
.
invflags
|=
ipt_to_arpt_flags
(
flags
);
}
}
static
void
nft_arp_parse_target
(
struct
xtables_target
*
target
,
void
*
data
)
{
struct
arptables_command_state
*
cs
=
data
;
cs
->
target
=
target
;
}
static
void
nft_arp_parse_immediate
(
const
char
*
jumpto
,
bool
nft_goto
,
static
void
nft_arp_parse_immediate
(
const
char
*
jumpto
,
bool
nft_goto
,
void
*
data
)
void
*
data
)
{
{
struct
ar
ptables_command_state
*
cs
=
data
;
struct
i
ptables_command_state
*
cs
=
data
;
cs
->
jumpto
=
jumpto
;
cs
->
jumpto
=
jumpto
;
}
}
...
@@ -294,8 +287,8 @@ static void parse_mask_ipv4(struct nft_xt_ctx *ctx, struct in_addr *mask)
...
@@ -294,8 +287,8 @@ static void parse_mask_ipv4(struct nft_xt_ctx *ctx, struct in_addr *mask)
static
void
nft_arp_parse_payload
(
struct
nft_xt_ctx
*
ctx
,
static
void
nft_arp_parse_payload
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
,
void
*
data
)
struct
nftnl_expr
*
e
,
void
*
data
)
{
{
struct
ar
ptables_command_state
*
cs
=
data
;
struct
i
ptables_command_state
*
cs
=
data
;
struct
arpt_entry
*
fw
=
&
cs
->
fw
;
struct
arpt_entry
*
fw
=
&
cs
->
arp
;
struct
in_addr
addr
;
struct
in_addr
addr
;
unsigned
short
int
ar_hrd
,
ar_pro
,
ar_op
,
ar_hln
;
unsigned
short
int
ar_hrd
,
ar_pro
,
ar_op
,
ar_hln
;
bool
inv
;
bool
inv
;
...
@@ -330,9 +323,6 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
...
@@ -330,9 +323,6 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
fw
->
arp
.
invflags
|=
ARPT_INV_ARPOP
;
fw
->
arp
.
invflags
|=
ARPT_INV_ARPOP
;
break
;
break
;
default:
default:
if
(
fw
->
arp
.
arhln
<
0
)
break
;
if
(
ctx
->
payload
.
offset
==
sizeof
(
struct
arphdr
)
+
if
(
ctx
->
payload
.
offset
==
sizeof
(
struct
arphdr
)
+
fw
->
arp
.
arhln
)
{
fw
->
arp
.
arhln
)
{
get_cmp_data
(
e
,
&
addr
,
sizeof
(
addr
),
&
inv
);
get_cmp_data
(
e
,
&
addr
,
sizeof
(
addr
),
&
inv
);
...
@@ -365,14 +355,14 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
...
@@ -365,14 +355,14 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
}
}
}
}
void
nft_rule_to_
arptables_command_state
(
struct
nftnl_rule
*
r
,
static
void
nft_
arp_
rule_to_
cs
(
const
struct
nftnl_rule
*
r
,
struct
ar
ptables_command_state
*
cs
)
struct
i
ptables_command_state
*
cs
)
{
{
struct
nftnl_expr_iter
*
iter
;
struct
nftnl_expr_iter
*
iter
;
struct
nftnl_expr
*
expr
;
struct
nftnl_expr
*
expr
;
int
family
=
nftnl_rule_get_u32
(
r
,
NFTNL_RULE_FAMILY
);
int
family
=
nftnl_rule_get_u32
(
r
,
NFTNL_RULE_FAMILY
);
struct
nft_xt_ctx
ctx
=
{
struct
nft_xt_ctx
ctx
=
{
.
s
tate
.
cs_arp
=
cs
,
.
c
s
=
cs
,
.
family
=
family
,
.
family
=
family
,
};
};
...
@@ -387,7 +377,7 @@ void nft_rule_to_arptables_command_state(struct nftnl_rule *r,
...
@@ -387,7 +377,7 @@ void nft_rule_to_arptables_command_state(struct nftnl_rule *r,
nftnl_expr_get_str
(
expr
,
NFTNL_EXPR_NAME
);
nftnl_expr_get_str
(
expr
,
NFTNL_EXPR_NAME
);
if
(
strcmp
(
name
,
"counter"
)
==
0
)
if
(
strcmp
(
name
,
"counter"
)
==
0
)
nft_parse_counter
(
expr
,
&
ctx
.
state
.
cs_arp
->
fw
.
counters
);
nft_parse_counter
(
expr
,
&
ctx
.
cs
->
arp
.
counters
);
else
if
(
strcmp
(
name
,
"payload"
)
==
0
)
else
if
(
strcmp
(
name
,
"payload"
)
==
0
)
nft_parse_payload
(
&
ctx
,
expr
);
nft_parse_payload
(
&
ctx
,
expr
);
else
if
(
strcmp
(
name
,
"meta"
)
==
0
)
else
if
(
strcmp
(
name
,
"meta"
)
==
0
)
...
@@ -418,10 +408,11 @@ void nft_rule_to_arptables_command_state(struct nftnl_rule *r,
...
@@ -418,10 +408,11 @@ void nft_rule_to_arptables_command_state(struct nftnl_rule *r,
static
void
nft_arp_print_header
(
unsigned
int
format
,
const
char
*
chain
,
static
void
nft_arp_print_header
(
unsigned
int
format
,
const
char
*
chain
,
const
char
*
pol
,
const
char
*
pol
,
const
struct
xt_counters
*
counters
,
const
struct
xt_counters
*
counters
,
bool
basechain
,
uint32_t
refs
)
bool
basechain
,
uint32_t
refs
,
uint32_t
entries
)
{
{
printf
(
"Chain %s"
,
chain
);
printf
(
"Chain %s"
,
chain
);
if
(
pol
)
{
if
(
basechain
&&
pol
)
{
printf
(
" (policy %s"
,
pol
);
printf
(
" (policy %s"
,
pol
);
if
(
!
(
format
&
FMT_NOCOUNTS
))
{
if
(
!
(
format
&
FMT_NOCOUNTS
))
{
fputc
(
' '
,
stdout
);
fputc
(
' '
,
stdout
);
...
@@ -436,7 +427,8 @@ static void nft_arp_print_header(unsigned int format, const char *chain,
...
@@ -436,7 +427,8 @@ static void nft_arp_print_header(unsigned int format, const char *chain,
}
}
}
}
static
void
print_fw_details
(
struct
arpt_entry
*
fw
,
unsigned
int
format
)
static
void
nft_arp_print_rule_details
(
const
struct
arpt_entry
*
fw
,
unsigned
int
format
)
{
{
char
buf
[
BUFSIZ
];
char
buf
[
BUFSIZ
];
char
iface
[
IFNAMSIZ
+
2
];
char
iface
[
IFNAMSIZ
+
2
];
...
@@ -542,6 +534,7 @@ after_devdst:
...
@@ -542,6 +534,7 @@ after_devdst:
if
(
tmp
<=
NUMOPCODES
&&
!
(
format
&
FMT_NUMERIC
))
if
(
tmp
<=
NUMOPCODES
&&
!
(
format
&
FMT_NUMERIC
))
printf
(
"--opcode %s"
,
opcodes
[
tmp
-
1
]);
printf
(
"--opcode %s"
,
opcodes
[
tmp
-
1
]);
else
else
printf
(
"--opcode %d"
,
tmp
);
if
(
fw
->
arp
.
arpop_mask
!=
65535
)
if
(
fw
->
arp
.
arpop_mask
!=
65535
)
printf
(
"/%d"
,
ntohs
(
fw
->
arp
.
arpop_mask
));
printf
(
"/%d"
,
ntohs
(
fw
->
arp
.
arpop_mask
));
...
@@ -578,36 +571,48 @@ after_devdst:
...
@@ -578,36 +571,48 @@ after_devdst:
}
}
static
void
static
void
nft_arp_print_firewall
(
struct
nftnl_rule
*
r
,
unsigned
int
num
,
__nft_arp_save_rule
(
const
void
*
data
,
unsigned
int
format
)
unsigned
int
format
)
{
{
struct
ar
ptables_command_state
cs
=
{}
;
const
struct
i
ptables_command_state
*
cs
=
data
;
nft_
rule_to_arptables_command_state
(
r
,
&
cs
);
nft_
arp_print_rule_details
(
&
cs
->
arp
,
format
);
if
(
format
&
FMT_LINENUMBERS
)
if
(
cs
->
jumpto
!=
NULL
&&
strcmp
(
cs
->
jumpto
,
""
)
!=
0
)
{
printf
(
"%u "
,
num
);
printf
(
"-j %s"
,
cs
->
jumpto
);
}
else
if
(
cs
->
target
)
{
print_fw_details
(
&
cs
.
fw
,
format
);
printf
(
"-j %s"
,
cs
->
target
->
name
);
cs
->
target
->
print
(
&
cs
->
arp
,
cs
->
target
->
t
,
format
&
FMT_NUMERIC
);
if
(
cs
.
jumpto
!=
NULL
&&
strcmp
(
cs
.
jumpto
,
""
)
!=
0
)
{
printf
(
"-j %s"
,
cs
.
jumpto
);
}
else
if
(
cs
.
target
)
{
printf
(
"-j %s"
,
cs
.
target
->
name
);
cs
.
target
->
print
(
&
cs
.
fw
,
cs
.
target
->
t
,
format
&
FMT_NUMERIC
);
}
}
if
(
!
(
format
&
FMT_NOCOUNTS
))
{
if
(
!
(
format
&
FMT_NOCOUNTS
))
{
printf
(
", pcnt="
);
printf
(
", pcnt="
);
xtables_print_num
(
cs
.
fw
.
counters
.
pcnt
,
format
);
xtables_print_num
(
cs
->
arp
.
counters
.
pcnt
,
format
);
printf
(
"-- bcnt="
);
printf
(
"-- bcnt="
);
xtables_print_num
(
cs
.
fw
.
counters
.
bcnt
,
format
);
xtables_print_num
(
cs
->
arp
.
counters
.
bcnt
,
format
);
}
}
if
(
!
(
format
&
FMT_NONEWLINE
))
if
(
!
(
format
&
FMT_NONEWLINE
))
fputc
(
'\n'
,
stdout
);
fputc
(
'\n'
,
stdout
);
}
}
static
void
nft_arp_save_rule
(
const
void
*
data
,
unsigned
int
format
)
{
__nft_arp_save_rule
(
data
,
format
|
FMT_NUMERIC
);
}
static
void
nft_arp_print_rule
(
struct
nftnl_rule
*
r
,
unsigned
int
num
,
unsigned
int
format
)
{
struct
iptables_command_state
cs
=
{};
if
(
format
&
FMT_LINENUMBERS
)
printf
(
"%u "
,
num
);
nft_arp_rule_to_cs
(
r
,
&
cs
);
__nft_arp_save_rule
(
&
cs
,
format
);
}
static
bool
nft_arp_is_same
(
const
void
*
data_a
,
static
bool
nft_arp_is_same
(
const
void
*
data_a
,
const
void
*
data_b
)
const
void
*
data_b
)
{
{
...
@@ -637,24 +642,31 @@ static bool nft_arp_is_same(const void *data_a,
...
@@ -637,24 +642,31 @@ static bool nft_arp_is_same(const void *data_a,
static
bool
nft_arp_rule_find
(
struct
nft_family_ops
*
ops
,
struct
nftnl_rule
*
r
,
static
bool
nft_arp_rule_find
(
struct
nft_family_ops
*
ops
,
struct
nftnl_rule
*
r
,
void
*
data
)
void
*
data
)
{
{
const
struct
ar
ptables_command_state
*
cs
=
data
;
const
struct
i
ptables_command_state
*
cs
=
data
;
struct
ar
ptables_command_state
this
=
{};
struct
i
ptables_command_state
this
=
{};
/* Delete by matching rule case */
/* Delete by matching rule case */
nft_rule_to_
arptables_command_state
(
r
,
&
this
);
nft_
arp_
rule_to_
cs
(
r
,
&
this
);
if
(
!
nft_arp_is_same
(
cs
,
&
this
))
if
(
!
nft_arp_is_same
(
&
cs
->
arp
,
&
this
.
arp
))
return
false
;
return
false
;
if
(
!
compare_targets
(
cs
->
target
,
this
.
target
))
if
(
!
compare_targets
(
cs
->
target
,
this
.
target
))
return
false
;
return
false
;
if
(
strcmp
(
cs
->
jumpto
,
this
.
jumpto
)
!=
0
)
if
(
this
.
jumpto
&&
strcmp
(
cs
->
jumpto
,
this
.
jumpto
)
!=
0
)
return
false
;
return
false
;
return
true
;
return
true
;
}
}
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
);
printf
(
":%s %s
\n
"
,
chain
,
policy
?:
"-"
);
}
struct
nft_family_ops
nft_family_ops_arp
=
{
struct
nft_family_ops
nft_family_ops_arp
=
{
.
add
=
nft_arp_add
,
.
add
=
nft_arp_add
,
.
is_same
=
nft_arp_is_same
,
.
is_same
=
nft_arp_is_same
,
...
@@ -663,10 +675,13 @@ struct nft_family_ops nft_family_ops_arp = {
...
@@ -663,10 +675,13 @@ struct nft_family_ops nft_family_ops_arp = {
.
parse_payload
=
nft_arp_parse_payload
,
.
parse_payload
=
nft_arp_parse_payload
,
.
parse_immediate
=
nft_arp_parse_immediate
,
.
parse_immediate
=
nft_arp_parse_immediate
,
.
print_header
=
nft_arp_print_header
,
.
print_header
=
nft_arp_print_header
,
.
print_
firewall
=
nft_arp_print_
firewall
,
.
print_
rule
=
nft_arp_print_
rule
,
.
save_
firewall
=
NULL
,
.
save_
rule
=
nft_arp_save_rule
,
.
save_counters
=
NULL
,
.
save_counters
=
NULL
,
.
save_chain
=
nft_arp_save_chain
,
.
post_parse
=
NULL
,
.
post_parse
=
NULL
,
.
rule_to_cs
=
nft_arp_rule_to_cs
,
.
clear_cs
=
nft_clear_iptables_command_state
,
.
rule_find
=
nft_arp_rule_find
,
.
rule_find
=
nft_arp_rule_find
,
.
parse_target
=
nft_
arp
_parse_target
,
.
parse_target
=
nft_
ipv46
_parse_target
,
};
};
iptables/nft-arp.h
View file @
3bc9369c
...
@@ -4,13 +4,4 @@
...
@@ -4,13 +4,4 @@
extern
char
*
opcodes
[];
extern
char
*
opcodes
[];
#define NUMOPCODES 9
#define NUMOPCODES 9
struct
arptables_command_state
{
struct
arpt_entry
fw
;
struct
xtables_target
*
target
;
const
char
*
jumpto
;
};
void
nft_rule_to_arptables_command_state
(
struct
nftnl_rule
*
r
,
struct
arptables_command_state
*
cs
);
#endif
#endif
iptables/nft-bridge.c
View file @
3bc9369c
...
@@ -16,7 +16,6 @@
...
@@ -16,7 +16,6 @@
#include <xtables.h>
#include <xtables.h>
#include <libiptc/libxtc.h>
#include <libiptc/libxtc.h>
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter/nf_tables.h>
#include <ebtables/ethernetdb.h>
#include "nft-shared.h"
#include "nft-shared.h"
#include "nft-bridge.h"
#include "nft-bridge.h"
...
@@ -29,9 +28,18 @@ void ebt_cs_clean(struct iptables_command_state *cs)
...
@@ -29,9 +28,18 @@ void ebt_cs_clean(struct iptables_command_state *cs)
xtables_rule_matches_free
(
&
cs
->
matches
);
xtables_rule_matches_free
(
&
cs
->
matches
);
for
(
m
=
cs
->
match_list
;
m
;)
{
for
(
m
=
cs
->
match_list
;
m
;)
{
if
(
!
m
->
ismatch
)
{
struct
xtables_target
*
target
=
m
->
u
.
watcher
;
if
(
target
->
t
)
{
free
(
target
->
t
);
target
->
t
=
NULL
;
}
if
(
target
==
target
->
next
)
free
(
target
);
}
nm
=
m
->
next
;
nm
=
m
->
next
;
if
(
!
m
->
ismatch
)
free
(
m
->
u
.
watcher
->
t
);
free
(
m
);
free
(
m
);
m
=
nm
;
m
=
nm
;
}
}
...
@@ -193,7 +201,7 @@ static int nft_bridge_add(struct nftnl_rule *r, void *data)
...
@@ -193,7 +201,7 @@ static int nft_bridge_add(struct nftnl_rule *r, void *data)
add_cmp_u16
(
r
,
fw
->
ethproto
,
op
);
add_cmp_u16
(
r
,
fw
->
ethproto
,
op
);
}
}
add_compat
(
r
,
fw
->
ethproto
,
fw
->
invflags
);
add_compat
(
r
,
fw
->
ethproto
,
fw
->
invflags
&
EBT_IPROTO
);
for
(
iter
=
cs
->
match_list
;
iter
;
iter
=
iter
->
next
)
{
for
(
iter
=
cs
->
match_list
;
iter
;
iter
=
iter
->
next
)
{
if
(
iter
->
ismatch
)
{
if
(
iter
->
ismatch
)
{
...
@@ -217,10 +225,7 @@ static void nft_bridge_parse_meta(struct nft_xt_ctx *ctx,
...
@@ -217,10 +225,7 @@ static void nft_bridge_parse_meta(struct nft_xt_ctx *ctx,
struct
iptables_command_state
*
cs
=
data
;
struct
iptables_command_state
*
cs
=
data
;
struct
ebt_entry
*
fw
=
&
cs
->
eb
;
struct
ebt_entry
*
fw
=
&
cs
->
eb
;
uint8_t
invflags
=
0
;
uint8_t
invflags
=
0
;
char
iifname
[
IFNAMSIZ
],
oifname
[
IFNAMSIZ
];
char
iifname
[
IFNAMSIZ
]
=
{},
oifname
[
IFNAMSIZ
]
=
{};
memset
(
iifname
,
0
,
sizeof
(
iifname
));
memset
(
oifname
,
0
,
sizeof
(
oifname
));
parse_meta
(
e
,
ctx
->
meta
.
key
,
iifname
,
NULL
,
oifname
,
NULL
,
&
invflags
);
parse_meta
(
e
,
ctx
->
meta
.
key
,
iifname
,
NULL
,
oifname
,
NULL
,
&
invflags
);
...
@@ -350,7 +355,7 @@ static void nft_bridge_parse_target(struct xtables_target *t, void *data)
...
@@ -350,7 +355,7 @@ static void nft_bridge_parse_target(struct xtables_target *t, void *data)
cs
->
target
=
t
;
cs
->
target
=
t
;
}
}
static
void
nft_rule_to_ebtables_command_state
(
struct
nftnl_rule
*
r
,
static
void
nft_rule_to_ebtables_command_state
(
const
struct
nftnl_rule
*
r
,
struct
iptables_command_state
*
cs
)
struct
iptables_command_state
*
cs
)
{
{
cs
->
eb
.
bitmask
=
EBT_NOPROTO
;
cs
->
eb
.
bitmask
=
EBT_NOPROTO
;
...
@@ -371,10 +376,10 @@ static void nft_bridge_print_table_header(const char *tablename)
...
@@ -371,10 +376,10 @@ static void nft_bridge_print_table_header(const char *tablename)
static
void
nft_bridge_print_header
(
unsigned
int
format
,
const
char
*
chain
,
static
void
nft_bridge_print_header
(
unsigned
int
format
,
const
char
*
chain
,
const
char
*
pol
,
const
char
*
pol
,
const
struct
xt_counters
*
counters
,
const
struct
xt_counters
*
counters
,
bool
basechain
,
uint32_t
refs
)
bool
basechain
,
uint32_t
refs
,
uint32_t
entries
)
{
{
printf
(
"Bridge chain: %s, entries: %u, policy: %s
\n
"
,
printf
(
"Bridge chain: %s, entries: %u, policy: %s
\n
"
,
chain
,
ref
s
,
basechain
?
pol
:
"RETURN"
);
chain
,
entrie
s
,
basechain
?
pol
:
"RETURN"
);
}
}
static
void
print_matches_and_watchers
(
const
struct
iptables_command_state
*
cs
,
static
void
print_matches_and_watchers
(
const
struct
iptables_command_state
*
cs
,
...
@@ -415,7 +420,7 @@ static void print_mac(char option, const unsigned char *mac,
...
@@ -415,7 +420,7 @@ static void print_mac(char option, const unsigned char *mac,
static
void
print_protocol
(
uint16_t
ethproto
,
bool
invert
,
unsigned
int
bitmask
)
static
void
print_protocol
(
uint16_t
ethproto
,
bool
invert
,
unsigned
int
bitmask
)
{
{
struct
ethertypeent
*
ent
;
struct
xt_
ethertypeent
*
ent
;
/* Dont print anything about the protocol if no protocol was
/* Dont print anything about the protocol if no protocol was
* specified, obviously this means any protocol will do. */
* specified, obviously this means any protocol will do. */
...
@@ -431,59 +436,87 @@ static void print_protocol(uint16_t ethproto, bool invert, unsigned int bitmask)
...
@@ -431,59 +436,87 @@ static void print_protocol(uint16_t ethproto, bool invert, unsigned int bitmask)
return
;
return
;
}
}
ent
=
getethertypebynumber
(
ntohs
(
ethproto
));
ent
=
xtables_
getethertypebynumber
(
ntohs
(
ethproto
));
if
(
!
ent
)
if
(
!
ent
)
printf
(
"0x%x "
,
ntohs
(
ethproto
));
printf
(
"0x%x "
,
ntohs
(
ethproto
));
else
else
printf
(
"%s "
,
ent
->
e_name
);
printf
(
"%s "
,
ent
->
e_name
);
}
}
static
void
nft_bridge_print_firewall
(
struct
nftnl_rule
*
r
,
unsigned
int
num
,
static
void
nft_bridge_save_rule
(
const
void
*
data
,
unsigned
int
format
)
unsigned
int
format
)
{
{
struct
iptables_command_state
cs
=
{};
const
struct
iptables_command_state
*
cs
=
data
;
nft_rule_to_ebtables_command_state
(
r
,
&
cs
);
if
(
format
&
FMT_LINENUMBERS
)
printf
(
"%d "
,
num
);
print_protocol
(
cs
.
eb
.
ethproto
,
cs
.
eb
.
invflags
&
EBT_IPROTO
,
cs
.
eb
.
bitmask
);
if
(
cs
->
eb
.
ethproto
)
if
(
cs
.
eb
.
bitmask
&
EBT_ISOURCE
)
print_protocol
(
cs
->
eb
.
ethproto
,
cs
->
eb
.
invflags
&
EBT_IPROTO
,
print_mac
(
's'
,
cs
.
eb
.
sourcemac
,
cs
.
eb
.
sourcemsk
,
cs
->
eb
.
bitmask
);
cs
.
eb
.
invflags
&
EBT_ISOURCE
);
if
(
cs
->
eb
.
bitmask
&
EBT_ISOURCE
)
if
(
cs
.
eb
.
bitmask
&
EBT_IDEST
)
print_mac
(
's'
,
cs
->
eb
.
sourcemac
,
cs
->
eb
.
sourcemsk
,
print_mac
(
'd'
,
cs
.
eb
.
destmac
,
cs
.
eb
.
destmsk
,
cs
->
eb
.
invflags
&
EBT_ISOURCE
);
cs
.
eb
.
invflags
&
EBT_IDEST
);
if
(
cs
->
eb
.
bitmask
&
EBT_IDEST
)
print_mac
(
'd'
,
cs
->
eb
.
destmac
,
cs
->
eb
.
destmsk
,
cs
->
eb
.
invflags
&
EBT_IDEST
);
print_iface
(
"-i"
,
cs
.
eb
.
in
,
cs
.
eb
.
invflags
&
EBT_IIN
);
print_iface
(
"-i"
,
cs
->
eb
.
in
,
cs
->
eb
.
invflags
&
EBT_IIN
);
print_iface
(
"--logical-in"
,
cs
.
eb
.
logical_in
,
cs
.
eb
.
invflags
&
EBT_ILOGICALIN
);
print_iface
(
"--logical-in"
,
cs
->
eb
.
logical_in
,
print_iface
(
"-o"
,
cs
.
eb
.
out
,
cs
.
eb
.
invflags
&
EBT_IOUT
);
cs
->
eb
.
invflags
&
EBT_ILOGICALIN
);
print_iface
(
"--logical-out"
,
cs
.
eb
.
logical_out
,
cs
.
eb
.
invflags
&
EBT_ILOGICALOUT
);
print_iface
(
"-o"
,
cs
->
eb
.
out
,
cs
->
eb
.
invflags
&
EBT_IOUT
);
print_iface
(
"--logical-out"
,
cs
->
eb
.
logical_out
,
cs
->
eb
.
invflags
&
EBT_ILOGICALOUT
);
print_matches_and_watchers
(
&
cs
,
format
);
print_matches_and_watchers
(
cs
,
format
);
printf
(
"-j "
);
printf
(
"-j "
);
if
(
cs
.
jumpto
!=
NULL
)
{
if
(
cs
->
jumpto
!=
NULL
)
{
if
(
strcmp
(
cs
.
jumpto
,
""
)
!=
0
)
if
(
strcmp
(
cs
->
jumpto
,
""
)
!=
0
)
printf
(
"%s"
,
cs
.
jumpto
);
printf
(
"%s"
,
cs
->
jumpto
);
else
else
printf
(
"CONTINUE"
);
printf
(
"CONTINUE"
);
}
}
else
if
(
cs
.
target
!=
NULL
&&
cs
.
target
->
print
!=
NULL
)
if
(
cs
->
target
!=
NULL
&&
cs
->
target
->
print
!=
NULL
)
{
cs
.
target
->
print
(
&
cs
.
fw
,
cs
.
target
->
t
,
format
&
FMT_NUMERIC
);
printf
(
" "
);
cs
->
target
->
print
(
&
cs
->
fw
,
cs
->
target
->
t
,
format
&
FMT_NUMERIC
);
}
if
(
!
(
format
&
FMT_NOCOUNTS
))
if
(
!
(
format
&
FMT_NOCOUNTS
))
{
printf
(
" , pcnt = %"
PRIu64
" -- bcnt = %"
PRIu64
""
,
const
char
*
counter_fmt
;
(
uint64_t
)
cs
.
counters
.
pcnt
,
(
uint64_t
)
cs
.
counters
.
bcnt
);
if
(
format
&
FMT_EBT_SAVE
)
counter_fmt
=
" -c %"
PRIu64
" %"
PRIu64
""
;
else
counter_fmt
=
" , pcnt = %"
PRIu64
" -- bcnt = %"
PRIu64
""
;
printf
(
counter_fmt
,
(
uint64_t
)
cs
->
counters
.
pcnt
,
(
uint64_t
)
cs
->
counters
.
bcnt
);
}
if
(
!
(
format
&
FMT_NONEWLINE
))
if
(
!
(
format
&
FMT_NONEWLINE
))
fputc
(
'\n'
,
stdout
);
fputc
(
'\n'
,
stdout
);
}
static
void
nft_bridge_print_rule
(
struct
nftnl_rule
*
r
,
unsigned
int
num
,
unsigned
int
format
)
{
struct
iptables_command_state
cs
=
{};
if
(
format
&
FMT_LINENUMBERS
)
printf
(
"%d "
,
num
);
nft_rule_to_ebtables_command_state
(
r
,
&
cs
);
nft_bridge_save_rule
(
&
cs
,
format
);
ebt_cs_clean
(
&
cs
);
ebt_cs_clean
(
&
cs
);
}
}
static
void
nft_bridge_save_chain
(
const
struct
nftnl_chain
*
c
,
const
char
*
policy
)
{
const
char
*
chain
=
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_NAME
);
printf
(
":%s %s
\n
"
,
chain
,
policy
?:
"ACCEPT"
);
}
static
bool
nft_bridge_is_same
(
const
void
*
data_a
,
const
void
*
data_b
)
static
bool
nft_bridge_is_same
(
const
void
*
data_a
,
const
void
*
data_b
)
{
{
const
struct
ebt_entry
*
a
=
data_a
;
const
struct
ebt_entry
*
a
=
data_a
;
...
@@ -732,10 +765,13 @@ struct nft_family_ops nft_family_ops_bridge = {
...
@@ -732,10 +765,13 @@ struct nft_family_ops nft_family_ops_bridge = {
.
parse_target
=
nft_bridge_parse_target
,
.
parse_target
=
nft_bridge_parse_target
,
.
print_table_header
=
nft_bridge_print_table_header
,
.
print_table_header
=
nft_bridge_print_table_header
,
.
print_header
=
nft_bridge_print_header
,
.
print_header
=
nft_bridge_print_header
,
.
print_
firewall
=
nft_bridge_print_
firewall
,
.
print_
rule
=
nft_bridge_print_
rule
,
.
save_
firewall
=
NULL
,
.
save_
rule
=
nft_bridge_save_rule
,
.
save_counters
=
NULL
,
.
save_counters
=
NULL
,
.
save_chain
=
nft_bridge_save_chain
,
.
post_parse
=
NULL
,
.
post_parse
=
NULL
,
.
rule_to_cs
=
nft_rule_to_ebtables_command_state
,
.
clear_cs
=
ebt_cs_clean
,
.
rule_find
=
nft_bridge_rule_find
,
.
rule_find
=
nft_bridge_rule_find
,
.
xlate
=
nft_bridge_xlate
,
.
xlate
=
nft_bridge_xlate
,
};
};
iptables/nft-bridge.h
View file @
3bc9369c
...
@@ -78,7 +78,7 @@ static const char *ebt_standard_targets[NUM_STANDARD_TARGETS] = {
...
@@ -78,7 +78,7 @@ static const char *ebt_standard_targets[NUM_STANDARD_TARGETS] = {
static
inline
const
char
*
nft_ebt_standard_target
(
unsigned
int
num
)
static
inline
const
char
*
nft_ebt_standard_target
(
unsigned
int
num
)
{
{
if
(
num
>
NUM_STANDARD_TARGETS
)
if
(
num
>
=
NUM_STANDARD_TARGETS
)
return
NULL
;
return
NULL
;
return
ebt_standard_targets
[
num
];
return
ebt_standard_targets
[
num
];
...
@@ -120,5 +120,7 @@ void ebt_add_match(struct xtables_match *m,
...
@@ -120,5 +120,7 @@ void ebt_add_match(struct xtables_match *m,
struct
iptables_command_state
*
cs
);
struct
iptables_command_state
*
cs
);
void
ebt_add_watcher
(
struct
xtables_target
*
watcher
,
void
ebt_add_watcher
(
struct
xtables_target
*
watcher
,
struct
iptables_command_state
*
cs
);
struct
iptables_command_state
*
cs
);
int
ebt_command_default
(
struct
iptables_command_state
*
cs
);
struct
xtables_target
*
ebt_command_jump
(
const
char
*
jumpto
);
#endif
#endif
iptables/nft-ipv4.c
View file @
3bc9369c
...
@@ -45,8 +45,7 @@ static int nft_ipv4_add(struct nftnl_rule *r, void *data)
...
@@ -45,8 +45,7 @@ static int nft_ipv4_add(struct nftnl_rule *r, void *data)
if
(
cs
->
fw
.
ip
.
proto
!=
0
)
{
if
(
cs
->
fw
.
ip
.
proto
!=
0
)
{
op
=
nft_invflags2cmp
(
cs
->
fw
.
ip
.
invflags
,
XT_INV_PROTO
);
op
=
nft_invflags2cmp
(
cs
->
fw
.
ip
.
invflags
,
XT_INV_PROTO
);
add_proto
(
r
,
offsetof
(
struct
iphdr
,
protocol
),
1
,
add_l4proto
(
r
,
cs
->
fw
.
ip
.
proto
,
op
);
cs
->
fw
.
ip
.
proto
,
op
);
}
}
if
(
cs
->
fw
.
ip
.
src
.
s_addr
!=
0
)
{
if
(
cs
->
fw
.
ip
.
src
.
s_addr
!=
0
)
{
...
@@ -75,7 +74,7 @@ static int nft_ipv4_add(struct nftnl_rule *r, void *data)
...
@@ -75,7 +74,7 @@ static int nft_ipv4_add(struct nftnl_rule *r, void *data)
add_cmp_u16
(
r
,
0
,
op
);
add_cmp_u16
(
r
,
0
,
op
);
}
}
add_compat
(
r
,
cs
->
fw
.
ip
.
proto
,
cs
->
fw
.
ip
.
invflags
);
add_compat
(
r
,
cs
->
fw
.
ip
.
proto
,
cs
->
fw
.
ip
.
invflags
&
XT_INV_PROTO
);
for
(
matchp
=
cs
->
matches
;
matchp
;
matchp
=
matchp
->
next
)
{
for
(
matchp
=
cs
->
matches
;
matchp
;
matchp
=
matchp
->
next
)
{
/* Use nft built-in comments support instead of comment match */
/* Use nft built-in comments support instead of comment match */
...
@@ -172,6 +171,16 @@ static void nft_ipv4_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e,
...
@@ -172,6 +171,16 @@ static void nft_ipv4_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e,
{
{
struct
iptables_command_state
*
cs
=
data
;
struct
iptables_command_state
*
cs
=
data
;
switch
(
ctx
->
meta
.
key
)
{
case
NFT_META_L4PROTO
:
cs
->
fw
.
ip
.
proto
=
nftnl_expr_get_u8
(
e
,
NFTNL_EXPR_CMP_DATA
);
if
(
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_CMP_OP
)
==
NFT_CMP_NEQ
)
cs
->
fw
.
ip
.
invflags
|=
XT_INV_PROTO
;
return
;
default:
break
;
}
parse_meta
(
e
,
ctx
->
meta
.
key
,
cs
->
fw
.
ip
.
iniface
,
cs
->
fw
.
ip
.
iniface_mask
,
parse_meta
(
e
,
ctx
->
meta
.
key
,
cs
->
fw
.
ip
.
iniface
,
cs
->
fw
.
ip
.
iniface_mask
,
cs
->
fw
.
ip
.
outiface
,
cs
->
fw
.
ip
.
outiface_mask
,
cs
->
fw
.
ip
.
outiface
,
cs
->
fw
.
ip
.
outiface_mask
,
&
cs
->
fw
.
ip
.
invflags
);
&
cs
->
fw
.
ip
.
invflags
);
...
@@ -225,6 +234,7 @@ static void nft_ipv4_parse_payload(struct nft_xt_ctx *ctx,
...
@@ -225,6 +234,7 @@ static void nft_ipv4_parse_payload(struct nft_xt_ctx *ctx,
break
;
break
;
case
offsetof
(
struct
iphdr
,
frag_off
):
case
offsetof
(
struct
iphdr
,
frag_off
):
cs
->
fw
.
ip
.
flags
|=
IPT_F_FRAG
;
cs
->
fw
.
ip
.
flags
|=
IPT_F_FRAG
;
inv
=
false
;
get_frag
(
ctx
,
e
,
&
inv
);
get_frag
(
ctx
,
e
,
&
inv
);
if
(
inv
)
if
(
inv
)
cs
->
fw
.
ip
.
invflags
|=
IPT_INV_FRAG
;
cs
->
fw
.
ip
.
invflags
|=
IPT_INV_FRAG
;
...
@@ -246,44 +256,6 @@ static void nft_ipv4_parse_immediate(const char *jumpto, bool nft_goto,
...
@@ -246,44 +256,6 @@ static void nft_ipv4_parse_immediate(const char *jumpto, bool nft_goto,
cs
->
fw
.
ip
.
flags
|=
IPT_F_GOTO
;
cs
->
fw
.
ip
.
flags
|=
IPT_F_GOTO
;
}
}
static
void
nft_ipv4_print_header
(
unsigned
int
format
,
const
char
*
chain
,
const
char
*
pol
,
const
struct
xt_counters
*
counters
,
bool
basechain
,
uint32_t
refs
)
{
print_header
(
format
,
chain
,
pol
,
counters
,
basechain
,
refs
);
}
static
void
print_ipv4_addr
(
const
struct
iptables_command_state
*
cs
,
unsigned
int
format
)
{
char
buf
[
BUFSIZ
];
fputc
(
cs
->
fw
.
ip
.
invflags
&
IPT_INV_SRCIP
?
'!'
:
' '
,
stdout
);
if
(
cs
->
fw
.
ip
.
smsk
.
s_addr
==
0L
&&
!
(
format
&
FMT_NUMERIC
))
printf
(
FMT
(
"%-19s "
,
"%s "
),
"anywhere"
);
else
{
if
(
format
&
FMT_NUMERIC
)
strcpy
(
buf
,
xtables_ipaddr_to_numeric
(
&
cs
->
fw
.
ip
.
src
));
else
strcpy
(
buf
,
xtables_ipaddr_to_anyname
(
&
cs
->
fw
.
ip
.
src
));
strcat
(
buf
,
xtables_ipmask_to_numeric
(
&
cs
->
fw
.
ip
.
smsk
));
printf
(
FMT
(
"%-19s "
,
"%s "
),
buf
);
}
fputc
(
cs
->
fw
.
ip
.
invflags
&
IPT_INV_DSTIP
?
'!'
:
' '
,
stdout
);
if
(
cs
->
fw
.
ip
.
dmsk
.
s_addr
==
0L
&&
!
(
format
&
FMT_NUMERIC
))
printf
(
FMT
(
"%-19s "
,
"-> %s"
),
"anywhere"
);
else
{
if
(
format
&
FMT_NUMERIC
)
strcpy
(
buf
,
xtables_ipaddr_to_numeric
(
&
cs
->
fw
.
ip
.
dst
));
else
strcpy
(
buf
,
xtables_ipaddr_to_anyname
(
&
cs
->
fw
.
ip
.
dst
));
strcat
(
buf
,
xtables_ipmask_to_numeric
(
&
cs
->
fw
.
ip
.
dmsk
));
printf
(
FMT
(
"%-19s "
,
"-> %s"
),
buf
);
}
}
static
void
print_fragment
(
unsigned
int
flags
,
unsigned
int
invflags
,
static
void
print_fragment
(
unsigned
int
flags
,
unsigned
int
invflags
,
unsigned
int
format
)
unsigned
int
format
)
{
{
...
@@ -297,20 +269,19 @@ static void print_fragment(unsigned int flags, unsigned int invflags,
...
@@ -297,20 +269,19 @@ static void print_fragment(unsigned int flags, unsigned int invflags,
fputc
(
' '
,
stdout
);
fputc
(
' '
,
stdout
);
}
}
static
void
nft_ipv4_print_
firewall
(
struct
nftnl_rule
*
r
,
unsigned
int
num
,
static
void
nft_ipv4_print_
rule
(
struct
nftnl_rule
*
r
,
unsigned
int
num
,
unsigned
int
format
)
unsigned
int
format
)
{
{
struct
iptables_command_state
cs
=
{};
struct
iptables_command_state
cs
=
{};
nft_rule_to_iptables_command_state
(
r
,
&
cs
);
nft_rule_to_iptables_command_state
(
r
,
&
cs
);
print_firewall_details
(
&
cs
,
cs
.
jumpto
,
cs
.
fw
.
ip
.
flags
,
print_rule_details
(
&
cs
,
cs
.
jumpto
,
cs
.
fw
.
ip
.
flags
,
cs
.
fw
.
ip
.
invflags
,
cs
.
fw
.
ip
.
proto
,
cs
.
fw
.
ip
.
invflags
,
cs
.
fw
.
ip
.
proto
,
num
,
format
);
num
,
format
);
print_fragment
(
cs
.
fw
.
ip
.
flags
,
cs
.
fw
.
ip
.
invflags
,
format
);
print_fragment
(
cs
.
fw
.
ip
.
flags
,
cs
.
fw
.
ip
.
invflags
,
format
);
print_ifaces
(
cs
.
fw
.
ip
.
iniface
,
cs
.
fw
.
ip
.
outiface
,
cs
.
fw
.
ip
.
invflags
,
print_ifaces
(
cs
.
fw
.
ip
.
iniface
,
cs
.
fw
.
ip
.
outiface
,
cs
.
fw
.
ip
.
invflags
,
format
);
format
);
print_ipv4_addr
(
&
cs
,
format
);
print_ipv4_addr
esses
(
&
cs
.
fw
,
format
);
if
(
format
&
FMT_NOTABLE
)
if
(
format
&
FMT_NOTABLE
)
fputs
(
" "
,
stdout
);
fputs
(
" "
,
stdout
);
...
@@ -338,7 +309,7 @@ static void save_ipv4_addr(char letter, const struct in_addr *addr,
...
@@ -338,7 +309,7 @@ static void save_ipv4_addr(char letter, const struct in_addr *addr,
mask_to_str
(
mask
));
mask_to_str
(
mask
));
}
}
static
void
nft_ipv4_save_
firewall
(
const
void
*
data
,
unsigned
int
format
)
static
void
nft_ipv4_save_
rule
(
const
void
*
data
,
unsigned
int
format
)
{
{
const
struct
iptables_command_state
*
cs
=
data
;
const
struct
iptables_command_state
*
cs
=
data
;
...
@@ -347,9 +318,9 @@ static void nft_ipv4_save_firewall(const void *data, unsigned int format)
...
@@ -347,9 +318,9 @@ static void nft_ipv4_save_firewall(const void *data, unsigned int format)
save_ipv4_addr
(
'd'
,
&
cs
->
fw
.
ip
.
dst
,
cs
->
fw
.
ip
.
dmsk
.
s_addr
,
save_ipv4_addr
(
'd'
,
&
cs
->
fw
.
ip
.
dst
,
cs
->
fw
.
ip
.
dmsk
.
s_addr
,
cs
->
fw
.
ip
.
invflags
&
IPT_INV_DSTIP
);
cs
->
fw
.
ip
.
invflags
&
IPT_INV_DSTIP
);
save_
firewall
_details
(
cs
,
cs
->
fw
.
ip
.
invflags
,
cs
->
fw
.
ip
.
proto
,
save_
rule
_details
(
cs
,
cs
->
fw
.
ip
.
invflags
,
cs
->
fw
.
ip
.
proto
,
cs
->
fw
.
ip
.
iniface
,
cs
->
fw
.
ip
.
iniface_mask
,
cs
->
fw
.
ip
.
iniface
,
cs
->
fw
.
ip
.
iniface_mask
,
cs
->
fw
.
ip
.
outiface
,
cs
->
fw
.
ip
.
outiface_mask
);
cs
->
fw
.
ip
.
outiface
,
cs
->
fw
.
ip
.
outiface_mask
);
if
(
cs
->
fw
.
ip
.
flags
&
IPT_F_FRAG
)
{
if
(
cs
->
fw
.
ip
.
flags
&
IPT_F_FRAG
)
{
if
(
cs
->
fw
.
ip
.
invflags
&
IPT_INV_FRAG
)
if
(
cs
->
fw
.
ip
.
invflags
&
IPT_INV_FRAG
)
...
@@ -357,14 +328,8 @@ static void nft_ipv4_save_firewall(const void *data, unsigned int format)
...
@@ -357,14 +328,8 @@ static void nft_ipv4_save_firewall(const void *data, unsigned int format)
printf
(
"-f "
);
printf
(
"-f "
);
}
}
save_matches_and_target
(
cs
->
matches
,
cs
->
target
,
save_matches_and_target
(
cs
,
cs
->
fw
.
ip
.
flags
&
IPT_F_GOTO
,
cs
->
jumpto
,
cs
->
fw
.
ip
.
flags
,
&
cs
->
fw
);
&
cs
->
fw
,
format
);
if
(
cs
->
target
==
NULL
&&
strlen
(
cs
->
jumpto
)
>
0
)
{
printf
(
"-%c %s"
,
cs
->
fw
.
ip
.
flags
&
IPT_F_GOTO
?
'g'
:
'j'
,
cs
->
jumpto
);
}
printf
(
"
\n
"
);
}
}
static
void
nft_ipv4_proto_parse
(
struct
iptables_command_state
*
cs
,
static
void
nft_ipv4_proto_parse
(
struct
iptables_command_state
*
cs
,
...
@@ -422,28 +387,6 @@ static void nft_ipv4_post_parse(int command,
...
@@ -422,28 +387,6 @@ static void nft_ipv4_post_parse(int command,
" source or destination IP addresses"
);
" source or destination IP addresses"
);
}
}
static
void
nft_ipv4_parse_target
(
struct
xtables_target
*
t
,
void
*
data
)
{
struct
iptables_command_state
*
cs
=
data
;
cs
->
target
=
t
;
}
static
bool
nft_ipv4_rule_find
(
struct
nft_family_ops
*
ops
,
struct
nftnl_rule
*
r
,
void
*
data
)
{
struct
iptables_command_state
*
cs
=
data
;
return
nft_ipv46_rule_find
(
ops
,
r
,
cs
);
}
static
void
nft_ipv4_save_counters
(
const
void
*
data
)
{
const
struct
iptables_command_state
*
cs
=
data
;
save_counters
(
cs
->
counters
.
pcnt
,
cs
->
counters
.
bcnt
);
}
static
int
nft_ipv4_xlate
(
const
void
*
data
,
struct
xt_xlate
*
xl
)
static
int
nft_ipv4_xlate
(
const
void
*
data
,
struct
xt_xlate
*
xl
)
{
{
const
struct
iptables_command_state
*
cs
=
data
;
const
struct
iptables_command_state
*
cs
=
data
;
...
@@ -512,13 +455,16 @@ struct nft_family_ops nft_family_ops_ipv4 = {
...
@@ -512,13 +455,16 @@ struct nft_family_ops nft_family_ops_ipv4 = {
.
parse_meta
=
nft_ipv4_parse_meta
,
.
parse_meta
=
nft_ipv4_parse_meta
,
.
parse_payload
=
nft_ipv4_parse_payload
,
.
parse_payload
=
nft_ipv4_parse_payload
,
.
parse_immediate
=
nft_ipv4_parse_immediate
,
.
parse_immediate
=
nft_ipv4_parse_immediate
,
.
print_header
=
nft_ipv4_print_header
,
.
print_header
=
print_header
,
.
print_firewall
=
nft_ipv4_print_firewall
,
.
print_rule
=
nft_ipv4_print_rule
,
.
save_firewall
=
nft_ipv4_save_firewall
,
.
save_rule
=
nft_ipv4_save_rule
,
.
save_counters
=
nft_ipv4_save_counters
,
.
save_counters
=
save_counters
,
.
save_chain
=
nft_ipv46_save_chain
,
.
proto_parse
=
nft_ipv4_proto_parse
,
.
proto_parse
=
nft_ipv4_proto_parse
,
.
post_parse
=
nft_ipv4_post_parse
,
.
post_parse
=
nft_ipv4_post_parse
,
.
parse_target
=
nft_ipv4_parse_target
,
.
parse_target
=
nft_ipv46_parse_target
,
.
rule_find
=
nft_ipv4_rule_find
,
.
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
,
.
xlate
=
nft_ipv4_xlate
,
};
};
iptables/nft-ipv6.c
View file @
3bc9369c
...
@@ -44,8 +44,7 @@ static int nft_ipv6_add(struct nftnl_rule *r, void *data)
...
@@ -44,8 +44,7 @@ static int nft_ipv6_add(struct nftnl_rule *r, void *data)
if
(
cs
->
fw6
.
ipv6
.
proto
!=
0
)
{
if
(
cs
->
fw6
.
ipv6
.
proto
!=
0
)
{
op
=
nft_invflags2cmp
(
cs
->
fw6
.
ipv6
.
invflags
,
XT_INV_PROTO
);
op
=
nft_invflags2cmp
(
cs
->
fw6
.
ipv6
.
invflags
,
XT_INV_PROTO
);
add_proto
(
r
,
offsetof
(
struct
ip6_hdr
,
ip6_nxt
),
1
,
add_l4proto
(
r
,
cs
->
fw6
.
ipv6
.
proto
,
op
);
cs
->
fw6
.
ipv6
.
proto
,
op
);
}
}
if
(
!
IN6_IS_ADDR_UNSPECIFIED
(
&
cs
->
fw6
.
ipv6
.
src
))
{
if
(
!
IN6_IS_ADDR_UNSPECIFIED
(
&
cs
->
fw6
.
ipv6
.
src
))
{
...
@@ -60,7 +59,7 @@ static int nft_ipv6_add(struct nftnl_rule *r, void *data)
...
@@ -60,7 +59,7 @@ static int nft_ipv6_add(struct nftnl_rule *r, void *data)
&
cs
->
fw6
.
ipv6
.
dst
,
&
cs
->
fw6
.
ipv6
.
dmsk
,
&
cs
->
fw6
.
ipv6
.
dst
,
&
cs
->
fw6
.
ipv6
.
dmsk
,
sizeof
(
struct
in6_addr
),
op
);
sizeof
(
struct
in6_addr
),
op
);
}
}
add_compat
(
r
,
cs
->
fw6
.
ipv6
.
proto
,
cs
->
fw6
.
ipv6
.
invflags
);
add_compat
(
r
,
cs
->
fw6
.
ipv6
.
proto
,
cs
->
fw6
.
ipv6
.
invflags
&
XT_INV_PROTO
);
for
(
matchp
=
cs
->
matches
;
matchp
;
matchp
=
matchp
->
next
)
{
for
(
matchp
=
cs
->
matches
;
matchp
;
matchp
=
matchp
->
next
)
{
/* Use nft built-in comments support instead of comment match */
/* Use nft built-in comments support instead of comment match */
...
@@ -115,6 +114,16 @@ static void nft_ipv6_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e,
...
@@ -115,6 +114,16 @@ static void nft_ipv6_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e,
{
{
struct
iptables_command_state
*
cs
=
data
;
struct
iptables_command_state
*
cs
=
data
;
switch
(
ctx
->
meta
.
key
)
{
case
NFT_META_L4PROTO
:
cs
->
fw6
.
ipv6
.
proto
=
nftnl_expr_get_u8
(
e
,
NFTNL_EXPR_CMP_DATA
);
if
(
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_CMP_OP
)
==
NFT_CMP_NEQ
)
cs
->
fw6
.
ipv6
.
invflags
|=
XT_INV_PROTO
;
return
;
default:
break
;
}
parse_meta
(
e
,
ctx
->
meta
.
key
,
cs
->
fw6
.
ipv6
.
iniface
,
parse_meta
(
e
,
ctx
->
meta
.
key
,
cs
->
fw6
.
ipv6
.
iniface
,
cs
->
fw6
.
ipv6
.
iniface_mask
,
cs
->
fw6
.
ipv6
.
outiface
,
cs
->
fw6
.
ipv6
.
iniface_mask
,
cs
->
fw6
.
ipv6
.
outiface
,
cs
->
fw6
.
ipv6
.
outiface_mask
,
&
cs
->
fw6
.
ipv6
.
invflags
);
cs
->
fw6
.
ipv6
.
outiface_mask
,
&
cs
->
fw6
.
ipv6
.
invflags
);
...
@@ -162,7 +171,6 @@ static void nft_ipv6_parse_payload(struct nft_xt_ctx *ctx,
...
@@ -162,7 +171,6 @@ static void nft_ipv6_parse_payload(struct nft_xt_ctx *ctx,
break
;
break
;
case
offsetof
(
struct
ip6_hdr
,
ip6_nxt
):
case
offsetof
(
struct
ip6_hdr
,
ip6_nxt
):
get_cmp_data
(
e
,
&
proto
,
sizeof
(
proto
),
&
inv
);
get_cmp_data
(
e
,
&
proto
,
sizeof
(
proto
),
&
inv
);
cs
->
fw6
.
ipv6
.
flags
|=
IP6T_F_PROTO
;
cs
->
fw6
.
ipv6
.
proto
=
proto
;
cs
->
fw6
.
ipv6
.
proto
=
proto
;
if
(
inv
)
if
(
inv
)
cs
->
fw6
.
ipv6
.
invflags
|=
IP6T_INV_PROTO
;
cs
->
fw6
.
ipv6
.
invflags
|=
IP6T_INV_PROTO
;
...
@@ -183,64 +191,24 @@ static void nft_ipv6_parse_immediate(const char *jumpto, bool nft_goto,
...
@@ -183,64 +191,24 @@ static void nft_ipv6_parse_immediate(const char *jumpto, bool nft_goto,
cs
->
fw6
.
ipv6
.
flags
|=
IP6T_F_GOTO
;
cs
->
fw6
.
ipv6
.
flags
|=
IP6T_F_GOTO
;
}
}
static
void
nft_ipv6_print_header
(
unsigned
int
format
,
const
char
*
chain
,
static
void
nft_ipv6_print_rule
(
struct
nftnl_rule
*
r
,
unsigned
int
num
,
const
char
*
pol
,
unsigned
int
format
)
const
struct
xt_counters
*
counters
,
bool
basechain
,
uint32_t
refs
)
{
print_header
(
format
,
chain
,
pol
,
counters
,
basechain
,
refs
);
}
static
void
print_ipv6_addr
(
const
struct
iptables_command_state
*
cs
,
unsigned
int
format
)
{
char
buf
[
BUFSIZ
];
fputc
(
cs
->
fw6
.
ipv6
.
invflags
&
IP6T_INV_SRCIP
?
'!'
:
' '
,
stdout
);
if
(
IN6_IS_ADDR_UNSPECIFIED
(
&
cs
->
fw6
.
ipv6
.
src
)
&&
!
(
format
&
FMT_NUMERIC
))
printf
(
FMT
(
"%-19s "
,
"%s "
),
"anywhere"
);
else
{
if
(
format
&
FMT_NUMERIC
)
strcpy
(
buf
,
xtables_ip6addr_to_numeric
(
&
cs
->
fw6
.
ipv6
.
src
));
else
strcpy
(
buf
,
xtables_ip6addr_to_anyname
(
&
cs
->
fw6
.
ipv6
.
src
));
strcat
(
buf
,
xtables_ip6mask_to_numeric
(
&
cs
->
fw6
.
ipv6
.
smsk
));
printf
(
FMT
(
"%-19s "
,
"%s "
),
buf
);
}
fputc
(
cs
->
fw6
.
ipv6
.
invflags
&
IP6T_INV_DSTIP
?
'!'
:
' '
,
stdout
);
if
(
IN6_IS_ADDR_UNSPECIFIED
(
&
cs
->
fw6
.
ipv6
.
dst
)
&&
!
(
format
&
FMT_NUMERIC
))
printf
(
FMT
(
"%-19s "
,
"-> %s"
),
"anywhere"
);
else
{
if
(
format
&
FMT_NUMERIC
)
strcpy
(
buf
,
xtables_ip6addr_to_numeric
(
&
cs
->
fw6
.
ipv6
.
dst
));
else
strcpy
(
buf
,
xtables_ip6addr_to_anyname
(
&
cs
->
fw6
.
ipv6
.
dst
));
strcat
(
buf
,
xtables_ip6mask_to_numeric
(
&
cs
->
fw6
.
ipv6
.
dmsk
));
printf
(
FMT
(
"%-19s "
,
"-> %s"
),
buf
);
}
}
static
void
nft_ipv6_print_firewall
(
struct
nftnl_rule
*
r
,
unsigned
int
num
,
unsigned
int
format
)
{
{
struct
iptables_command_state
cs
=
{};
struct
iptables_command_state
cs
=
{};
nft_rule_to_iptables_command_state
(
r
,
&
cs
);
nft_rule_to_iptables_command_state
(
r
,
&
cs
);
print_firewall_details
(
&
cs
,
cs
.
jumpto
,
cs
.
fw6
.
ipv6
.
flags
,
print_rule_details
(
&
cs
,
cs
.
jumpto
,
cs
.
fw6
.
ipv6
.
flags
,
cs
.
fw6
.
ipv6
.
invflags
,
cs
.
fw6
.
ipv6
.
proto
,
cs
.
fw6
.
ipv6
.
invflags
,
cs
.
fw6
.
ipv6
.
proto
,
num
,
format
);
num
,
format
);
if
(
format
&
FMT_OPTIONS
)
{
if
(
format
&
FMT_NOTABLE
)
fputs
(
"opt "
,
stdout
);
fputs
(
" "
,
stdout
);
}
print_ifaces
(
cs
.
fw6
.
ipv6
.
iniface
,
cs
.
fw6
.
ipv6
.
outiface
,
print_ifaces
(
cs
.
fw6
.
ipv6
.
iniface
,
cs
.
fw6
.
ipv6
.
outiface
,
cs
.
fw6
.
ipv6
.
invflags
,
format
);
cs
.
fw6
.
ipv6
.
invflags
,
format
);
print_ipv6_addr
(
&
cs
,
format
);
print_ipv6_addr
esses
(
&
cs
.
fw6
,
format
);
if
(
format
&
FMT_NOTABLE
)
if
(
format
&
FMT_NOTABLE
)
fputs
(
" "
,
stdout
);
fputs
(
" "
,
stdout
);
...
@@ -276,7 +244,7 @@ static void save_ipv6_addr(char letter, const struct in6_addr *addr,
...
@@ -276,7 +244,7 @@ static void save_ipv6_addr(char letter, const struct in6_addr *addr,
printf
(
"/%d "
,
l
);
printf
(
"/%d "
,
l
);
}
}
static
void
nft_ipv6_save_
firewall
(
const
void
*
data
,
unsigned
int
format
)
static
void
nft_ipv6_save_
rule
(
const
void
*
data
,
unsigned
int
format
)
{
{
const
struct
iptables_command_state
*
cs
=
data
;
const
struct
iptables_command_state
*
cs
=
data
;
...
@@ -285,19 +253,12 @@ static void nft_ipv6_save_firewall(const void *data, unsigned int format)
...
@@ -285,19 +253,12 @@ static void nft_ipv6_save_firewall(const void *data, unsigned int format)
save_ipv6_addr
(
'd'
,
&
cs
->
fw6
.
ipv6
.
dst
,
&
cs
->
fw6
.
ipv6
.
dmsk
,
save_ipv6_addr
(
'd'
,
&
cs
->
fw6
.
ipv6
.
dst
,
&
cs
->
fw6
.
ipv6
.
dmsk
,
cs
->
fw6
.
ipv6
.
invflags
&
IP6T_INV_DSTIP
);
cs
->
fw6
.
ipv6
.
invflags
&
IP6T_INV_DSTIP
);
save_firewall_details
(
cs
,
cs
->
fw6
.
ipv6
.
invflags
,
cs
->
fw6
.
ipv6
.
proto
,
save_rule_details
(
cs
,
cs
->
fw6
.
ipv6
.
invflags
,
cs
->
fw6
.
ipv6
.
proto
,
cs
->
fw6
.
ipv6
.
iniface
,
cs
->
fw6
.
ipv6
.
iniface_mask
,
cs
->
fw6
.
ipv6
.
iniface
,
cs
->
fw6
.
ipv6
.
iniface_mask
,
cs
->
fw6
.
ipv6
.
outiface
,
cs
->
fw6
.
ipv6
.
outiface
,
cs
->
fw6
.
ipv6
.
outiface_mask
);
cs
->
fw6
.
ipv6
.
outiface_mask
);
save_matches_and_target
(
cs
->
matches
,
cs
->
target
,
cs
->
jumpto
,
cs
->
fw6
.
ipv6
.
flags
,
&
cs
->
fw6
);
if
(
cs
->
target
==
NULL
&&
strlen
(
cs
->
jumpto
)
>
0
)
{
save_matches_and_target
(
cs
,
cs
->
fw6
.
ipv6
.
flags
&
IP6T_F_GOTO
,
printf
(
"-%c %s"
,
cs
->
fw6
.
ipv6
.
flags
&
IP6T_F_GOTO
?
'g'
:
'j'
,
&
cs
->
fw6
,
format
);
cs
->
jumpto
);
}
printf
(
"
\n
"
);
}
}
/* These are invalid numbers as upper layer protocol */
/* These are invalid numbers as upper layer protocol */
...
@@ -326,9 +287,6 @@ static void nft_ipv6_proto_parse(struct iptables_command_state *cs,
...
@@ -326,9 +287,6 @@ static void nft_ipv6_proto_parse(struct iptables_command_state *cs,
static
void
nft_ipv6_post_parse
(
int
command
,
struct
iptables_command_state
*
cs
,
static
void
nft_ipv6_post_parse
(
int
command
,
struct
iptables_command_state
*
cs
,
struct
xtables_args
*
args
)
struct
xtables_args
*
args
)
{
{
if
(
args
->
proto
!=
0
)
args
->
flags
|=
IP6T_F_PROTO
;
cs
->
fw6
.
ipv6
.
flags
=
args
->
flags
;
cs
->
fw6
.
ipv6
.
flags
=
args
->
flags
;
/* We already set invflags in proto_parse, but we need to refresh it
/* We already set invflags in proto_parse, but we need to refresh it
* to include new parsed options.
* to include new parsed options.
...
@@ -375,28 +333,6 @@ static void nft_ipv6_post_parse(int command, struct iptables_command_state *cs,
...
@@ -375,28 +333,6 @@ static void nft_ipv6_post_parse(int command, struct iptables_command_state *cs,
" source or destination IP addresses"
);
" source or destination IP addresses"
);
}
}
static
void
nft_ipv6_parse_target
(
struct
xtables_target
*
t
,
void
*
data
)
{
struct
iptables_command_state
*
cs
=
data
;
cs
->
target
=
t
;
}
static
bool
nft_ipv6_rule_find
(
struct
nft_family_ops
*
ops
,
struct
nftnl_rule
*
r
,
void
*
data
)
{
struct
iptables_command_state
*
cs
=
data
;
return
nft_ipv46_rule_find
(
ops
,
r
,
cs
);
}
static
void
nft_ipv6_save_counters
(
const
void
*
data
)
{
const
struct
iptables_command_state
*
cs
=
data
;
save_counters
(
cs
->
counters
.
pcnt
,
cs
->
counters
.
bcnt
);
}
static
void
xlate_ipv6_addr
(
const
char
*
selector
,
const
struct
in6_addr
*
addr
,
static
void
xlate_ipv6_addr
(
const
char
*
selector
,
const
struct
in6_addr
*
addr
,
const
struct
in6_addr
*
mask
,
const
struct
in6_addr
*
mask
,
int
invert
,
struct
xt_xlate
*
xl
)
int
invert
,
struct
xt_xlate
*
xl
)
...
@@ -467,13 +403,16 @@ struct nft_family_ops nft_family_ops_ipv6 = {
...
@@ -467,13 +403,16 @@ struct nft_family_ops nft_family_ops_ipv6 = {
.
parse_meta
=
nft_ipv6_parse_meta
,
.
parse_meta
=
nft_ipv6_parse_meta
,
.
parse_payload
=
nft_ipv6_parse_payload
,
.
parse_payload
=
nft_ipv6_parse_payload
,
.
parse_immediate
=
nft_ipv6_parse_immediate
,
.
parse_immediate
=
nft_ipv6_parse_immediate
,
.
print_header
=
nft_ipv6_print_header
,
.
print_header
=
print_header
,
.
print_firewall
=
nft_ipv6_print_firewall
,
.
print_rule
=
nft_ipv6_print_rule
,
.
save_firewall
=
nft_ipv6_save_firewall
,
.
save_rule
=
nft_ipv6_save_rule
,
.
save_counters
=
nft_ipv6_save_counters
,
.
save_counters
=
save_counters
,
.
save_chain
=
nft_ipv46_save_chain
,
.
proto_parse
=
nft_ipv6_proto_parse
,
.
proto_parse
=
nft_ipv6_proto_parse
,
.
post_parse
=
nft_ipv6_post_parse
,
.
post_parse
=
nft_ipv6_post_parse
,
.
parse_target
=
nft_ipv6_parse_target
,
.
parse_target
=
nft_ipv46_parse_target
,
.
rule_find
=
nft_ipv6_rule_find
,
.
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
,
.
xlate
=
nft_ipv6_xlate
,
};
};
iptables/nft-shared.c
View file @
3bc9369c
...
@@ -16,11 +16,13 @@
...
@@ -16,11 +16,13 @@
#include <stdbool.h>
#include <stdbool.h>
#include <netdb.h>
#include <netdb.h>
#include <errno.h>
#include <errno.h>
#include <inttypes.h>
#include <xtables.h>
#include <xtables.h>
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter/xt_comment.h>
#include <linux/netfilter/xt_comment.h>
#include <linux/netfilter/xt_limit.h>
#include <libmnl/libmnl.h>
#include <libmnl/libmnl.h>
#include <libnftnl/rule.h>
#include <libnftnl/rule.h>
...
@@ -186,6 +188,12 @@ void add_proto(struct nftnl_rule *r, int offset, size_t len,
...
@@ -186,6 +188,12 @@ void add_proto(struct nftnl_rule *r, int offset, size_t len,
add_cmp_u8
(
r
,
proto
,
op
);
add_cmp_u8
(
r
,
proto
,
op
);
}
}
void
add_l4proto
(
struct
nftnl_rule
*
r
,
uint8_t
proto
,
uint32_t
op
)
{
add_meta
(
r
,
NFT_META_L4PROTO
);
add_cmp_u8
(
r
,
proto
,
op
);
}
bool
is_same_interfaces
(
const
char
*
a_iniface
,
const
char
*
a_outiface
,
bool
is_same_interfaces
(
const
char
*
a_iniface
,
const
char
*
a_outiface
,
unsigned
const
char
*
a_iniface_mask
,
unsigned
const
char
*
a_iniface_mask
,
unsigned
const
char
*
a_outiface_mask
,
unsigned
const
char
*
a_outiface_mask
,
...
@@ -294,21 +302,6 @@ int parse_meta(struct nftnl_expr *e, uint8_t key, char *iniface,
...
@@ -294,21 +302,6 @@ int parse_meta(struct nftnl_expr *e, uint8_t key, char *iniface,
return
0
;
return
0
;
}
}
static
void
*
nft_get_data
(
struct
nft_xt_ctx
*
ctx
)
{
switch
(
ctx
->
family
)
{
case
NFPROTO_IPV4
:
case
NFPROTO_IPV6
:
case
NFPROTO_BRIDGE
:
return
ctx
->
state
.
cs
;
case
NFPROTO_ARP
:
return
ctx
->
state
.
cs_arp
;
default:
/* Should not happen */
return
NULL
;
}
}
void
nft_parse_target
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
)
void
nft_parse_target
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
)
{
{
uint32_t
tg_len
;
uint32_t
tg_len
;
...
@@ -318,7 +311,7 @@ void nft_parse_target(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
...
@@ -318,7 +311,7 @@ void nft_parse_target(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
struct
xt_entry_target
*
t
;
struct
xt_entry_target
*
t
;
size_t
size
;
size_t
size
;
struct
nft_family_ops
*
ops
;
struct
nft_family_ops
*
ops
;
void
*
data
=
nft_get_data
(
ctx
)
;
void
*
data
=
ctx
->
cs
;
target
=
xtables_find_target
(
targname
,
XTF_TRY_LOAD
);
target
=
xtables_find_target
(
targname
,
XTF_TRY_LOAD
);
if
(
target
==
NULL
)
if
(
target
==
NULL
)
...
@@ -326,11 +319,7 @@ void nft_parse_target(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
...
@@ -326,11 +319,7 @@ void nft_parse_target(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
size
=
XT_ALIGN
(
sizeof
(
struct
xt_entry_target
))
+
tg_len
;
size
=
XT_ALIGN
(
sizeof
(
struct
xt_entry_target
))
+
tg_len
;
t
=
calloc
(
1
,
size
);
t
=
xtables_calloc
(
1
,
size
);
if
(
t
==
NULL
)
{
fprintf
(
stderr
,
"OOM"
);
exit
(
EXIT_FAILURE
);
}
memcpy
(
&
t
->
data
,
targinfo
,
tg_len
);
memcpy
(
&
t
->
data
,
targinfo
,
tg_len
);
t
->
u
.
target_size
=
size
;
t
->
u
.
target_size
=
size
;
t
->
u
.
user
.
revision
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_TG_REV
);
t
->
u
.
user
.
revision
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_TG_REV
);
...
@@ -356,7 +345,7 @@ void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
...
@@ -356,7 +345,7 @@ void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
case
NFPROTO_IPV4
:
case
NFPROTO_IPV4
:
case
NFPROTO_IPV6
:
case
NFPROTO_IPV6
:
case
NFPROTO_BRIDGE
:
case
NFPROTO_BRIDGE
:
matches
=
&
ctx
->
state
.
cs
->
matches
;
matches
=
&
ctx
->
cs
->
matches
;
break
;
break
;
default:
default:
fprintf
(
stderr
,
"BUG: nft_parse_match() unknown family %d
\n
"
,
fprintf
(
stderr
,
"BUG: nft_parse_match() unknown family %d
\n
"
,
...
@@ -368,12 +357,7 @@ void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
...
@@ -368,12 +357,7 @@ void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
if
(
match
==
NULL
)
if
(
match
==
NULL
)
return
;
return
;
m
=
calloc
(
1
,
sizeof
(
struct
xt_entry_match
)
+
mt_len
);
m
=
xtables_calloc
(
1
,
sizeof
(
struct
xt_entry_match
)
+
mt_len
);
if
(
m
==
NULL
)
{
fprintf
(
stderr
,
"OOM"
);
exit
(
EXIT_FAILURE
);
}
memcpy
(
&
m
->
data
,
mt_info
,
mt_len
);
memcpy
(
&
m
->
data
,
mt_info
,
mt_len
);
m
->
u
.
match_size
=
mt_len
+
XT_ALIGN
(
sizeof
(
struct
xt_entry_match
));
m
->
u
.
match_size
=
mt_len
+
XT_ALIGN
(
sizeof
(
struct
xt_entry_match
));
m
->
u
.
user
.
revision
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_TG_REV
);
m
->
u
.
user
.
revision
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_TG_REV
);
...
@@ -383,7 +367,7 @@ void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
...
@@ -383,7 +367,7 @@ void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
ops
=
nft_family_ops_lookup
(
ctx
->
family
);
ops
=
nft_family_ops_lookup
(
ctx
->
family
);
if
(
ops
->
parse_match
!=
NULL
)
if
(
ops
->
parse_match
!=
NULL
)
ops
->
parse_match
(
match
,
nft_get_data
(
ctx
)
);
ops
->
parse_match
(
match
,
ctx
->
cs
);
}
}
void
print_proto
(
uint16_t
proto
,
int
invert
)
void
print_proto
(
uint16_t
proto
,
int
invert
)
...
@@ -446,7 +430,7 @@ static void nft_meta_set_to_target(struct nft_xt_ctx *ctx)
...
@@ -446,7 +430,7 @@ static void nft_meta_set_to_target(struct nft_xt_ctx *ctx)
target
->
t
=
t
;
target
->
t
=
t
;
ops
=
nft_family_ops_lookup
(
ctx
->
family
);
ops
=
nft_family_ops_lookup
(
ctx
->
family
);
ops
->
parse_target
(
target
,
nft_get_data
(
ctx
)
);
ops
->
parse_target
(
target
,
ctx
->
cs
);
}
}
void
nft_parse_meta
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
)
void
nft_parse_meta
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
)
...
@@ -491,7 +475,7 @@ void nft_parse_bitwise(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
...
@@ -491,7 +475,7 @@ void nft_parse_bitwise(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
void
nft_parse_cmp
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
)
void
nft_parse_cmp
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
)
{
{
struct
nft_family_ops
*
ops
=
nft_family_ops_lookup
(
ctx
->
family
);
struct
nft_family_ops
*
ops
=
nft_family_ops_lookup
(
ctx
->
family
);
void
*
data
=
nft_get_data
(
ctx
)
;
void
*
data
=
ctx
->
cs
;
uint32_t
reg
;
uint32_t
reg
;
reg
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_CMP_SREG
);
reg
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_CMP_SREG
);
...
@@ -521,7 +505,7 @@ void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
...
@@ -521,7 +505,7 @@ void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
struct
nft_family_ops
*
ops
;
struct
nft_family_ops
*
ops
;
const
char
*
jumpto
=
NULL
;
const
char
*
jumpto
=
NULL
;
bool
nft_goto
=
false
;
bool
nft_goto
=
false
;
void
*
data
=
nft_get_data
(
ctx
)
;
void
*
data
=
ctx
->
cs
;
int
verdict
;
int
verdict
;
if
(
nftnl_expr_is_set
(
e
,
NFTNL_EXPR_IMM_DATA
))
{
if
(
nftnl_expr_is_set
(
e
,
NFTNL_EXPR_IMM_DATA
))
{
...
@@ -554,6 +538,7 @@ void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
...
@@ -554,6 +538,7 @@ void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
break
;;
break
;;
case
NFT_GOTO
:
case
NFT_GOTO
:
nft_goto
=
true
;
nft_goto
=
true
;
/* fall through */
case
NFT_JUMP
:
case
NFT_JUMP
:
jumpto
=
chain
;
jumpto
=
chain
;
break
;
break
;
...
@@ -563,14 +548,57 @@ void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
...
@@ -563,14 +548,57 @@ void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
ops
->
parse_immediate
(
jumpto
,
nft_goto
,
data
);
ops
->
parse_immediate
(
jumpto
,
nft_goto
,
data
);
}
}
void
nft_rule_to_iptables_command_state
(
struct
nftnl_rule
*
r
,
static
void
nft_parse_limit
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
)
{
__u32
burst
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_LIMIT_BURST
);
__u64
unit
=
nftnl_expr_get_u64
(
e
,
NFTNL_EXPR_LIMIT_UNIT
);
__u64
rate
=
nftnl_expr_get_u64
(
e
,
NFTNL_EXPR_LIMIT_RATE
);
struct
xtables_rule_match
**
matches
;
struct
xtables_match
*
match
;
struct
nft_family_ops
*
ops
;
struct
xt_rateinfo
*
rinfo
;
size_t
size
;
switch
(
ctx
->
family
)
{
case
NFPROTO_IPV4
:
case
NFPROTO_IPV6
:
case
NFPROTO_BRIDGE
:
matches
=
&
ctx
->
cs
->
matches
;
break
;
default:
fprintf
(
stderr
,
"BUG: nft_parse_match() unknown family %d
\n
"
,
ctx
->
family
);
exit
(
EXIT_FAILURE
);
}
match
=
xtables_find_match
(
"limit"
,
XTF_TRY_LOAD
,
matches
);
if
(
match
==
NULL
)
return
;
size
=
XT_ALIGN
(
sizeof
(
struct
xt_entry_match
))
+
match
->
size
;
match
->
m
=
xtables_calloc
(
1
,
size
);
match
->
m
->
u
.
match_size
=
size
;
strcpy
(
match
->
m
->
u
.
user
.
name
,
match
->
name
);
match
->
m
->
u
.
user
.
revision
=
match
->
revision
;
xs_init_match
(
match
);
rinfo
=
(
void
*
)
match
->
m
->
data
;
rinfo
->
avg
=
XT_LIMIT_SCALE
*
unit
/
rate
;
rinfo
->
burst
=
burst
;
ops
=
nft_family_ops_lookup
(
ctx
->
family
);
if
(
ops
->
parse_match
!=
NULL
)
ops
->
parse_match
(
match
,
ctx
->
cs
);
}
void
nft_rule_to_iptables_command_state
(
const
struct
nftnl_rule
*
r
,
struct
iptables_command_state
*
cs
)
struct
iptables_command_state
*
cs
)
{
{
struct
nftnl_expr_iter
*
iter
;
struct
nftnl_expr_iter
*
iter
;
struct
nftnl_expr
*
expr
;
struct
nftnl_expr
*
expr
;
int
family
=
nftnl_rule_get_u32
(
r
,
NFTNL_RULE_FAMILY
);
int
family
=
nftnl_rule_get_u32
(
r
,
NFTNL_RULE_FAMILY
);
struct
nft_xt_ctx
ctx
=
{
struct
nft_xt_ctx
ctx
=
{
.
state
.
cs
=
cs
,
.
cs
=
cs
,
.
family
=
family
,
.
family
=
family
,
};
};
...
@@ -585,7 +613,7 @@ void nft_rule_to_iptables_command_state(struct nftnl_rule *r,
...
@@ -585,7 +613,7 @@ void nft_rule_to_iptables_command_state(struct nftnl_rule *r,
nftnl_expr_get_str
(
expr
,
NFTNL_EXPR_NAME
);
nftnl_expr_get_str
(
expr
,
NFTNL_EXPR_NAME
);
if
(
strcmp
(
name
,
"counter"
)
==
0
)
if
(
strcmp
(
name
,
"counter"
)
==
0
)
nft_parse_counter
(
expr
,
&
ctx
.
state
.
cs
->
counters
);
nft_parse_counter
(
expr
,
&
ctx
.
cs
->
counters
);
else
if
(
strcmp
(
name
,
"payload"
)
==
0
)
else
if
(
strcmp
(
name
,
"payload"
)
==
0
)
nft_parse_payload
(
&
ctx
,
expr
);
nft_parse_payload
(
&
ctx
,
expr
);
else
if
(
strcmp
(
name
,
"meta"
)
==
0
)
else
if
(
strcmp
(
name
,
"meta"
)
==
0
)
...
@@ -600,6 +628,8 @@ void nft_rule_to_iptables_command_state(struct nftnl_rule *r,
...
@@ -600,6 +628,8 @@ void nft_rule_to_iptables_command_state(struct nftnl_rule *r,
nft_parse_match
(
&
ctx
,
expr
);
nft_parse_match
(
&
ctx
,
expr
);
else
if
(
strcmp
(
name
,
"target"
)
==
0
)
else
if
(
strcmp
(
name
,
"target"
)
==
0
)
nft_parse_target
(
&
ctx
,
expr
);
nft_parse_target
(
&
ctx
,
expr
);
else
if
(
strcmp
(
name
,
"limit"
)
==
0
)
nft_parse_limit
(
&
ctx
,
expr
);
expr
=
nftnl_expr_iter_next
(
iter
);
expr
=
nftnl_expr_iter_next
(
iter
);
}
}
...
@@ -608,7 +638,7 @@ void nft_rule_to_iptables_command_state(struct nftnl_rule *r,
...
@@ -608,7 +638,7 @@ void nft_rule_to_iptables_command_state(struct nftnl_rule *r,
if
(
nftnl_rule_is_set
(
r
,
NFTNL_RULE_USERDATA
))
{
if
(
nftnl_rule_is_set
(
r
,
NFTNL_RULE_USERDATA
))
{
const
void
*
data
;
const
void
*
data
;
uint32_t
len
;
uint32_t
len
,
size
;
struct
xtables_match
*
match
;
struct
xtables_match
*
match
;
struct
xt_entry_match
*
m
;
struct
xt_entry_match
*
m
;
...
@@ -618,15 +648,12 @@ void nft_rule_to_iptables_command_state(struct nftnl_rule *r,
...
@@ -618,15 +648,12 @@ void nft_rule_to_iptables_command_state(struct nftnl_rule *r,
if
(
match
==
NULL
)
if
(
match
==
NULL
)
return
;
return
;
m
=
calloc
(
1
,
sizeof
(
struct
xt_entry_match
)
+
size
=
XT_ALIGN
(
sizeof
(
struct
xt_entry_match
))
+
match
->
size
;
sizeof
(
struct
xt_comment_info
));
m
=
xtables_calloc
(
1
,
size
);
if
(
m
==
NULL
)
{
fprintf
(
stderr
,
"OOM"
);
exit
(
EXIT_FAILURE
);
}
memcpy
(
&
m
->
data
,
get_comment
(
data
,
len
),
len
);
strncpy
((
char
*
)
m
->
data
,
get_comment
(
data
,
len
),
m
->
u
.
match_size
=
len
+
XT_ALIGN
(
sizeof
(
struct
xt_entry_match
));
match
->
size
-
1
);
m
->
u
.
match_size
=
size
;
m
->
u
.
user
.
revision
=
0
;
m
->
u
.
user
.
revision
=
0
;
strcpy
(
m
->
u
.
user
.
name
,
match
->
name
);
strcpy
(
m
->
u
.
user
.
name
,
match
->
name
);
...
@@ -641,9 +668,16 @@ void nft_rule_to_iptables_command_state(struct nftnl_rule *r,
...
@@ -641,9 +668,16 @@ void nft_rule_to_iptables_command_state(struct nftnl_rule *r,
cs
->
jumpto
=
""
;
cs
->
jumpto
=
""
;
}
}
void
nft_clear_iptables_command_state
(
struct
iptables_command_state
*
cs
)
{
xtables_rule_matches_free
(
&
cs
->
matches
);
if
(
cs
->
target
)
free
(
cs
->
target
->
t
);
}
void
print_header
(
unsigned
int
format
,
const
char
*
chain
,
const
char
*
pol
,
void
print_header
(
unsigned
int
format
,
const
char
*
chain
,
const
char
*
pol
,
const
struct
xt_counters
*
counters
,
bool
basechain
,
const
struct
xt_counters
*
counters
,
bool
basechain
,
uint32_t
refs
)
uint32_t
refs
,
uint32_t
entries
)
{
{
printf
(
"Chain %s"
,
chain
);
printf
(
"Chain %s"
,
chain
);
if
(
basechain
)
{
if
(
basechain
)
{
...
@@ -685,10 +719,10 @@ void print_header(unsigned int format, const char *chain, const char *pol,
...
@@ -685,10 +719,10 @@ void print_header(unsigned int format, const char *chain, const char *pol,
printf
(
"
\n
"
);
printf
(
"
\n
"
);
}
}
void
print_
firewall
_details
(
const
struct
iptables_command_state
*
cs
,
void
print_
rule
_details
(
const
struct
iptables_command_state
*
cs
,
const
char
*
targname
,
uint8_t
flags
,
const
char
*
targname
,
uint8_t
flags
,
uint8_t
invflags
,
uint8_t
proto
,
uint8_t
invflags
,
uint8_t
proto
,
unsigned
int
num
,
unsigned
int
format
)
unsigned
int
num
,
unsigned
int
format
)
{
{
if
(
format
&
FMT_LINENUMBERS
)
if
(
format
&
FMT_LINENUMBERS
)
printf
(
FMT
(
"%-4u "
,
"%u "
),
num
);
printf
(
FMT
(
"%-4u "
,
"%u "
),
num
);
...
@@ -712,45 +746,6 @@ void print_firewall_details(const struct iptables_command_state *cs,
...
@@ -712,45 +746,6 @@ void print_firewall_details(const struct iptables_command_state *cs,
}
}
}
}
void
print_ifaces
(
const
char
*
iniface
,
const
char
*
outiface
,
uint8_t
invflags
,
unsigned
int
format
)
{
char
iface
[
IFNAMSIZ
+
2
];
if
(
!
(
format
&
FMT_VIA
))
return
;
if
(
invflags
&
IPT_INV_VIA_IN
)
{
iface
[
0
]
=
'!'
;
iface
[
1
]
=
'\0'
;
}
else
iface
[
0
]
=
'\0'
;
if
(
iniface
[
0
]
!=
'\0'
)
strcat
(
iface
,
iniface
);
else
if
(
format
&
FMT_NUMERIC
)
strcat
(
iface
,
"*"
);
else
strcat
(
iface
,
"any"
);
printf
(
FMT
(
" %-6s "
,
"in %s "
),
iface
);
if
(
invflags
&
IPT_INV_VIA_OUT
)
{
iface
[
0
]
=
'!'
;
iface
[
1
]
=
'\0'
;
}
else
iface
[
0
]
=
'\0'
;
if
(
outiface
[
0
]
!=
'\0'
)
strcat
(
iface
,
outiface
);
else
if
(
format
&
FMT_NUMERIC
)
strcat
(
iface
,
"*"
);
else
strcat
(
iface
,
"any"
);
printf
(
FMT
(
"%-6s "
,
"out %s "
),
iface
);
}
static
void
static
void
print_iface
(
char
letter
,
const
char
*
iface
,
const
unsigned
char
*
mask
,
int
inv
)
print_iface
(
char
letter
,
const
char
*
iface
,
const
unsigned
char
*
mask
,
int
inv
)
{
{
...
@@ -775,12 +770,12 @@ print_iface(char letter, const char *iface, const unsigned char *mask, int inv)
...
@@ -775,12 +770,12 @@ print_iface(char letter, const char *iface, const unsigned char *mask, int inv)
printf
(
" "
);
printf
(
" "
);
}
}
void
save_
firewall
_details
(
const
struct
iptables_command_state
*
cs
,
void
save_
rule
_details
(
const
struct
iptables_command_state
*
cs
,
uint8_t
invflags
,
uint16_t
proto
,
uint8_t
invflags
,
uint16_t
proto
,
const
char
*
iniface
,
const
char
*
iniface
,
unsigned
const
char
*
iniface_mask
,
unsigned
const
char
*
iniface_mask
,
const
char
*
outiface
,
const
char
*
outiface
,
unsigned
const
char
*
outiface_mask
)
unsigned
const
char
*
outiface_mask
)
{
{
if
(
iniface
!=
NULL
)
{
if
(
iniface
!=
NULL
)
{
print_iface
(
'i'
,
iniface
,
iniface_mask
,
print_iface
(
'i'
,
iniface
,
iniface_mask
,
...
@@ -804,19 +799,31 @@ void save_firewall_details(const struct iptables_command_state *cs,
...
@@ -804,19 +799,31 @@ void save_firewall_details(const struct iptables_command_state *cs,
}
}
}
}
void
save_counters
(
uint64_t
pcnt
,
uint64_t
bcnt
)
void
save_counters
(
const
void
*
data
)
{
{
printf
(
"[%llu:%llu] "
,
(
unsigned
long
long
)
pcnt
,
const
struct
iptables_command_state
*
cs
=
data
;
(
unsigned
long
long
)
bcnt
);
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
);
uint64_t
pkts
=
nftnl_chain_get_u64
(
c
,
NFTNL_CHAIN_PACKETS
);
uint64_t
bytes
=
nftnl_chain_get_u64
(
c
,
NFTNL_CHAIN_BYTES
);
printf
(
":%s %s [%"
PRIu64
":%"
PRIu64
"]
\n
"
,
chain
,
policy
?:
"-"
,
pkts
,
bytes
);
}
}
void
save_matches_and_target
(
struct
x
tables_
rule_match
*
m
,
void
save_matches_and_target
(
const
struct
ip
tables_
command_state
*
cs
,
struct
xtables_target
*
target
,
bool
goto_flag
,
const
void
*
fw
,
const
char
*
jumpto
,
uint8_t
flags
,
const
void
*
fw
)
unsigned
int
format
)
{
{
struct
xtables_rule_match
*
matchp
;
struct
xtables_rule_match
*
matchp
;
for
(
matchp
=
m
;
matchp
;
matchp
=
matchp
->
next
)
{
for
(
matchp
=
cs
->
matches
;
matchp
;
matchp
=
matchp
->
next
)
{
if
(
matchp
->
match
->
alias
)
{
if
(
matchp
->
match
->
alias
)
{
printf
(
"-m %s"
,
printf
(
"-m %s"
,
matchp
->
match
->
alias
(
matchp
->
match
->
m
));
matchp
->
match
->
alias
(
matchp
->
match
->
m
));
...
@@ -830,15 +837,24 @@ void save_matches_and_target(struct xtables_rule_match *m,
...
@@ -830,15 +837,24 @@ void save_matches_and_target(struct xtables_rule_match *m,
printf
(
" "
);
printf
(
" "
);
}
}
if
(
target
!=
NULL
)
{
if
((
format
&
(
FMT_NOCOUNTS
|
FMT_C_COUNTS
))
==
FMT_C_COUNTS
)
if
(
target
->
alias
)
{
printf
(
"-c %llu %llu "
,
printf
(
"-j %s"
,
target
->
alias
(
target
->
t
));
(
unsigned
long
long
)
cs
->
counters
.
pcnt
,
(
unsigned
long
long
)
cs
->
counters
.
bcnt
);
if
(
cs
->
target
!=
NULL
)
{
if
(
cs
->
target
->
alias
)
{
printf
(
"-j %s"
,
cs
->
target
->
alias
(
cs
->
target
->
t
));
}
else
}
else
printf
(
"-j %s"
,
jumpto
);
printf
(
"-j %s"
,
cs
->
jumpto
);
if
(
target
->
save
!=
NULL
)
if
(
cs
->
target
->
save
!=
NULL
)
target
->
save
(
fw
,
target
->
t
);
cs
->
target
->
save
(
fw
,
cs
->
target
->
t
);
}
else
if
(
strlen
(
cs
->
jumpto
)
>
0
)
{
printf
(
"-%c %s"
,
goto_flag
?
'g'
:
'j'
,
cs
->
jumpto
);
}
}
printf
(
"
\n
"
);
}
}
void
print_matches_and_target
(
struct
iptables_command_state
*
cs
,
void
print_matches_and_target
(
struct
iptables_command_state
*
cs
,
...
@@ -934,16 +950,23 @@ bool compare_targets(struct xtables_target *tg1, struct xtables_target *tg2)
...
@@ -934,16 +950,23 @@ bool compare_targets(struct xtables_target *tg1, struct xtables_target *tg2)
return
true
;
return
true
;
}
}
void
nft_ipv46_parse_target
(
struct
xtables_target
*
t
,
void
*
data
)
{
struct
iptables_command_state
*
cs
=
data
;
cs
->
target
=
t
;
}
bool
nft_ipv46_rule_find
(
struct
nft_family_ops
*
ops
,
bool
nft_ipv46_rule_find
(
struct
nft_family_ops
*
ops
,
struct
nftnl_rule
*
r
,
struct
iptables_command_state
*
cs
)
struct
nftnl_rule
*
r
,
void
*
data
)
{
{
struct
iptables_command_state
this
=
{};
struct
iptables_command_state
*
cs
=
data
,
this
=
{};
nft_rule_to_iptables_command_state
(
r
,
&
this
);
nft_rule_to_iptables_command_state
(
r
,
&
this
);
DEBUGP
(
"comparing with... "
);
DEBUGP
(
"comparing with... "
);
#ifdef DEBUG_DEL
#ifdef DEBUG_DEL
nft_rule_print_save
(
&
this
,
r
,
NFT_RULE_APPEND
,
0
);
nft_rule_print_save
(
r
,
NFT_RULE_APPEND
,
0
);
#endif
#endif
if
(
!
ops
->
is_same
(
cs
,
&
this
))
if
(
!
ops
->
is_same
(
cs
,
&
this
))
return
false
;
return
false
;
...
...
iptables/nft-shared.h
View file @
3bc9369c
...
@@ -5,17 +5,15 @@
...
@@ -5,17 +5,15 @@
#include <libnftnl/rule.h>
#include <libnftnl/rule.h>
#include <libnftnl/expr.h>
#include <libnftnl/expr.h>
#include <libnftnl/chain.h>
#include <linux/netfilter_arp/arp_tables.h>
#include <linux/netfilter_arp/arp_tables.h>
#include "xshared.h"
#include "xshared.h"
#if 0
#ifdef DEBUG
#define DEBUGP(x, args...) fprintf(stdout, x, ## args)
#define NLDEBUG
#define NLDEBUG
#define DEBUG_DEL
#define DEBUG_DEL
#else
#define DEBUGP(x, args...)
#endif
#endif
/*
/*
...
@@ -47,10 +45,7 @@ enum {
...
@@ -47,10 +45,7 @@ enum {
};
};
struct
nft_xt_ctx
{
struct
nft_xt_ctx
{
union
{
struct
iptables_command_state
*
cs
;
struct
iptables_command_state
*
cs
;
struct
arptables_command_state
*
cs_arp
;
}
state
;
struct
nftnl_expr_iter
*
iter
;
struct
nftnl_expr_iter
*
iter
;
int
family
;
int
family
;
uint32_t
flags
;
uint32_t
flags
;
...
@@ -93,17 +88,21 @@ struct nft_family_ops {
...
@@ -93,17 +88,21 @@ struct nft_family_ops {
void
(
*
print_header
)(
unsigned
int
format
,
const
char
*
chain
,
void
(
*
print_header
)(
unsigned
int
format
,
const
char
*
chain
,
const
char
*
pol
,
const
char
*
pol
,
const
struct
xt_counters
*
counters
,
bool
basechain
,
const
struct
xt_counters
*
counters
,
bool
basechain
,
uint32_t
refs
);
uint32_t
refs
,
uint32_t
entries
);
void
(
*
print_
firewall
)(
struct
nftnl_rule
*
r
,
unsigned
int
num
,
void
(
*
print_
rule
)(
struct
nftnl_rule
*
r
,
unsigned
int
num
,
unsigned
int
format
);
unsigned
int
format
);
void
(
*
save_
firewall
)(
const
void
*
data
,
unsigned
int
format
);
void
(
*
save_
rule
)(
const
void
*
data
,
unsigned
int
format
);
void
(
*
save_counters
)(
const
void
*
data
);
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
,
void
(
*
proto_parse
)(
struct
iptables_command_state
*
cs
,
struct
xtables_args
*
args
);
struct
xtables_args
*
args
);
void
(
*
post_parse
)(
int
command
,
struct
iptables_command_state
*
cs
,
void
(
*
post_parse
)(
int
command
,
struct
iptables_command_state
*
cs
,
struct
xtables_args
*
args
);
struct
xtables_args
*
args
);
void
(
*
parse_match
)(
struct
xtables_match
*
m
,
void
*
data
);
void
(
*
parse_match
)(
struct
xtables_match
*
m
,
void
*
data
);
void
(
*
parse_target
)(
struct
xtables_target
*
t
,
void
*
data
);
void
(
*
parse_target
)(
struct
xtables_target
*
t
,
void
*
data
);
void
(
*
rule_to_cs
)(
const
struct
nftnl_rule
*
r
,
struct
iptables_command_state
*
cs
);
void
(
*
clear_cs
)(
struct
iptables_command_state
*
cs
);
bool
(
*
rule_find
)(
struct
nft_family_ops
*
ops
,
struct
nftnl_rule
*
r
,
bool
(
*
rule_find
)(
struct
nft_family_ops
*
ops
,
struct
nftnl_rule
*
r
,
void
*
data
);
void
*
data
);
int
(
*
xlate
)(
const
void
*
data
,
struct
xt_xlate
*
xl
);
int
(
*
xlate
)(
const
void
*
data
,
struct
xt_xlate
*
xl
);
...
@@ -123,6 +122,7 @@ void add_addr(struct nftnl_rule *r, int offset,
...
@@ -123,6 +122,7 @@ void add_addr(struct nftnl_rule *r, int offset,
void
*
data
,
void
*
mask
,
size_t
len
,
uint32_t
op
);
void
*
data
,
void
*
mask
,
size_t
len
,
uint32_t
op
);
void
add_proto
(
struct
nftnl_rule
*
r
,
int
offset
,
size_t
len
,
void
add_proto
(
struct
nftnl_rule
*
r
,
int
offset
,
size_t
len
,
uint8_t
proto
,
uint32_t
op
);
uint8_t
proto
,
uint32_t
op
);
void
add_l4proto
(
struct
nftnl_rule
*
r
,
uint8_t
proto
,
uint32_t
op
);
void
add_compat
(
struct
nftnl_rule
*
r
,
uint32_t
proto
,
bool
inv
);
void
add_compat
(
struct
nftnl_rule
*
r
,
uint32_t
proto
,
bool
inv
);
bool
is_same_interfaces
(
const
char
*
a_iniface
,
const
char
*
a_outiface
,
bool
is_same_interfaces
(
const
char
*
a_iniface
,
const
char
*
a_outiface
,
...
@@ -145,36 +145,36 @@ void nft_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e);
...
@@ -145,36 +145,36 @@ void nft_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e);
void
nft_parse_payload
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
);
void
nft_parse_payload
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
);
void
nft_parse_counter
(
struct
nftnl_expr
*
e
,
struct
xt_counters
*
counters
);
void
nft_parse_counter
(
struct
nftnl_expr
*
e
,
struct
xt_counters
*
counters
);
void
nft_parse_immediate
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
);
void
nft_parse_immediate
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
);
void
nft_rule_to_iptables_command_state
(
struct
nftnl_rule
*
r
,
void
nft_rule_to_iptables_command_state
(
const
struct
nftnl_rule
*
r
,
struct
iptables_command_state
*
cs
);
struct
iptables_command_state
*
cs
);
void
nft_clear_iptables_command_state
(
struct
iptables_command_state
*
cs
);
void
print_header
(
unsigned
int
format
,
const
char
*
chain
,
const
char
*
pol
,
void
print_header
(
unsigned
int
format
,
const
char
*
chain
,
const
char
*
pol
,
const
struct
xt_counters
*
counters
,
bool
basechain
,
const
struct
xt_counters
*
counters
,
bool
basechain
,
uint32_t
refs
);
uint32_t
refs
,
uint32_t
entries
);
void
print_firewall_details
(
const
struct
iptables_command_state
*
cs
,
void
print_rule_details
(
const
struct
iptables_command_state
*
cs
,
const
char
*
targname
,
uint8_t
flags
,
const
char
*
targname
,
uint8_t
flags
,
uint8_t
invflags
,
uint8_t
proto
,
uint8_t
invflags
,
uint8_t
proto
,
unsigned
int
num
,
unsigned
int
format
);
unsigned
int
num
,
unsigned
int
format
);
void
print_ifaces
(
const
char
*
iniface
,
const
char
*
outiface
,
uint8_t
invflags
,
unsigned
int
format
);
void
print_matches_and_target
(
struct
iptables_command_state
*
cs
,
void
print_matches_and_target
(
struct
iptables_command_state
*
cs
,
unsigned
int
format
);
unsigned
int
format
);
void
save_
firewall
_details
(
const
struct
iptables_command_state
*
cs
,
void
save_
rule
_details
(
const
struct
iptables_command_state
*
cs
,
uint8_t
invflags
,
uint16_t
proto
,
uint8_t
invflags
,
uint16_t
proto
,
const
char
*
iniface
,
const
char
*
iniface
,
unsigned
const
char
*
iniface_mask
,
unsigned
const
char
*
iniface_mask
,
const
char
*
outiface
,
const
char
*
outiface
,
unsigned
const
char
*
outiface_mask
);
unsigned
const
char
*
outiface_mask
);
void
save_counters
(
uint64_t
pcnt
,
uint64_t
bcnt
);
void
save_counters
(
const
void
*
data
);
void
save_matches_and_target
(
struct
xtables_rule_match
*
m
,
void
nft_ipv46_save_chain
(
const
struct
nftnl_chain
*
c
,
const
char
*
policy
);
struct
x
tables_
target
*
target
,
void
save_matches_and_target
(
const
struct
ip
tables_
command_state
*
cs
,
const
char
*
jumpto
,
bool
goto_flag
,
const
void
*
fw
,
u
int8_t
flags
,
const
void
*
fw
);
u
nsigned
int
format
);
struct
nft_family_ops
*
nft_family_ops_lookup
(
int
family
);
struct
nft_family_ops
*
nft_family_ops_lookup
(
int
family
);
struct
nft_handle
;
struct
nft_handle
;
void
nft_ipv46_parse_target
(
struct
xtables_target
*
t
,
void
*
data
);
bool
nft_ipv46_rule_find
(
struct
nft_family_ops
*
ops
,
struct
nftnl_rule
*
r
,
bool
nft_ipv46_rule_find
(
struct
nft_family_ops
*
ops
,
struct
nftnl_rule
*
r
,
struct
iptables_command_state
*
cs
);
void
*
data
);
bool
compare_matches
(
struct
xtables_rule_match
*
mt1
,
struct
xtables_rule_match
*
mt2
);
bool
compare_matches
(
struct
xtables_rule_match
*
mt1
,
struct
xtables_rule_match
*
mt2
);
bool
compare_targets
(
struct
xtables_target
*
tg1
,
struct
xtables_target
*
tg2
);
bool
compare_targets
(
struct
xtables_target
*
tg1
,
struct
xtables_target
*
tg2
);
...
@@ -243,6 +243,7 @@ struct nft_xt_restore_parse {
...
@@ -243,6 +243,7 @@ struct nft_xt_restore_parse {
FILE
*
in
;
FILE
*
in
;
int
testing
;
int
testing
;
const
char
*
tablename
;
const
char
*
tablename
;
bool
commit
;
};
};
struct
nftnl_chain_list
;
struct
nftnl_chain_list
;
...
...
iptables/nft.c
View file @
3bc9369c
...
@@ -38,6 +38,8 @@
...
@@ -38,6 +38,8 @@
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter/nf_tables_compat.h>
#include <linux/netfilter/nf_tables_compat.h>
#include <linux/netfilter/xt_limit.h>
#include <libmnl/libmnl.h>
#include <libmnl/libmnl.h>
#include <libnftnl/table.h>
#include <libnftnl/table.h>
#include <libnftnl/chain.h>
#include <libnftnl/chain.h>
...
@@ -246,6 +248,7 @@ enum obj_update_type {
...
@@ -246,6 +248,7 @@ enum obj_update_type {
NFT_COMPAT_CHAIN_USER_FLUSH
,
NFT_COMPAT_CHAIN_USER_FLUSH
,
NFT_COMPAT_CHAIN_UPDATE
,
NFT_COMPAT_CHAIN_UPDATE
,
NFT_COMPAT_CHAIN_RENAME
,
NFT_COMPAT_CHAIN_RENAME
,
NFT_COMPAT_CHAIN_ZERO
,
NFT_COMPAT_RULE_APPEND
,
NFT_COMPAT_RULE_APPEND
,
NFT_COMPAT_RULE_INSERT
,
NFT_COMPAT_RULE_INSERT
,
NFT_COMPAT_RULE_REPLACE
,
NFT_COMPAT_RULE_REPLACE
,
...
@@ -310,6 +313,7 @@ static int mnl_append_error(const struct nft_handle *h,
...
@@ -310,6 +313,7 @@ static int mnl_append_error(const struct nft_handle *h,
nftnl_table_get_str
(
o
->
table
,
NFTNL_TABLE_NAME
));
nftnl_table_get_str
(
o
->
table
,
NFTNL_TABLE_NAME
));
break
;
break
;
case
NFT_COMPAT_CHAIN_ADD
:
case
NFT_COMPAT_CHAIN_ADD
:
case
NFT_COMPAT_CHAIN_ZERO
:
case
NFT_COMPAT_CHAIN_USER_ADD
:
case
NFT_COMPAT_CHAIN_USER_ADD
:
case
NFT_COMPAT_CHAIN_USER_DEL
:
case
NFT_COMPAT_CHAIN_USER_DEL
:
case
NFT_COMPAT_CHAIN_USER_FLUSH
:
case
NFT_COMPAT_CHAIN_USER_FLUSH
:
...
@@ -327,9 +331,7 @@ static int mnl_append_error(const struct nft_handle *h,
...
@@ -327,9 +331,7 @@ static int mnl_append_error(const struct nft_handle *h,
nftnl_rule_get_str
(
o
->
rule
,
NFTNL_RULE_CHAIN
));
nftnl_rule_get_str
(
o
->
rule
,
NFTNL_RULE_CHAIN
));
#if 0
#if 0
{
{
struct iptables_command_state cs = {};
nft_rule_print_save(o->rule, NFT_RULE_APPEND, FMT_NOCOUNTS);
nft_rule_to_iptables_command_state(o->rule, &cs);
nft_rule_print_save(&cs, o->rule, NFT_RULE_APPEND, FMT_NOCOUNTS);
}
}
#endif
#endif
break
;
break
;
...
@@ -630,7 +632,7 @@ static void nft_chain_builtin_add(struct nft_handle *h,
...
@@ -630,7 +632,7 @@ static void nft_chain_builtin_add(struct nft_handle *h,
}
}
/* find if built-in table already exists */
/* find if built-in table already exists */
static
struct
builtin_table
*
struct
builtin_table
*
nft_table_builtin_find
(
struct
nft_handle
*
h
,
const
char
*
table
)
nft_table_builtin_find
(
struct
nft_handle
*
h
,
const
char
*
table
)
{
{
int
i
;
int
i
;
...
@@ -651,7 +653,7 @@ nft_table_builtin_find(struct nft_handle *h, const char *table)
...
@@ -651,7 +653,7 @@ nft_table_builtin_find(struct nft_handle *h, const char *table)
}
}
/* find if built-in chain already exists */
/* find if built-in chain already exists */
static
struct
builtin_chain
*
struct
builtin_chain
*
nft_chain_builtin_find
(
struct
builtin_table
*
t
,
const
char
*
chain
)
nft_chain_builtin_find
(
struct
builtin_table
*
t
,
const
char
*
chain
)
{
{
int
i
;
int
i
;
...
@@ -675,7 +677,7 @@ static void nft_chain_builtin_init(struct nft_handle *h,
...
@@ -675,7 +677,7 @@ static void nft_chain_builtin_init(struct nft_handle *h,
struct
nftnl_chain
*
c
;
struct
nftnl_chain
*
c
;
/* Initialize built-in chains if they don't exist yet */
/* Initialize built-in chains if they don't exist yet */
for
(
i
=
0
;
i
<
NF_I
P
_NUMHOOKS
&&
table
->
chains
[
i
].
name
!=
NULL
;
i
++
)
{
for
(
i
=
0
;
i
<
NF_I
NET
_NUMHOOKS
&&
table
->
chains
[
i
].
name
!=
NULL
;
i
++
)
{
c
=
nft_chain_list_find
(
list
,
table
->
name
,
c
=
nft_chain_list_find
(
list
,
table
->
name
,
table
->
chains
[
i
].
name
);
table
->
chains
[
i
].
name
);
...
@@ -815,7 +817,7 @@ static void nft_chain_print_debug(struct nftnl_chain *c, struct nlmsghdr *nlh)
...
@@ -815,7 +817,7 @@ static void nft_chain_print_debug(struct nftnl_chain *c, struct nlmsghdr *nlh)
#ifdef NLDEBUG
#ifdef NLDEBUG
char
tmp
[
1024
];
char
tmp
[
1024
];
nft_chain_snprintf
(
tmp
,
sizeof
(
tmp
),
c
,
0
,
0
);
nft
nl
_chain_snprintf
(
tmp
,
sizeof
(
tmp
),
c
,
0
,
0
);
printf
(
"DEBUG: chain: %s
\n
"
,
tmp
);
printf
(
"DEBUG: chain: %s
\n
"
,
tmp
);
mnl_nlmsg_fprintf
(
stdout
,
nlh
,
nlh
->
nlmsg_len
,
sizeof
(
struct
nfgenmsg
));
mnl_nlmsg_fprintf
(
stdout
,
nlh
,
nlh
->
nlmsg_len
,
sizeof
(
struct
nfgenmsg
));
#endif
#endif
...
@@ -831,9 +833,13 @@ static struct nftnl_chain *nft_chain_new(struct nft_handle *h,
...
@@ -831,9 +833,13 @@ static struct nftnl_chain *nft_chain_new(struct nft_handle *h,
struct
builtin_chain
*
_c
;
struct
builtin_chain
*
_c
;
_t
=
nft_table_builtin_find
(
h
,
table
);
_t
=
nft_table_builtin_find
(
h
,
table
);
if
(
!
_t
)
{
errno
=
ENXIO
;
return
NULL
;
}
/* if this built-in table does not exists, create it */
/* if this built-in table does not exists, create it */
if
(
_t
!=
NULL
)
nft_table_builtin_add
(
h
,
_t
);
nft_table_builtin_add
(
h
,
_t
);
_c
=
nft_chain_builtin_find
(
_t
,
chain
);
_c
=
nft_chain_builtin_find
(
_t
,
chain
);
if
(
_c
!=
NULL
)
{
if
(
_c
!=
NULL
)
{
...
@@ -869,6 +875,8 @@ int nft_chain_set(struct nft_handle *h, const char *table,
...
@@ -869,6 +875,8 @@ int nft_chain_set(struct nft_handle *h, const char *table,
c
=
nft_chain_new
(
h
,
table
,
chain
,
NF_DROP
,
counters
);
c
=
nft_chain_new
(
h
,
table
,
chain
,
NF_DROP
,
counters
);
else
if
(
strcmp
(
policy
,
"ACCEPT"
)
==
0
)
else
if
(
strcmp
(
policy
,
"ACCEPT"
)
==
0
)
c
=
nft_chain_new
(
h
,
table
,
chain
,
NF_ACCEPT
,
counters
);
c
=
nft_chain_new
(
h
,
table
,
chain
,
NF_ACCEPT
,
counters
);
else
errno
=
EINVAL
;
if
(
c
==
NULL
)
if
(
c
==
NULL
)
return
0
;
return
0
;
...
@@ -896,11 +904,50 @@ static int __add_match(struct nftnl_expr *e, struct xt_entry_match *m)
...
@@ -896,11 +904,50 @@ static int __add_match(struct nftnl_expr *e, struct xt_entry_match *m)
return
0
;
return
0
;
}
}
static
int
add_nft_limit
(
struct
nftnl_rule
*
r
,
struct
xt_entry_match
*
m
)
{
struct
xt_rateinfo
*
rinfo
=
(
void
*
)
m
->
data
;
static
const
uint32_t
mult
[]
=
{
XT_LIMIT_SCALE
*
24
*
60
*
60
,
/* day */
XT_LIMIT_SCALE
*
60
*
60
,
/* hour */
XT_LIMIT_SCALE
*
60
,
/* min */
XT_LIMIT_SCALE
,
/* sec */
};
struct
nftnl_expr
*
expr
;
int
i
;
expr
=
nftnl_expr_alloc
(
"limit"
);
if
(
!
expr
)
return
-
ENOMEM
;
for
(
i
=
1
;
i
<
ARRAY_SIZE
(
mult
);
i
++
)
{
if
(
rinfo
->
avg
>
mult
[
i
]
||
mult
[
i
]
/
rinfo
->
avg
<
mult
[
i
]
%
rinfo
->
avg
)
break
;
}
nftnl_expr_set_u32
(
expr
,
NFTNL_EXPR_LIMIT_TYPE
,
NFT_LIMIT_PKTS
);
nftnl_expr_set_u32
(
expr
,
NFTNL_EXPR_LIMIT_FLAGS
,
0
);
nftnl_expr_set_u64
(
expr
,
NFTNL_EXPR_LIMIT_RATE
,
mult
[
i
-
1
]
/
rinfo
->
avg
);
nftnl_expr_set_u64
(
expr
,
NFTNL_EXPR_LIMIT_UNIT
,
mult
[
i
-
1
]
/
XT_LIMIT_SCALE
);
nftnl_expr_set_u32
(
expr
,
NFTNL_EXPR_LIMIT_BURST
,
rinfo
->
burst
);
nftnl_rule_add_expr
(
r
,
expr
);
return
0
;
}
int
add_match
(
struct
nftnl_rule
*
r
,
struct
xt_entry_match
*
m
)
int
add_match
(
struct
nftnl_rule
*
r
,
struct
xt_entry_match
*
m
)
{
{
struct
nftnl_expr
*
expr
;
struct
nftnl_expr
*
expr
;
int
ret
;
int
ret
;
if
(
!
strcmp
(
m
->
u
.
user
.
name
,
"limit"
))
return
add_nft_limit
(
r
,
m
);
expr
=
nftnl_expr_alloc
(
"match"
);
expr
=
nftnl_expr_alloc
(
"match"
);
if
(
expr
==
NULL
)
if
(
expr
==
NULL
)
return
-
ENOMEM
;
return
-
ENOMEM
;
...
@@ -1031,7 +1078,7 @@ static void nft_rule_print_debug(struct nftnl_rule *r, struct nlmsghdr *nlh)
...
@@ -1031,7 +1078,7 @@ static void nft_rule_print_debug(struct nftnl_rule *r, struct nlmsghdr *nlh)
#ifdef NLDEBUG
#ifdef NLDEBUG
char
tmp
[
1024
];
char
tmp
[
1024
];
nft_rule_snprintf
(
tmp
,
sizeof
(
tmp
),
r
,
0
,
0
);
nft
nl
_rule_snprintf
(
tmp
,
sizeof
(
tmp
),
r
,
0
,
0
);
printf
(
"DEBUG: rule: %s
\n
"
,
tmp
);
printf
(
"DEBUG: rule: %s
\n
"
,
tmp
);
mnl_nlmsg_fprintf
(
stdout
,
nlh
,
nlh
->
nlmsg_len
,
sizeof
(
struct
nfgenmsg
));
mnl_nlmsg_fprintf
(
stdout
,
nlh
,
nlh
->
nlmsg_len
,
sizeof
(
struct
nfgenmsg
));
#endif
#endif
...
@@ -1173,10 +1220,16 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
...
@@ -1173,10 +1220,16 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
}
else
}
else
type
=
NFT_COMPAT_RULE_APPEND
;
type
=
NFT_COMPAT_RULE_APPEND
;
if
(
batch_rule_add
(
h
,
type
,
r
)
<
0
)
if
(
batch_rule_add
(
h
,
type
,
r
)
<
0
)
{
nftnl_rule_free
(
r
);
nftnl_rule_free
(
r
);
return
0
;
}
nft_rule_list_get
(
h
);
if
(
verbose
)
h
->
ops
->
print_rule
(
r
,
0
,
FMT_PRINT_RULE
);
if
(
!
nft_rule_list_get
(
h
))
return
0
;
nftnl_rule_list_add_tail
(
r
,
h
->
rule_cache
);
nftnl_rule_list_add_tail
(
r
,
h
->
rule_cache
);
...
@@ -1184,18 +1237,19 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
...
@@ -1184,18 +1237,19 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
}
}
void
void
nft_rule_print_save
(
const
void
*
data
,
nft_rule_print_save
(
const
struct
nftnl_rule
*
r
,
enum
nft_rule_print
type
,
struct
nftnl_rule
*
r
,
enum
nft_rule_print
type
,
unsigned
int
format
)
unsigned
int
format
)
{
{
const
char
*
chain
=
nftnl_rule_get_str
(
r
,
NFTNL_RULE_CHAIN
);
const
char
*
chain
=
nftnl_rule_get_str
(
r
,
NFTNL_RULE_CHAIN
);
int
family
=
nftnl_rule_get_u32
(
r
,
NFTNL_RULE_FAMILY
);
int
family
=
nftnl_rule_get_u32
(
r
,
NFTNL_RULE_FAMILY
);
struct
iptables_command_state
cs
=
{};
struct
nft_family_ops
*
ops
;
struct
nft_family_ops
*
ops
;
ops
=
nft_family_ops_lookup
(
family
);
ops
=
nft_family_ops_lookup
(
family
);
ops
->
rule_to_cs
(
r
,
&
cs
);
if
(
!
(
format
&
FMT_NOCOUNTS
)
&&
ops
->
save_counters
)
if
(
!
(
format
&
(
FMT_NOCOUNTS
|
FMT_C_COUNTS
)
)
&&
ops
->
save_counters
)
ops
->
save_counters
(
data
);
ops
->
save_counters
(
&
cs
);
/* print chain name */
/* print chain name */
switch
(
type
)
{
switch
(
type
)
{
...
@@ -1207,9 +1261,11 @@ nft_rule_print_save(const void *data,
...
@@ -1207,9 +1261,11 @@ nft_rule_print_save(const void *data,
break
;
break
;
}
}
if
(
ops
->
save_
firewall
)
if
(
ops
->
save_
rule
)
ops
->
save_
firewall
(
data
,
format
);
ops
->
save_
rule
(
&
cs
,
format
);
if
(
ops
->
clear_cs
)
ops
->
clear_cs
(
&
cs
);
}
}
static
int
nftnl_chain_list_cb
(
const
struct
nlmsghdr
*
nlh
,
void
*
data
)
static
int
nftnl_chain_list_cb
(
const
struct
nlmsghdr
*
nlh
,
void
*
data
)
...
@@ -1274,32 +1330,15 @@ static const char *policy_name[NF_ACCEPT+1] = {
...
@@ -1274,32 +1330,15 @@ static const char *policy_name[NF_ACCEPT+1] = {
[
NF_ACCEPT
]
=
"ACCEPT"
,
[
NF_ACCEPT
]
=
"ACCEPT"
,
};
};
static
void
nft_chain_print_save
(
struct
nftnl_chain
*
c
,
bool
basechain
)
{
const
char
*
chain
=
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_NAME
);
uint64_t
pkts
=
nftnl_chain_get_u64
(
c
,
NFTNL_CHAIN_PACKETS
);
uint64_t
bytes
=
nftnl_chain_get_u64
(
c
,
NFTNL_CHAIN_BYTES
);
/* print chain name */
if
(
basechain
)
{
uint32_t
pol
=
NF_ACCEPT
;
/* no default chain policy? don't crash, display accept */
if
(
nftnl_chain_get
(
c
,
NFTNL_CHAIN_POLICY
))
pol
=
nftnl_chain_get_u32
(
c
,
NFTNL_CHAIN_POLICY
);
printf
(
":%s %s [%"
PRIu64
":%"
PRIu64
"]
\n
"
,
chain
,
policy_name
[
pol
],
pkts
,
bytes
);
}
else
printf
(
":%s - [%"
PRIu64
":%"
PRIu64
"]
\n
"
,
chain
,
pkts
,
bytes
);
}
int
nft_chain_save
(
struct
nft_handle
*
h
,
struct
nftnl_chain_list
*
list
,
int
nft_chain_save
(
struct
nft_handle
*
h
,
struct
nftnl_chain_list
*
list
,
const
char
*
table
)
const
char
*
table
)
{
{
struct
nftnl_chain_list_iter
*
iter
;
struct
nftnl_chain_list_iter
*
iter
;
struct
nft_family_ops
*
ops
;
struct
nftnl_chain
*
c
;
struct
nftnl_chain
*
c
;
ops
=
nft_family_ops_lookup
(
h
->
family
);
iter
=
nftnl_chain_list_iter_create
(
list
);
iter
=
nftnl_chain_list_iter_create
(
list
);
if
(
iter
==
NULL
)
if
(
iter
==
NULL
)
return
0
;
return
0
;
...
@@ -1308,13 +1347,21 @@ int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list,
...
@@ -1308,13 +1347,21 @@ int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list,
while
(
c
!=
NULL
)
{
while
(
c
!=
NULL
)
{
const
char
*
chain_table
=
const
char
*
chain_table
=
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_TABLE
);
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_TABLE
);
bool
basechain
=
false
;
const
char
*
policy
=
NULL
;
if
(
strcmp
(
table
,
chain_table
)
!=
0
)
if
(
strcmp
(
table
,
chain_table
)
!=
0
)
goto
next
;
goto
next
;
basechain
=
nft_chain_builtin
(
c
);
if
(
nft_chain_builtin
(
c
))
{
nft_chain_print_save
(
c
,
basechain
);
uint32_t
pol
=
NF_ACCEPT
;
if
(
nftnl_chain_get
(
c
,
NFTNL_CHAIN_POLICY
))
pol
=
nftnl_chain_get_u32
(
c
,
NFTNL_CHAIN_POLICY
);
policy
=
policy_name
[
pol
];
}
if
(
ops
->
save_chain
)
ops
->
save_chain
(
c
,
policy
);
next:
next:
c
=
nftnl_chain_list_iter_next
(
iter
);
c
=
nftnl_chain_list_iter_next
(
iter
);
}
}
...
@@ -1380,7 +1427,7 @@ retry:
...
@@ -1380,7 +1427,7 @@ retry:
return
list
;
return
list
;
}
}
int
nft_rule_save
(
struct
nft_handle
*
h
,
const
char
*
table
,
bool
counters
)
int
nft_rule_save
(
struct
nft_handle
*
h
,
const
char
*
table
,
unsigned
int
format
)
{
{
struct
nftnl_rule_list
*
list
;
struct
nftnl_rule_list
*
list
;
struct
nftnl_rule_list_iter
*
iter
;
struct
nftnl_rule_list_iter
*
iter
;
...
@@ -1398,15 +1445,11 @@ int nft_rule_save(struct nft_handle *h, const char *table, bool counters)
...
@@ -1398,15 +1445,11 @@ int nft_rule_save(struct nft_handle *h, const char *table, bool counters)
while
(
r
!=
NULL
)
{
while
(
r
!=
NULL
)
{
const
char
*
rule_table
=
const
char
*
rule_table
=
nftnl_rule_get_str
(
r
,
NFTNL_RULE_TABLE
);
nftnl_rule_get_str
(
r
,
NFTNL_RULE_TABLE
);
struct
iptables_command_state
cs
=
{};
if
(
strcmp
(
table
,
rule_table
)
!=
0
)
if
(
strcmp
(
table
,
rule_table
)
!=
0
)
goto
next
;
goto
next
;
nft_rule_to_iptables_command_state
(
r
,
&
cs
);
nft_rule_print_save
(
r
,
NFT_RULE_APPEND
,
format
);
nft_rule_print_save
(
&
cs
,
r
,
NFT_RULE_APPEND
,
counters
?
0
:
FMT_NOCOUNTS
);
next:
next:
r
=
nftnl_rule_list_iter_next
(
iter
);
r
=
nftnl_rule_list_iter_next
(
iter
);
...
@@ -1448,7 +1491,6 @@ static int __nft_chain_user_flush(struct nftnl_chain *c, void *data)
...
@@ -1448,7 +1491,6 @@ static int __nft_chain_user_flush(struct nftnl_chain *c, void *data)
struct
nft_handle
*
h
=
d
->
handle
;
struct
nft_handle
*
h
=
d
->
handle
;
const
char
*
table
=
d
->
table
;
const
char
*
table
=
d
->
table
;
const
char
*
chain
=
d
->
chain
;
const
char
*
chain
=
d
->
chain
;
int
ret
;
if
(
strcmp
(
table
,
table_name
)
!=
0
)
if
(
strcmp
(
table
,
table_name
)
!=
0
)
return
0
;
return
0
;
...
@@ -1456,13 +1498,8 @@ static int __nft_chain_user_flush(struct nftnl_chain *c, void *data)
...
@@ -1456,13 +1498,8 @@ static int __nft_chain_user_flush(struct nftnl_chain *c, void *data)
if
(
strcmp
(
chain
,
chain_name
)
!=
0
)
if
(
strcmp
(
chain
,
chain_name
)
!=
0
)
return
0
;
return
0
;
if
(
!
nftnl_chain_is_set
(
c
,
NFTNL_CHAIN_HOOKNUM
))
{
if
(
!
nftnl_chain_is_set
(
c
,
NFTNL_CHAIN_HOOKNUM
))
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_USER_FLUSH
,
c
);
__nft_rule_flush
(
h
,
table
,
chain
);
if
(
ret
<
0
)
return
ret
;
nftnl_chain_list_del
(
c
);
}
return
0
;
return
0
;
}
}
...
@@ -1483,9 +1520,10 @@ int nft_chain_user_flush(struct nft_handle *h, struct nftnl_chain_list *list,
...
@@ -1483,9 +1520,10 @@ int nft_chain_user_flush(struct nft_handle *h, struct nftnl_chain_list *list,
return
1
;
return
1
;
}
}
int
nft_rule_flush
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
)
int
nft_rule_flush
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
bool
verbose
)
{
{
int
ret
;
int
ret
=
0
;
struct
nftnl_chain_list
*
list
;
struct
nftnl_chain_list
*
list
;
struct
nftnl_chain_list_iter
*
iter
;
struct
nftnl_chain_list_iter
*
iter
;
struct
nftnl_chain
*
c
;
struct
nftnl_chain
*
c
;
...
@@ -1497,13 +1535,15 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table)
...
@@ -1497,13 +1535,15 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table)
list
=
nftnl_chain_list_get
(
h
);
list
=
nftnl_chain_list_get
(
h
);
if
(
list
==
NULL
)
{
if
(
list
==
NULL
)
{
ret
=
0
;
ret
=
1
;
goto
err
;
goto
err
;
}
}
iter
=
nftnl_chain_list_iter_create
(
list
);
iter
=
nftnl_chain_list_iter_create
(
list
);
if
(
iter
==
NULL
)
if
(
iter
==
NULL
)
{
ret
=
1
;
goto
err
;
goto
err
;
}
c
=
nftnl_chain_list_iter_next
(
iter
);
c
=
nftnl_chain_list_iter_next
(
iter
);
while
(
c
!=
NULL
)
{
while
(
c
!=
NULL
)
{
...
@@ -1518,6 +1558,9 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table)
...
@@ -1518,6 +1558,9 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table)
if
(
chain
!=
NULL
&&
strcmp
(
chain
,
chain_name
)
!=
0
)
if
(
chain
!=
NULL
&&
strcmp
(
chain
,
chain_name
)
!=
0
)
goto
next
;
goto
next
;
if
(
verbose
)
fprintf
(
stdout
,
"Flushing chain `%s'
\n
"
,
chain_name
);
__nft_rule_flush
(
h
,
table_name
,
chain_name
);
__nft_rule_flush
(
h
,
table_name
,
chain_name
);
if
(
chain
!=
NULL
)
if
(
chain
!=
NULL
)
...
@@ -1565,7 +1608,8 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl
...
@@ -1565,7 +1608,8 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl
#define NLM_F_NONREC 0x100
/* Do not delete recursively */
#define NLM_F_NONREC 0x100
/* Do not delete recursively */
#endif
#endif
int
nft_chain_user_del
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
)
int
nft_chain_user_del
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
bool
verbose
)
{
{
struct
nftnl_chain_list
*
list
;
struct
nftnl_chain_list
*
list
;
struct
nftnl_chain_list_iter
*
iter
;
struct
nftnl_chain_list_iter
*
iter
;
...
@@ -1600,6 +1644,9 @@ int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *tabl
...
@@ -1600,6 +1644,9 @@ int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *tabl
if
(
chain
!=
NULL
&&
strcmp
(
chain
,
chain_name
)
!=
0
)
if
(
chain
!=
NULL
&&
strcmp
(
chain
,
chain_name
)
!=
0
)
goto
next
;
goto
next
;
if
(
verbose
)
fprintf
(
stdout
,
"Deleting chain `%s'
\n
"
,
chain
);
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_USER_DEL
,
c
);
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_USER_DEL
,
c
);
if
(
ret
<
0
)
if
(
ret
<
0
)
...
@@ -1672,6 +1719,21 @@ nft_chain_find(struct nft_handle *h, const char *table, const char *chain)
...
@@ -1672,6 +1719,21 @@ nft_chain_find(struct nft_handle *h, const char *table, const char *chain)
return
nft_chain_list_find
(
list
,
table
,
chain
);
return
nft_chain_list_find
(
list
,
table
,
chain
);
}
}
bool
nft_chain_exists
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
)
{
struct
builtin_table
*
t
=
nft_table_builtin_find
(
h
,
table
);
/* xtables does not support custom tables */
if
(
!
t
)
return
false
;
if
(
nft_chain_builtin_find
(
t
,
chain
))
return
true
;
return
!!
nft_chain_find
(
h
,
table
,
chain
);
}
int
nft_chain_user_rename
(
struct
nft_handle
*
h
,
const
char
*
chain
,
int
nft_chain_user_rename
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
const
char
*
newname
)
const
char
*
table
,
const
char
*
newname
)
{
{
...
@@ -1777,12 +1839,15 @@ bool nft_table_find(struct nft_handle *h, const char *tablename)
...
@@ -1777,12 +1839,15 @@ bool nft_table_find(struct nft_handle *h, const char *tablename)
const
char
*
this_tablename
=
const
char
*
this_tablename
=
nftnl_table_get
(
t
,
NFTNL_TABLE_NAME
);
nftnl_table_get
(
t
,
NFTNL_TABLE_NAME
);
if
(
strcmp
(
tablename
,
this_tablename
)
==
0
)
if
(
strcmp
(
tablename
,
this_tablename
)
==
0
)
{
return
true
;
ret
=
true
;
break
;
}
t
=
nftnl_table_list_iter_next
(
iter
);
t
=
nftnl_table_list_iter_next
(
iter
);
}
}
nftnl_table_list_iter_destroy
(
iter
);
nftnl_table_list_free
(
list
);
nftnl_table_list_free
(
list
);
err:
err:
...
@@ -1815,6 +1880,7 @@ int nft_for_each_table(struct nft_handle *h,
...
@@ -1815,6 +1880,7 @@ int nft_for_each_table(struct nft_handle *h,
t
=
nftnl_table_list_iter_next
(
iter
);
t
=
nftnl_table_list_iter_next
(
iter
);
}
}
nftnl_table_list_iter_destroy
(
iter
);
nftnl_table_list_free
(
list
);
nftnl_table_list_free
(
list
);
return
0
;
return
0
;
}
}
...
@@ -1833,7 +1899,7 @@ static int __nft_table_flush(struct nft_handle *h, const char *table)
...
@@ -1833,7 +1899,7 @@ static int __nft_table_flush(struct nft_handle *h, const char *table)
batch_table_add
(
h
,
NFT_COMPAT_TABLE_FLUSH
,
t
);
batch_table_add
(
h
,
NFT_COMPAT_TABLE_FLUSH
,
t
);
_t
=
nft_table_builtin_find
(
h
,
table
);
_t
=
nft_table_builtin_find
(
h
,
table
);
assert
(
t
);
assert
(
_
t
);
_t
->
initialized
=
false
;
_t
->
initialized
=
false
;
flush_chain_cache
(
h
,
table
);
flush_chain_cache
(
h
,
table
);
...
@@ -1878,9 +1944,11 @@ next:
...
@@ -1878,9 +1944,11 @@ next:
t
=
nftnl_table_list_iter_next
(
iter
);
t
=
nftnl_table_list_iter_next
(
iter
);
}
}
h
->
rule_cache
=
nftnl_rule_list_alloc
();
if
(
!
h
->
rule_cache
)
{
if
(
h
->
rule_cache
==
NULL
)
h
->
rule_cache
=
nftnl_rule_list_alloc
();
return
-
1
;
if
(
h
->
rule_cache
==
NULL
)
return
-
1
;
}
err_table_iter:
err_table_iter:
nftnl_table_list_iter_destroy
(
iter
);
nftnl_table_list_iter_destroy
(
iter
);
...
@@ -1963,7 +2031,7 @@ int nft_rule_check(struct nft_handle *h, const char *chain,
...
@@ -1963,7 +2031,7 @@ int nft_rule_check(struct nft_handle *h, const char *chain,
const
char
*
table
,
void
*
data
,
bool
verbose
)
const
char
*
table
,
void
*
data
,
bool
verbose
)
{
{
struct
nftnl_rule_list
*
list
;
struct
nftnl_rule_list
*
list
;
int
ret
;
struct
nftnl_rule
*
r
;
nft_fn
=
nft_rule_check
;
nft_fn
=
nft_rule_check
;
...
@@ -1971,11 +2039,15 @@ int nft_rule_check(struct nft_handle *h, const char *chain,
...
@@ -1971,11 +2039,15 @@ int nft_rule_check(struct nft_handle *h, const char *chain,
if
(
list
==
NULL
)
if
(
list
==
NULL
)
return
0
;
return
0
;
r
et
=
nft_rule_find
(
h
,
list
,
chain
,
table
,
data
,
-
1
)
?
1
:
0
;
r
=
nft_rule_find
(
h
,
list
,
chain
,
table
,
data
,
-
1
);
if
(
r
et
==
0
)
if
(
r
==
NULL
)
{
errno
=
ENOENT
;
errno
=
ENOENT
;
return
0
;
}
if
(
verbose
)
h
->
ops
->
print_rule
(
r
,
0
,
FMT_PRINT_RULE
);
return
ret
;
return
1
;
}
}
int
nft_rule_delete
(
struct
nft_handle
*
h
,
const
char
*
chain
,
int
nft_rule_delete
(
struct
nft_handle
*
h
,
const
char
*
chain
,
...
@@ -1996,6 +2068,8 @@ int nft_rule_delete(struct nft_handle *h, const char *chain,
...
@@ -1996,6 +2068,8 @@ int nft_rule_delete(struct nft_handle *h, const char *chain,
ret
=
__nft_rule_del
(
h
,
list
,
r
);
ret
=
__nft_rule_del
(
h
,
list
,
r
);
if
(
ret
<
0
)
if
(
ret
<
0
)
errno
=
ENOMEM
;
errno
=
ENOMEM
;
if
(
verbose
)
h
->
ops
->
print_rule
(
r
,
0
,
FMT_PRINT_RULE
);
}
else
}
else
errno
=
ENOENT
;
errno
=
ENOENT
;
...
@@ -2021,6 +2095,9 @@ nft_rule_add(struct nft_handle *h, const char *chain,
...
@@ -2021,6 +2095,9 @@ nft_rule_add(struct nft_handle *h, const char *chain,
return
NULL
;
return
NULL
;
}
}
if
(
verbose
)
h
->
ops
->
print_rule
(
r
,
0
,
FMT_PRINT_RULE
);
return
r
;
return
r
;
}
}
...
@@ -2092,8 +2169,6 @@ int nft_rule_delete_num(struct nft_handle *h, const char *chain,
...
@@ -2092,8 +2169,6 @@ int nft_rule_delete_num(struct nft_handle *h, const char *chain,
r
=
nft_rule_find
(
h
,
list
,
chain
,
table
,
NULL
,
rulenum
);
r
=
nft_rule_find
(
h
,
list
,
chain
,
table
,
NULL
,
rulenum
);
if
(
r
!=
NULL
)
{
if
(
r
!=
NULL
)
{
ret
=
1
;
DEBUGP
(
"deleting rule by number %d
\n
"
,
rulenum
);
DEBUGP
(
"deleting rule by number %d
\n
"
,
rulenum
);
ret
=
__nft_rule_del
(
h
,
list
,
r
);
ret
=
__nft_rule_del
(
h
,
list
,
r
);
if
(
ret
<
0
)
if
(
ret
<
0
)
...
@@ -2143,7 +2218,7 @@ __nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
...
@@ -2143,7 +2218,7 @@ __nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
struct
nftnl_rule_list
*
list
;
struct
nftnl_rule_list
*
list
;
struct
nftnl_rule_list_iter
*
iter
;
struct
nftnl_rule_list_iter
*
iter
;
struct
nftnl_rule
*
r
;
struct
nftnl_rule
*
r
;
int
rule_ctr
=
0
,
ret
=
0
;
int
rule_ctr
=
0
;
list
=
nft_rule_list_get
(
h
);
list
=
nft_rule_list_get
(
h
);
if
(
list
==
NULL
)
if
(
list
==
NULL
)
...
@@ -2151,7 +2226,7 @@ __nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
...
@@ -2151,7 +2226,7 @@ __nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
iter
=
nftnl_rule_list_iter_create
(
list
);
iter
=
nftnl_rule_list_iter_create
(
list
);
if
(
iter
==
NULL
)
if
(
iter
==
NULL
)
goto
err
;
return
0
;
r
=
nftnl_rule_list_iter_next
(
iter
);
r
=
nftnl_rule_list_iter_next
(
iter
);
while
(
r
!=
NULL
)
{
while
(
r
!=
NULL
)
{
...
@@ -2172,21 +2247,51 @@ __nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
...
@@ -2172,21 +2247,51 @@ __nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
}
}
cb
(
r
,
rule_ctr
,
format
);
cb
(
r
,
rule_ctr
,
format
);
if
(
rulenum
>
0
&&
rule_ctr
==
rulenum
)
{
if
(
rulenum
>
0
)
ret
=
1
;
break
;
break
;
}
next:
next:
r
=
nftnl_rule_list_iter_next
(
iter
);
r
=
nftnl_rule_list_iter_next
(
iter
);
}
}
nftnl_rule_list_iter_destroy
(
iter
);
nftnl_rule_list_iter_destroy
(
iter
);
err:
return
1
;
if
(
ret
==
0
)
}
errno
=
ENOENT
;
return
ret
;
static
int
nft_rule_count
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
)
{
struct
nftnl_rule_list_iter
*
iter
;
struct
nftnl_rule_list
*
list
;
struct
nftnl_rule
*
r
;
int
rule_ctr
=
0
;
list
=
nft_rule_list_get
(
h
);
if
(
list
==
NULL
)
return
0
;
iter
=
nftnl_rule_list_iter_create
(
list
);
if
(
iter
==
NULL
)
return
0
;
r
=
nftnl_rule_list_iter_next
(
iter
);
while
(
r
!=
NULL
)
{
const
char
*
rule_table
=
nftnl_rule_get_str
(
r
,
NFTNL_RULE_TABLE
);
const
char
*
rule_chain
=
nftnl_rule_get_str
(
r
,
NFTNL_RULE_CHAIN
);
if
(
strcmp
(
table
,
rule_table
)
!=
0
||
strcmp
(
chain
,
rule_chain
)
!=
0
)
goto
next
;
rule_ctr
++
;
next:
r
=
nftnl_rule_list_iter_next
(
iter
);
}
nftnl_rule_list_iter_destroy
(
iter
);
return
rule_ctr
;
}
}
int
nft_rule_list
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
int
nft_rule_list
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
...
@@ -2204,8 +2309,10 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
...
@@ -2204,8 +2309,10 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
/* Force table and chain creation, otherwise first iptables -L
/* Force table and chain creation, otherwise first iptables -L
* lists no table/chains.
* lists no table/chains.
*/
*/
if
(
!
list_empty
(
&
h
->
obj_list
))
if
(
!
list_empty
(
&
h
->
obj_list
))
{
nft_commit
(
h
);
nft_commit
(
h
);
flush_chain_cache
(
h
,
NULL
);
}
}
}
ops
=
nft_family_ops_lookup
(
h
->
family
);
ops
=
nft_family_ops_lookup
(
h
->
family
);
...
@@ -2217,7 +2324,7 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
...
@@ -2217,7 +2324,7 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
if
(
chain
&&
rulenum
)
{
if
(
chain
&&
rulenum
)
{
__nft_rule_list
(
h
,
chain
,
table
,
__nft_rule_list
(
h
,
chain
,
table
,
rulenum
,
format
,
ops
->
print_
firewall
);
rulenum
,
format
,
ops
->
print_
rule
);
return
1
;
return
1
;
}
}
...
@@ -2227,7 +2334,7 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
...
@@ -2227,7 +2334,7 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
if
(
iter
==
NULL
)
if
(
iter
==
NULL
)
goto
err
;
goto
err
;
if
(
ops
->
print_table_header
)
if
(
!
chain
&&
ops
->
print_table_header
)
ops
->
print_table_header
(
table
);
ops
->
print_table_header
(
table
);
c
=
nftnl_chain_list_iter_next
(
iter
);
c
=
nftnl_chain_list_iter_next
(
iter
);
...
@@ -2245,47 +2352,52 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
...
@@ -2245,47 +2352,52 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
.
bcnt
=
nftnl_chain_get_u64
(
c
,
NFTNL_CHAIN_BYTES
),
.
bcnt
=
nftnl_chain_get_u64
(
c
,
NFTNL_CHAIN_BYTES
),
};
};
bool
basechain
=
false
;
bool
basechain
=
false
;
uint32_t
entries
;
if
(
nftnl_chain_get
(
c
,
NFTNL_CHAIN_HOOKNUM
))
if
(
nftnl_chain_get
(
c
,
NFTNL_CHAIN_HOOKNUM
))
basechain
=
true
;
basechain
=
true
;
if
(
strcmp
(
table
,
chain_table
)
!=
0
)
if
(
strcmp
(
table
,
chain_table
)
!=
0
)
goto
next
;
goto
next
;
if
(
chain
&&
strcmp
(
chain
,
chain_name
)
!=
0
)
if
(
chain
)
{
goto
next
;
if
(
strcmp
(
chain
,
chain_name
)
!=
0
)
goto
next
;
else
if
(
ops
->
print_table_header
)
ops
->
print_table_header
(
table
);
}
if
(
found
)
if
(
found
)
printf
(
"
\n
"
);
printf
(
"
\n
"
);
entries
=
nft_rule_count
(
h
,
chain_name
,
table
);
ops
->
print_header
(
format
,
chain_name
,
policy_name
[
policy
],
ops
->
print_header
(
format
,
chain_name
,
policy_name
[
policy
],
&
ctrs
,
basechain
,
refs
);
&
ctrs
,
basechain
,
refs
-
entries
,
entries
);
__nft_rule_list
(
h
,
chain_name
,
table
,
__nft_rule_list
(
h
,
chain_name
,
table
,
rulenum
,
format
,
ops
->
print_firewall
);
rulenum
,
format
,
ops
->
print_rule
);
found
=
true
;
/* we printed the chain we wanted, stop processing. */
/* we printed the chain we wanted, stop processing. */
if
(
chain
)
if
(
chain
)
break
;
break
;
found
=
true
;
next:
next:
c
=
nftnl_chain_list_iter_next
(
iter
);
c
=
nftnl_chain_list_iter_next
(
iter
);
}
}
nftnl_chain_list_iter_destroy
(
iter
);
nftnl_chain_list_iter_destroy
(
iter
);
err:
err:
if
(
chain
&&
!
found
)
return
0
;
return
1
;
return
1
;
}
}
static
void
static
void
list_save
(
struct
nftnl_rule
*
r
,
unsigned
int
num
,
unsigned
int
format
)
list_save
(
struct
nftnl_rule
*
r
,
unsigned
int
num
,
unsigned
int
format
)
{
{
struct
iptables_command_state
cs
=
{};
nft_rule_print_save
(
r
,
NFT_RULE_APPEND
,
format
);
nft_rule_to_iptables_command_state
(
r
,
&
cs
);
nft_rule_print_save
(
&
cs
,
r
,
NFT_RULE_APPEND
,
!
(
format
&
FMT_NOCOUNTS
));
}
}
static
int
static
int
...
@@ -2340,8 +2452,26 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain,
...
@@ -2340,8 +2452,26 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain,
{
{
struct
nftnl_chain_list
*
list
;
struct
nftnl_chain_list
*
list
;
struct
nftnl_chain_list_iter
*
iter
;
struct
nftnl_chain_list_iter
*
iter
;
unsigned
int
format
=
0
;
struct
nftnl_chain
*
c
;
struct
nftnl_chain
*
c
;
int
ret
=
1
;
int
ret
=
0
;
/* If built-in chains don't exist for this table, create them */
if
(
nft_xtables_config_load
(
h
,
XTABLES_CONFIG_DEFAULT
,
0
)
<
0
)
{
nft_xt_builtin_init
(
h
,
table
);
/* Force table and chain creation, otherwise first iptables -L
* lists no table/chains.
*/
if
(
!
list_empty
(
&
h
->
obj_list
))
{
nft_commit
(
h
);
flush_chain_cache
(
h
,
NULL
);
}
}
if
(
!
nft_is_table_compatible
(
h
,
table
))
{
xtables_error
(
OTHER_PROBLEM
,
"table `%s' is incompatible, use 'nft' tool.
\n
"
,
table
);
return
0
;
}
list
=
nft_chain_dump
(
h
);
list
=
nft_chain_dump
(
h
);
...
@@ -2354,6 +2484,11 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain,
...
@@ -2354,6 +2484,11 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain,
if
(
iter
==
NULL
)
if
(
iter
==
NULL
)
goto
err
;
goto
err
;
if
(
counters
<
0
)
format
=
FMT_C_COUNTS
;
else
if
(
counters
==
0
)
format
=
FMT_NOCOUNTS
;
c
=
nftnl_chain_list_iter_next
(
iter
);
c
=
nftnl_chain_list_iter_next
(
iter
);
while
(
c
!=
NULL
)
{
while
(
c
!=
NULL
)
{
const
char
*
chain_table
=
const
char
*
chain_table
=
...
@@ -2367,7 +2502,7 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain,
...
@@ -2367,7 +2502,7 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain,
goto
next
;
goto
next
;
ret
=
__nft_rule_list
(
h
,
chain_name
,
table
,
rulenum
,
ret
=
__nft_rule_list
(
h
,
chain_name
,
table
,
rulenum
,
counters
?
0
:
FMT_NOCOUNTS
,
list_save
);
format
,
list_save
);
/* we printed the chain we wanted, stop processing. */
/* we printed the chain we wanted, stop processing. */
if
(
chain
)
if
(
chain
)
...
@@ -2456,10 +2591,11 @@ static void batch_obj_del(struct nft_handle *h, struct obj_update *o)
...
@@ -2456,10 +2591,11 @@ static void batch_obj_del(struct nft_handle *h, struct obj_update *o)
case
NFT_COMPAT_TABLE_FLUSH
:
case
NFT_COMPAT_TABLE_FLUSH
:
nftnl_table_free
(
o
->
table
);
nftnl_table_free
(
o
->
table
);
break
;
break
;
case
NFT_COMPAT_CHAIN_
ADD
:
case
NFT_COMPAT_CHAIN_
ZERO
:
case
NFT_COMPAT_CHAIN_USER_ADD
:
case
NFT_COMPAT_CHAIN_USER_ADD
:
case
NFT_COMPAT_CHAIN_USER_DEL
:
break
;
break
;
case
NFT_COMPAT_CHAIN_ADD
:
case
NFT_COMPAT_CHAIN_USER_DEL
:
case
NFT_COMPAT_CHAIN_USER_FLUSH
:
case
NFT_COMPAT_CHAIN_USER_FLUSH
:
case
NFT_COMPAT_CHAIN_UPDATE
:
case
NFT_COMPAT_CHAIN_UPDATE
:
case
NFT_COMPAT_CHAIN_RENAME
:
case
NFT_COMPAT_CHAIN_RENAME
:
...
@@ -2507,6 +2643,7 @@ static int nft_action(struct nft_handle *h, int action)
...
@@ -2507,6 +2643,7 @@ static int nft_action(struct nft_handle *h, int action)
n
->
seq
,
n
->
table
);
n
->
seq
,
n
->
table
);
break
;
break
;
case
NFT_COMPAT_CHAIN_ADD
:
case
NFT_COMPAT_CHAIN_ADD
:
case
NFT_COMPAT_CHAIN_ZERO
:
nft_compat_chain_batch_add
(
h
,
NFT_MSG_NEWCHAIN
,
nft_compat_chain_batch_add
(
h
,
NFT_MSG_NEWCHAIN
,
NLM_F_CREATE
,
n
->
seq
,
NLM_F_CREATE
,
n
->
seq
,
n
->
chain
);
n
->
chain
);
...
@@ -2708,6 +2845,7 @@ const char *nft_strerror(int err)
...
@@ -2708,6 +2845,7 @@ const char *nft_strerror(int err)
"Bad rule (does a matching rule exist in that chain?)"
},
"Bad rule (does a matching rule exist in that chain?)"
},
{
nft_chain_set
,
ENOENT
,
"Bad built-in chain name"
},
{
nft_chain_set
,
ENOENT
,
"Bad built-in chain name"
},
{
nft_chain_set
,
EINVAL
,
"Bad policy name"
},
{
nft_chain_set
,
EINVAL
,
"Bad policy name"
},
{
nft_chain_set
,
ENXIO
,
"Bad table name"
},
{
NULL
,
ELOOP
,
"Loop found in table"
},
{
NULL
,
ELOOP
,
"Loop found in table"
},
{
NULL
,
EPERM
,
"Permission denied (you must be root)"
},
{
NULL
,
EPERM
,
"Permission denied (you must be root)"
},
{
NULL
,
0
,
"Incompatible with this kernel"
},
{
NULL
,
0
,
"Incompatible with this kernel"
},
...
@@ -2858,8 +2996,8 @@ int nft_xtables_config_load(struct nft_handle *h, const char *filename,
...
@@ -2858,8 +2996,8 @@ int nft_xtables_config_load(struct nft_handle *h, const char *filename,
return
h
->
config_done
;
return
h
->
config_done
;
}
}
int
nft_chain_zero_counters
(
struct
nft_handle
*
h
,
const
char
*
chain
,
int
nft_chain_zero_counters
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
)
const
char
*
table
,
bool
verbose
)
{
{
struct
nftnl_chain_list
*
list
;
struct
nftnl_chain_list
*
list
;
struct
nftnl_chain_list_iter
*
iter
;
struct
nftnl_chain_list_iter
*
iter
;
...
@@ -2887,12 +3025,15 @@ int nft_chain_zero_counters(struct nft_handle *h, const char *chain,
...
@@ -2887,12 +3025,15 @@ int nft_chain_zero_counters(struct nft_handle *h, const char *chain,
if
(
chain
!=
NULL
&&
strcmp
(
chain
,
chain_name
)
!=
0
)
if
(
chain
!=
NULL
&&
strcmp
(
chain
,
chain_name
)
!=
0
)
goto
next
;
goto
next
;
if
(
verbose
)
fprintf
(
stdout
,
"Zeroing chain `%s'
\n
"
,
chain_name
);
nftnl_chain_set_u64
(
c
,
NFTNL_CHAIN_PACKETS
,
0
);
nftnl_chain_set_u64
(
c
,
NFTNL_CHAIN_PACKETS
,
0
);
nftnl_chain_set_u64
(
c
,
NFTNL_CHAIN_BYTES
,
0
);
nftnl_chain_set_u64
(
c
,
NFTNL_CHAIN_BYTES
,
0
);
nftnl_chain_unset
(
c
,
NFTNL_CHAIN_HANDLE
);
nftnl_chain_unset
(
c
,
NFTNL_CHAIN_HANDLE
);
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_
ADD
,
c
);
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_
ZERO
,
c
);
if
(
chain
!=
NULL
)
if
(
chain
!=
NULL
)
break
;
break
;
...
@@ -2929,8 +3070,9 @@ static const char *supported_exprs[NFT_COMPAT_EXPR_MAX] = {
...
@@ -2929,8 +3070,9 @@ static const char *supported_exprs[NFT_COMPAT_EXPR_MAX] = {
};
};
static
int
nft_is_expr_compatible
(
const
char
*
name
)
static
int
nft_is_expr_compatible
(
const
struct
nftnl_expr
*
expr
)
{
{
const
char
*
name
=
nftnl_expr_get_str
(
expr
,
NFTNL_EXPR_NAME
);
int
i
;
int
i
;
for
(
i
=
0
;
i
<
NFT_COMPAT_EXPR_MAX
;
i
++
)
{
for
(
i
=
0
;
i
<
NFT_COMPAT_EXPR_MAX
;
i
++
)
{
...
@@ -2938,6 +3080,11 @@ static int nft_is_expr_compatible(const char *name)
...
@@ -2938,6 +3080,11 @@ static int nft_is_expr_compatible(const char *name)
return
0
;
return
0
;
}
}
if
(
!
strcmp
(
name
,
"limit"
)
&&
nftnl_expr_get_u32
(
expr
,
NFTNL_EXPR_LIMIT_TYPE
)
==
NFT_LIMIT_PKTS
&&
nftnl_expr_get_u32
(
expr
,
NFTNL_EXPR_LIMIT_FLAGS
)
==
0
)
return
0
;
return
1
;
return
1
;
}
}
...
@@ -2953,9 +3100,7 @@ static bool nft_is_rule_compatible(struct nftnl_rule *rule)
...
@@ -2953,9 +3100,7 @@ static bool nft_is_rule_compatible(struct nftnl_rule *rule)
expr
=
nftnl_expr_iter_next
(
iter
);
expr
=
nftnl_expr_iter_next
(
iter
);
while
(
expr
!=
NULL
)
{
while
(
expr
!=
NULL
)
{
const
char
*
name
=
nftnl_expr_get_str
(
expr
,
NFTNL_EXPR_NAME
);
if
(
nft_is_expr_compatible
(
expr
)
==
0
)
{
if
(
nft_is_expr_compatible
(
name
)
==
0
)
{
expr
=
nftnl_expr_iter_next
(
iter
);
expr
=
nftnl_expr_iter_next
(
iter
);
continue
;
continue
;
}
}
...
@@ -3021,7 +3166,12 @@ static int nft_are_chains_compatible(struct nft_handle *h, const char *tablename
...
@@ -3021,7 +3166,12 @@ static int nft_are_chains_compatible(struct nft_handle *h, const char *tablename
chain
=
nftnl_chain_list_iter_next
(
iter
);
chain
=
nftnl_chain_list_iter_next
(
iter
);
while
(
chain
!=
NULL
)
{
while
(
chain
!=
NULL
)
{
if
(
!
nft_chain_builtin
(
chain
))
const
char
*
chain_table
;
chain_table
=
nftnl_chain_get_str
(
chain
,
NFTNL_CHAIN_TABLE
);
if
(
strcmp
(
chain_table
,
tablename
)
||
!
nft_chain_builtin
(
chain
))
goto
next
;
goto
next
;
ret
=
nft_is_chain_compatible
(
h
,
chain
);
ret
=
nft_is_chain_compatible
(
h
,
chain
);
...
@@ -3041,16 +3191,9 @@ bool nft_is_table_compatible(struct nft_handle *h, const char *tablename)
...
@@ -3041,16 +3191,9 @@ bool nft_is_table_compatible(struct nft_handle *h, const char *tablename)
struct
nftnl_rule_list
*
list
;
struct
nftnl_rule_list
*
list
;
struct
nftnl_rule_list_iter
*
iter
;
struct
nftnl_rule_list_iter
*
iter
;
struct
nftnl_rule
*
rule
;
struct
nftnl_rule
*
rule
;
int
ret
=
0
,
i
;
int
ret
=
0
;
for
(
i
=
0
;
i
<
TABLES_MAX
;
i
++
)
{
if
(
!
h
->
tables
[
i
].
name
)
continue
;
if
(
strcmp
(
h
->
tables
[
i
].
name
,
tablename
)
==
0
)
break
;
}
if
(
i
==
TABLES_MAX
)
if
(
!
nft_table_builtin_find
(
h
,
tablename
)
)
return
false
;
return
false
;
ret
=
nft_are_chains_compatible
(
h
,
tablename
);
ret
=
nft_are_chains_compatible
(
h
,
tablename
);
...
@@ -3067,9 +3210,15 @@ bool nft_is_table_compatible(struct nft_handle *h, const char *tablename)
...
@@ -3067,9 +3210,15 @@ bool nft_is_table_compatible(struct nft_handle *h, const char *tablename)
rule
=
nftnl_rule_list_iter_next
(
iter
);
rule
=
nftnl_rule_list_iter_next
(
iter
);
while
(
rule
!=
NULL
)
{
while
(
rule
!=
NULL
)
{
const
char
*
table
=
nftnl_rule_get_str
(
rule
,
NFTNL_RULE_TABLE
);
if
(
strcmp
(
table
,
tablename
))
goto
next_rule
;
ret
=
nft_is_rule_compatible
(
rule
);
ret
=
nft_is_rule_compatible
(
rule
);
if
(
ret
!=
0
)
if
(
ret
!=
0
)
break
;
break
;
next_rule:
rule
=
nftnl_rule_list_iter_next
(
iter
);
rule
=
nftnl_rule_list_iter_next
(
iter
);
}
}
...
...
iptables/nft.h
View file @
3bc9369c
...
@@ -68,6 +68,7 @@ bool nft_table_find(struct nft_handle *h, const char *tablename);
...
@@ -68,6 +68,7 @@ bool nft_table_find(struct nft_handle *h, const char *tablename);
int
nft_table_purge_chains
(
struct
nft_handle
*
h
,
const
char
*
table
,
struct
nftnl_chain_list
*
list
);
int
nft_table_purge_chains
(
struct
nft_handle
*
h
,
const
char
*
table
,
struct
nftnl_chain_list
*
list
);
int
nft_table_flush
(
struct
nft_handle
*
h
,
const
char
*
table
);
int
nft_table_flush
(
struct
nft_handle
*
h
,
const
char
*
table
);
void
nft_table_new
(
struct
nft_handle
*
h
,
const
char
*
table
);
void
nft_table_new
(
struct
nft_handle
*
h
,
const
char
*
table
);
struct
builtin_table
*
nft_table_builtin_find
(
struct
nft_handle
*
h
,
const
char
*
table
);
/*
/*
* Operations with chains.
* Operations with chains.
...
@@ -79,11 +80,13 @@ struct nftnl_chain_list *nft_chain_dump(struct nft_handle *h);
...
@@ -79,11 +80,13 @@ struct nftnl_chain_list *nft_chain_dump(struct nft_handle *h);
struct
nftnl_chain
*
nft_chain_list_find
(
struct
nftnl_chain_list
*
list
,
const
char
*
table
,
const
char
*
chain
);
struct
nftnl_chain
*
nft_chain_list_find
(
struct
nftnl_chain_list
*
list
,
const
char
*
table
,
const
char
*
chain
);
int
nft_chain_save
(
struct
nft_handle
*
h
,
struct
nftnl_chain_list
*
list
,
const
char
*
table
);
int
nft_chain_save
(
struct
nft_handle
*
h
,
struct
nftnl_chain_list
*
list
,
const
char
*
table
);
int
nft_chain_user_add
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
);
int
nft_chain_user_add
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
);
int
nft_chain_user_del
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
);
int
nft_chain_user_del
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
bool
verbose
);
int
nft_chain_user_flush
(
struct
nft_handle
*
h
,
struct
nftnl_chain_list
*
list
,
int
nft_chain_user_flush
(
struct
nft_handle
*
h
,
struct
nftnl_chain_list
*
list
,
const
char
*
chain
,
const
char
*
table
);
const
char
*
chain
,
const
char
*
table
);
int
nft_chain_user_rename
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
const
char
*
newname
);
int
nft_chain_user_rename
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
const
char
*
newname
);
int
nft_chain_zero_counters
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
);
int
nft_chain_zero_counters
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
bool
verbose
);
struct
builtin_chain
*
nft_chain_builtin_find
(
struct
builtin_table
*
t
,
const
char
*
chain
);
bool
nft_chain_exists
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
);
/*
/*
* Operations with rule-set.
* Operations with rule-set.
...
@@ -98,8 +101,8 @@ int nft_rule_delete_num(struct nft_handle *h, const char *chain, const char *tab
...
@@ -98,8 +101,8 @@ int nft_rule_delete_num(struct nft_handle *h, const char *chain, const char *tab
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
,
void
*
data
,
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
(
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_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
,
bool
counters
);
int
nft_rule_save
(
struct
nft_handle
*
h
,
const
char
*
table
,
unsigned
int
format
);
int
nft_rule_flush
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
);
int
nft_rule_flush
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
bool
verbose
);
int
nft_rule_zero_counters
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
int
rulenum
);
int
nft_rule_zero_counters
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
int
rulenum
);
/*
/*
...
@@ -119,8 +122,7 @@ enum nft_rule_print {
...
@@ -119,8 +122,7 @@ enum nft_rule_print {
NFT_RULE_DEL
,
NFT_RULE_DEL
,
};
};
void
nft_rule_print_save
(
const
void
*
data
,
void
nft_rule_print_save
(
const
struct
nftnl_rule
*
r
,
enum
nft_rule_print
type
,
struct
nftnl_rule
*
r
,
enum
nft_rule_print
type
,
unsigned
int
format
);
unsigned
int
format
);
uint32_t
nft_invflags2cmp
(
uint32_t
invflags
,
uint32_t
flag
);
uint32_t
nft_invflags2cmp
(
uint32_t
invflags
,
uint32_t
flag
);
...
@@ -144,9 +146,12 @@ const char *nft_strerror(int err);
...
@@ -144,9 +146,12 @@ const char *nft_strerror(int err);
/* For xtables.c */
/* For xtables.c */
int
do_commandx
(
struct
nft_handle
*
h
,
int
argc
,
char
*
argv
[],
char
**
table
,
bool
restore
);
int
do_commandx
(
struct
nft_handle
*
h
,
int
argc
,
char
*
argv
[],
char
**
table
,
bool
restore
);
/* For xtables-arptables.c */
/* For xtables-arptables.c */
int
do_commandarp
(
struct
nft_handle
*
h
,
int
argc
,
char
*
argv
[],
char
**
table
);
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 */
/* For xtables-eb.c */
int
do_commandeb
(
struct
nft_handle
*
h
,
int
argc
,
char
*
argv
[],
char
**
table
);
int
nft_init_eb
(
struct
nft_handle
*
h
,
const
char
*
pname
);
int
ebt_get_current_chain
(
const
char
*
chain
);
int
do_commandeb
(
struct
nft_handle
*
h
,
int
argc
,
char
*
argv
[],
char
**
table
,
bool
restore
);
/*
/*
* Parse config for tables and chain helper functions
* Parse config for tables and chain helper functions
...
...
iptables/tests/shell/README
0 → 100644
View file @
3bc9369c
To run the test suite (as root):
$ cd iptables/tests/shell
# ./run-tests.sh
Test files are executable files with the pattern <<name_N>> , where N is the
expected return code of the executable. Since they are located with `find',
test-files can be spreaded in any sub-directories.
You can turn on a verbose execution by calling:
# ./run-tests.sh -v
And to run test suite for pariticular test files:
# ./run-tests.sh <PATH_OF_TESTFILES>
Also, test-files will receive the environment variable $XT_MULTI which contains
the path to the old iptables (xtables-legacy-multi) or new iptables (xtables-nft-multi)
binary being tested.
iptables/tests/shell/run-tests.sh
View file @
3bc9369c
...
@@ -65,13 +65,13 @@ do_test() {
...
@@ -65,13 +65,13 @@ do_test() {
if
[
"
$VERBOSE
"
=
"y"
]
;
then
if
[
"
$VERBOSE
"
=
"y"
]
;
then
XT_MULTI
=
$xtables_multi
unshare
-n
${
testfile
}
XT_MULTI
=
$xtables_multi
unshare
-n
${
testfile
}
rc_got
=
$?
else
else
XT_MULTI
=
$xtables_multi
unshare
-n
${
testfile
}
>
/dev/null 2>&1
XT_MULTI
=
$xtables_multi
unshare
-n
${
testfile
}
>
/dev/null 2>&1
rc_got
=
$?
echo
-en
"
\0
33[1A
\0
33[K"
# clean the [EXECUTING] foobar line
fi
fi
rc_got
=
$?
echo
-en
"
\0
33[1A
\0
33[K"
# clean the [EXECUTING] foobar line
if
[
"
$rc_got
"
==
"
$rc_spec
"
]
;
then
if
[
"
$rc_got
"
==
"
$rc_spec
"
]
;
then
msg_info
"[OK]
$testfile
"
msg_info
"[OK]
$testfile
"
((
ok++
))
((
ok++
))
...
...
iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0
0 → 100755
View file @
3bc9369c
#!/bin/bash
set
-e
#set -x
# there is no legacy backend to test
[[
$XT_MULTI
==
*
/xtables-nft-multi
]]
||
{
echo
"skip
$XT_MULTI
"
;
exit
0
;
}
# fill arptables manually
$XT_MULTI
arptables
-F
$XT_MULTI
arptables
-A
INPUT
-s
10.0.0.0/8
-j
ACCEPT
$XT_MULTI
arptables
-A
INPUT
-d
192.168.123.1
-j
ACCEPT
#$XT_MULTI arptables -A INPUT --source-mac fe:ed:ba:be:00:01 -j ACCEPT
#$XT_MULTI arptables -A INPUT --destination-mac fe:ed:ba:be:00:01 -j ACCEPT
$XT_MULTI
arptables
-N
foo
$XT_MULTI
arptables
-A
foo
-i
lo
-j
ACCEPT
$XT_MULTI
arptables
-A
foo
-l
6
-j
ACCEPT
$XT_MULTI
arptables
-A
foo
--opcode
Request
-j
ACCEPT
$XT_MULTI
arptables
-A
foo
--h-type
1
--proto-type
0x800
-j
ACCEPT
$XT_MULTI
arptables
-A
foo
-l
6
--h-type
1
--proto-type
0x800
-i
lo
--opcode
Request
-j
ACCEPT
$XT_MULTI
arptables
-A
INPUT
-j
foo
$XT_MULTI
arptables
-A
INPUT
$XT_MULTI
arptables
-A
OUTPUT
-o
lo
-j
ACCEPT
$XT_MULTI
arptables
-A
OUTPUT
-o
eth134
-j
mangle
--mangle-ip-s
10.0.0.1
$XT_MULTI
arptables
-A
OUTPUT
-o
eth432
-j
CLASSIFY
--set-class
feed:babe
$XT_MULTI
arptables
-A
OUTPUT
-o
eth432
--opcode
Request
-j
CLASSIFY
--set-class
feed:babe
$XT_MULTI
arptables
-P
OUTPUT DROP
# compare against stored arptables dump
DUMP
=
'*filter
:INPUT ACCEPT
:OUTPUT DROP
:foo -
-A INPUT -s 10.0.0.0/8 -j ACCEPT
-A INPUT -d 192.168.123.1 -j ACCEPT
-A INPUT -j foo
-A INPUT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -o eth134 -j mangle --mangle-ip-s 10.0.0.1
-A OUTPUT -o eth432 -j CLASSIFY --set-class feed:babe
-A OUTPUT -o eth432 --opcode 1 -j CLASSIFY --set-class feed:babe
-A foo -i lo -j ACCEPT
-A foo --h-length 6 -j ACCEPT
-A foo --opcode 1 -j ACCEPT
-A foo --h-type 1 --proto-type 0x800 -j ACCEPT
-A foo -i lo --h-length 6 --opcode 1 --h-type 1 --proto-type 0x800 -j ACCEPT
'
diff
-u
<
(
echo
-e
"
$DUMP
"
)
<
(
$XT_MULTI
arptables-save
)
# make sure dump can be restored and check it didn't change
$XT_MULTI
arptables
-F
$XT_MULTI
arptables-restore
<<<
$DUMP
diff
-u
<
(
echo
-e
"
$DUMP
"
)
<
(
$XT_MULTI
arptables-save
)
iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0
0 → 100755
View file @
3bc9369c
#!/bin/bash
set
-e
# there is no legacy backend to test
[[
$XT_MULTI
==
*
/xtables-nft-multi
]]
||
{
echo
"skip
$XT_MULTI
"
;
exit
0
;
}
# arptables-restore reuses preloaded targets and matches, make sure defaults
# apply to consecutive rules using the same target/match as a previous one
DUMP
=
'*filter
:OUTPUT ACCEPT
-A OUTPUT -j mangle --mangle-ip-s 10.0.0.1
-A OUTPUT -j mangle --mangle-ip-d 10.0.0.2
'
# note how mangle-ip-s is unset in second rule
EXPECT
=
'*filter
:INPUT ACCEPT
:OUTPUT ACCEPT
-A OUTPUT -j mangle --mangle-ip-s 10.0.0.1
-A OUTPUT -j mangle --mangle-ip-d 10.0.0.2
'
$XT_MULTI
arptables
-F
$XT_MULTI
arptables-restore
<<<
$DUMP
diff
-u
<
(
echo
-e
"
$EXPECT
"
)
<
(
$XT_MULTI
arptables-save |
grep
-v
'^#'
)
iptables/tests/shell/testcases/chain/000
4
newchain_0
→
iptables/tests/shell/testcases/chain/000
2
newchain_0
View file @
3bc9369c
File moved
iptables/tests/shell/testcases/chain/000
5
rename_1
→
iptables/tests/shell/testcases/chain/000
3
rename_1
View file @
3bc9369c
File moved
iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0
View file @
3bc9369c
...
@@ -28,6 +28,36 @@ case "$XT_MULTI" in
...
@@ -28,6 +28,36 @@ case "$XT_MULTI" in
exit
1
exit
1
fi
fi
$XT_MULTI
ebtables
-L
FOO |
grep
-q
'entries: 0'
if
[
$?
-ne
0
]
;
then
echo
"Unexpected entries count in empty unreferenced chain"
$XT_MULTI
ebtables
-L
exit
1
fi
$XT_MULTI
ebtables
-A
FORWARD
-j
FOO
$XT_MULTI
ebtables
-L
FORWARD |
grep
-q
'entries: 1'
if
[
$?
-ne
0
]
;
then
echo
"Unexpected entries count in FORWARD chain"
$XT_MULTI
ebtables
-L
exit
1
fi
$XT_MULTI
ebtables
-L
FOO |
grep
-q
'entries: 0'
if
[
$?
-ne
0
]
;
then
echo
"Unexpected entries count in empty referenced chain"
$XT_MULTI
ebtables
-L
exit
1
fi
$XT_MULTI
ebtables
-A
FOO
-j
ACCEPT
$XT_MULTI
ebtables
-L
FOO |
grep
-q
'entries: 1'
if
[
$?
-ne
0
]
;
then
echo
"Unexpected entries count in non-empty referenced chain"
$XT_MULTI
ebtables
-L
exit
1
fi
$XT_MULTI
ebtables
-t
filter
-N
BAR
||
exit
1
$XT_MULTI
ebtables
-t
filter
-N
BAR
||
exit
1
$XT_MULTI
ebtables
-t
filter
-N
BAZ
||
exit
1
$XT_MULTI
ebtables
-t
filter
-N
BAZ
||
exit
1
...
...
iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0
0 → 100755
View file @
3bc9369c
#!/bin/bash
set
-e
#set -x
# there is no legacy backend to test
[[
$XT_MULTI
==
*
/xtables-nft-multi
]]
||
{
echo
"skip
$XT_MULTI
"
;
exit
0
;
}
# fill ebtables manually
$XT_MULTI
ebtables
--init-table
$XT_MULTI
ebtables
-A
INPUT
-p
IPv4
-i
lo
-j
ACCEPT
$XT_MULTI
ebtables
-P
FORWARD DROP
$XT_MULTI
ebtables
-A
OUTPUT
-s
ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
-j
DROP
$XT_MULTI
ebtables
-N
foo
$XT_MULTI
ebtables
-A
foo
--802_3-sap
0x23
-j
ACCEPT
$XT_MULTI
ebtables
-A
foo
--802_3-sap
0xaa
--802_3-type
0x1337
-j
ACCEPT
#$XT_MULTI ebtables -A foo --among-dst fe:ed:ba:be:00:01,fe:ed:ba:be:00:02,fe:ed:ba:be:00:03 -j ACCEPT
$XT_MULTI
ebtables
-A
foo
-p
ARP
--arp-gratuitous
-j
ACCEPT
$XT_MULTI
ebtables
-A
foo
-p
ARP
--arp-opcode
Request
-j
ACCEPT
$XT_MULTI
ebtables
-A
foo
-p
ARP
--arp-ip-src
10.0.0.1
-j
ACCEPT
$XT_MULTI
ebtables
-A
foo
-p
ARP
--arp-ip-dst
10.0.0.0/8
-j
ACCEPT
$XT_MULTI
ebtables
-A
foo
-p
ARP
--arp-mac-src
fe:ed:ba:be:00:01
-j
ACCEPT
$XT_MULTI
ebtables
-A
foo
-p
ARP
--arp-mac-dst
fe:ed:ba:be:00:01/ff:ff:ff:00:00:00
-j
ACCEPT
$XT_MULTI
ebtables
-A
foo
-p
IPv4
--ip-src
10.0.0.1
-j
ACCEPT
$XT_MULTI
ebtables
-A
foo
-p
IPv4
--ip-dst
10.0.0.0/8
-j
ACCEPT
$XT_MULTI
ebtables
-A
foo
-p
IPv4
--ip-tos
0x10
-j
ACCEPT
$XT_MULTI
ebtables
-A
foo
-p
IPv4
--ip-protocol
tcp
-j
ACCEPT
#$XT_MULTI ebtables -A foo -p IPv4 --ip-sport 23 -j ACCEPT
#$XT_MULTI ebtables -A foo -p IPv4 --ip-dport 1024:4096 -j ACCEPT
$XT_MULTI
ebtables
-A
foo
-p
IPv6
--ip6-src
feed:babe::1
-j
ACCEPT
$XT_MULTI
ebtables
-A
foo
-p
IPv6
--ip6-dst
feed:babe::/64
-j
ACCEPT
$XT_MULTI
ebtables
-A
foo
-p
IPv6
--ip6-proto
tcp
-j
ACCEPT
#$XT_MULTI ebtables -A foo -p IPv6 --ip6-sport 23 -j ACCEPT
#$XT_MULTI ebtables -A foo -p IPv6 --ip6-dport 1024:4096 -j ACCEPT
$XT_MULTI
ebtables
-A
foo
--limit
100
--limit-burst
42
-j
ACCEPT
$XT_MULTI
ebtables
-A
foo
--log
$XT_MULTI
ebtables
-A
foo
--mark-set
0x23
--mark-target
ACCEPT
$XT_MULTI
ebtables
-A
foo
--nflog
$XT_MULTI
ebtables
-A
foo
--pkttype-type
multicast
-j
ACCEPT
$XT_MULTI
ebtables
-A
foo
--stp-type
config
-j
ACCEPT
#$XT_MULTI ebtables -A foo --vlan-id 42 -j ACCEPT
$XT_MULTI
ebtables
-A
foo
--802_3-sap
0x23
--limit
100
-j
ACCEPT
$XT_MULTI
ebtables
-A
foo
--pkttype-type
multicast
--log
$XT_MULTI
ebtables
-A
foo
--pkttype-type
multicast
--limit
100
-j
ACCEPT
$XT_MULTI
ebtables
-A
FORWARD
-j
foo
$XT_MULTI
ebtables
-t
nat
-A
PREROUTING
--redirect-target
ACCEPT
#$XT_MULTI ebtables -t nat -A PREROUTING --to-src fe:ed:ba:be:00:01
$XT_MULTI
ebtables
-t
nat
-A
OUTPUT
-j
ACCEPT
$XT_MULTI
ebtables
-t
nat
-P
OUTPUT DROP
$XT_MULTI
ebtables
-t
nat
-A
POSTROUTING
-j
ACCEPT
#$XT_MULTI ebtables -t nat -A POSTROUTING --to-dst fe:ed:ba:be:00:01 --dnat-target ACCEPT
# compare against stored ebtables dump
DUMP
=
'*filter
:INPUT ACCEPT
:FORWARD DROP
:OUTPUT ACCEPT
:foo ACCEPT
-A INPUT -p IPv4 -i lo -j ACCEPT
-A FORWARD -j foo
-A OUTPUT -s Broadcast -j DROP
-A foo --802_3-sap 0x23 -j ACCEPT
-A foo --802_3-sap 0xaa --802_3-type 0x1337 -j ACCEPT
-A foo -p ARP --arp-gratuitous -j ACCEPT
-A foo -p ARP --arp-op Request -j ACCEPT
-A foo -p ARP --arp-ip-src 10.0.0.1 -j ACCEPT
-A foo -p ARP --arp-ip-dst 10.0.0.0/8 -j ACCEPT
-A foo -p ARP --arp-mac-src fe:ed:ba:be:0:1 -j ACCEPT
-A foo -p ARP --arp-mac-dst fe:ed:ba:0:0:0/ff:ff:ff:0:0:0 -j ACCEPT
-A foo -p IPv4 --ip-src 10.0.0.1 -j ACCEPT
-A foo -p IPv4 --ip-dst 10.0.0.0/8 -j ACCEPT
-A foo -p IPv4 --ip-tos 0x10 -j ACCEPT
-A foo -p IPv4 --ip-proto tcp -j ACCEPT
-A foo -p IPv6 --ip6-src feed:babe::1 -j ACCEPT
-A foo -p IPv6 --ip6-dst feed:babe::/64 -j ACCEPT
-A foo -p IPv6 --ip6-proto tcp -j ACCEPT
-A foo --limit 100/sec --limit-burst 42 -j ACCEPT
-A foo --log-level notice --log-prefix "" -j CONTINUE
-A foo -j mark --mark-set 0x23 --mark-target ACCEPT
-A foo --nflog-group 1 -j CONTINUE
-A foo --pkttype-type multicast -j ACCEPT
-A foo --stp-type config -j ACCEPT
-A foo --802_3-sap 0x23 --limit 100/sec --limit-burst 5 -j ACCEPT
-A foo --pkttype-type multicast --log-level notice --log-prefix "" -j CONTINUE
-A foo --pkttype-type multicast --limit 100/sec --limit-burst 5 -j ACCEPT
*nat
:PREROUTING ACCEPT
:OUTPUT DROP
:POSTROUTING ACCEPT
-A PREROUTING -j redirect
-A OUTPUT -j ACCEPT
-A POSTROUTING -j ACCEPT
'
diff
-u
<
(
echo
-e
"
$DUMP
"
)
<
(
$XT_MULTI
ebtables-save |
grep
-v
'^#'
)
# make sure dump can be restored and check it didn't change
$XT_MULTI
ebtables
--init-table
$XT_MULTI
ebtables-restore
<<<
$DUMP
diff
-u
<
(
echo
-e
"
$DUMP
"
)
<
(
$XT_MULTI
ebtables-save |
grep
-v
'^#'
)
iptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_0
0 → 100755
View file @
3bc9369c
#!/bin/bash
set
-e
# there is no legacy backend to test
[[
$XT_MULTI
==
*
/xtables-nft-multi
]]
||
{
echo
"skip
$XT_MULTI
"
;
exit
0
;
}
# ebtables-restore reuses preloaded targets and matches, make sure defaults
# apply to consecutive rules using the same target/match as a previous one
DUMP
=
'*filter
:FORWARD ACCEPT
-A FORWARD --limit 100 --limit-burst 42 -j ACCEPT
-A FORWARD --limit 1000 -j ACCEPT
-A FORWARD --log --log-prefix "foobar"
-A FORWARD --log
'
# note how limit-burst is 5 in second rule and log-prefix empty in fourth one
EXPECT
=
'*filter
:INPUT ACCEPT
:FORWARD ACCEPT
:OUTPUT ACCEPT
-A FORWARD --limit 100/sec --limit-burst 42 -j ACCEPT
-A FORWARD --limit 1000/sec --limit-burst 5 -j ACCEPT
-A FORWARD --log-level notice --log-prefix "foobar" -j CONTINUE
-A FORWARD --log-level notice --log-prefix "" -j CONTINUE
'
$XT_MULTI
ebtables
--init-table
$XT_MULTI
ebtables-restore
<<<
$DUMP
diff
-u
<
(
echo
-e
"
$EXPECT
"
)
<
(
$XT_MULTI
ebtables-save |
grep
-v
'^#'
)
Prev
1
2
3
4
5
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