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
fe62f28a
Commit
fe62f28a
authored
Jul 10, 2018
by
Arturo Borrero Gonzalez
Browse files
Merge tag 'upstream/1.8.0'
Upstream version 1.8.0
parents
0b132590
278668fa
Changes
119
Hide whitespace changes
Inline
Side-by-side
iptables/nft-shared.c
View file @
fe62f28a
...
@@ -20,6 +20,7 @@
...
@@ -20,6 +20,7 @@
#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 <libmnl/libmnl.h>
#include <libmnl/libmnl.h>
#include <libnftnl/rule.h>
#include <libnftnl/rule.h>
...
@@ -83,7 +84,7 @@ void add_bitwise_u16(struct nftnl_rule *r, int mask, int xor)
...
@@ -83,7 +84,7 @@ void add_bitwise_u16(struct nftnl_rule *r, int mask, int xor)
nftnl_rule_add_expr
(
r
,
expr
);
nftnl_rule_add_expr
(
r
,
expr
);
}
}
static
void
add_bitwise
(
struct
nftnl_rule
*
r
,
uint8_t
*
mask
,
size_t
len
)
void
add_bitwise
(
struct
nftnl_rule
*
r
,
uint8_t
*
mask
,
size_t
len
)
{
{
struct
nftnl_expr
*
expr
;
struct
nftnl_expr
*
expr
;
uint32_t
xor
[
4
]
=
{
0
};
uint32_t
xor
[
4
]
=
{
0
};
...
@@ -138,9 +139,10 @@ void add_iniface(struct nftnl_rule *r, char *iface, uint32_t op)
...
@@ -138,9 +139,10 @@ void add_iniface(struct nftnl_rule *r, char *iface, uint32_t op)
iface_len
=
strlen
(
iface
);
iface_len
=
strlen
(
iface
);
add_meta
(
r
,
NFT_META_IIFNAME
);
add_meta
(
r
,
NFT_META_IIFNAME
);
if
(
iface
[
iface_len
-
1
]
==
'+'
)
if
(
iface
[
iface_len
-
1
]
==
'+'
)
{
add_cmp_ptr
(
r
,
op
,
iface
,
iface_len
-
1
);
if
(
iface_len
>
1
)
else
add_cmp_ptr
(
r
,
op
,
iface
,
iface_len
-
1
);
}
else
add_cmp_ptr
(
r
,
op
,
iface
,
iface_len
+
1
);
add_cmp_ptr
(
r
,
op
,
iface
,
iface_len
+
1
);
}
}
...
@@ -151,17 +153,28 @@ void add_outiface(struct nftnl_rule *r, char *iface, uint32_t op)
...
@@ -151,17 +153,28 @@ void add_outiface(struct nftnl_rule *r, char *iface, uint32_t op)
iface_len
=
strlen
(
iface
);
iface_len
=
strlen
(
iface
);
add_meta
(
r
,
NFT_META_OIFNAME
);
add_meta
(
r
,
NFT_META_OIFNAME
);
if
(
iface
[
iface_len
-
1
]
==
'+'
)
if
(
iface
[
iface_len
-
1
]
==
'+'
)
{
add_cmp_ptr
(
r
,
op
,
iface
,
iface_len
-
1
);
if
(
iface_len
>
1
)
else
add_cmp_ptr
(
r
,
op
,
iface
,
iface_len
-
1
);
}
else
add_cmp_ptr
(
r
,
op
,
iface
,
iface_len
+
1
);
add_cmp_ptr
(
r
,
op
,
iface
,
iface_len
+
1
);
}
}
void
add_addr
(
struct
nftnl_rule
*
r
,
int
offset
,
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
)
{
{
const
char
*
m
=
mask
;
int
i
;
add_payload
(
r
,
offset
,
len
,
NFT_PAYLOAD_NETWORK_HEADER
);
add_payload
(
r
,
offset
,
len
,
NFT_PAYLOAD_NETWORK_HEADER
);
add_bitwise
(
r
,
mask
,
len
);
for
(
i
=
0
;
i
<
len
;
i
++
)
{
if
(
m
[
i
]
!=
0xff
)
break
;
}
if
(
i
!=
len
)
add_bitwise
(
r
,
mask
,
len
);
add_cmp_ptr
(
r
,
op
,
data
,
len
);
add_cmp_ptr
(
r
,
op
,
data
,
len
);
}
}
...
@@ -207,6 +220,30 @@ bool is_same_interfaces(const char *a_iniface, const char *a_outiface,
...
@@ -207,6 +220,30 @@ bool is_same_interfaces(const char *a_iniface, const char *a_outiface,
return
true
;
return
true
;
}
}
static
void
parse_ifname
(
const
char
*
name
,
unsigned
int
len
,
char
*
dst
,
unsigned
char
*
mask
)
{
if
(
len
==
0
)
return
;
memcpy
(
dst
,
name
,
len
);
if
(
name
[
len
-
1
]
==
'\0'
)
{
if
(
mask
)
memset
(
mask
,
0xff
,
len
);
return
;
}
if
(
len
>=
IFNAMSIZ
)
return
;
/* wildcard */
dst
[
len
++
]
=
'+'
;
if
(
len
>=
IFNAMSIZ
)
return
;
dst
[
len
++
]
=
0
;
if
(
mask
)
memset
(
mask
,
0xff
,
len
+
1
);
}
int
parse_meta
(
struct
nftnl_expr
*
e
,
uint8_t
key
,
char
*
iniface
,
int
parse_meta
(
struct
nftnl_expr
*
e
,
uint8_t
key
,
char
*
iniface
,
unsigned
char
*
iniface_mask
,
char
*
outiface
,
unsigned
char
*
iniface_mask
,
char
*
outiface
,
unsigned
char
*
outiface_mask
,
uint8_t
*
invflags
)
unsigned
char
*
outiface_mask
,
uint8_t
*
invflags
)
...
@@ -234,35 +271,21 @@ int parse_meta(struct nftnl_expr *e, uint8_t key, char *iniface,
...
@@ -234,35 +271,21 @@ int parse_meta(struct nftnl_expr *e, uint8_t key, char *iniface,
memset
(
outiface_mask
,
0xff
,
strlen
(
outiface
)
+
1
);
memset
(
outiface_mask
,
0xff
,
strlen
(
outiface
)
+
1
);
break
;
break
;
case
NFT_META_BRI_IIFNAME
:
case
NFT_META_IIFNAME
:
case
NFT_META_IIFNAME
:
ifname
=
nftnl_expr_get
(
e
,
NFTNL_EXPR_CMP_DATA
,
&
len
);
ifname
=
nftnl_expr_get
(
e
,
NFTNL_EXPR_CMP_DATA
,
&
len
);
if
(
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_CMP_OP
)
==
NFT_CMP_NEQ
)
if
(
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_CMP_OP
)
==
NFT_CMP_NEQ
)
*
invflags
|=
IPT_INV_VIA_IN
;
*
invflags
|=
IPT_INV_VIA_IN
;
memcpy
(
iniface
,
ifname
,
len
);
parse_ifname
(
ifname
,
len
,
iniface
,
iniface_mask
);
if
(
iniface
[
len
]
==
'\0'
)
memset
(
iniface_mask
,
0xff
,
len
);
else
{
iniface
[
len
]
=
'+'
;
iniface
[
len
+
1
]
=
'\0'
;
memset
(
iniface_mask
,
0xff
,
len
+
1
);
}
break
;
break
;
case
NFT_META_BRI_OIFNAME
:
case
NFT_META_OIFNAME
:
case
NFT_META_OIFNAME
:
ifname
=
nftnl_expr_get
(
e
,
NFTNL_EXPR_CMP_DATA
,
&
len
);
ifname
=
nftnl_expr_get
(
e
,
NFTNL_EXPR_CMP_DATA
,
&
len
);
if
(
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_CMP_OP
)
==
NFT_CMP_NEQ
)
if
(
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_CMP_OP
)
==
NFT_CMP_NEQ
)
*
invflags
|=
IPT_INV_VIA_OUT
;
*
invflags
|=
IPT_INV_VIA_OUT
;
memcpy
(
outiface
,
ifname
,
len
);
parse_ifname
(
ifname
,
len
,
outiface
,
outiface_mask
);
if
(
outiface
[
len
]
==
'\0'
)
memset
(
outiface_mask
,
0xff
,
len
);
else
{
outiface
[
len
]
=
'+'
;
outiface
[
len
+
1
]
=
'\0'
;
memset
(
outiface_mask
,
0xff
,
len
+
1
);
}
break
;
break
;
default:
default:
return
-
1
;
return
-
1
;
...
@@ -276,11 +299,10 @@ static void *nft_get_data(struct nft_xt_ctx *ctx)
...
@@ -276,11 +299,10 @@ static void *nft_get_data(struct nft_xt_ctx *ctx)
switch
(
ctx
->
family
)
{
switch
(
ctx
->
family
)
{
case
NFPROTO_IPV4
:
case
NFPROTO_IPV4
:
case
NFPROTO_IPV6
:
case
NFPROTO_IPV6
:
case
NFPROTO_BRIDGE
:
return
ctx
->
state
.
cs
;
return
ctx
->
state
.
cs
;
case
NFPROTO_ARP
:
case
NFPROTO_ARP
:
return
ctx
->
state
.
cs_arp
;
return
ctx
->
state
.
cs_arp
;
case
NFPROTO_BRIDGE
:
return
ctx
->
state
.
cs_eb
;
default:
default:
/* Should not happen */
/* Should not happen */
return
NULL
;
return
NULL
;
...
@@ -333,10 +355,8 @@ void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
...
@@ -333,10 +355,8 @@ void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
switch
(
ctx
->
family
)
{
switch
(
ctx
->
family
)
{
case
NFPROTO_IPV4
:
case
NFPROTO_IPV4
:
case
NFPROTO_IPV6
:
case
NFPROTO_IPV6
:
matches
=
&
ctx
->
state
.
cs
->
matches
;
break
;
case
NFPROTO_BRIDGE
:
case
NFPROTO_BRIDGE
:
matches
=
&
ctx
->
state
.
cs
_eb
->
matches
;
matches
=
&
ctx
->
state
.
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
"
,
...
@@ -394,10 +414,54 @@ void get_cmp_data(struct nftnl_expr *e, void *data, size_t dlen, bool *inv)
...
@@ -394,10 +414,54 @@ void get_cmp_data(struct nftnl_expr *e, void *data, size_t dlen, bool *inv)
*
inv
=
false
;
*
inv
=
false
;
}
}
static
void
nft_meta_set_to_target
(
struct
nft_xt_ctx
*
ctx
)
{
const
struct
nft_family_ops
*
ops
;
struct
xtables_target
*
target
;
struct
xt_entry_target
*
t
;
unsigned
int
size
;
const
char
*
targname
;
switch
(
ctx
->
meta
.
key
)
{
case
NFT_META_NFTRACE
:
if
(
ctx
->
immediate
.
data
[
0
]
==
0
)
return
;
targname
=
"TRACE"
;
break
;
default:
return
;
}
target
=
xtables_find_target
(
targname
,
XTF_TRY_LOAD
);
if
(
target
==
NULL
)
return
;
size
=
XT_ALIGN
(
sizeof
(
struct
xt_entry_target
))
+
target
->
size
;
t
=
xtables_calloc
(
1
,
size
);
t
->
u
.
target_size
=
size
;
t
->
u
.
user
.
revision
=
target
->
revision
;
strcpy
(
t
->
u
.
user
.
name
,
targname
);
target
->
t
=
t
;
ops
=
nft_family_ops_lookup
(
ctx
->
family
);
ops
->
parse_target
(
target
,
nft_get_data
(
ctx
));
}
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
)
{
{
ctx
->
reg
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_META_DREG
);
ctx
->
meta
.
key
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_META_KEY
);
ctx
->
meta
.
key
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_META_KEY
);
if
(
nftnl_expr_is_set
(
e
,
NFTNL_EXPR_META_SREG
)
&&
(
ctx
->
flags
&
NFT_XT_CTX_IMMEDIATE
)
&&
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_META_SREG
)
==
ctx
->
immediate
.
reg
)
{
ctx
->
flags
&=
~
NFT_XT_CTX_IMMEDIATE
;
nft_meta_set_to_target
(
ctx
);
return
;
}
ctx
->
reg
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_META_DREG
);
ctx
->
flags
|=
NFT_XT_CTX_META
;
ctx
->
flags
|=
NFT_XT_CTX_META
;
}
}
...
@@ -453,13 +517,30 @@ void nft_parse_counter(struct nftnl_expr *e, struct xt_counters *counters)
...
@@ -453,13 +517,30 @@ 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
)
{
{
int
verdict
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_IMM_VERDICT
);
const
char
*
chain
=
nftnl_expr_get_str
(
e
,
NFTNL_EXPR_IMM_CHAIN
);
const
char
*
chain
=
nftnl_expr_get_str
(
e
,
NFTNL_EXPR_IMM_CHAIN
);
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
=
nft_get_data
(
ctx
);
int
verdict
;
if
(
nftnl_expr_is_set
(
e
,
NFTNL_EXPR_IMM_DATA
))
{
const
void
*
imm_data
;
uint32_t
len
;
imm_data
=
nftnl_expr_get_data
(
e
,
NFTNL_EXPR_IMM_DATA
,
&
len
);
if
(
len
>
sizeof
(
ctx
->
immediate
.
data
))
return
;
memcpy
(
ctx
->
immediate
.
data
,
imm_data
,
len
);
ctx
->
immediate
.
len
=
len
;
ctx
->
immediate
.
reg
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_IMM_DREG
);
ctx
->
flags
|=
NFT_XT_CTX_IMMEDIATE
;
return
;
}
verdict
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_IMM_VERDICT
);
/* Standard target? */
/* Standard target? */
switch
(
verdict
)
{
switch
(
verdict
)
{
case
NF_ACCEPT
:
case
NF_ACCEPT
:
...
@@ -537,7 +618,8 @@ void nft_rule_to_iptables_command_state(struct nftnl_rule *r,
...
@@ -537,7 +618,8 @@ 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
)
+
len
);
m
=
calloc
(
1
,
sizeof
(
struct
xt_entry_match
)
+
sizeof
(
struct
xt_comment_info
));
if
(
m
==
NULL
)
{
if
(
m
==
NULL
)
{
fprintf
(
stderr
,
"OOM"
);
fprintf
(
stderr
,
"OOM"
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
...
@@ -838,7 +920,9 @@ bool compare_targets(struct xtables_target *tg1, struct xtables_target *tg2)
...
@@ -838,7 +920,9 @@ bool compare_targets(struct xtables_target *tg1, struct xtables_target *tg2)
if
(
tg1
==
NULL
&&
tg2
==
NULL
)
if
(
tg1
==
NULL
&&
tg2
==
NULL
)
return
true
;
return
true
;
if
((
tg1
==
NULL
&&
tg2
!=
NULL
)
||
(
tg1
!=
NULL
&&
tg2
==
NULL
))
if
(
tg1
==
NULL
||
tg2
==
NULL
)
return
false
;
if
(
tg1
->
userspacesize
!=
tg2
->
userspacesize
)
return
false
;
return
false
;
if
(
strcmp
(
tg1
->
t
->
u
.
user
.
name
,
tg2
->
t
->
u
.
user
.
name
)
!=
0
)
if
(
strcmp
(
tg1
->
t
->
u
.
user
.
name
,
tg2
->
t
->
u
.
user
.
name
)
!=
0
)
...
@@ -881,3 +965,32 @@ bool nft_ipv46_rule_find(struct nft_family_ops *ops,
...
@@ -881,3 +965,32 @@ bool nft_ipv46_rule_find(struct nft_family_ops *ops,
return
true
;
return
true
;
}
}
void
nft_check_xt_legacy
(
int
family
,
bool
is_ipt_save
)
{
static
const
char
tables6
[]
=
"/proc/net/ip6_tables_names"
;
static
const
char
tables4
[]
=
"/proc/net/ip_tables_names"
;
const
char
*
prefix
=
"ip"
;
FILE
*
fp
=
NULL
;
char
buf
[
1024
];
switch
(
family
)
{
case
NFPROTO_IPV4
:
fp
=
fopen
(
tables4
,
"r"
);
break
;
case
NFPROTO_IPV6
:
fp
=
fopen
(
tables6
,
"r"
);
prefix
=
"ip6"
;
break
;
default:
break
;
}
if
(
!
fp
)
return
;
if
(
fgets
(
buf
,
sizeof
(
buf
),
fp
))
fprintf
(
stderr
,
"# Warning: %stables-legacy tables present, use %stables-legacy%s to see them
\n
"
,
prefix
,
prefix
,
is_ipt_save
?
"-save"
:
""
);
fclose
(
fp
);
}
iptables/nft-shared.h
View file @
fe62f28a
...
@@ -43,13 +43,13 @@ enum {
...
@@ -43,13 +43,13 @@ enum {
NFT_XT_CTX_PAYLOAD
=
(
1
<<
0
),
NFT_XT_CTX_PAYLOAD
=
(
1
<<
0
),
NFT_XT_CTX_META
=
(
1
<<
1
),
NFT_XT_CTX_META
=
(
1
<<
1
),
NFT_XT_CTX_BITWISE
=
(
1
<<
2
),
NFT_XT_CTX_BITWISE
=
(
1
<<
2
),
NFT_XT_CTX_IMMEDIATE
=
(
1
<<
3
),
};
};
struct
nft_xt_ctx
{
struct
nft_xt_ctx
{
union
{
union
{
struct
iptables_command_state
*
cs
;
struct
iptables_command_state
*
cs
;
struct
arptables_command_state
*
cs_arp
;
struct
arptables_command_state
*
cs_arp
;
struct
ebtables_command_state
*
cs_eb
;
}
state
;
}
state
;
struct
nftnl_expr_iter
*
iter
;
struct
nftnl_expr_iter
*
iter
;
int
family
;
int
family
;
...
@@ -63,6 +63,10 @@ struct nft_xt_ctx {
...
@@ -63,6 +63,10 @@ struct nft_xt_ctx {
struct
{
struct
{
uint32_t
key
;
uint32_t
key
;
}
meta
;
}
meta
;
struct
{
uint32_t
data
[
4
];
uint32_t
len
,
reg
;
}
immediate
;
struct
{
struct
{
uint32_t
mask
[
4
];
uint32_t
mask
[
4
];
uint32_t
xor
[
4
];
uint32_t
xor
[
4
];
...
@@ -107,6 +111,7 @@ struct nft_family_ops {
...
@@ -107,6 +111,7 @@ struct nft_family_ops {
void
add_meta
(
struct
nftnl_rule
*
r
,
uint32_t
key
);
void
add_meta
(
struct
nftnl_rule
*
r
,
uint32_t
key
);
void
add_payload
(
struct
nftnl_rule
*
r
,
int
offset
,
int
len
,
uint32_t
base
);
void
add_payload
(
struct
nftnl_rule
*
r
,
int
offset
,
int
len
,
uint32_t
base
);
void
add_bitwise
(
struct
nftnl_rule
*
r
,
uint8_t
*
mask
,
size_t
len
);
void
add_bitwise_u16
(
struct
nftnl_rule
*
r
,
int
mask
,
int
xor
);
void
add_bitwise_u16
(
struct
nftnl_rule
*
r
,
int
mask
,
int
xor
);
void
add_cmp_ptr
(
struct
nftnl_rule
*
r
,
uint32_t
op
,
void
*
data
,
size_t
len
);
void
add_cmp_ptr
(
struct
nftnl_rule
*
r
,
uint32_t
op
,
void
*
data
,
size_t
len
);
void
add_cmp_u8
(
struct
nftnl_rule
*
r
,
uint8_t
val
,
uint32_t
op
);
void
add_cmp_u8
(
struct
nftnl_rule
*
r
,
uint8_t
val
,
uint32_t
op
);
...
@@ -223,9 +228,9 @@ struct nft_xt_cmd_parse {
...
@@ -223,9 +228,9 @@ struct nft_xt_cmd_parse {
unsigned
int
command
;
unsigned
int
command
;
unsigned
int
rulenum
;
unsigned
int
rulenum
;
char
*
table
;
char
*
table
;
char
*
chain
;
const
char
*
chain
;
char
*
newname
;
const
char
*
newname
;
char
*
policy
;
const
char
*
policy
;
bool
restore
;
bool
restore
;
int
verbose
;
int
verbose
;
};
};
...
@@ -245,17 +250,18 @@ struct nftnl_chain_list;
...
@@ -245,17 +250,18 @@ struct nftnl_chain_list;
struct
nft_xt_restore_cb
{
struct
nft_xt_restore_cb
{
void
(
*
table_new
)(
struct
nft_handle
*
h
,
const
char
*
table
);
void
(
*
table_new
)(
struct
nft_handle
*
h
,
const
char
*
table
);
struct
nftnl_chain_list
*
(
*
chain_list
)(
struct
nft_handle
*
h
);
struct
nftnl_chain_list
*
(
*
chain_list
)(
struct
nft_handle
*
h
);
int
(
*
chains_purge
)(
struct
nft_handle
*
h
,
const
char
*
table
,
struct
nftnl_chain_list
*
clist
);
void
(
*
chain_del
)(
struct
nftnl_chain_list
*
clist
,
const
char
*
curtable
,
void
(
*
chain_del
)(
struct
nftnl_chain_list
*
clist
,
const
char
*
curtable
,
const
char
*
chain
);
const
char
*
chain
);
int
(
*
chain_user_flush
)(
struct
nft_handle
*
h
,
struct
nftnl_chain_list
*
clist
,
const
char
*
table
,
const
char
*
chain
);
int
(
*
chain_set
)(
struct
nft_handle
*
h
,
const
char
*
table
,
int
(
*
chain_set
)(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
,
const
char
*
policy
,
const
char
*
chain
,
const
char
*
policy
,
const
struct
xt_counters
*
counters
);
const
struct
xt_counters
*
counters
);
int
(
*
chain_user_add
)(
struct
nft_handle
*
h
,
const
char
*
chain
,
int
(
*
chain_user_add
)(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
);
const
char
*
table
);
int
(
*
ru
le_flush
)(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
);
int
(
*
tab
le_flush
)(
struct
nft_handle
*
h
,
const
char
*
table
);
int
(
*
do_command
)(
struct
nft_handle
*
h
,
int
argc
,
char
*
argv
[],
int
(
*
do_command
)(
struct
nft_handle
*
h
,
int
argc
,
char
*
argv
[],
char
**
table
,
bool
restore
);
char
**
table
,
bool
restore
);
...
@@ -269,4 +275,5 @@ void xtables_restore_parse(struct nft_handle *h,
...
@@ -269,4 +275,5 @@ void xtables_restore_parse(struct nft_handle *h,
struct
nft_xt_restore_cb
*
cb
,
struct
nft_xt_restore_cb
*
cb
,
int
argc
,
char
*
argv
[]);
int
argc
,
char
*
argv
[]);
void
nft_check_xt_legacy
(
int
family
,
bool
is_ipt_save
);
#endif
#endif
iptables/nft.c
View file @
fe62f28a
...
@@ -19,6 +19,7 @@
...
@@ -19,6 +19,7 @@
#include <time.h>
#include <time.h>
#include <stdarg.h>
#include <stdarg.h>
#include <inttypes.h>
#include <inttypes.h>
#include <assert.h>
#include <xtables.h>
#include <xtables.h>
#include <libiptc/libxtc.h>
#include <libiptc/libxtc.h>
...
@@ -44,6 +45,7 @@
...
@@ -44,6 +45,7 @@
#include <libnftnl/expr.h>
#include <libnftnl/expr.h>
#include <libnftnl/set.h>
#include <libnftnl/set.h>
#include <libnftnl/udata.h>
#include <libnftnl/udata.h>
#include <libnftnl/batch.h>
#include <netinet/in.h>
/* inet_ntoa */
#include <netinet/in.h>
/* inet_ntoa */
#include <arpa/inet.h>
#include <arpa/inet.h>
...
@@ -60,7 +62,7 @@ int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh,
...
@@ -60,7 +62,7 @@ int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh,
void
*
data
)
void
*
data
)
{
{
int
ret
;
int
ret
;
char
buf
[
MNL_SOCKET_BUFFER_SIZE
];
char
buf
[
16536
];
if
(
mnl_socket_sendto
(
h
->
nl
,
nlh
,
nlh
->
nlmsg_len
)
<
0
)
if
(
mnl_socket_sendto
(
h
->
nl
,
nlh
,
nlh
->
nlmsg_len
)
<
0
)
return
-
1
;
return
-
1
;
...
@@ -80,13 +82,7 @@ int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh,
...
@@ -80,13 +82,7 @@ int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh,
return
0
;
return
0
;
}
}
static
LIST_HEAD
(
batch_page_list
);
#define NFT_NLMSG_MAXSIZE (UINT16_MAX + getpagesize())
static
int
batch_num_pages
;
struct
batch_page
{
struct
list_head
head
;
struct
mnl_nlmsg_batch
*
batch
;
};
/* selected batch page is 256 Kbytes long to load ruleset of
/* selected batch page is 256 Kbytes long to load ruleset of
* half a million rules without hitting -EMSGSIZE due to large
* half a million rules without hitting -EMSGSIZE due to large
...
@@ -94,44 +90,74 @@ struct batch_page {
...
@@ -94,44 +90,74 @@ struct batch_page {
*/
*/
#define BATCH_PAGE_SIZE getpagesize() * 32
#define BATCH_PAGE_SIZE getpagesize() * 32
static
struct
mnl_nlmsg
_batch
*
mnl_
nftnl_
batch_
alloc
(
void
)
static
struct
nftnl
_batch
*
mnl_batch_
init
(
void
)
{
{
st
atic
char
*
buf
;
st
ruct
nftnl_batch
*
batch
;
/* libmnl needs higher buffer to handle batch overflows */
batch
=
nftnl_batch_alloc
(
BATCH_PAGE_SIZE
,
NFT_NLMSG_MAXSIZE
);
buf
=
malloc
(
BATCH_PAGE_SIZE
+
getpagesize
());
if
(
batch
==
NULL
)
if
(
buf
==
NULL
)
return
NULL
;
return
NULL
;
return
mnl_nlmsg_batch_start
(
buf
,
BATCH_PAGE_SIZE
)
;
return
batch
;
}
}
static
struct
mnl_nlmsg_batch
*
static
void
mnl_nft_batch_continue
(
struct
nftnl_batch
*
batch
)
mnl_nftnl_batch_page_add
(
struct
mnl_nlmsg_batch
*
batch
)
{
{
struct
batch_page
*
batch_page
;
assert
(
nftnl_batch_update
(
batch
)
>=
0
);
}
batch_page
=
malloc
(
sizeof
(
struct
batch_page
));
static
uint32_t
mnl_batch_begin
(
struct
nftnl_batch
*
batch
,
uint32_t
seqnum
)
if
(
batch_page
==
NULL
)
{
return
NULL
;
nftnl_batch_begin
(
nftnl_batch_buffer
(
batch
),
seqnum
);
mnl_nft_batch_continue
(
batch
);
return
seqnum
;
}
static
void
mnl_batch_end
(
struct
nftnl_batch
*
batch
,
uint32_t
seqnum
)
{
nftnl_batch_end
(
nftnl_batch_buffer
(
batch
),
seqnum
);
mnl_nft_batch_continue
(
batch
);
}
static
void
mnl_batch_reset
(
struct
nftnl_batch
*
batch
)
{
nftnl_batch_free
(
batch
);
}
batch_page
->
batch
=
batch
;
struct
mnl_err
{
list_add_tail
(
&
batch_page
->
head
,
&
batch_page_list
);
struct
list_head
head
;
batch_num_pages
++
;
int
err
;
uint32_t
seqnum
;
};
static
void
mnl_err_list_node_add
(
struct
list_head
*
err_list
,
int
error
,
int
seqnum
)
{
struct
mnl_err
*
err
=
malloc
(
sizeof
(
struct
mnl_err
));
return
mnl_nftnl_batch_alloc
();
err
->
seqnum
=
seqnum
;
err
->
err
=
error
;
list_add_tail
(
&
err
->
head
,
err_list
);
}
static
void
mnl_err_list_free
(
struct
mnl_err
*
err
)
{
list_del
(
&
err
->
head
);
free
(
err
);
}
}
static
int
nlbuffsiz
;
static
int
nlbuffsiz
;
static
void
mnl_nft_set_sndbuffer
(
const
struct
mnl_socket
*
nl
)
static
void
mnl_set_sndbuffer
(
const
struct
mnl_socket
*
nl
,
struct
nftnl_batch
*
batch
)
{
{
int
newbuffsiz
;
int
newbuffsiz
;
if
(
batch_num_pages
*
BATCH_PAGE_SIZE
<=
nlbuffsiz
)
if
(
nftnl_batch_iovec_len
(
batch
)
*
BATCH_PAGE_SIZE
<=
nlbuffsiz
)
return
;
return
;
newbuffsiz
=
batch_num_pages
*
BATCH_PAGE_SIZE
;
newbuffsiz
=
nftnl_batch_iovec_len
(
batch
)
*
BATCH_PAGE_SIZE
;
/* Rise sender buffer length to avoid hitting -EMSGSIZE */
/* Rise sender buffer length to avoid hitting -EMSGSIZE */
if
(
setsockopt
(
mnl_socket_get_fd
(
nl
),
SOL_SOCKET
,
SO_SNDBUFFORCE
,
if
(
setsockopt
(
mnl_socket_get_fd
(
nl
),
SOL_SOCKET
,
SO_SNDBUFFORCE
,
...
@@ -141,57 +167,32 @@ static void mnl_nft_set_sndbuffer(const struct mnl_socket *nl)
...
@@ -141,57 +167,32 @@ static void mnl_nft_set_sndbuffer(const struct mnl_socket *nl)
nlbuffsiz
=
newbuffsiz
;
nlbuffsiz
=
newbuffsiz
;
}
}
static
void
mnl_nftnl_batch_reset
(
void
)
static
ssize_t
mnl_nft_socket_sendmsg
(
const
struct
mnl_socket
*
nf_sock
,
{
struct
nftnl_batch
*
batch
)
struct
batch_page
*
batch_page
,
*
next
;
list_for_each_entry_safe
(
batch_page
,
next
,
&
batch_page_list
,
head
)
{
list_del
(
&
batch_page
->
head
);
free
(
mnl_nlmsg_batch_head
(
batch_page
->
batch
));
mnl_nlmsg_batch_stop
(
batch_page
->
batch
);
free
(
batch_page
);
batch_num_pages
--
;
}
}
static
ssize_t
mnl_nft_socket_sendmsg
(
const
struct
mnl_socket
*
nl
)
{
{
static
const
struct
sockaddr_nl
snl
=
{
static
const
struct
sockaddr_nl
snl
=
{
.
nl_family
=
AF_NETLINK
.
nl_family
=
AF_NETLINK
};
};
struct
iovec
iov
[
batch_num_pages
];
uint32_t
iov_len
=
nftnl_batch_iovec_len
(
batch
);
struct
iovec
iov
[
iov_len
];
struct
msghdr
msg
=
{
struct
msghdr
msg
=
{
.
msg_name
=
(
struct
sockaddr
*
)
&
snl
,
.
msg_name
=
(
struct
sockaddr
*
)
&
snl
,
.
msg_namelen
=
sizeof
(
snl
),
.
msg_namelen
=
sizeof
(
snl
),
.
msg_iov
=
iov
,
.
msg_iov
=
iov
,
.
msg_iovlen
=
batch_num_pages
,
.
msg_iovlen
=
iov_len
,
};
};
struct
batch_page
*
batch_page
;
int
i
=
0
,
ret
;
mnl_nft_set_sndbuffer
(
nl
);
list_for_each_entry
(
batch_page
,
&
batch_page_list
,
head
)
{
iov
[
i
].
iov_base
=
mnl_nlmsg_batch_head
(
batch_page
->
batch
);
iov
[
i
].
iov_len
=
mnl_nlmsg_batch_size
(
batch_page
->
batch
);
i
++
;
#ifdef NL_DEBUG
mnl_nlmsg_fprintf
(
stdout
,
mnl_nlmsg_batch_head
(
batch_page
->
batch
),
mnl_nlmsg_batch_size
(
batch_page
->
batch
),
sizeof
(
struct
nfgenmsg
));
#endif
}
ret
=
sendmsg
(
mnl_socket_get_fd
(
nl
),
&
msg
,
0
);
mnl_set_sndbuffer
(
nf_sock
,
batch
);
mnl_
nftnl_batch_
reset
(
);
nftnl_batch_
iovec
(
batch
,
iov
,
iov_len
);
return
ret
;
return
sendmsg
(
mnl_socket_get_fd
(
nf_sock
),
&
msg
,
0
)
;
}
}
static
int
mnl_nftnl_batch_talk
(
struct
nft_handle
*
h
)
static
int
mnl_batch_talk
(
const
struct
mnl_socket
*
nf_sock
,
struct
nftnl_batch
*
batch
,
struct
list_head
*
err_list
)
{
{
int
ret
,
fd
=
mnl_socket_get_fd
(
h
->
nl
);
const
struct
mnl_socket
*
nl
=
nf_sock
;
int
ret
,
fd
=
mnl_socket_get_fd
(
nl
),
portid
=
mnl_socket_get_portid
(
nl
);
char
rcv_buf
[
MNL_SOCKET_BUFFER_SIZE
];
char
rcv_buf
[
MNL_SOCKET_BUFFER_SIZE
];
fd_set
readfds
;
fd_set
readfds
;
struct
timeval
tv
=
{
struct
timeval
tv
=
{
...
@@ -200,7 +201,7 @@ static int mnl_nftnl_batch_talk(struct nft_handle *h)
...
@@ -200,7 +201,7 @@ static int mnl_nftnl_batch_talk(struct nft_handle *h)
};
};
int
err
=
0
;
int
err
=
0
;
ret
=
mnl_nft_socket_sendmsg
(
h
->
nl
);
ret
=
mnl_nft_socket_sendmsg
(
nf_sock
,
batch
);
if
(
ret
==
-
1
)
if
(
ret
==
-
1
)
return
-
1
;
return
-
1
;
...
@@ -213,16 +214,18 @@ static int mnl_nftnl_batch_talk(struct nft_handle *h)
...
@@ -213,16 +214,18 @@ static int mnl_nftnl_batch_talk(struct nft_handle *h)
return
-
1
;
return
-
1
;
while
(
ret
>
0
&&
FD_ISSET
(
fd
,
&
readfds
))
{
while
(
ret
>
0
&&
FD_ISSET
(
fd
,
&
readfds
))
{
ret
=
mnl_socket_recvfrom
(
h
->
nl
,
rcv_buf
,
sizeof
(
rcv_buf
));
struct
nlmsghdr
*
nlh
=
(
struct
nlmsghdr
*
)
rcv_buf
;
ret
=
mnl_socket_recvfrom
(
nl
,
rcv_buf
,
sizeof
(
rcv_buf
));
if
(
ret
==
-
1
)
if
(
ret
==
-
1
)
return
-
1
;
return
-
1
;
ret
=
mnl_cb_run
(
rcv_buf
,
ret
,
0
,
h
->
portid
,
NULL
,
NULL
);
ret
=
mnl_cb_run
(
rcv_buf
,
ret
,
0
,
portid
,
NULL
,
NULL
);
/*
Annotate first error and continue
, make sure we get all
/*
Continue on error
, make sure we get all
acknowledgments */
* acknoledgments.
if
(
ret
==
-
1
)
{
*/
mnl_err_list_node_add
(
err_list
,
errno
,
nlh
->
nlmsg_seq
);
if
(
!
err
&&
ret
=
=
-
1
)
err
=
-
1
;
err
=
errno
;
}
ret
=
select
(
fd
+
1
,
&
readfds
,
NULL
,
NULL
,
&
tv
);
ret
=
select
(
fd
+
1
,
&
readfds
,
NULL
,
NULL
,
&
tv
);
if
(
ret
==
-
1
)
if
(
ret
==
-
1
)
...
@@ -231,29 +234,16 @@ static int mnl_nftnl_batch_talk(struct nft_handle *h)
...
@@ -231,29 +234,16 @@ static int mnl_nftnl_batch_talk(struct nft_handle *h)
FD_ZERO
(
&
readfds
);
FD_ZERO
(
&
readfds
);
FD_SET
(
fd
,
&
readfds
);
FD_SET
(
fd
,
&
readfds
);
}
}
errno
=
err
;
return
err
;
return
err
?
-
1
:
0
;
}
static
void
mnl_nftnl_batch_begin
(
struct
mnl_nlmsg_batch
*
batch
,
uint32_t
seq
)
{
nftnl_batch_begin
(
mnl_nlmsg_batch_current
(
batch
),
seq
);
if
(
!
mnl_nlmsg_batch_next
(
batch
))
mnl_nftnl_batch_page_add
(
batch
);
}
static
void
mnl_nftnl_batch_end
(
struct
mnl_nlmsg_batch
*
batch
,
uint32_t
seq
)
{
nftnl_batch_end
(
mnl_nlmsg_batch_current
(
batch
),
seq
);
if
(
!
mnl_nlmsg_batch_next
(
batch
))
mnl_nftnl_batch_page_add
(
batch
);
}
}
enum
obj_update_type
{
enum
obj_update_type
{
NFT_COMPAT_TABLE_ADD
,
NFT_COMPAT_TABLE_ADD
,
NFT_COMPAT_TABLE_FLUSH
,
NFT_COMPAT_CHAIN_ADD
,
NFT_COMPAT_CHAIN_ADD
,
NFT_COMPAT_CHAIN_USER_ADD
,
NFT_COMPAT_CHAIN_USER_ADD
,
NFT_COMPAT_CHAIN_USER_DEL
,
NFT_COMPAT_CHAIN_USER_DEL
,
NFT_COMPAT_CHAIN_USER_FLUSH
,
NFT_COMPAT_CHAIN_UPDATE
,
NFT_COMPAT_CHAIN_UPDATE
,
NFT_COMPAT_CHAIN_RENAME
,
NFT_COMPAT_CHAIN_RENAME
,
NFT_COMPAT_RULE_APPEND
,
NFT_COMPAT_RULE_APPEND
,
...
@@ -271,14 +261,83 @@ enum obj_action {
...
@@ -271,14 +261,83 @@ enum obj_action {
struct
obj_update
{
struct
obj_update
{
struct
list_head
head
;
struct
list_head
head
;
enum
obj_update_type
type
;
enum
obj_update_type
type
;
unsigned
int
seq
;
union
{
union
{
struct
nftnl_table
*
table
;
struct
nftnl_table
*
table
;
struct
nftnl_chain
*
chain
;
struct
nftnl_chain
*
chain
;
struct
nftnl_rule
*
rule
;
struct
nftnl_rule
*
rule
;
void
*
ptr
;
void
*
ptr
;
};
};
struct
{
unsigned
int
lineno
;
}
error
;
};
};
static
int
mnl_append_error
(
const
struct
nft_handle
*
h
,
const
struct
obj_update
*
o
,
const
struct
mnl_err
*
err
,
char
*
buf
,
unsigned
int
len
)
{
static
const
char
*
type_name
[]
=
{
[
NFT_COMPAT_TABLE_ADD
]
=
"TABLE_ADD"
,
[
NFT_COMPAT_TABLE_FLUSH
]
=
"TABLE_FLUSH"
,
[
NFT_COMPAT_CHAIN_ADD
]
=
"CHAIN_ADD"
,
[
NFT_COMPAT_CHAIN_USER_ADD
]
=
"CHAIN_USER_ADD"
,
[
NFT_COMPAT_CHAIN_USER_DEL
]
=
"CHAIN_USER_DEL"
,
[
NFT_COMPAT_CHAIN_USER_FLUSH
]
=
"CHAIN_USER_FLUSH"
,
[
NFT_COMPAT_CHAIN_UPDATE
]
=
"CHAIN_UPDATE"
,
[
NFT_COMPAT_CHAIN_RENAME
]
=
"CHAIN_RENAME"
,
[
NFT_COMPAT_RULE_APPEND
]
=
"RULE_APPEND"
,
[
NFT_COMPAT_RULE_INSERT
]
=
"RULE_INSERT"
,
[
NFT_COMPAT_RULE_REPLACE
]
=
"RULE_REPLACE"
,
[
NFT_COMPAT_RULE_DELETE
]
=
"RULE_DELETE"
,
[
NFT_COMPAT_RULE_FLUSH
]
=
"RULE_FLUSH"
,
};
char
errmsg
[
256
];
char
tcr
[
128
];
if
(
o
->
error
.
lineno
)
snprintf
(
errmsg
,
sizeof
(
errmsg
),
"
\n
line %u: %s failed (%s)"
,
o
->
error
.
lineno
,
type_name
[
o
->
type
],
strerror
(
err
->
err
));
else
snprintf
(
errmsg
,
sizeof
(
errmsg
),
" %s failed (%s)"
,
type_name
[
o
->
type
],
strerror
(
err
->
err
));
switch
(
o
->
type
)
{
case
NFT_COMPAT_TABLE_ADD
:
case
NFT_COMPAT_TABLE_FLUSH
:
snprintf
(
tcr
,
sizeof
(
tcr
),
"table %s"
,
nftnl_table_get_str
(
o
->
table
,
NFTNL_TABLE_NAME
));
break
;
case
NFT_COMPAT_CHAIN_ADD
:
case
NFT_COMPAT_CHAIN_USER_ADD
:
case
NFT_COMPAT_CHAIN_USER_DEL
:
case
NFT_COMPAT_CHAIN_USER_FLUSH
:
case
NFT_COMPAT_CHAIN_UPDATE
:
case
NFT_COMPAT_CHAIN_RENAME
:
snprintf
(
tcr
,
sizeof
(
tcr
),
"chain %s"
,
nftnl_chain_get_str
(
o
->
chain
,
NFTNL_CHAIN_NAME
));
break
;
case
NFT_COMPAT_RULE_APPEND
:
case
NFT_COMPAT_RULE_INSERT
:
case
NFT_COMPAT_RULE_REPLACE
:
case
NFT_COMPAT_RULE_DELETE
:
case
NFT_COMPAT_RULE_FLUSH
:
snprintf
(
tcr
,
sizeof
(
tcr
),
"rule in chain %s"
,
nftnl_rule_get_str
(
o
->
rule
,
NFTNL_RULE_CHAIN
));
#if 0
{
struct iptables_command_state cs = {};
nft_rule_to_iptables_command_state(o->rule, &cs);
nft_rule_print_save(&cs, o->rule, NFT_RULE_APPEND, FMT_NOCOUNTS);
}
#endif
break
;
}
return
snprintf
(
buf
,
len
,
"%s: %s"
,
errmsg
,
tcr
);
}
static
int
batch_add
(
struct
nft_handle
*
h
,
enum
obj_update_type
type
,
void
*
ptr
)
static
int
batch_add
(
struct
nft_handle
*
h
,
enum
obj_update_type
type
,
void
*
ptr
)
{
{
struct
obj_update
*
obj
;
struct
obj_update
*
obj
;
...
@@ -288,6 +347,7 @@ static int batch_add(struct nft_handle *h, enum obj_update_type type, void *ptr)
...
@@ -288,6 +347,7 @@ static int batch_add(struct nft_handle *h, enum obj_update_type type, void *ptr)
return
-
1
;
return
-
1
;
obj
->
ptr
=
ptr
;
obj
->
ptr
=
ptr
;
obj
->
error
.
lineno
=
h
->
error
.
lineno
;
obj
->
type
=
type
;
obj
->
type
=
type
;
list_add_tail
(
&
obj
->
head
,
&
h
->
obj_list
);
list_add_tail
(
&
obj
->
head
,
&
h
->
obj_list
);
h
->
obj_list_num
++
;
h
->
obj_list_num
++
;
...
@@ -455,12 +515,6 @@ struct builtin_table xtables_arp[TABLES_MAX] = {
...
@@ -455,12 +515,6 @@ struct builtin_table xtables_arp[TABLES_MAX] = {
.
prio
=
NF_IP_PRI_FILTER
,
.
prio
=
NF_IP_PRI_FILTER
,
.
hook
=
NF_ARP_IN
,
.
hook
=
NF_ARP_IN
,
},
},
{
.
name
=
"FORWARD"
,
.
type
=
"filter"
,
.
prio
=
NF_IP_PRI_FILTER
,
.
hook
=
NF_ARP_FORWARD
,
},
{
{
.
name
=
"OUTPUT"
,
.
name
=
"OUTPUT"
,
.
type
=
"filter"
,
.
type
=
"filter"
,
...
@@ -522,30 +576,6 @@ struct builtin_table xtables_bridge[TABLES_MAX] = {
...
@@ -522,30 +576,6 @@ struct builtin_table xtables_bridge[TABLES_MAX] = {
},
},
};
};
int
nft_table_add
(
struct
nft_handle
*
h
,
struct
nftnl_table
*
t
,
uint16_t
flags
)
{
char
buf
[
MNL_SOCKET_BUFFER_SIZE
];
struct
nlmsghdr
*
nlh
;
int
ret
;
nlh
=
nftnl_table_nlmsg_build_hdr
(
buf
,
NFT_MSG_NEWTABLE
,
h
->
family
,
NLM_F_ACK
|
flags
,
h
->
seq
);
nftnl_table_nlmsg_build_payload
(
nlh
,
t
);
nftnl_table_free
(
t
);
#ifdef NLDEBUG
char
tmp
[
1024
];
nft_table_snprintf
(
tmp
,
sizeof
(
tmp
),
t
,
0
,
0
);
printf
(
"DEBUG: table: %s
\n
"
,
tmp
);
mnl_nlmsg_fprintf
(
stdout
,
nlh
,
nlh
->
nlmsg_len
,
sizeof
(
struct
nfgenmsg
));
#endif
ret
=
mnl_talk
(
h
,
nlh
,
NULL
,
NULL
);
return
(
ret
==
0
||
(
ret
==
-
1
&&
errno
==
EEXIST
))
?
0
:
-
1
;
}
static
int
nft_table_builtin_add
(
struct
nft_handle
*
h
,
static
int
nft_table_builtin_add
(
struct
nft_handle
*
h
,
struct
builtin_table
*
_t
)
struct
builtin_table
*
_t
)
{
{
...
@@ -561,13 +591,7 @@ static int nft_table_builtin_add(struct nft_handle *h,
...
@@ -561,13 +591,7 @@ static int nft_table_builtin_add(struct nft_handle *h,
nftnl_table_set
(
t
,
NFTNL_TABLE_NAME
,
(
char
*
)
_t
->
name
);
nftnl_table_set
(
t
,
NFTNL_TABLE_NAME
,
(
char
*
)
_t
->
name
);
if
(
h
->
batch_support
)
ret
=
batch_table_add
(
h
,
NFT_COMPAT_TABLE_ADD
,
t
);
ret
=
batch_table_add
(
h
,
NFT_COMPAT_TABLE_ADD
,
t
);
else
ret
=
nft_table_add
(
h
,
t
,
NLM_F_EXCL
);
if
(
ret
==
0
)
_t
->
initialized
=
true
;
return
ret
;
return
ret
;
}
}
...
@@ -592,29 +616,6 @@ nft_chain_builtin_alloc(struct builtin_table *table,
...
@@ -592,29 +616,6 @@ nft_chain_builtin_alloc(struct builtin_table *table,
return
c
;
return
c
;
}
}
int
nft_chain_add
(
struct
nft_handle
*
h
,
struct
nftnl_chain
*
c
,
uint16_t
flags
)
{
char
buf
[
MNL_SOCKET_BUFFER_SIZE
];
struct
nlmsghdr
*
nlh
;
/* NLM_F_CREATE requests module autoloading */
nlh
=
nftnl_chain_nlmsg_build_hdr
(
buf
,
NFT_MSG_NEWCHAIN
,
h
->
family
,
NLM_F_ACK
|
flags
|
NLM_F_CREATE
,
h
->
seq
);
nftnl_chain_nlmsg_build_payload
(
nlh
,
c
);
nftnl_chain_free
(
c
);
#ifdef NLDEBUG
char
tmp
[
1024
];
nft_chain_snprintf
(
tmp
,
sizeof
(
tmp
),
c
,
0
,
0
);
printf
(
"DEBUG: chain: %s
\n
"
,
tmp
);
mnl_nlmsg_fprintf
(
stdout
,
nlh
,
nlh
->
nlmsg_len
,
sizeof
(
struct
nfgenmsg
));
#endif
return
mnl_talk
(
h
,
nlh
,
NULL
,
NULL
);
}
static
void
nft_chain_builtin_add
(
struct
nft_handle
*
h
,
static
void
nft_chain_builtin_add
(
struct
nft_handle
*
h
,
struct
builtin_table
*
table
,
struct
builtin_table
*
table
,
struct
builtin_chain
*
chain
)
struct
builtin_chain
*
chain
)
...
@@ -625,10 +626,7 @@ static void nft_chain_builtin_add(struct nft_handle *h,
...
@@ -625,10 +626,7 @@ static void nft_chain_builtin_add(struct nft_handle *h,
if
(
c
==
NULL
)
if
(
c
==
NULL
)
return
;
return
;
if
(
h
->
batch_support
)
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_ADD
,
c
);
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_ADD
,
c
);
else
nft_chain_add
(
h
,
c
,
NLM_F_EXCL
);
}
}
/* find if built-in table already exists */
/* find if built-in table already exists */
...
@@ -686,28 +684,27 @@ static void nft_chain_builtin_init(struct nft_handle *h,
...
@@ -686,28 +684,27 @@ static void nft_chain_builtin_init(struct nft_handle *h,
nft_chain_builtin_add
(
h
,
table
,
&
table
->
chains
[
i
]);
nft_chain_builtin_add
(
h
,
table
,
&
table
->
chains
[
i
]);
}
}
nftnl_chain_list_free
(
list
);
}
}
static
int
nft_xt_builtin_init
(
struct
nft_handle
*
h
,
const
char
*
table
)
static
int
nft_xt_builtin_init
(
struct
nft_handle
*
h
,
const
char
*
table
)
{
{
int
ret
=
0
;
struct
builtin_table
*
t
;
struct
builtin_table
*
t
;
t
=
nft_table_builtin_find
(
h
,
table
);
t
=
nft_table_builtin_find
(
h
,
table
);
if
(
t
==
NULL
)
{
if
(
t
==
NULL
)
ret
=
-
1
;
ret
urn
-
1
;
goto
out
;
}
if
(
t
->
initialized
)
if
(
nft_table_builtin_add
(
h
,
t
)
<
0
)
{
return
0
;
/* Built-in table already initialized, skip. */
if
(
errno
==
EEXIST
)
if
(
nft_table_builtin_add
(
h
,
t
)
<
0
)
goto
out
;
return
-
1
;
}
nft_chain_builtin_init
(
h
,
t
);
nft_chain_builtin_init
(
h
,
t
);
out:
return
ret
;
t
->
initialized
=
true
;
return
0
;
}
}
static
bool
nft_chain_builtin
(
struct
nftnl_chain
*
c
)
static
bool
nft_chain_builtin
(
struct
nftnl_chain
*
c
)
...
@@ -718,47 +715,20 @@ static bool nft_chain_builtin(struct nftnl_chain *c)
...
@@ -718,47 +715,20 @@ static bool nft_chain_builtin(struct nftnl_chain *c)
return
nftnl_chain_get
(
c
,
NFTNL_CHAIN_HOOKNUM
)
!=
NULL
;
return
nftnl_chain_get
(
c
,
NFTNL_CHAIN_HOOKNUM
)
!=
NULL
;
}
}
static
bool
mnl_batch_supported
(
struct
nft_handle
*
h
)
static
int
nft_restart
(
struct
nft_handle
*
h
)
{
{
char
buf
[
MNL_SOCKET_BUFFER_SIZE
];
mnl_socket_close
(
h
->
nl
);
uint32_t
seq
=
1
;
int
ret
;
mnl_nftnl_batch_begin
(
h
->
batch
,
seq
++
);
nftnl_set_nlmsg_build_hdr
(
mnl_nlmsg_batch_current
(
h
->
batch
),
NFT_MSG_NEWSET
,
AF_INET
,
NLM_F_ACK
,
seq
++
);
mnl_nlmsg_batch_next
(
h
->
batch
);
mnl_nftnl_batch_end
(
h
->
batch
,
seq
++
);
ret
=
mnl_socket_sendto
(
h
->
nl
,
mnl_nlmsg_batch_head
(
h
->
batch
),
mnl_nlmsg_batch_size
(
h
->
batch
));
if
(
ret
<
0
)
goto
err
;
mnl_nlmsg_batch_reset
(
h
->
batch
);
h
->
nl
=
mnl_socket_open
(
NETLINK_NETFILTER
);
if
(
h
->
nl
==
NULL
)
return
-
1
;
ret
=
mnl_socket_recvfrom
(
h
->
nl
,
buf
,
sizeof
(
buf
));
if
(
mnl_socket_bind
(
h
->
nl
,
0
,
MNL_SOCKET_AUTOPID
)
<
0
)
while
(
ret
>
0
)
{
return
-
1
;
ret
=
mnl_cb_run
(
buf
,
ret
,
0
,
mnl_socket_get_portid
(
h
->
nl
),
NULL
,
NULL
);
if
(
ret
<=
0
)
break
;
ret
=
mnl_socket_recvfrom
(
h
->
nl
,
buf
,
sizeof
(
buf
));
h
->
portid
=
mnl_socket_get_portid
(
h
->
nl
);
}
/* We're sending an incomplete message to see if the kernel supports
return
0
;
* set messages in batches. EINVAL means that we sent an incomplete
* message with missing attributes. The kernel just ignores messages
* that we cannot include in the batch.
*/
return
(
ret
==
-
1
&&
errno
==
EINVAL
)
?
true
:
false
;
err:
mnl_nlmsg_batch_reset
(
h
->
batch
);
return
ret
;
}
}
int
nft_init
(
struct
nft_handle
*
h
,
struct
builtin_table
*
t
)
int
nft_init
(
struct
nft_handle
*
h
,
struct
builtin_table
*
t
)
...
@@ -767,35 +737,77 @@ int nft_init(struct nft_handle *h, struct builtin_table *t)
...
@@ -767,35 +737,77 @@ int nft_init(struct nft_handle *h, struct builtin_table *t)
if
(
h
->
nl
==
NULL
)
if
(
h
->
nl
==
NULL
)
return
-
1
;
return
-
1
;
if
(
mnl_socket_bind
(
h
->
nl
,
0
,
MNL_SOCKET_AUTOPID
)
<
0
)
if
(
mnl_socket_bind
(
h
->
nl
,
0
,
MNL_SOCKET_AUTOPID
)
<
0
)
{
mnl_socket_close
(
h
->
nl
);
return
-
1
;
return
-
1
;
}
h
->
portid
=
mnl_socket_get_portid
(
h
->
nl
);
h
->
portid
=
mnl_socket_get_portid
(
h
->
nl
);
h
->
tables
=
t
;
h
->
tables
=
t
;
INIT_LIST_HEAD
(
&
h
->
obj_list
);
INIT_LIST_HEAD
(
&
h
->
obj_list
);
INIT_LIST_HEAD
(
&
h
->
err_list
);
return
0
;
}
h
->
batch
=
mnl_nftnl_batch_alloc
();
static
int
__flush_rule_cache
(
struct
nftnl_rule
*
r
,
void
*
data
)
h
->
batch_support
=
mnl_batch_supported
(
h
);
{
const
char
*
tablename
=
data
;
if
(
!
strcmp
(
nftnl_rule_get_str
(
r
,
NFTNL_RULE_TABLE
),
tablename
))
{
nftnl_rule_list_del
(
r
);
nftnl_rule_free
(
r
);
}
return
0
;
return
0
;
}
}
static
void
flush_rule_cache
(
struct
nft_handle
*
h
)
static
void
flush_rule_cache
(
struct
nft_handle
*
h
,
const
char
*
tablename
)
{
{
if
(
!
h
->
rule_cache
)
if
(
!
h
->
rule_cache
)
return
;
return
;
nftnl_rule_list_free
(
h
->
rule_cache
);
if
(
tablename
)
{
h
->
rule_cache
=
NULL
;
nftnl_rule_list_foreach
(
h
->
rule_cache
,
__flush_rule_cache
,
(
void
*
)
tablename
);
}
else
{
nftnl_rule_list_free
(
h
->
rule_cache
);
h
->
rule_cache
=
NULL
;
}
}
static
int
__flush_chain_cache
(
struct
nftnl_chain
*
c
,
void
*
data
)
{
const
char
*
tablename
=
data
;
if
(
!
strcmp
(
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_TABLE
),
tablename
))
{
nftnl_chain_list_del
(
c
);
nftnl_chain_free
(
c
);
}
return
0
;
}
static
void
flush_chain_cache
(
struct
nft_handle
*
h
,
const
char
*
tablename
)
{
if
(
!
h
->
chain_cache
)
return
;
if
(
tablename
)
{
nftnl_chain_list_foreach
(
h
->
chain_cache
,
__flush_chain_cache
,
(
void
*
)
tablename
);
}
else
{
nftnl_chain_list_free
(
h
->
chain_cache
);
h
->
chain_cache
=
NULL
;
}
}
}
void
nft_fini
(
struct
nft_handle
*
h
)
void
nft_fini
(
struct
nft_handle
*
h
)
{
{
flush_rule_cache
(
h
);
flush_chain_cache
(
h
,
NULL
);
flush_rule_cache
(
h
,
NULL
);
mnl_socket_close
(
h
->
nl
);
mnl_socket_close
(
h
->
nl
);
free
(
mnl_nlmsg_batch_head
(
h
->
batch
));
mnl_nlmsg_batch_stop
(
h
->
batch
);
}
}
static
void
nft_chain_print_debug
(
struct
nftnl_chain
*
c
,
struct
nlmsghdr
*
nlh
)
static
void
nft_chain_print_debug
(
struct
nftnl_chain
*
c
,
struct
nlmsghdr
*
nlh
)
...
@@ -861,10 +873,7 @@ int nft_chain_set(struct nft_handle *h, const char *table,
...
@@ -861,10 +873,7 @@ int nft_chain_set(struct nft_handle *h, const char *table,
if
(
c
==
NULL
)
if
(
c
==
NULL
)
return
0
;
return
0
;
if
(
h
->
batch_support
)
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_UPDATE
,
c
);
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_UPDATE
,
c
);
else
ret
=
nft_chain_add
(
h
,
c
,
0
);
/* the core expects 1 for success and 0 for error */
/* the core expects 1 for success and 0 for error */
return
ret
==
0
?
1
:
0
;
return
ret
==
0
?
1
:
0
;
...
@@ -920,11 +929,36 @@ static int __add_target(struct nftnl_expr *e, struct xt_entry_target *t)
...
@@ -920,11 +929,36 @@ static int __add_target(struct nftnl_expr *e, struct xt_entry_target *t)
return
0
;
return
0
;
}
}
static
int
add_meta_nftrace
(
struct
nftnl_rule
*
r
)
{
struct
nftnl_expr
*
expr
;
expr
=
nftnl_expr_alloc
(
"immediate"
);
if
(
expr
==
NULL
)
return
-
ENOMEM
;
nftnl_expr_set_u32
(
expr
,
NFTNL_EXPR_IMM_DREG
,
NFT_REG32_01
);
nftnl_expr_set_u8
(
expr
,
NFTNL_EXPR_IMM_DATA
,
1
);
nftnl_rule_add_expr
(
r
,
expr
);
expr
=
nftnl_expr_alloc
(
"meta"
);
if
(
expr
==
NULL
)
return
-
ENOMEM
;
nftnl_expr_set_u32
(
expr
,
NFTNL_EXPR_META_KEY
,
NFT_META_NFTRACE
);
nftnl_expr_set_u32
(
expr
,
NFTNL_EXPR_META_SREG
,
NFT_REG32_01
);
nftnl_rule_add_expr
(
r
,
expr
);
return
0
;
}
int
add_target
(
struct
nftnl_rule
*
r
,
struct
xt_entry_target
*
t
)
int
add_target
(
struct
nftnl_rule
*
r
,
struct
xt_entry_target
*
t
)
{
{
struct
nftnl_expr
*
expr
;
struct
nftnl_expr
*
expr
;
int
ret
;
int
ret
;
if
(
strcmp
(
t
->
u
.
user
.
name
,
"TRACE"
)
==
0
)
return
add_meta_nftrace
(
r
);
expr
=
nftnl_expr_alloc
(
"target"
);
expr
=
nftnl_expr_alloc
(
"target"
);
if
(
expr
==
NULL
)
if
(
expr
==
NULL
)
return
-
ENOMEM
;
return
-
ENOMEM
;
...
@@ -1028,13 +1062,21 @@ enum udata_type {
...
@@ -1028,13 +1062,21 @@ enum udata_type {
int
add_comment
(
struct
nftnl_rule
*
r
,
const
char
*
comment
)
int
add_comment
(
struct
nftnl_rule
*
r
,
const
char
*
comment
)
{
{
struct
nftnl_udata_buf
*
udata
;
struct
nftnl_udata_buf
*
udata
;
uint32_t
len
;
if
(
nftnl_rule_get_data
(
r
,
NFTNL_RULE_USERDATA
,
&
len
))
return
-
EALREADY
;
udata
=
nftnl_udata_buf_alloc
(
NFT_USERDATA_MAXLEN
);
udata
=
nftnl_udata_buf_alloc
(
NFT_USERDATA_MAXLEN
);
if
(
!
udata
)
if
(
!
udata
)
return
-
ENOMEM
;
return
-
ENOMEM
;
if
(
strnlen
(
comment
,
255
)
==
255
)
return
-
ENOSPC
;
if
(
!
nftnl_udata_put_strz
(
udata
,
UDATA_TYPE_COMMENT
,
comment
))
if
(
!
nftnl_udata_put_strz
(
udata
,
UDATA_TYPE_COMMENT
,
comment
))
return
-
ENOMEM
;
return
-
ENOMEM
;
nftnl_rule_set_data
(
r
,
NFTNL_RULE_USERDATA
,
nftnl_rule_set_data
(
r
,
NFTNL_RULE_USERDATA
,
nftnl_udata_buf_data
(
udata
),
nftnl_udata_buf_data
(
udata
),
nftnl_udata_buf_len
(
udata
));
nftnl_udata_buf_len
(
udata
));
...
@@ -1106,6 +1148,8 @@ err:
...
@@ -1106,6 +1148,8 @@ err:
return
NULL
;
return
NULL
;
}
}
static
struct
nftnl_rule_list
*
nft_rule_list_get
(
struct
nft_handle
*
h
);
int
int
nft_rule_append
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
nft_rule_append
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
,
uint64_t
handle
,
bool
verbose
)
void
*
data
,
uint64_t
handle
,
bool
verbose
)
...
@@ -1132,7 +1176,10 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
...
@@ -1132,7 +1176,10 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
if
(
batch_rule_add
(
h
,
type
,
r
)
<
0
)
if
(
batch_rule_add
(
h
,
type
,
r
)
<
0
)
nftnl_rule_free
(
r
);
nftnl_rule_free
(
r
);
flush_rule_cache
(
h
);
nft_rule_list_get
(
h
);
nftnl_rule_list_add_tail
(
r
,
h
->
rule_cache
);
return
1
;
return
1
;
}
}
...
@@ -1188,10 +1235,14 @@ err:
...
@@ -1188,10 +1235,14 @@ err:
static
struct
nftnl_chain_list
*
nftnl_chain_list_get
(
struct
nft_handle
*
h
)
static
struct
nftnl_chain_list
*
nftnl_chain_list_get
(
struct
nft_handle
*
h
)
{
{
char
buf
[
MNL_SOCKET_BUFFER_SIZE
];
char
buf
[
16536
];
struct
nlmsghdr
*
nlh
;
struct
nlmsghdr
*
nlh
;
struct
nftnl_chain_list
*
list
;
struct
nftnl_chain_list
*
list
;
int
ret
;
if
(
h
->
chain_cache
)
return
h
->
chain_cache
;
retry:
list
=
nftnl_chain_list_alloc
();
list
=
nftnl_chain_list_alloc
();
if
(
list
==
NULL
)
{
if
(
list
==
NULL
)
{
errno
=
ENOMEM
;
errno
=
ENOMEM
;
...
@@ -1201,7 +1252,14 @@ static struct nftnl_chain_list *nftnl_chain_list_get(struct nft_handle *h)
...
@@ -1201,7 +1252,14 @@ static struct nftnl_chain_list *nftnl_chain_list_get(struct nft_handle *h)
nlh
=
nftnl_chain_nlmsg_build_hdr
(
buf
,
NFT_MSG_GETCHAIN
,
h
->
family
,
nlh
=
nftnl_chain_nlmsg_build_hdr
(
buf
,
NFT_MSG_GETCHAIN
,
h
->
family
,
NLM_F_DUMP
,
h
->
seq
);
NLM_F_DUMP
,
h
->
seq
);
mnl_talk
(
h
,
nlh
,
nftnl_chain_list_cb
,
list
);
ret
=
mnl_talk
(
h
,
nlh
,
nftnl_chain_list_cb
,
list
);
if
(
ret
<
0
&&
errno
==
EINTR
)
{
assert
(
nft_restart
(
h
)
>=
0
);
nftnl_chain_list_free
(
list
);
goto
retry
;
}
h
->
chain_cache
=
list
;
return
list
;
return
list
;
}
}
...
@@ -1262,7 +1320,6 @@ next:
...
@@ -1262,7 +1320,6 @@ next:
}
}
nftnl_chain_list_iter_destroy
(
iter
);
nftnl_chain_list_iter_destroy
(
iter
);
nftnl_chain_list_free
(
list
);
return
1
;
return
1
;
}
}
...
@@ -1291,7 +1348,7 @@ err:
...
@@ -1291,7 +1348,7 @@ err:
static
struct
nftnl_rule_list
*
nft_rule_list_get
(
struct
nft_handle
*
h
)
static
struct
nftnl_rule_list
*
nft_rule_list_get
(
struct
nft_handle
*
h
)
{
{
char
buf
[
MNL_SOCKET_BUFFER_SIZE
];
char
buf
[
16536
];
struct
nlmsghdr
*
nlh
;
struct
nlmsghdr
*
nlh
;
struct
nftnl_rule_list
*
list
;
struct
nftnl_rule_list
*
list
;
int
ret
;
int
ret
;
...
@@ -1299,6 +1356,7 @@ static struct nftnl_rule_list *nft_rule_list_get(struct nft_handle *h)
...
@@ -1299,6 +1356,7 @@ static struct nftnl_rule_list *nft_rule_list_get(struct nft_handle *h)
if
(
h
->
rule_cache
)
if
(
h
->
rule_cache
)
return
h
->
rule_cache
;
return
h
->
rule_cache
;
retry:
list
=
nftnl_rule_list_alloc
();
list
=
nftnl_rule_list_alloc
();
if
(
list
==
NULL
)
if
(
list
==
NULL
)
return
0
;
return
0
;
...
@@ -1308,6 +1366,12 @@ static struct nftnl_rule_list *nft_rule_list_get(struct nft_handle *h)
...
@@ -1308,6 +1366,12 @@ static struct nftnl_rule_list *nft_rule_list_get(struct nft_handle *h)
ret
=
mnl_talk
(
h
,
nlh
,
nftnl_rule_list_cb
,
list
);
ret
=
mnl_talk
(
h
,
nlh
,
nftnl_rule_list_cb
,
list
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
if
(
errno
==
EINTR
)
{
assert
(
nft_restart
(
h
)
>=
0
);
nftnl_rule_list_free
(
list
);
goto
retry
;
}
nftnl_rule_list_free
(
list
);
nftnl_rule_list_free
(
list
);
return
NULL
;
return
NULL
;
}
}
...
@@ -1370,6 +1434,55 @@ __nft_rule_flush(struct nft_handle *h, const char *table, const char *chain)
...
@@ -1370,6 +1434,55 @@ __nft_rule_flush(struct nft_handle *h, const char *table, const char *chain)
nftnl_rule_free
(
r
);
nftnl_rule_free
(
r
);
}
}
struct
chain_user_flush_data
{
struct
nft_handle
*
handle
;
const
char
*
table
;
const
char
*
chain
;
};
static
int
__nft_chain_user_flush
(
struct
nftnl_chain
*
c
,
void
*
data
)
{
const
char
*
table_name
=
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_TABLE
);
const
char
*
chain_name
=
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_NAME
);
struct
chain_user_flush_data
*
d
=
data
;
struct
nft_handle
*
h
=
d
->
handle
;
const
char
*
table
=
d
->
table
;
const
char
*
chain
=
d
->
chain
;
int
ret
;
if
(
strcmp
(
table
,
table_name
)
!=
0
)
return
0
;
if
(
strcmp
(
chain
,
chain_name
)
!=
0
)
return
0
;
if
(
!
nftnl_chain_is_set
(
c
,
NFTNL_CHAIN_HOOKNUM
))
{
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_USER_FLUSH
,
c
);
if
(
ret
<
0
)
return
ret
;
nftnl_chain_list_del
(
c
);
}
return
0
;
}
int
nft_chain_user_flush
(
struct
nft_handle
*
h
,
struct
nftnl_chain_list
*
list
,
const
char
*
table
,
const
char
*
chain
)
{
struct
chain_user_flush_data
d
=
{
.
handle
=
h
,
.
table
=
table
,
.
chain
=
chain
,
};
nft_fn
=
nft_chain_user_flush
;
nftnl_chain_list_foreach
(
list
,
__nft_chain_user_flush
,
&
d
);
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
)
{
{
int
ret
;
int
ret
;
...
@@ -1377,6 +1490,9 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table)
...
@@ -1377,6 +1490,9 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table)
struct
nftnl_chain_list_iter
*
iter
;
struct
nftnl_chain_list_iter
*
iter
;
struct
nftnl_chain
*
c
;
struct
nftnl_chain
*
c
;
if
(
nft_xtables_config_load
(
h
,
XTABLES_CONFIG_DEFAULT
,
0
)
<
0
)
nft_xt_builtin_init
(
h
,
table
);
nft_fn
=
nft_rule_flush
;
nft_fn
=
nft_rule_flush
;
list
=
nftnl_chain_list_get
(
h
);
list
=
nftnl_chain_list_get
(
h
);
...
@@ -1409,12 +1525,9 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table)
...
@@ -1409,12 +1525,9 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table)
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
);
flush_rule_cache
(
h
);
flush_rule_cache
(
h
,
table
);
err:
err:
nftnl_chain_list_free
(
list
);
/* the core expects 1 for success and 0 for error */
/* the core expects 1 for success and 0 for error */
return
ret
==
0
?
1
:
0
;
return
ret
==
0
?
1
:
0
;
}
}
...
@@ -1437,19 +1550,11 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl
...
@@ -1437,19 +1550,11 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl
nftnl_chain_set
(
c
,
NFTNL_CHAIN_TABLE
,
(
char
*
)
table
);
nftnl_chain_set
(
c
,
NFTNL_CHAIN_TABLE
,
(
char
*
)
table
);
nftnl_chain_set
(
c
,
NFTNL_CHAIN_NAME
,
(
char
*
)
chain
);
nftnl_chain_set
(
c
,
NFTNL_CHAIN_NAME
,
(
char
*
)
chain
);
if
(
h
->
batch_support
)
{
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_USER_ADD
,
c
);
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_USER_ADD
,
c
);
}
else
{
char
buf
[
MNL_SOCKET_BUFFER_SIZE
];
struct
nlmsghdr
*
nlh
;
nlh
=
nftnl_chain_nlmsg_build_hdr
(
buf
,
NFT_MSG_NEWCHAIN
,
nft_chain_dump
(
h
);
h
->
family
,
NLM_F_ACK
|
NLM_F_EXCL
,
h
->
seq
);
nftnl_chain_list_add
(
c
,
h
->
chain_cache
);
nftnl_chain_nlmsg_build_payload
(
nlh
,
c
);
nftnl_chain_free
(
c
);
ret
=
mnl_talk
(
h
,
nlh
,
NULL
,
NULL
);
}
/* the core expects 1 for success and 0 for error */
/* the core expects 1 for success and 0 for error */
return
ret
==
0
?
1
:
0
;
return
ret
==
0
?
1
:
0
;
...
@@ -1460,18 +1565,6 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl
...
@@ -1460,18 +1565,6 @@ 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
static
int
__nft_chain_del
(
struct
nft_handle
*
h
,
struct
nftnl_chain
*
c
)
{
char
buf
[
MNL_SOCKET_BUFFER_SIZE
];
struct
nlmsghdr
*
nlh
;
nlh
=
nftnl_chain_nlmsg_build_hdr
(
buf
,
NFT_MSG_DELCHAIN
,
h
->
family
,
NLM_F_NONREC
|
NLM_F_ACK
,
h
->
seq
);
nftnl_chain_nlmsg_build_payload
(
nlh
,
c
);
return
mnl_talk
(
h
,
nlh
,
NULL
,
NULL
);
}
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
)
{
{
struct
nftnl_chain_list
*
list
;
struct
nftnl_chain_list
*
list
;
...
@@ -1480,6 +1573,8 @@ int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *tabl
...
@@ -1480,6 +1573,8 @@ int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *tabl
int
ret
=
0
;
int
ret
=
0
;
int
deleted_ctr
=
0
;
int
deleted_ctr
=
0
;
nft_fn
=
nft_chain_user_del
;
list
=
nftnl_chain_list_get
(
h
);
list
=
nftnl_chain_list_get
(
h
);
if
(
list
==
NULL
)
if
(
list
==
NULL
)
goto
err
;
goto
err
;
...
@@ -1505,15 +1600,13 @@ int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *tabl
...
@@ -1505,15 +1600,13 @@ 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
(
h
->
batch_support
)
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_USER_DEL
,
c
);
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_USER_DEL
,
c
);
else
ret
=
__nft_chain_del
(
h
,
c
);
if
(
ret
<
0
)
if
(
ret
<
0
)
break
;
break
;
deleted_ctr
++
;
deleted_ctr
++
;
nftnl_chain_list_del
(
c
);
if
(
chain
!=
NULL
)
if
(
chain
!=
NULL
)
break
;
break
;
...
@@ -1523,11 +1616,9 @@ next:
...
@@ -1523,11 +1616,9 @@ next:
nftnl_chain_list_iter_destroy
(
iter
);
nftnl_chain_list_iter_destroy
(
iter
);
err:
err:
if
(
!
h
->
batch_support
)
nftnl_chain_list_free
(
list
);
/* chain not found */
/* chain not found */
if
(
deleted_ctr
==
0
)
{
if
(
chain
!=
NULL
&&
deleted_ctr
==
0
)
{
ret
=
-
1
;
ret
=
-
1
;
errno
=
ENOENT
;
errno
=
ENOENT
;
}
}
...
@@ -1614,19 +1705,7 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain,
...
@@ -1614,19 +1705,7 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain,
nftnl_chain_set
(
c
,
NFTNL_CHAIN_NAME
,
(
char
*
)
newname
);
nftnl_chain_set
(
c
,
NFTNL_CHAIN_NAME
,
(
char
*
)
newname
);
nftnl_chain_set_u64
(
c
,
NFTNL_CHAIN_HANDLE
,
handle
);
nftnl_chain_set_u64
(
c
,
NFTNL_CHAIN_HANDLE
,
handle
);
if
(
h
->
batch_support
)
{
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_RENAME
,
c
);
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_RENAME
,
c
);
}
else
{
char
buf
[
MNL_SOCKET_BUFFER_SIZE
];
struct
nlmsghdr
*
nlh
;
nlh
=
nftnl_chain_nlmsg_build_hdr
(
buf
,
NFT_MSG_NEWCHAIN
,
h
->
family
,
NLM_F_ACK
,
h
->
seq
);
nftnl_chain_nlmsg_build_payload
(
nlh
,
c
);
nftnl_chain_free
(
c
);
ret
=
mnl_talk
(
h
,
nlh
,
NULL
,
NULL
);
}
/* the core expects 1 for success and 0 for error */
/* the core expects 1 for success and 0 for error */
return
ret
==
0
?
1
:
0
;
return
ret
==
0
?
1
:
0
;
...
@@ -1655,10 +1734,12 @@ err:
...
@@ -1655,10 +1734,12 @@ err:
static
struct
nftnl_table_list
*
nftnl_table_list_get
(
struct
nft_handle
*
h
)
static
struct
nftnl_table_list
*
nftnl_table_list_get
(
struct
nft_handle
*
h
)
{
{
char
buf
[
MNL_SOCKET_BUFFER_SIZE
];
char
buf
[
16536
];
struct
nlmsghdr
*
nlh
;
struct
nlmsghdr
*
nlh
;
struct
nftnl_table_list
*
list
;
struct
nftnl_table_list
*
list
;
int
ret
;
retry:
list
=
nftnl_table_list_alloc
();
list
=
nftnl_table_list_alloc
();
if
(
list
==
NULL
)
if
(
list
==
NULL
)
return
0
;
return
0
;
...
@@ -1666,7 +1747,12 @@ static struct nftnl_table_list *nftnl_table_list_get(struct nft_handle *h)
...
@@ -1666,7 +1747,12 @@ static struct nftnl_table_list *nftnl_table_list_get(struct nft_handle *h)
nlh
=
nftnl_rule_nlmsg_build_hdr
(
buf
,
NFT_MSG_GETTABLE
,
h
->
family
,
nlh
=
nftnl_rule_nlmsg_build_hdr
(
buf
,
NFT_MSG_GETTABLE
,
h
->
family
,
NLM_F_DUMP
,
h
->
seq
);
NLM_F_DUMP
,
h
->
seq
);
mnl_talk
(
h
,
nlh
,
nftnl_table_list_cb
,
list
);
ret
=
mnl_talk
(
h
,
nlh
,
nftnl_table_list_cb
,
list
);
if
(
ret
<
0
&&
errno
==
EINTR
)
{
assert
(
nft_restart
(
h
)
>=
0
);
nftnl_table_list_free
(
list
);
goto
retry
;
}
return
list
;
return
list
;
}
}
...
@@ -1707,20 +1793,17 @@ int nft_for_each_table(struct nft_handle *h,
...
@@ -1707,20 +1793,17 @@ int nft_for_each_table(struct nft_handle *h,
int
(
*
func
)(
struct
nft_handle
*
h
,
const
char
*
tablename
,
bool
counters
),
int
(
*
func
)(
struct
nft_handle
*
h
,
const
char
*
tablename
,
bool
counters
),
bool
counters
)
bool
counters
)
{
{
int
ret
=
1
;
struct
nftnl_table_list
*
list
;
struct
nftnl_table_list
*
list
;
struct
nftnl_table_list_iter
*
iter
;
struct
nftnl_table_list_iter
*
iter
;
struct
nftnl_table
*
t
;
struct
nftnl_table
*
t
;
list
=
nftnl_table_list_get
(
h
);
list
=
nftnl_table_list_get
(
h
);
if
(
list
==
NULL
)
{
if
(
list
==
NULL
)
ret
=
0
;
return
-
1
;
goto
err
;
}
iter
=
nftnl_table_list_iter_create
(
list
);
iter
=
nftnl_table_list_iter_create
(
list
);
if
(
iter
==
NULL
)
if
(
iter
==
NULL
)
return
0
;
return
-
1
;
t
=
nftnl_table_list_iter_next
(
iter
);
t
=
nftnl_table_list_iter_next
(
iter
);
while
(
t
!=
NULL
)
{
while
(
t
!=
NULL
)
{
...
@@ -1733,43 +1816,85 @@ int nft_for_each_table(struct nft_handle *h,
...
@@ -1733,43 +1816,85 @@ int nft_for_each_table(struct nft_handle *h,
}
}
nftnl_table_list_free
(
list
);
nftnl_table_list_free
(
list
);
return
0
;
}
err:
static
int
__nft_table_flush
(
struct
nft_handle
*
h
,
const
char
*
table
)
/* the core expects 1 for success and 0 for error */
{
return
ret
==
0
?
1
:
0
;
struct
builtin_table
*
_t
;
struct
nftnl_table
*
t
;
t
=
nftnl_table_alloc
();
if
(
t
==
NULL
)
return
-
1
;
nftnl_table_set_str
(
t
,
NFTNL_TABLE_NAME
,
table
);
batch_table_add
(
h
,
NFT_COMPAT_TABLE_FLUSH
,
t
);
_t
=
nft_table_builtin_find
(
h
,
table
);
assert
(
t
);
_t
->
initialized
=
false
;
flush_chain_cache
(
h
,
table
);
flush_rule_cache
(
h
,
table
);
return
0
;
}
}
int
nft_table_purge_chains
(
struct
nft_handle
*
h
,
const
char
*
this_table
,
int
nft_table_flush
(
struct
nft_handle
*
h
,
const
char
*
table
)
struct
nftnl_chain_list
*
chain_list
)
{
{
struct
nftnl_chain_list_iter
*
iter
;
struct
nftnl_table_list_iter
*
iter
;
struct
nftnl_chain
*
chain_obj
;
struct
nftnl_table_list
*
list
;
struct
nftnl_table
*
t
;
int
ret
=
0
;
iter
=
nftnl_chain_list_iter_create
(
chain_list
);
nft_fn
=
nft_table_flush
;
if
(
iter
==
NULL
)
return
0
;
chain_obj
=
nftnl_chain_list_iter_next
(
iter
);
list
=
nftnl_table_list_get
(
h
);
while
(
chain_obj
!=
NULL
)
{
if
(
list
==
NULL
)
{
const
char
*
table
=
ret
=
-
1
;
nftnl_chain_get_str
(
chain_obj
,
NFTNL_CHAIN_TABLE
);
goto
err_out
;
}
if
(
strcmp
(
this_table
,
table
)
!=
0
)
iter
=
nftnl_table_list_iter_create
(
list
);
goto
next
;
if
(
iter
==
NULL
)
{
ret
=
-
1
;
goto
err_table_list
;
}
t
=
nftnl_table_list_iter_next
(
iter
);
while
(
t
!=
NULL
)
{
const
char
*
table_name
=
nftnl_table_get_str
(
t
,
NFTNL_TABLE_NAME
);
if
(
nft_chain_builtin
(
chain_obj
)
)
if
(
strcmp
(
table_name
,
table
)
!=
0
)
goto
next
;
goto
next
;
if
(
__nft_chain_del
(
h
,
chain_obj
)
<
0
)
{
ret
=
__nft_table_flush
(
h
,
table
);
if
(
errno
!=
EBUSY
)
if
(
ret
<
0
)
return
-
1
;
goto
err_table_iter
;
}
next:
next:
chain_obj
=
nftnl_
chain
_list_iter_next
(
iter
);
t
=
nftnl_
table
_list_iter_next
(
iter
);
}
}
nftnl_chain_list_iter_destroy
(
iter
);
return
0
;
h
->
rule_cache
=
nftnl_rule_list_alloc
();
if
(
h
->
rule_cache
==
NULL
)
return
-
1
;
err_table_iter:
nftnl_table_list_iter_destroy
(
iter
);
err_table_list:
nftnl_table_list_free
(
list
);
err_out:
/* the core expects 1 for success and 0 for error */
return
ret
==
0
?
1
:
0
;
}
void
nft_table_new
(
struct
nft_handle
*
h
,
const
char
*
table
)
{
if
(
nft_xtables_config_load
(
h
,
XTABLES_CONFIG_DEFAULT
,
0
)
<
0
)
nft_xt_builtin_init
(
h
,
table
);
}
}
static
int
__nft_rule_del
(
struct
nft_handle
*
h
,
struct
nftnl_rule_list
*
list
,
static
int
__nft_rule_del
(
struct
nft_handle
*
h
,
struct
nftnl_rule_list
*
list
,
...
@@ -1874,12 +1999,10 @@ int nft_rule_delete(struct nft_handle *h, const char *chain,
...
@@ -1874,12 +1999,10 @@ int nft_rule_delete(struct nft_handle *h, const char *chain,
}
else
}
else
errno
=
ENOENT
;
errno
=
ENOENT
;
flush_rule_cache
(
h
);
return
ret
;
return
ret
;
}
}
static
int
static
struct
nftnl_rule
*
nft_rule_add
(
struct
nft_handle
*
h
,
const
char
*
chain
,
nft_rule_add
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
struct
iptables_command_state
*
cs
,
const
char
*
table
,
struct
iptables_command_state
*
cs
,
uint64_t
handle
,
bool
verbose
)
uint64_t
handle
,
bool
verbose
)
...
@@ -1888,25 +2011,24 @@ nft_rule_add(struct nft_handle *h, const char *chain,
...
@@ -1888,25 +2011,24 @@ nft_rule_add(struct nft_handle *h, const char *chain,
r
=
nft_rule_new
(
h
,
chain
,
table
,
cs
);
r
=
nft_rule_new
(
h
,
chain
,
table
,
cs
);
if
(
r
==
NULL
)
if
(
r
==
NULL
)
return
0
;
return
NULL
;
if
(
handle
>
0
)
if
(
handle
>
0
)
nftnl_rule_set_u64
(
r
,
NFTNL_RULE_POSITION
,
handle
);
nftnl_rule_set_u64
(
r
,
NFTNL_RULE_POSITION
,
handle
);
if
(
batch_rule_add
(
h
,
NFT_COMPAT_RULE_INSERT
,
r
)
<
0
)
{
if
(
batch_rule_add
(
h
,
NFT_COMPAT_RULE_INSERT
,
r
)
<
0
)
{
nftnl_rule_free
(
r
);
nftnl_rule_free
(
r
);
return
0
;
return
NULL
;
}
}
flush_rule_cache
(
h
);
return
r
;
return
1
;
}
}
int
nft_rule_insert
(
struct
nft_handle
*
h
,
const
char
*
chain
,
int
nft_rule_insert
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
,
int
rulenum
,
bool
verbose
)
const
char
*
table
,
void
*
data
,
int
rulenum
,
bool
verbose
)
{
{
struct
nftnl_rule
*
r
,
*
new_rule
;
struct
nftnl_rule_list
*
list
;
struct
nftnl_rule_list
*
list
;
struct
nftnl_rule
*
r
;
uint64_t
handle
=
0
;
uint64_t
handle
=
0
;
/* If built-in chains don't exist for this table, create them */
/* If built-in chains don't exist for this table, create them */
...
@@ -1927,11 +2049,9 @@ int nft_rule_insert(struct nft_handle *h, const char *chain,
...
@@ -1927,11 +2049,9 @@ int nft_rule_insert(struct nft_handle *h, const char *chain,
*/
*/
r
=
nft_rule_find
(
h
,
list
,
chain
,
table
,
data
,
r
=
nft_rule_find
(
h
,
list
,
chain
,
table
,
data
,
rulenum
-
1
);
rulenum
-
1
);
if
(
r
!=
NULL
)
{
if
(
r
!=
NULL
)
flush_rule_cache
(
h
);
return
nft_rule_append
(
h
,
chain
,
table
,
data
,
return
nft_rule_append
(
h
,
chain
,
table
,
data
,
0
,
verbose
);
0
,
verbose
);
}
errno
=
ENOENT
;
errno
=
ENOENT
;
goto
err
;
goto
err
;
...
@@ -1939,13 +2059,21 @@ int nft_rule_insert(struct nft_handle *h, const char *chain,
...
@@ -1939,13 +2059,21 @@ int nft_rule_insert(struct nft_handle *h, const char *chain,
handle
=
nftnl_rule_get_u64
(
r
,
NFTNL_RULE_HANDLE
);
handle
=
nftnl_rule_get_u64
(
r
,
NFTNL_RULE_HANDLE
);
DEBUGP
(
"adding after rule handle %"
PRIu64
"
\n
"
,
handle
);
DEBUGP
(
"adding after rule handle %"
PRIu64
"
\n
"
,
handle
);
}
else
{
flush
_rule_
cache
(
h
);
nft
_rule_
list_get
(
h
);
}
}
return
nft_rule_add
(
h
,
chain
,
table
,
data
,
handle
,
verbose
);
new_rule
=
nft_rule_add
(
h
,
chain
,
table
,
data
,
handle
,
verbose
);
if
(
!
new_rule
)
goto
err
;
if
(
handle
)
nftnl_rule_list_insert_at
(
new_rule
,
r
);
else
nftnl_rule_list_add
(
new_rule
,
h
->
rule_cache
);
return
1
;
err:
err:
flush_rule_cache
(
h
);
return
0
;
return
0
;
}
}
...
@@ -1973,8 +2101,6 @@ int nft_rule_delete_num(struct nft_handle *h, const char *chain,
...
@@ -1973,8 +2101,6 @@ int nft_rule_delete_num(struct nft_handle *h, const char *chain,
}
else
}
else
errno
=
ENOENT
;
errno
=
ENOENT
;
flush_rule_cache
(
h
);
return
ret
;
return
ret
;
}
}
...
@@ -1997,14 +2123,14 @@ int nft_rule_replace(struct nft_handle *h, const char *chain,
...
@@ -1997,14 +2123,14 @@ int nft_rule_replace(struct nft_handle *h, const char *chain,
(
unsigned
long
long
)
(
unsigned
long
long
)
nftnl_rule_get_u64
(
r
,
NFTNL_RULE_HANDLE
));
nftnl_rule_get_u64
(
r
,
NFTNL_RULE_HANDLE
));
nftnl_rule_list_del
(
r
);
ret
=
nft_rule_append
(
h
,
chain
,
table
,
data
,
ret
=
nft_rule_append
(
h
,
chain
,
table
,
data
,
nftnl_rule_get_u64
(
r
,
NFTNL_RULE_HANDLE
),
nftnl_rule_get_u64
(
r
,
NFTNL_RULE_HANDLE
),
verbose
);
verbose
);
}
else
}
else
errno
=
ENOENT
;
errno
=
ENOENT
;
flush_rule_cache
(
h
);
return
ret
;
return
ret
;
}
}
...
@@ -2084,6 +2210,11 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
...
@@ -2084,6 +2210,11 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
ops
=
nft_family_ops_lookup
(
h
->
family
);
ops
=
nft_family_ops_lookup
(
h
->
family
);
if
(
!
nft_is_table_compatible
(
h
,
table
))
{
xtables_error
(
OTHER_PROBLEM
,
"table `%s' is incompatible, use 'nft' tool.
\n
"
,
table
);
return
0
;
}
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_firewall
);
...
@@ -2144,8 +2275,6 @@ next:
...
@@ -2144,8 +2275,6 @@ next:
nftnl_chain_list_iter_destroy
(
iter
);
nftnl_chain_list_iter_destroy
(
iter
);
err:
err:
nftnl_chain_list_free
(
list
);
return
1
;
return
1
;
}
}
...
@@ -2249,8 +2378,6 @@ next:
...
@@ -2249,8 +2378,6 @@ next:
nftnl_chain_list_iter_destroy
(
iter
);
nftnl_chain_list_iter_destroy
(
iter
);
err:
err:
nftnl_chain_list_free
(
list
);
return
ret
;
return
ret
;
}
}
...
@@ -2284,8 +2411,6 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain,
...
@@ -2284,8 +2411,6 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain,
false
);
false
);
error:
error:
flush_rule_cache
(
h
);
return
ret
;
return
ret
;
}
}
...
@@ -2295,10 +2420,9 @@ static void nft_compat_table_batch_add(struct nft_handle *h, uint16_t type,
...
@@ -2295,10 +2420,9 @@ static void nft_compat_table_batch_add(struct nft_handle *h, uint16_t type,
{
{
struct
nlmsghdr
*
nlh
;
struct
nlmsghdr
*
nlh
;
nlh
=
nftnl_table_nlmsg_build_hdr
(
mnl_nlmsg_batch_current
(
h
->
batch
),
nlh
=
nftnl_table_nlmsg_build_hdr
(
nftnl_batch_buffer
(
h
->
batch
),
type
,
h
->
family
,
flags
,
seq
);
type
,
h
->
family
,
flags
,
seq
);
nftnl_table_nlmsg_build_payload
(
nlh
,
table
);
nftnl_table_nlmsg_build_payload
(
nlh
,
table
);
nftnl_table_free
(
table
);
}
}
static
void
nft_compat_chain_batch_add
(
struct
nft_handle
*
h
,
uint16_t
type
,
static
void
nft_compat_chain_batch_add
(
struct
nft_handle
*
h
,
uint16_t
type
,
...
@@ -2307,11 +2431,10 @@ static void nft_compat_chain_batch_add(struct nft_handle *h, uint16_t type,
...
@@ -2307,11 +2431,10 @@ static void nft_compat_chain_batch_add(struct nft_handle *h, uint16_t type,
{
{
struct
nlmsghdr
*
nlh
;
struct
nlmsghdr
*
nlh
;
nlh
=
nftnl_chain_nlmsg_build_hdr
(
mnl_nlmsg_batch_current
(
h
->
batch
),
nlh
=
nftnl_chain_nlmsg_build_hdr
(
nftnl_batch_buffer
(
h
->
batch
),
type
,
h
->
family
,
flags
,
seq
);
type
,
h
->
family
,
flags
,
seq
);
nftnl_chain_nlmsg_build_payload
(
nlh
,
chain
);
nftnl_chain_nlmsg_build_payload
(
nlh
,
chain
);
nft_chain_print_debug
(
chain
,
nlh
);
nft_chain_print_debug
(
chain
,
nlh
);
nftnl_chain_free
(
chain
);
}
}
static
void
nft_compat_rule_batch_add
(
struct
nft_handle
*
h
,
uint16_t
type
,
static
void
nft_compat_rule_batch_add
(
struct
nft_handle
*
h
,
uint16_t
type
,
...
@@ -2320,97 +2443,160 @@ static void nft_compat_rule_batch_add(struct nft_handle *h, uint16_t type,
...
@@ -2320,97 +2443,160 @@ static void nft_compat_rule_batch_add(struct nft_handle *h, uint16_t type,
{
{
struct
nlmsghdr
*
nlh
;
struct
nlmsghdr
*
nlh
;
nlh
=
nftnl_rule_nlmsg_build_hdr
(
mnl_nlmsg_batch_current
(
h
->
batch
),
nlh
=
nftnl_rule_nlmsg_build_hdr
(
nftnl_batch_buffer
(
h
->
batch
),
type
,
h
->
family
,
flags
,
seq
);
type
,
h
->
family
,
flags
,
seq
);
nftnl_rule_nlmsg_build_payload
(
nlh
,
rule
);
nftnl_rule_nlmsg_build_payload
(
nlh
,
rule
);
nft_rule_print_debug
(
rule
,
nlh
);
nft_rule_print_debug
(
rule
,
nlh
);
nftnl_rule_free
(
rule
);
}
static
void
batch_obj_del
(
struct
nft_handle
*
h
,
struct
obj_update
*
o
)
{
switch
(
o
->
type
)
{
case
NFT_COMPAT_TABLE_ADD
:
case
NFT_COMPAT_TABLE_FLUSH
:
nftnl_table_free
(
o
->
table
);
break
;
case
NFT_COMPAT_CHAIN_ADD
:
case
NFT_COMPAT_CHAIN_USER_ADD
:
case
NFT_COMPAT_CHAIN_USER_DEL
:
break
;
case
NFT_COMPAT_CHAIN_USER_FLUSH
:
case
NFT_COMPAT_CHAIN_UPDATE
:
case
NFT_COMPAT_CHAIN_RENAME
:
nftnl_chain_free
(
o
->
chain
);
break
;
case
NFT_COMPAT_RULE_APPEND
:
case
NFT_COMPAT_RULE_INSERT
:
case
NFT_COMPAT_RULE_REPLACE
:
case
NFT_COMPAT_RULE_DELETE
:
break
;
case
NFT_COMPAT_RULE_FLUSH
:
nftnl_rule_free
(
o
->
rule
);
break
;
}
h
->
obj_list_num
--
;
list_del
(
&
o
->
head
);
free
(
o
);
}
}
static
int
nft_action
(
struct
nft_handle
*
h
,
int
action
)
static
int
nft_action
(
struct
nft_handle
*
h
,
int
action
)
{
{
struct
obj_update
*
n
,
*
tmp
;
struct
obj_update
*
n
,
*
tmp
;
struct
mnl_err
*
err
,
*
ne
;
unsigned
int
buflen
,
i
,
len
;
bool
show_errors
=
true
;
char
errmsg
[
1024
];
uint32_t
seq
=
1
;
uint32_t
seq
=
1
;
int
ret
=
0
;
int
ret
=
0
;
mnl_nftnl_batch_begin
(
h
->
batch
,
seq
++
);
h
->
batch
=
mnl_batch_init
(
);
list_for_each_entry_safe
(
n
,
tmp
,
&
h
->
obj_list
,
head
)
{
mnl_batch_begin
(
h
->
batch
,
seq
++
);
list_for_each_entry
(
n
,
&
h
->
obj_list
,
head
)
{
n
->
seq
=
seq
++
;
switch
(
n
->
type
)
{
switch
(
n
->
type
)
{
case
NFT_COMPAT_TABLE_ADD
:
case
NFT_COMPAT_TABLE_ADD
:
nft_compat_table_batch_add
(
h
,
NFT_MSG_NEWTABLE
,
nft_compat_table_batch_add
(
h
,
NFT_MSG_NEWTABLE
,
NLM_F_CREATE
,
seq
++
,
NLM_F_CREATE
,
n
->
seq
,
n
->
table
);
n
->
table
);
break
;
break
;
case
NFT_COMPAT_TABLE_FLUSH
:
nft_compat_table_batch_add
(
h
,
NFT_MSG_DELTABLE
,
0
,
n
->
seq
,
n
->
table
);
break
;
case
NFT_COMPAT_CHAIN_ADD
:
case
NFT_COMPAT_CHAIN_ADD
:
nft_compat_chain_batch_add
(
h
,
NFT_MSG_NEWCHAIN
,
nft_compat_chain_batch_add
(
h
,
NFT_MSG_NEWCHAIN
,
NLM_F_CREATE
,
seq
++
,
NLM_F_CREATE
,
n
->
seq
,
n
->
chain
);
n
->
chain
);
break
;
break
;
case
NFT_COMPAT_CHAIN_USER_ADD
:
case
NFT_COMPAT_CHAIN_USER_ADD
:
nft_compat_chain_batch_add
(
h
,
NFT_MSG_NEWCHAIN
,
nft_compat_chain_batch_add
(
h
,
NFT_MSG_NEWCHAIN
,
NLM_F_EXCL
,
seq
++
,
NLM_F_EXCL
,
n
->
seq
,
n
->
chain
);
n
->
chain
);
break
;
break
;
case
NFT_COMPAT_CHAIN_USER_DEL
:
case
NFT_COMPAT_CHAIN_USER_DEL
:
nft_compat_chain_batch_add
(
h
,
NFT_MSG_DELCHAIN
,
nft_compat_chain_batch_add
(
h
,
NFT_MSG_DELCHAIN
,
NLM_F_NONREC
,
seq
++
,
NLM_F_NONREC
,
n
->
seq
,
n
->
chain
);
break
;
case
NFT_COMPAT_CHAIN_USER_FLUSH
:
nft_compat_chain_batch_add
(
h
,
NFT_MSG_DELCHAIN
,
0
,
n
->
seq
,
n
->
chain
);
n
->
chain
);
break
;
break
;
case
NFT_COMPAT_CHAIN_UPDATE
:
case
NFT_COMPAT_CHAIN_UPDATE
:
nft_compat_chain_batch_add
(
h
,
NFT_MSG_NEWCHAIN
,
nft_compat_chain_batch_add
(
h
,
NFT_MSG_NEWCHAIN
,
h
->
restore
?
h
->
restore
?
NLM_F_CREATE
:
0
,
NLM_F_CREATE
:
0
,
seq
++
,
n
->
chain
);
n
->
seq
,
n
->
chain
);
break
;
break
;
case
NFT_COMPAT_CHAIN_RENAME
:
case
NFT_COMPAT_CHAIN_RENAME
:
nft_compat_chain_batch_add
(
h
,
NFT_MSG_NEWCHAIN
,
0
,
nft_compat_chain_batch_add
(
h
,
NFT_MSG_NEWCHAIN
,
0
,
seq
++
,
n
->
chain
);
n
->
seq
,
n
->
chain
);
break
;
break
;
case
NFT_COMPAT_RULE_APPEND
:
case
NFT_COMPAT_RULE_APPEND
:
nft_compat_rule_batch_add
(
h
,
NFT_MSG_NEWRULE
,
nft_compat_rule_batch_add
(
h
,
NFT_MSG_NEWRULE
,
NLM_F_CREATE
|
NLM_F_APPEND
,
NLM_F_CREATE
|
NLM_F_APPEND
,
seq
++
,
n
->
rule
);
n
->
seq
,
n
->
rule
);
break
;
break
;
case
NFT_COMPAT_RULE_INSERT
:
case
NFT_COMPAT_RULE_INSERT
:
nft_compat_rule_batch_add
(
h
,
NFT_MSG_NEWRULE
,
nft_compat_rule_batch_add
(
h
,
NFT_MSG_NEWRULE
,
NLM_F_CREATE
,
seq
++
,
NLM_F_CREATE
,
n
->
seq
,
n
->
rule
);
n
->
rule
);
break
;
break
;
case
NFT_COMPAT_RULE_REPLACE
:
case
NFT_COMPAT_RULE_REPLACE
:
nft_compat_rule_batch_add
(
h
,
NFT_MSG_NEWRULE
,
nft_compat_rule_batch_add
(
h
,
NFT_MSG_NEWRULE
,
NLM_F_CREATE
|
NLM_F_REPLACE
,
NLM_F_CREATE
|
NLM_F_REPLACE
,
seq
++
,
n
->
rule
);
n
->
seq
,
n
->
rule
);
break
;
break
;
case
NFT_COMPAT_RULE_DELETE
:
case
NFT_COMPAT_RULE_DELETE
:
case
NFT_COMPAT_RULE_FLUSH
:
case
NFT_COMPAT_RULE_FLUSH
:
nft_compat_rule_batch_add
(
h
,
NFT_MSG_DELRULE
,
0
,
nft_compat_rule_batch_add
(
h
,
NFT_MSG_DELRULE
,
0
,
seq
++
,
n
->
rule
);
n
->
seq
,
n
->
rule
);
break
;
break
;
}
}
h
->
obj_list_num
--
;
mnl_nft_batch_continue
(
h
->
batch
);
list_del
(
&
n
->
head
);
free
(
n
);
if
(
!
mnl_nlmsg_batch_next
(
h
->
batch
))
h
->
batch
=
mnl_nftnl_batch_page_add
(
h
->
batch
);
}
}
switch
(
action
)
{
switch
(
action
)
{
case
NFT_COMPAT_COMMIT
:
case
NFT_COMPAT_COMMIT
:
mnl_
nftnl_
batch_end
(
h
->
batch
,
seq
++
);
mnl_batch_end
(
h
->
batch
,
seq
++
);
break
;
break
;
case
NFT_COMPAT_ABORT
:
case
NFT_COMPAT_ABORT
:
break
;
break
;
}
}
if
(
!
mnl_nlmsg_batch_is_empty
(
h
->
batch
))
ret
=
mnl_batch_talk
(
h
->
nl
,
h
->
batch
,
&
h
->
err_list
);
h
->
batch
=
mnl_nftnl_batch_page_add
(
h
->
batch
);
i
=
0
;
buflen
=
sizeof
(
errmsg
);
ret
=
mnl_nftnl_batch_talk
(
h
);
list_for_each_entry_safe
(
n
,
tmp
,
&
h
->
obj_list
,
head
)
{
list_for_each_entry_safe
(
err
,
ne
,
&
h
->
err_list
,
head
)
{
if
(
err
->
seqnum
>
n
->
seq
)
break
;
mnl_nlmsg_batch_reset
(
h
->
batch
);
if
(
err
->
seqnum
==
n
->
seq
&&
show_errors
)
{
if
(
n
->
error
.
lineno
==
0
)
show_errors
=
false
;
len
=
mnl_append_error
(
h
,
n
,
err
,
errmsg
+
i
,
buflen
);
if
(
len
>
0
&&
len
<=
buflen
)
{
buflen
-=
len
;
i
+=
len
;
}
}
mnl_err_list_free
(
err
);
}
batch_obj_del
(
h
,
n
);
}
mnl_batch_reset
(
h
->
batch
);
if
(
i
)
xtables_error
(
RESOURCE_PROBLEM
,
"%s"
,
errmsg
);
return
ret
==
0
?
1
:
0
;
return
ret
==
0
?
1
:
0
;
}
}
...
@@ -2428,16 +2614,29 @@ int nft_abort(struct nft_handle *h)
...
@@ -2428,16 +2614,29 @@ int nft_abort(struct nft_handle *h)
int
nft_compatible_revision
(
const
char
*
name
,
uint8_t
rev
,
int
opt
)
int
nft_compatible_revision
(
const
char
*
name
,
uint8_t
rev
,
int
opt
)
{
{
struct
mnl_socket
*
nl
;
struct
mnl_socket
*
nl
;
char
buf
[
MNL_SOCKET_BUFFER_SIZE
];
char
buf
[
16536
];
struct
nlmsghdr
*
nlh
;
struct
nlmsghdr
*
nlh
;
uint32_t
portid
,
seq
,
type
;
uint32_t
portid
,
seq
,
type
=
0
;
uint32_t
pf
=
AF_INET
;
int
ret
=
0
;
int
ret
=
0
;
if
(
opt
==
IPT_SO_GET_REVISION_MATCH
||
switch
(
opt
)
{
opt
==
IP6T_SO_GET_REVISION_MATCH
)
case
IPT_SO_GET_REVISION_MATCH
:
type
=
0
;
break
;
else
case
IP6T_SO_GET_REVISION_MATCH
:
pf
=
AF_INET6
;
break
;
case
IPT_SO_GET_REVISION_TARGET
:
type
=
1
;
break
;
case
IP6T_SO_GET_REVISION_TARGET
:
type
=
1
;
type
=
1
;
pf
=
AF_INET6
;
break
;
default:
/* No revision support (arp, ebtables), assume latest version ok */
return
1
;
}
nlh
=
mnl_nlmsg_put_header
(
buf
);
nlh
=
mnl_nlmsg_put_header
(
buf
);
nlh
->
nlmsg_type
=
(
NFNL_SUBSYS_NFT_COMPAT
<<
8
)
|
NFNL_MSG_COMPAT_GET
;
nlh
->
nlmsg_type
=
(
NFNL_SUBSYS_NFT_COMPAT
<<
8
)
|
NFNL_MSG_COMPAT_GET
;
...
@@ -2445,7 +2644,7 @@ int nft_compatible_revision(const char *name, uint8_t rev, int opt)
...
@@ -2445,7 +2644,7 @@ int nft_compatible_revision(const char *name, uint8_t rev, int opt)
nlh
->
nlmsg_seq
=
seq
=
time
(
NULL
);
nlh
->
nlmsg_seq
=
seq
=
time
(
NULL
);
struct
nfgenmsg
*
nfg
=
mnl_nlmsg_put_extra_header
(
nlh
,
sizeof
(
*
nfg
));
struct
nfgenmsg
*
nfg
=
mnl_nlmsg_put_extra_header
(
nlh
,
sizeof
(
*
nfg
));
nfg
->
nfgen_family
=
AF_INET
;
nfg
->
nfgen_family
=
pf
;
nfg
->
version
=
NFNETLINK_V0
;
nfg
->
version
=
NFNETLINK_V0
;
nfg
->
res_id
=
0
;
nfg
->
res_id
=
0
;
...
@@ -2498,19 +2697,18 @@ const char *nft_strerror(int err)
...
@@ -2498,19 +2697,18 @@ const char *nft_strerror(int err)
{
nft_chain_user_del
,
EMLINK
,
{
nft_chain_user_del
,
EMLINK
,
"Can't delete chain with references left"
},
"Can't delete chain with references left"
},
{
nft_chain_user_add
,
EEXIST
,
"Chain already exists"
},
{
nft_chain_user_add
,
EEXIST
,
"Chain already exists"
},
{
nft_rule_
add
,
E2BIG
,
"Index of insertion too big"
},
{
nft_rule_
insert
,
ENOENT
,
"Index of insertion too big"
},
{
nft_rule_check
,
ENOENT
,
"Bad rule (does a matching rule exist in that chain?)"
},
{
nft_rule_check
,
ENOENT
,
"Bad rule (does a matching rule exist in that chain?)"
},
{
nft_rule_replace
,
ENOENT
,
"Index of replacement too big"
},
{
nft_rule_replace
,
ENOENT
,
"Index of replacement too big"
},
{
nft_rule_delete_num
,
E
2BIG
,
"Index of deletion too big"
},
{
nft_rule_delete_num
,
E
NOENT
,
"Index of deletion too big"
},
/* { TC_READ_COUNTER, E2BIG, "Index of counter too big" },
/* { TC_READ_COUNTER, E2BIG, "Index of counter too big" },
{ TC_ZERO_COUNTER, E2BIG, "Index of counter too big" }, */
{ TC_ZERO_COUNTER, E2BIG, "Index of counter too big" }, */
{
nft_rule_add
,
ELOOP
,
"Loop found in table"
},
{
nft_rule_add
,
EINVAL
,
"Target problem"
},
/* ENOENT for DELETE probably means no matching rule */
/* ENOENT for DELETE probably means no matching rule */
{
nft_rule_delete
,
ENOENT
,
{
nft_rule_delete
,
ENOENT
,
"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"
},
{
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"
},
{
NULL
,
ENOPROTOOPT
,
"iptables who? (do you need to insmod?)"
},
{
NULL
,
ENOPROTOOPT
,
"iptables who? (do you need to insmod?)"
},
...
@@ -2540,8 +2738,8 @@ static void xtables_config_perror(uint32_t flags, const char *fmt, ...)
...
@@ -2540,8 +2738,8 @@ static void xtables_config_perror(uint32_t flags, const char *fmt, ...)
va_end
(
args
);
va_end
(
args
);
}
}
int
nft_xtables_config_load
(
struct
nft_handle
*
h
,
const
char
*
filename
,
static
int
__
nft_xtables_config_load
(
struct
nft_handle
*
h
,
const
char
*
filename
,
uint32_t
flags
)
uint32_t
flags
)
{
{
struct
nftnl_table_list
*
table_list
=
NULL
;
struct
nftnl_table_list
*
table_list
=
NULL
;
struct
nftnl_chain_list
*
chain_list
=
NULL
;
struct
nftnl_chain_list
*
chain_list
=
NULL
;
...
@@ -2552,9 +2750,6 @@ int nft_xtables_config_load(struct nft_handle *h, const char *filename,
...
@@ -2552,9 +2750,6 @@ int nft_xtables_config_load(struct nft_handle *h, const char *filename,
uint32_t
table_family
,
chain_family
;
uint32_t
table_family
,
chain_family
;
bool
found
=
false
;
bool
found
=
false
;
if
(
h
->
restore
)
return
0
;
table_list
=
nftnl_table_list_alloc
();
table_list
=
nftnl_table_list_alloc
();
chain_list
=
nftnl_chain_list_alloc
();
chain_list
=
nftnl_chain_list_alloc
();
...
@@ -2636,6 +2831,8 @@ int nft_xtables_config_load(struct nft_handle *h, const char *filename,
...
@@ -2636,6 +2831,8 @@ int nft_xtables_config_load(struct nft_handle *h, const char *filename,
nftnl_chain_list_iter_destroy
(
citer
);
nftnl_chain_list_iter_destroy
(
citer
);
nftnl_chain_list_free
(
chain_list
);
nftnl_chain_list_free
(
chain_list
);
h
->
config_done
=
1
;
return
0
;
return
0
;
err:
err:
...
@@ -2647,9 +2844,20 @@ err:
...
@@ -2647,9 +2844,20 @@ err:
if
(
citer
!=
NULL
)
if
(
citer
!=
NULL
)
nftnl_chain_list_iter_destroy
(
citer
);
nftnl_chain_list_iter_destroy
(
citer
);
h
->
config_done
=
-
1
;
return
-
1
;
return
-
1
;
}
}
int
nft_xtables_config_load
(
struct
nft_handle
*
h
,
const
char
*
filename
,
uint32_t
flags
)
{
if
(
!
h
->
config_done
)
return
__nft_xtables_config_load
(
h
,
filename
,
flags
);
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
)
{
{
...
@@ -2684,18 +2892,7 @@ int nft_chain_zero_counters(struct nft_handle *h, const char *chain,
...
@@ -2684,18 +2892,7 @@ int nft_chain_zero_counters(struct nft_handle *h, const char *chain,
nftnl_chain_unset
(
c
,
NFTNL_CHAIN_HANDLE
);
nftnl_chain_unset
(
c
,
NFTNL_CHAIN_HANDLE
);
if
(
h
->
batch_support
)
{
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_ADD
,
c
);
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_ADD
,
c
);
}
else
{
struct
nlmsghdr
*
nlh
;
char
buf
[
MNL_SOCKET_BUFFER_SIZE
];
nlh
=
nftnl_chain_nlmsg_build_hdr
(
buf
,
NFT_MSG_NEWCHAIN
,
h
->
family
,
NLM_F_ACK
,
h
->
seq
);
nftnl_chain_nlmsg_build_payload
(
nlh
,
c
);
ret
=
mnl_talk
(
h
,
nlh
,
NULL
,
NULL
);
}
if
(
chain
!=
NULL
)
if
(
chain
!=
NULL
)
break
;
break
;
...
@@ -2703,9 +2900,6 @@ next:
...
@@ -2703,9 +2900,6 @@ next:
c
=
nftnl_chain_list_iter_next
(
iter
);
c
=
nftnl_chain_list_iter_next
(
iter
);
}
}
if
(
!
h
->
batch_support
)
nftnl_chain_list_free
(
list
);
nftnl_chain_list_iter_destroy
(
iter
);
nftnl_chain_list_iter_destroy
(
iter
);
err:
err:
...
@@ -2747,15 +2941,15 @@ static int nft_is_expr_compatible(const char *name)
...
@@ -2747,15 +2941,15 @@ static int nft_is_expr_compatible(const char *name)
return
1
;
return
1
;
}
}
static
int
nft_is_rule_compatible
(
struct
nftnl_rule
*
rule
)
static
bool
nft_is_rule_compatible
(
struct
nftnl_rule
*
rule
)
{
{
struct
nftnl_expr_iter
*
iter
;
struct
nftnl_expr_iter
*
iter
;
struct
nftnl_expr
*
expr
;
struct
nftnl_expr
*
expr
;
int
ret
=
0
;
bool
compatible
=
false
;
iter
=
nftnl_expr_iter_create
(
rule
);
iter
=
nftnl_expr_iter_create
(
rule
);
if
(
iter
==
NULL
)
if
(
iter
==
NULL
)
return
-
1
;
return
false
;
expr
=
nftnl_expr_iter_next
(
iter
);
expr
=
nftnl_expr_iter_next
(
iter
);
while
(
expr
!=
NULL
)
{
while
(
expr
!=
NULL
)
{
...
@@ -2766,37 +2960,51 @@ static int nft_is_rule_compatible(struct nftnl_rule *rule)
...
@@ -2766,37 +2960,51 @@ static int nft_is_rule_compatible(struct nftnl_rule *rule)
continue
;
continue
;
}
}
ret
=
1
;
compatible
=
true
;
break
;
break
;
}
}
nftnl_expr_iter_destroy
(
iter
);
nftnl_expr_iter_destroy
(
iter
);
return
ret
;
return
compatible
;
}
}
static
int
nft_is_chain_compatible
(
const
char
*
table
,
const
char
*
chain
)
static
int
nft_is_chain_compatible
(
const
struct
nft_handle
*
h
,
const
struct
nftnl_chain
*
chain
)
{
{
const
char
*
cur_table
;
const
char
*
table
,
*
name
,
*
type
,
*
cur_table
;
struct
builtin_chain
*
chains
;
struct
builtin_chain
*
chains
;
int
i
,
j
;
int
i
,
j
,
prio
;
enum
nf_inet_hooks
hook
;
table
=
nftnl_chain_get
(
chain
,
NFTNL_CHAIN_TABLE
);
name
=
nftnl_chain_get
(
chain
,
NFTNL_CHAIN_NAME
);
type
=
nftnl_chain_get
(
chain
,
NFTNL_CHAIN_TYPE
);
prio
=
nftnl_chain_get_u32
(
chain
,
NFTNL_CHAIN_PRIO
);
hook
=
nftnl_chain_get_u32
(
chain
,
NFTNL_CHAIN_HOOKNUM
);
for
(
i
=
0
;
i
<
TABLES_MAX
;
i
++
)
{
for
(
i
=
0
;
i
<
TABLES_MAX
;
i
++
)
{
cur_table
=
x
tables
_ipv4
[
i
].
name
;
cur_table
=
h
->
tables
[
i
].
name
;
chains
=
x
tables
_ipv4
[
i
].
chains
;
chains
=
h
->
tables
[
i
].
chains
;
if
(
strcmp
(
table
,
cur_table
)
!=
0
)
if
(
!
cur_table
||
strcmp
(
table
,
cur_table
)
!=
0
)
continue
;
continue
;
for
(
j
=
0
;
j
<
NF_INET_NUMHOOKS
&&
chains
[
j
].
name
;
j
++
)
{
for
(
j
=
0
;
j
<
NF_INET_NUMHOOKS
&&
chains
[
j
].
name
;
j
++
)
{
if
(
strcmp
(
chain
,
chains
[
j
].
name
)
==
0
)
if
(
strcmp
(
name
,
chains
[
j
].
name
)
!=
0
)
continue
;
if
(
strcmp
(
type
,
chains
[
j
].
type
)
==
0
&&
prio
==
chains
[
j
].
prio
&&
hook
==
chains
[
j
].
hook
)
return
0
;
return
0
;
break
;
}
}
}
}
return
1
;
return
1
;
}
}
static
int
nft_are_chains_compatible
(
struct
nft_handle
*
h
)
static
int
nft_are_chains_compatible
(
struct
nft_handle
*
h
,
const
char
*
tablename
)
{
{
struct
nftnl_chain_list
*
list
;
struct
nftnl_chain_list
*
list
;
struct
nftnl_chain_list_iter
*
iter
;
struct
nftnl_chain_list_iter
*
iter
;
...
@@ -2816,101 +3024,55 @@ static int nft_are_chains_compatible(struct nft_handle *h)
...
@@ -2816,101 +3024,55 @@ static int nft_are_chains_compatible(struct nft_handle *h)
if
(
!
nft_chain_builtin
(
chain
))
if
(
!
nft_chain_builtin
(
chain
))
goto
next
;
goto
next
;
const
char
*
table
=
nftnl_chain_get
(
chain
,
NFTNL_CHAIN_TABLE
);
ret
=
nft_is_chain_compatible
(
h
,
chain
);
const
char
*
name
=
nftnl_chain_get
(
chain
,
NFTNL_CHAIN_NAME
);
if
(
ret
!=
0
)
if
(
nft_is_chain_compatible
(
table
,
name
)
==
1
)
{
ret
=
1
;
break
;
break
;
}
next:
next:
chain
=
nftnl_chain_list_iter_next
(
iter
);
chain
=
nftnl_chain_list_iter_next
(
iter
);
}
}
nftnl_chain_list_iter_destroy
(
iter
);
nftnl_chain_list_iter_destroy
(
iter
);
nftnl_chain_list_free
(
list
);
return
ret
;
}
static
int
nft_is_table_compatible
(
const
char
*
name
)
{
int
i
;
for
(
i
=
0
;
i
<
TABLES_MAX
;
i
++
)
{
if
(
strcmp
(
xtables_ipv4
[
i
].
name
,
name
)
==
0
)
return
0
;
}
return
1
;
}
static
int
nft_are_tables_compatible
(
struct
nft_handle
*
h
)
{
struct
nftnl_table_list
*
list
;
struct
nftnl_table_list_iter
*
iter
;
struct
nftnl_table
*
table
;
int
ret
=
0
;
list
=
nftnl_table_list_get
(
h
);
if
(
list
==
NULL
)
return
-
1
;
iter
=
nftnl_table_list_iter_create
(
list
);
if
(
iter
==
NULL
)
return
-
1
;
table
=
nftnl_table_list_iter_next
(
iter
);
while
(
table
!=
NULL
)
{
const
char
*
name
=
nftnl_table_get
(
table
,
NFTNL_TABLE_NAME
);
if
(
nft_is_table_compatible
(
name
)
==
0
)
{
table
=
nftnl_table_list_iter_next
(
iter
);
continue
;
}
ret
=
1
;
break
;
}
nftnl_table_list_iter_destroy
(
iter
);
nftnl_table_list_free
(
list
);
return
ret
;
return
ret
;
}
}
int
nft_is_
ruleset
_compatible
(
struct
nft_handle
*
h
)
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
;
int
ret
=
0
,
i
;
ret
=
nft_are_tables_compatible
(
h
);
for
(
i
=
0
;
i
<
TABLES_MAX
;
i
++
)
{
if
(
ret
!=
0
)
if
(
!
h
->
tables
[
i
].
name
)
return
ret
;
continue
;
if
(
strcmp
(
h
->
tables
[
i
].
name
,
tablename
)
==
0
)
break
;
}
if
(
i
==
TABLES_MAX
)
return
false
;
ret
=
nft_are_chains_compatible
(
h
);
ret
=
nft_are_chains_compatible
(
h
,
tablename
);
if
(
ret
!=
0
)
if
(
ret
!=
0
)
return
ret
;
return
false
;
list
=
nft_rule_list_get
(
h
);
list
=
nft_rule_list_get
(
h
);
if
(
list
==
NULL
)
if
(
list
==
NULL
)
return
-
1
;
return
true
;
iter
=
nftnl_rule_list_iter_create
(
list
);
iter
=
nftnl_rule_list_iter_create
(
list
);
if
(
iter
==
NULL
)
if
(
iter
==
NULL
)
return
-
1
;
return
true
;
rule
=
nftnl_rule_list_iter_next
(
iter
);
rule
=
nftnl_rule_list_iter_next
(
iter
);
while
(
rule
!=
NULL
)
{
while
(
rule
!=
NULL
)
{
ret
=
nft_is_rule_compatible
(
rule
);
ret
=
nft_is_rule_compatible
(
rule
);
if
(
ret
!=
0
)
if
(
ret
!=
0
)
break
;
break
;
rule
=
nftnl_rule_list_iter_next
(
iter
);
rule
=
nftnl_rule_list_iter_next
(
iter
);
}
}
nftnl_rule_list_iter_destroy
(
iter
);
nftnl_rule_list_iter_destroy
(
iter
);
return
ret
;
return
ret
==
0
;
}
}
iptables/nft.h
View file @
fe62f28a
...
@@ -32,12 +32,19 @@ struct nft_handle {
...
@@ -32,12 +32,19 @@ struct nft_handle {
uint32_t
seq
;
uint32_t
seq
;
struct
list_head
obj_list
;
struct
list_head
obj_list
;
int
obj_list_num
;
int
obj_list_num
;
struct
mnl_nlmsg_batch
*
batch
;
struct
nftnl_batch
*
batch
;
struct
list_head
err_list
;
struct
nft_family_ops
*
ops
;
struct
nft_family_ops
*
ops
;
struct
builtin_table
*
tables
;
struct
builtin_table
*
tables
;
struct
nftnl_chain_list
*
chain_cache
;
struct
nftnl_rule_list
*
rule_cache
;
struct
nftnl_rule_list
*
rule_cache
;
bool
restore
;
bool
restore
;
bool
batch_support
;
int8_t
config_done
;
/* meta data, for error reporting */
struct
{
unsigned
int
lineno
;
}
error
;
};
};
extern
struct
builtin_table
xtables_ipv4
[
TABLES_MAX
];
extern
struct
builtin_table
xtables_ipv4
[
TABLES_MAX
];
...
@@ -56,23 +63,25 @@ void nft_fini(struct nft_handle *h);
...
@@ -56,23 +63,25 @@ void nft_fini(struct nft_handle *h);
struct
nftnl_table
;
struct
nftnl_table
;
struct
nftnl_chain_list
;
struct
nftnl_chain_list
;
int
nft_table_add
(
struct
nft_handle
*
h
,
struct
nftnl_table
*
t
,
uint16_t
flags
);
int
nft_for_each_table
(
struct
nft_handle
*
h
,
int
(
*
func
)(
struct
nft_handle
*
h
,
const
char
*
tablename
,
bool
counters
),
bool
counters
);
int
nft_for_each_table
(
struct
nft_handle
*
h
,
int
(
*
func
)(
struct
nft_handle
*
h
,
const
char
*
tablename
,
bool
counters
),
bool
counters
);
bool
nft_table_find
(
struct
nft_handle
*
h
,
const
char
*
tablename
);
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
);
void
nft_table_new
(
struct
nft_handle
*
h
,
const
char
*
table
);
/*
/*
* Operations with chains.
* Operations with chains.
*/
*/
struct
nftnl_chain
;
struct
nftnl_chain
;
int
nft_chain_add
(
struct
nft_handle
*
h
,
struct
nftnl_chain
*
c
,
uint16_t
flags
);
int
nft_chain_set
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
,
const
char
*
policy
,
const
struct
xt_counters
*
counters
);
int
nft_chain_set
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
,
const
char
*
policy
,
const
struct
xt_counters
*
counters
);
struct
nftnl_chain_list
*
nft_chain_dump
(
struct
nft_handle
*
h
);
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
);
int
nft_chain_user_flush
(
struct
nft_handle
*
h
,
struct
nftnl_chain_list
*
list
,
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
);
...
@@ -182,6 +191,6 @@ int nft_arp_rule_insert(struct nft_handle *h, const char *chain,
...
@@ -182,6 +191,6 @@ int nft_arp_rule_insert(struct nft_handle *h, const char *chain,
void
nft_rule_to_arpt_entry
(
struct
nftnl_rule
*
r
,
struct
arpt_entry
*
fw
);
void
nft_rule_to_arpt_entry
(
struct
nftnl_rule
*
r
,
struct
arpt_entry
*
fw
);
int
nft_is_
ruleset
_compatible
(
struct
nft_handle
*
h
);
bool
nft_is_
table
_compatible
(
struct
nft_handle
*
h
,
const
char
*
name
);
#endif
#endif
iptables/tests/shell/run-tests.sh
0 → 100755
View file @
fe62f28a
#!/bin/bash
#configuration
TESTDIR
=
"./
$(
dirname
$0
)
/"
RETURNCODE_SEPARATOR
=
"_"
XTABLES_NFT_MULTI
=
"
$(
dirname
$0
)
/../../xtables-nft-multi"
XTABLES_LEGACY_MULTI
=
"
$(
dirname
$0
)
/../../xtables-legacy-multi"
export
XTABLES_LIBDIR
=
${
TESTDIR
}
/../../../extensions
msg_error
()
{
echo
"E:
$1
..."
>
&2
exit
1
}
msg_warn
()
{
echo
"W:
$1
"
>
&2
}
msg_info
()
{
echo
"I:
$1
"
}
if
[
"
$(
id
-u
)
"
!=
"0"
]
;
then
msg_error
"this requires root!"
fi
if
[
!
-d
"
$TESTDIR
"
]
;
then
msg_error
"missing testdir
$TESTDIR
"
fi
if
[
"
$1
"
==
"-v"
]
;
then
VERBOSE
=
y
shift
fi
for
arg
in
"
$@
"
;
do
if
grep
^.
*${
RETURNCODE_SEPARATOR
}
[
0-9]
\\
+
$
<<<
$arg
>
/dev/null
;
then
SINGLE+
=
"
$arg
"
VERBOSE
=
y
else
msg_error
"unknown parameter '
$arg
'"
fi
done
find_tests
()
{
if
[
!
-z
"
$SINGLE
"
]
;
then
echo
$SINGLE
return
fi
find
${
TESTDIR
}
-executable
-regex
\
.
*${
RETURNCODE_SEPARATOR
}
[
0-9]+ |
sort
}
ok
=
0
failed
=
0
do_test
()
{
testfile
=
"
$1
"
xtables_multi
=
"
$2
"
rc_spec
=
`
echo
$(
basename
${
testfile
}
)
|
cut
-d
_
-f2-
`
msg_info
"[EXECUTING]
$testfile
"
if
[
"
$VERBOSE
"
=
"y"
]
;
then
XT_MULTI
=
$xtables_multi
unshare
-n
${
testfile
}
else
XT_MULTI
=
$xtables_multi
unshare
-n
${
testfile
}
>
/dev/null 2>&1
fi
rc_got
=
$?
echo
-en
"
\0
33[1A
\0
33[K"
# clean the [EXECUTING] foobar line
if
[
"
$rc_got
"
==
"
$rc_spec
"
]
;
then
msg_info
"[OK]
$testfile
"
((
ok++
))
else
((
failed++
))
msg_warn
"[FAILED]
$testfile
: expected
$rc_spec
but got
$rc_got
"
fi
}
echo
""
for
testfile
in
$(
find_tests
)
;
do
do_test
"
$testfile
"
"
$XTABLES_LEGACY_MULTI
"
done
msg_info
"legacy results: [OK]
$ok
[FAILED]
$failed
[TOTAL]
$((
ok+failed
))
"
legacy_ok
=
$ok
legacy_fail
=
$failed
ok
=
0
failed
=
0
for
testfile
in
$(
find_tests
)
;
do
do_test
"
$testfile
"
"
$XTABLES_NFT_MULTI
"
done
msg_info
"nft results: [OK]
$ok
[FAILED]
$failed
[TOTAL]
$((
ok+failed
))
"
ok
=
$((
legacy_ok+ok
))
failed
=
$((
legacy_fail+failed
))
msg_info
"combined results: [OK]
$ok
[FAILED]
$failed
[TOTAL]
$((
ok+failed
))
"
exit
0
iptables/tests/shell/testcases/chain/0001duplicate_1
0 → 100755
View file @
fe62f28a
#!/bin/bash
set
-x
$XT_MULTI
iptables
-t
filter
-N
c1
||
exit
0
$XT_MULTI
iptables
-t
filter
-N
c1
||
exit
1
$XT_MULTI
ip6tables
-t
filter
-N
c1
||
exit
0
$XT_MULTI
ip6tables
-t
filter
-N
c1
||
exit
1
echo
"E: Duplicate chains"
>
&2
exit
0
iptables/tests/shell/testcases/chain/0004newchain_0
0 → 100755
View file @
fe62f28a
#!/bin/bash
set
-e
$XT_MULTI
iptables
-N
c1
$XT_MULTI
ip6tables
-N
c1
$XT_MULTI
iptables
-N
c2
$XT_MULTI
ip6tables
-N
c2
iptables/tests/shell/testcases/chain/0005rename_1
0 → 100755
View file @
fe62f28a
#!/bin/bash
$XT_MULTI
iptables
-N
c1
||
exit
0
$XT_MULTI
iptables
-N
c2
||
exit
0
$XT_MULTI
iptables
-E
c1 c2
||
exit
1
$XT_MULTI
ip6tables
-N
c1
||
exit
0
$XT_MULTI
ip6tables
-N
c2
||
exit
0
$XT_MULTI
ip6tables
-E
c1 c2
||
exit
1
echo
"E: Renamed with existing chain"
>
&2
exit
0
iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0
0 → 100755
View file @
fe62f28a
#!/bin/sh
set
-x
case
"
$XT_MULTI
"
in
*
/xtables-nft-multi
)
for
t
in
filter nat
;
do
$XT_MULTI
ebtables
-t
$t
-L
||
exit
1
$XT_MULTI
ebtables
-t
$t
-X
||
exit
1
$XT_MULTI
ebtables
-t
$t
-F
||
exit
1
done
for
t
in
broute foobar
;
do
$XT_MULTI
ebtables
-t
$t
-L
&&
$XT_MULTI
ebtables
-t
$t
-X
&&
$XT_MULTI
ebtables
-t
$t
-F
if
[
$?
-eq
0
]
;
then
echo
"Expect nonzero return for unsupported table"
exit
1
fi
done
$XT_MULTI
ebtables
-t
filter
-N
FOO
||
exit
1
$XT_MULTI
ebtables
-t
filter
-N
FOO
if
[
$?
-eq
0
]
;
then
echo
"Duplicate chain FOO"
$XT_MULTI
ebtables
-t
filter
-L
exit
1
fi
$XT_MULTI
ebtables
-t
filter
-N
BAR
||
exit
1
$XT_MULTI
ebtables
-t
filter
-N
BAZ
||
exit
1
$XT_MULTI
ebtables
-t
filter
-L
|
grep
-q
FOO
||
exit
1
$XT_MULTI
ebtables
-t
filter
-L
|
grep
-q
BAR
||
exit
1
$XT_MULTI
ebtables
-t
filter
-L
|
grep
-q
BAZ
||
exit
1
$XT_MULTI
ebtables
-t
filter
-L
BAZ
||
exit
1
$XT_MULTI
ebtables
-t
filter
-X
BAZ
||
exit
1
$XT_MULTI
ebtables
-t
filter
-L
BAZ |
grep
-q
BAZ
if
[
$?
-eq
0
]
;
then
echo
"Deleted chain -L BAZ ok, expected failure"
$XT_MULTI
ebtables
-t
filter
-L
exit
1
fi
$XT_MULTI
ebtables
-t
$t
-F
||
exit
0
;;
*
)
echo
"skip
$XT_MULTI
"
;;
esac
iptables/tests/shell/testcases/firewalld-restore/0001-firewalld_0
0 → 100755
View file @
fe62f28a
#!/bin/sh
$XT_MULTI
iptables
-w
-L
-n
>
/dev/null
||
exit
1
$XT_MULTI
iptables
-w2
-L
-n
>
/dev/null
||
exit
1
echo
-n
'#foo'
|
$XT_MULTI
iptables-restore
-w
||
exit
1
# table probing
for
table
in
security raw mangle nat filter
;
do
$XT_MULTI
iptables
-w2
-t
$table
-L
-n
>
/dev/null
done
$XT_MULTI
iptables
-w2
-p
icmp
--help
|
grep
-q
'Valid ICMP Types'
||
exit
1
cat
<<
EOF
|
$XT_MULTI
iptables-restore -w -n
*nat
-F
-X
-Z
-N PREROUTING_direct
-I PREROUTING 1 -j PREROUTING_direct
-N PREROUTING_ZONES_SOURCE
-N PREROUTING_ZONES
-I PREROUTING 2 -j PREROUTING_ZONES_SOURCE
-I PREROUTING 3 -j PREROUTING_ZONES
-N POSTROUTING_direct
-I POSTROUTING 1 -j POSTROUTING_direct
-N POSTROUTING_ZONES_SOURCE
-N POSTROUTING_ZONES
-I POSTROUTING 2 -j POSTROUTING_ZONES_SOURCE
-I POSTROUTING 3 -j POSTROUTING_ZONES
-N OUTPUT_direct
-I OUTPUT 1 -j OUTPUT_direct
COMMIT
*mangle
-F
-X
-Z
-N PREROUTING_direct
-I PREROUTING 1 -j PREROUTING_direct
-N PREROUTING_ZONES_SOURCE
-N PREROUTING_ZONES
-I PREROUTING 2 -j PREROUTING_ZONES_SOURCE
-I PREROUTING 3 -j PREROUTING_ZONES
-N POSTROUTING_direct
-I POSTROUTING 1 -j POSTROUTING_direct
-N INPUT_direct
-I INPUT 1 -j INPUT_direct
-N OUTPUT_direct
-I OUTPUT 1 -j OUTPUT_direct
-N FORWARD_direct
-I FORWARD 1 -j FORWARD_direct
COMMIT
*raw
-F
-X
-Z
-N PREROUTING_direct
-I PREROUTING 1 -j PREROUTING_direct
-N PREROUTING_ZONES_SOURCE
-N PREROUTING_ZONES
-I PREROUTING 2 -j PREROUTING_ZONES_SOURCE
-I PREROUTING 3 -j PREROUTING_ZONES
-N OUTPUT_direct
-I OUTPUT 1 -j OUTPUT_direct
COMMIT
*filter
-F
-X
-Z
-N INPUT_direct
-N INPUT_ZONES_SOURCE
-N INPUT_ZONES
-I INPUT 1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-I INPUT 2 -i lo -j ACCEPT
-I INPUT 3 -j INPUT_direct
-I INPUT 4 -j INPUT_ZONES_SOURCE
-I INPUT 5 -j INPUT_ZONES
-I INPUT 6 -m conntrack --ctstate INVALID -j DROP
-I INPUT 7 -j REJECT --reject-with icmp-host-prohibited
-N FORWARD_direct
-N FORWARD_IN_ZONES_SOURCE
-N FORWARD_IN_ZONES
-N FORWARD_OUT_ZONES_SOURCE
-N FORWARD_OUT_ZONES
-I FORWARD 1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-I FORWARD 2 -i lo -j ACCEPT
-I FORWARD 3 -j FORWARD_direct
-I FORWARD 4 -j FORWARD_IN_ZONES_SOURCE
-I FORWARD 5 -j FORWARD_IN_ZONES
-I FORWARD 6 -j FORWARD_OUT_ZONES_SOURCE
-I FORWARD 7 -j FORWARD_OUT_ZONES
-I FORWARD 8 -m conntrack --ctstate INVALID -j DROP
-I FORWARD 9 -j REJECT --reject-with icmp-host-prohibited
-N OUTPUT_direct
-I OUTPUT 1 -j OUTPUT_direct
COMMIT
EOF
if
[
$?
-ne
0
]
;
then
echo
"Error during first iptables-restore"
exit
1
fi
cat
<<
EOF
|
$XT_MULTI
iptables-restore -w -n
*raw
-N PRE_public
-N PRE_public_log
-N PRE_public_deny
-N PRE_public_allow
-I PRE_public 1 -j PRE_public_log
-I PRE_public 2 -j PRE_public_deny
-I PRE_public 3 -j PRE_public_allow
-A PREROUTING_ZONES -i + -g PRE_public
COMMIT
*filter
-N IN_public
-N IN_public_log
-N IN_public_deny
-N IN_public_allow
-I IN_public 1 -j IN_public_log
-I IN_public 2 -j IN_public_deny
-I IN_public 3 -j IN_public_allow
-A IN_public_allow -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
-A IN_public_allow -p udp --dport 5353 -d 224.0.0.251 -m conntrack --ctstate NEW -j ACCEPT
-N FWDI_public
-N FWDI_public_log
-N FWDI_public_deny
-N FWDI_public_allow
-I FWDI_public 1 -j FWDI_public_log
-I FWDI_public 2 -j FWDI_public_deny
-I FWDI_public 3 -j FWDI_public_allow
-I IN_public 4 -p icmp -j ACCEPT
-I FWDI_public 4 -p icmp -j ACCEPT
-A INPUT_ZONES -i + -g IN_public
-A FORWARD_IN_ZONES -i + -g FWDI_public
-N FWDO_public
-N FWDO_public_log
-N FWDO_public_deny
-N FWDO_public_allow
-I FWDO_public 1 -j FWDO_public_log
-I FWDO_public 2 -j FWDO_public_deny
-I FWDO_public 3 -j FWDO_public_allow
-A FORWARD_OUT_ZONES -o + -g FWDO_public
COMMIT
*nat
-N PRE_public
-N PRE_public_log
-N PRE_public_deny
-N PRE_public_allow
-I PRE_public 1 -j PRE_public_log
-I PRE_public 2 -j PRE_public_deny
-I PRE_public 3 -j PRE_public_allow
-A PREROUTING_ZONES -i + -g PRE_public
-N POST_public
-N POST_public_log
-N POST_public_deny
-N POST_public_allow
-I POST_public 1 -j POST_public_log
-I POST_public 2 -j POST_public_deny
-I POST_public 3 -j POST_public_allow
-A POSTROUTING_ZONES -o + -g POST_public
COMMIT
*mangle
-N PRE_public
-N PRE_public_log
-N PRE_public_deny
-N PRE_public_allow
-I PRE_public 1 -j PRE_public_log
-I PRE_public 2 -j PRE_public_deny
-I PRE_public 3 -j PRE_public_allow
-A PREROUTING_ZONES -i + -g PRE_public
COMMIT
EOF
if
[
$?
-ne
0
]
;
then
echo
"Error during 2nd iptables-restore"
exit
1
fi
cat
<<
EOF
|
$XT_MULTI
iptables-restore -w -n
*mangle
-P PREROUTING ACCEPT
-P POSTROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P FORWARD ACCEPT
COMMIT
*raw
-P PREROUTING ACCEPT
-P OUTPUT ACCEPT
COMMIT
*filter
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P FORWARD ACCEPT
COMMIT
EOF
if
[
$?
-ne
0
]
;
then
echo
"Error during 3rd iptables-restore"
exit
1
fi
cat
<<
EOF
|
$XT_MULTI
iptables-restore -w -n
*filter
-I INPUT_ZONES 1 -i enp3s0 -g IN_public
-I FORWARD_IN_ZONES 1 -i enp3s0 -g FWDI_public
-I FORWARD_OUT_ZONES 1 -o enp3s0 -g FWDO_public
COMMIT
*nat
-I PREROUTING_ZONES 1 -i enp3s0 -g PRE_public
-I POSTROUTING_ZONES 1 -o enp3s0 -g POST_public
COMMIT
*mangle
-I PREROUTING_ZONES 1 -i enp3s0 -g PRE_public
COMMIT
*raw
-I PREROUTING_ZONES 1 -i enp3s0 -g PRE_public
COMMIT
EOF
if
[
$?
-ne
0
]
;
then
echo
"Error during 4th iptables-restore"
exit
1
fi
tmpfile
=
$(
mktemp
)
||
exit
1
for
table
in
nat mangle raw filter
;
do
$XT_MULTI
iptables-save
-t
$table
|
grep
-v
'^#'
>>
"
$tmpfile
"
done
case
"
$XT_MULTI
"
in
*
/xtables-nft-multi
)
# nft-multi displays chain names in different order, work around this for now
tmpfile2
=
$(
mktemp
)
sort
"
$tmpfile
"
>
"
$tmpfile2
"
sort
$(
dirname
"
$0
"
)
/dumps/ipt-save-completed.txt
>
"
$tmpfile
"
diff
-u
$tmpfile
$tmpfile2
RET
=
$?
rm
-f
"
$tmpfile2
"
;;
*
)
diff
-u
$tmpfile
$(
dirname
"
$0
"
)
/dumps/ipt-save-completed.txt
RET
=
$?
;;
esac
rm
-f
"
$tmpfile
"
exit
$RET
iptables/tests/shell/testcases/firewalld-restore/0002-firewalld-restart_0
0 → 100755
View file @
fe62f28a
#!/bin/sh
# simulate restart after it went down, so first restore
# the complete ruleset
$XT_MULTI
iptables-restore <
$(
dirname
"
$0
"
)
/dumps/ipt-save-completed.txt
# add dummy rules to see if they get cleared or not.
for
table
in
raw mangle nat filter
;
do
$XT_MULTI
iptables
-t
$table
-N
FOO
$table
||
exit
1
$XT_MULTI
iptables
-t
$table
-A
OUTPUT
-m
comment
--comment
'"dummy rule in table $table OUTPUT"'
||
exit
1
$XT_MULTI
iptables
-t
$table
-A
FOO
$table
-m
comment
--comment
'"dummy rule in table $table FOO$table"'
||
exit
1
done
# then run the other test script so it finds already-existing ruleset.
exec
$(
dirname
"
$0
"
)
/0001-firewalld_0
iptables/tests/shell/testcases/firewalld-restore/dumps/ipt-save-completed.txt
0 → 100644
View file @
fe62f28a
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT_direct - [0:0]
:POSTROUTING_ZONES - [0:0]
:POSTROUTING_ZONES_SOURCE - [0:0]
:POSTROUTING_direct - [0:0]
:POST_public - [0:0]
:POST_public_allow - [0:0]
:POST_public_deny - [0:0]
:POST_public_log - [0:0]
:PREROUTING_ZONES - [0:0]
:PREROUTING_ZONES_SOURCE - [0:0]
:PREROUTING_direct - [0:0]
:PRE_public - [0:0]
:PRE_public_allow - [0:0]
:PRE_public_deny - [0:0]
:PRE_public_log - [0:0]
-A PREROUTING -j PREROUTING_direct
-A PREROUTING -j PREROUTING_ZONES_SOURCE
-A PREROUTING -j PREROUTING_ZONES
-A OUTPUT -j OUTPUT_direct
-A POSTROUTING -j POSTROUTING_direct
-A POSTROUTING -j POSTROUTING_ZONES_SOURCE
-A POSTROUTING -j POSTROUTING_ZONES
-A POSTROUTING_ZONES -o enp3s0 -g POST_public
-A POSTROUTING_ZONES -g POST_public
-A POST_public -j POST_public_log
-A POST_public -j POST_public_deny
-A POST_public -j POST_public_allow
-A PREROUTING_ZONES -i enp3s0 -g PRE_public
-A PREROUTING_ZONES -g PRE_public
-A PRE_public -j PRE_public_log
-A PRE_public -j PRE_public_deny
-A PRE_public -j PRE_public_allow
COMMIT
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:FORWARD_direct - [0:0]
:INPUT_direct - [0:0]
:OUTPUT_direct - [0:0]
:POSTROUTING_direct - [0:0]
:PREROUTING_ZONES - [0:0]
:PREROUTING_ZONES_SOURCE - [0:0]
:PREROUTING_direct - [0:0]
:PRE_public - [0:0]
:PRE_public_allow - [0:0]
:PRE_public_deny - [0:0]
:PRE_public_log - [0:0]
-A PREROUTING -j PREROUTING_direct
-A PREROUTING -j PREROUTING_ZONES_SOURCE
-A PREROUTING -j PREROUTING_ZONES
-A INPUT -j INPUT_direct
-A FORWARD -j FORWARD_direct
-A OUTPUT -j OUTPUT_direct
-A POSTROUTING -j POSTROUTING_direct
-A PREROUTING_ZONES -i enp3s0 -g PRE_public
-A PREROUTING_ZONES -g PRE_public
-A PRE_public -j PRE_public_log
-A PRE_public -j PRE_public_deny
-A PRE_public -j PRE_public_allow
COMMIT
*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:OUTPUT_direct - [0:0]
:PREROUTING_ZONES - [0:0]
:PREROUTING_ZONES_SOURCE - [0:0]
:PREROUTING_direct - [0:0]
:PRE_public - [0:0]
:PRE_public_allow - [0:0]
:PRE_public_deny - [0:0]
:PRE_public_log - [0:0]
-A PREROUTING -j PREROUTING_direct
-A PREROUTING -j PREROUTING_ZONES_SOURCE
-A PREROUTING -j PREROUTING_ZONES
-A OUTPUT -j OUTPUT_direct
-A PREROUTING_ZONES -i enp3s0 -g PRE_public
-A PREROUTING_ZONES -g PRE_public
-A PRE_public -j PRE_public_log
-A PRE_public -j PRE_public_deny
-A PRE_public -j PRE_public_allow
COMMIT
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:FORWARD_IN_ZONES - [0:0]
:FORWARD_IN_ZONES_SOURCE - [0:0]
:FORWARD_OUT_ZONES - [0:0]
:FORWARD_OUT_ZONES_SOURCE - [0:0]
:FORWARD_direct - [0:0]
:FWDI_public - [0:0]
:FWDI_public_allow - [0:0]
:FWDI_public_deny - [0:0]
:FWDI_public_log - [0:0]
:FWDO_public - [0:0]
:FWDO_public_allow - [0:0]
:FWDO_public_deny - [0:0]
:FWDO_public_log - [0:0]
:INPUT_ZONES - [0:0]
:INPUT_ZONES_SOURCE - [0:0]
:INPUT_direct - [0:0]
:IN_public - [0:0]
:IN_public_allow - [0:0]
:IN_public_deny - [0:0]
:IN_public_log - [0:0]
:OUTPUT_direct - [0:0]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -j INPUT_direct
-A INPUT -j INPUT_ZONES_SOURCE
-A INPUT -j INPUT_ZONES
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i lo -j ACCEPT
-A FORWARD -j FORWARD_direct
-A FORWARD -j FORWARD_IN_ZONES_SOURCE
-A FORWARD -j FORWARD_IN_ZONES
-A FORWARD -j FORWARD_OUT_ZONES_SOURCE
-A FORWARD -j FORWARD_OUT_ZONES
-A FORWARD -m conntrack --ctstate INVALID -j DROP
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
-A OUTPUT -j OUTPUT_direct
-A FORWARD_IN_ZONES -i enp3s0 -g FWDI_public
-A FORWARD_IN_ZONES -g FWDI_public
-A FORWARD_OUT_ZONES -o enp3s0 -g FWDO_public
-A FORWARD_OUT_ZONES -g FWDO_public
-A FWDI_public -j FWDI_public_log
-A FWDI_public -j FWDI_public_deny
-A FWDI_public -j FWDI_public_allow
-A FWDI_public -p icmp -j ACCEPT
-A FWDO_public -j FWDO_public_log
-A FWDO_public -j FWDO_public_deny
-A FWDO_public -j FWDO_public_allow
-A INPUT_ZONES -i enp3s0 -g IN_public
-A INPUT_ZONES -g IN_public
-A IN_public -j IN_public_log
-A IN_public -j IN_public_deny
-A IN_public -j IN_public_allow
-A IN_public -p icmp -j ACCEPT
-A IN_public_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
-A IN_public_allow -d 224.0.0.251/32 -p udp -m udp --dport 5353 -m conntrack --ctstate NEW -j ACCEPT
COMMIT
iptables/tests/shell/testcases/ipt-save/0001load-dumps_0
0 → 100755
View file @
fe62f28a
#!/bin/bash
RET
=
0
tmpfile
=
""
set
-x
clean_tmpfile
()
{
if
[
!
-z
"
$tmpfile
"
]
;
then
rm
-f
"
$tmpfile
"
fi
}
trap
clean_tmpfile EXIT
do_diff
()
{
A
=
"
$1
"
B
=
"
$2
"
AT
=
$(
mktemp
)
grep
-v
"^#"
"
$A
"
>
"
$AT
"
diff
-u
"
$AT
"
"
$B
"
x
=
$?
rm
-f
"
$AT
"
echo
"Return
$x
for
$XT_MULTI
$A
"
return
$x
}
tmpfile
=
$(
mktemp
)
||
exit
1
do_simple
()
{
iptables
=
"
$1
"
dumpfile
=
"
$2
"
$XT_MULTI
${
iptables
}
-restore
<
"
$dumpfile
"
$XT_MULTI
${
iptables
}
-save
|
grep
-v
"^#"
>
"
$tmpfile
"
do_diff
$dumpfile
"
$tmpfile
"
if
[
$?
-ne
0
]
;
then
# cp "$tmpfile" "$dumpfile.got"
RET
=
1
fi
}
do_simple
"iptables"
$(
dirname
"
$0
"
)
/dumps/ipt-save-filter.txt
do_simple
"iptables"
$(
dirname
"
$0
"
)
/dumps/policy-drop.txt
do_simple
"iptables"
$(
dirname
"
$0
"
)
/dumps/wireless.txt
exit
$RET
iptables/tests/shell/testcases/ipt-save/0002load-fedora27-firewalld_0
0 → 100755
View file @
fe62f28a
#!/bin/bash
RET
=
0
tmpfile
=
""
clean_tmpfile
()
{
if
[
!
-z
"
$tmpfile
"
]
;
then
rm
-f
"
$tmpfile
"
fi
}
trap
clean_tmpfile EXIT
do_diff
()
{
A
=
"
$1
"
B
=
"
$2
"
AT
=
$(
mktemp
)
grep
-v
"^#"
"
$A
"
>
"
$AT
"
diff
-u
"
$AT
"
"
$B
"
x
=
$?
rm
-f
"
$AT
"
return
$x
}
tmpfile
=
$(
mktemp
)
||
exit
1
do_simple
()
{
iptables
=
"
$1
"
dumpfile
=
"
$2
"
opt
=
"
$3
"
$XT_MULTI
${
iptables
}
-restore
$opt
<
"
$dumpfile
"
if
[
$?
-ne
0
]
;
then
echo
"
$XT_MULTI
${
iptables
}
-restore
$opt
$dumpfile
failed"
1>&2
exit
1
fi
:>
"
$tmpfile
"
for
table
in
mangle raw filter
;
do
$XT_MULTI
${
iptables
}
-save
-t
$table
$opt
|
grep
-v
"^#"
>>
"
$tmpfile
"
done
do_diff
$dumpfile
"
$tmpfile
"
if
[
$?
-ne
0
]
;
then
RET
=
1
fi
}
# fedora27-iptables dump contains chain counters to test counter restore/save
do_simple
"iptables"
$(
dirname
"
$0
"
)
/dumps/fedora27-iptables
"-c"
do_simple
"ip6tables"
$(
dirname
"
$0
"
)
/dumps/fedora27-ip6tables
exit
$RET
iptables/tests/shell/testcases/ipt-save/dumps/fedora27-ip6tables
0 → 100644
View file @
fe62f28a
# Generated by ip6tables-save v1.6.1 on Sat Feb 17 10:51:39 2018
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:FORWARD_direct - [0:0]
:INPUT_direct - [0:0]
:OUTPUT_direct - [0:0]
:POSTROUTING_direct - [0:0]
:PREROUTING_ZONES - [0:0]
:PREROUTING_ZONES_SOURCE - [0:0]
:PREROUTING_direct - [0:0]
:PRE_FedoraWorkstation - [0:0]
:PRE_FedoraWorkstation_allow - [0:0]
:PRE_FedoraWorkstation_deny - [0:0]
:PRE_FedoraWorkstation_log - [0:0]
-A PREROUTING -j PREROUTING_direct
-A PREROUTING -j PREROUTING_ZONES_SOURCE
-A PREROUTING -j PREROUTING_ZONES
-A INPUT -j INPUT_direct
-A FORWARD -j FORWARD_direct
-A OUTPUT -j OUTPUT_direct
-A POSTROUTING -j POSTROUTING_direct
-A PREROUTING_ZONES -i wlp58s0 -g PRE_FedoraWorkstation
-A PREROUTING_ZONES -g PRE_FedoraWorkstation
-A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_log
-A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_deny
-A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_allow
COMMIT
# Completed on Sat Feb 17 10:51:39 2018
# Generated by ip6tables-save v1.6.1 on Sat Feb 17 10:51:39 2018
*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:OUTPUT_direct - [0:0]
:PREROUTING_ZONES - [0:0]
:PREROUTING_ZONES_SOURCE - [0:0]
:PREROUTING_direct - [0:0]
:PRE_FedoraWorkstation - [0:0]
:PRE_FedoraWorkstation_allow - [0:0]
:PRE_FedoraWorkstation_deny - [0:0]
:PRE_FedoraWorkstation_log - [0:0]
-A PREROUTING -p ipv6-icmp -m icmp6 --icmpv6-type 134 -j ACCEPT
-A PREROUTING -j PREROUTING_direct
-A PREROUTING -j PREROUTING_ZONES_SOURCE
-A PREROUTING -j PREROUTING_ZONES
-A OUTPUT -j OUTPUT_direct
-A PREROUTING_ZONES -i wlp58s0 -g PRE_FedoraWorkstation
-A PREROUTING_ZONES -g PRE_FedoraWorkstation
-A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_log
-A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_deny
-A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_allow
COMMIT
# Completed on Sat Feb 17 10:51:39 2018
# Generated by ip6tables-save v1.6.1 on Sat Feb 17 10:51:39 2018
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:FORWARD_IN_ZONES - [0:0]
:FORWARD_IN_ZONES_SOURCE - [0:0]
:FORWARD_OUT_ZONES - [0:0]
:FORWARD_OUT_ZONES_SOURCE - [0:0]
:FORWARD_direct - [0:0]
:FWDI_FedoraWorkstation - [0:0]
:FWDI_FedoraWorkstation_allow - [0:0]
:FWDI_FedoraWorkstation_deny - [0:0]
:FWDI_FedoraWorkstation_log - [0:0]
:FWDO_FedoraWorkstation - [0:0]
:FWDO_FedoraWorkstation_allow - [0:0]
:FWDO_FedoraWorkstation_deny - [0:0]
:FWDO_FedoraWorkstation_log - [0:0]
:INPUT_ZONES - [0:0]
:INPUT_ZONES_SOURCE - [0:0]
:INPUT_direct - [0:0]
:IN_FedoraWorkstation - [0:0]
:IN_FedoraWorkstation_allow - [0:0]
:IN_FedoraWorkstation_deny - [0:0]
:IN_FedoraWorkstation_log - [0:0]
:OUTPUT_direct - [0:0]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -j INPUT_direct
-A INPUT -j INPUT_ZONES_SOURCE
-A INPUT -j INPUT_ZONES
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -j REJECT --reject-with icmp6-adm-prohibited
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i lo -j ACCEPT
-A FORWARD -j FORWARD_direct
-A FORWARD -j FORWARD_IN_ZONES_SOURCE
-A FORWARD -j FORWARD_IN_ZONES
-A FORWARD -j FORWARD_OUT_ZONES_SOURCE
-A FORWARD -j FORWARD_OUT_ZONES
-A FORWARD -m conntrack --ctstate INVALID -j DROP
-A FORWARD -j REJECT --reject-with icmp6-adm-prohibited
-A OUTPUT -j OUTPUT_direct
-A FORWARD_IN_ZONES -i wlp58s0 -g FWDI_FedoraWorkstation
-A FORWARD_IN_ZONES -g FWDI_FedoraWorkstation
-A FORWARD_OUT_ZONES -o wlp58s0 -g FWDO_FedoraWorkstation
-A FORWARD_OUT_ZONES -g FWDO_FedoraWorkstation
-A FWDI_FedoraWorkstation -j FWDI_FedoraWorkstation_log
-A FWDI_FedoraWorkstation -j FWDI_FedoraWorkstation_deny
-A FWDI_FedoraWorkstation -j FWDI_FedoraWorkstation_allow
-A FWDI_FedoraWorkstation -p ipv6-icmp -j ACCEPT
-A FWDO_FedoraWorkstation -j FWDO_FedoraWorkstation_log
-A FWDO_FedoraWorkstation -j FWDO_FedoraWorkstation_deny
-A FWDO_FedoraWorkstation -j FWDO_FedoraWorkstation_allow
-A INPUT_ZONES -i wlp58s0 -g IN_FedoraWorkstation
-A INPUT_ZONES -g IN_FedoraWorkstation
-A IN_FedoraWorkstation -j IN_FedoraWorkstation_log
-A IN_FedoraWorkstation -j IN_FedoraWorkstation_deny
-A IN_FedoraWorkstation -j IN_FedoraWorkstation_allow
-A IN_FedoraWorkstation -p ipv6-icmp -j ACCEPT
-A IN_FedoraWorkstation_allow -p udp -m udp --dport 137 -m conntrack --ctstate NEW -j ACCEPT
-A IN_FedoraWorkstation_allow -p udp -m udp --dport 138 -m conntrack --ctstate NEW -j ACCEPT
-A IN_FedoraWorkstation_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
-A IN_FedoraWorkstation_allow -d ff02::fb/128 -p udp -m udp --dport 5353 -m conntrack --ctstate NEW -j ACCEPT
-A IN_FedoraWorkstation_allow -d fe80::/64 -p udp -m udp --dport 546 -m conntrack --ctstate NEW -j ACCEPT
-A IN_FedoraWorkstation_allow -p udp -m udp --dport 1025:65535 -m conntrack --ctstate NEW -j ACCEPT
-A IN_FedoraWorkstation_allow -p tcp -m tcp --dport 1025:65535 -m conntrack --ctstate NEW -j ACCEPT
COMMIT
# Completed on Sat Feb 17 10:51:39 2018
iptables/tests/shell/testcases/ipt-save/dumps/fedora27-iptables
0 → 100644
View file @
fe62f28a
# Completed on Sat Feb 17 10:50:33 2018
# Generated by iptables-save v1.6.1 on Sat Feb 17 10:50:33 2018
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:FORWARD_direct - [0:0]
:INPUT_direct - [0:0]
:OUTPUT_direct - [0:0]
:POSTROUTING_direct - [0:0]
:PREROUTING_ZONES - [0:0]
:PREROUTING_ZONES_SOURCE - [0:0]
:PREROUTING_direct - [0:0]
:PRE_FedoraWorkstation - [0:0]
:PRE_FedoraWorkstation_allow - [0:0]
:PRE_FedoraWorkstation_deny - [0:0]
:PRE_FedoraWorkstation_log - [0:0]
[1:2] -A PREROUTING -j PREROUTING_direct
[3:4] -A PREROUTING -j PREROUTING_ZONES_SOURCE
[0:0] -A PREROUTING -j PREROUTING_ZONES
[0:0] -A INPUT -j INPUT_direct
[0:0] -A FORWARD -j FORWARD_direct
[0:0] -A OUTPUT -j OUTPUT_direct
[0:0] -A POSTROUTING -o virbr0 -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill
[0:0] -A POSTROUTING -j POSTROUTING_direct
[0:0] -A PREROUTING_ZONES -i wlp58s0 -g PRE_FedoraWorkstation
[0:0] -A PREROUTING_ZONES -g PRE_FedoraWorkstation
[0:0] -A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_log
[0:0] -A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_deny
[0:0] -A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_allow
COMMIT
# Completed on Sat Feb 17 10:50:33 2018
# Generated by iptables-save v1.6.1 on Sat Feb 17 10:50:33 2018
*raw
:PREROUTING ACCEPT [1681:2620433]
:OUTPUT ACCEPT [1619:171281]
:OUTPUT_direct - [0:0]
:PREROUTING_ZONES - [0:0]
:PREROUTING_ZONES_SOURCE - [0:0]
:PREROUTING_direct - [0:0]
:PRE_FedoraWorkstation - [0:0]
:PRE_FedoraWorkstation_allow - [0:0]
:PRE_FedoraWorkstation_deny - [0:0]
:PRE_FedoraWorkstation_log - [0:0]
[0:0] -A PREROUTING -j PREROUTING_direct
[0:0] -A PREROUTING -j PREROUTING_ZONES_SOURCE
[0:0] -A PREROUTING -j PREROUTING_ZONES
[0:0] -A OUTPUT -j OUTPUT_direct
[0:0] -A PREROUTING_ZONES -i wlp58s0 -g PRE_FedoraWorkstation
[0:0] -A PREROUTING_ZONES -g PRE_FedoraWorkstation
[0:0] -A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_log
[0:0] -A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_deny
[0:0] -A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_allow
[0:0] -A PRE_FedoraWorkstation_allow -p udp -m udp --dport 137 -j CT --helper netbios-ns
COMMIT
# Completed on Sat Feb 17 10:50:33 2018
# Generated by iptables-save v1.6.1 on Sat Feb 17 10:50:33 2018
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1619:171281]
:FORWARD_IN_ZONES - [0:0]
:FORWARD_IN_ZONES_SOURCE - [0:0]
:FORWARD_OUT_ZONES - [0:0]
:FORWARD_OUT_ZONES_SOURCE - [0:0]
:FORWARD_direct - [0:0]
:FWDI_FedoraWorkstation - [0:0]
:FWDI_FedoraWorkstation_allow - [0:0]
:FWDI_FedoraWorkstation_deny - [0:0]
:FWDI_FedoraWorkstation_log - [0:0]
:FWDO_FedoraWorkstation - [0:0]
:FWDO_FedoraWorkstation_allow - [0:0]
:FWDO_FedoraWorkstation_deny - [0:0]
:FWDO_FedoraWorkstation_log - [0:0]
:INPUT_ZONES - [0:0]
:INPUT_ZONES_SOURCE - [0:0]
:INPUT_direct - [0:0]
:IN_FedoraWorkstation - [0:0]
:IN_FedoraWorkstation_allow - [0:0]
:IN_FedoraWorkstation_deny - [0:0]
:IN_FedoraWorkstation_log - [0:0]
:OUTPUT_direct - [0:0]
[5:6] -A INPUT -i virbr0 -p udp -m udp --dport 53 -j ACCEPT
[0:123456789] -A INPUT -i virbr0 -p tcp -m tcp --dport 53 -j ACCEPT
[0:0] -A INPUT -i virbr0 -p udp -m udp --dport 67 -j ACCEPT
[0:0] -A INPUT -i virbr0 -p tcp -m tcp --dport 67 -j ACCEPT
[0:0] -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[0:0] -A INPUT -i lo -j ACCEPT
[0:0] -A INPUT -j INPUT_direct
[0:0] -A INPUT -j INPUT_ZONES_SOURCE
[0:0] -A INPUT -j INPUT_ZONES
[0:0] -A INPUT -m conntrack --ctstate INVALID -j DROP
[0:0] -A INPUT -j REJECT --reject-with icmp-host-prohibited
[0:0] -A FORWARD -d 192.168.122.0/24 -o virbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[0:0] -A FORWARD -s 192.168.122.0/24 -i virbr0 -j ACCEPT
[0:0] -A FORWARD -i virbr0 -o virbr0 -j ACCEPT
[0:0] -A FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable
[0:0] -A FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable
[0:0] -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[0:0] -A FORWARD -i lo -j ACCEPT
[0:0] -A FORWARD -j FORWARD_direct
[0:0] -A FORWARD -j FORWARD_IN_ZONES_SOURCE
[0:0] -A FORWARD -j FORWARD_IN_ZONES
[0:0] -A FORWARD -j FORWARD_OUT_ZONES_SOURCE
[0:0] -A FORWARD -j FORWARD_OUT_ZONES
[0:0] -A FORWARD -m conntrack --ctstate INVALID -j DROP
[0:0] -A FORWARD -j REJECT --reject-with icmp-host-prohibited
[0:0] -A OUTPUT -o virbr0 -p udp -m udp --dport 68 -j ACCEPT
[0:0] -A OUTPUT -j OUTPUT_direct
[0:0] -A FORWARD_IN_ZONES -i wlp58s0 -g FWDI_FedoraWorkstation
[0:0] -A FORWARD_IN_ZONES -g FWDI_FedoraWorkstation
[0:0] -A FORWARD_OUT_ZONES -o wlp58s0 -g FWDO_FedoraWorkstation
[0:0] -A FORWARD_OUT_ZONES -g FWDO_FedoraWorkstation
[0:0] -A FWDI_FedoraWorkstation -j FWDI_FedoraWorkstation_log
[0:0] -A FWDI_FedoraWorkstation -j FWDI_FedoraWorkstation_deny
[0:0] -A FWDI_FedoraWorkstation -j FWDI_FedoraWorkstation_allow
[0:0] -A FWDI_FedoraWorkstation -p icmp -j ACCEPT
[0:0] -A FWDO_FedoraWorkstation -j FWDO_FedoraWorkstation_log
[0:0] -A FWDO_FedoraWorkstation -j FWDO_FedoraWorkstation_deny
[0:0] -A FWDO_FedoraWorkstation -j FWDO_FedoraWorkstation_allow
[0:0] -A INPUT_ZONES -i wlp58s0 -g IN_FedoraWorkstation
[0:0] -A INPUT_ZONES -g IN_FedoraWorkstation
[0:0] -A IN_FedoraWorkstation -j IN_FedoraWorkstation_log
[0:0] -A IN_FedoraWorkstation -j IN_FedoraWorkstation_deny
[0:0] -A IN_FedoraWorkstation -j IN_FedoraWorkstation_allow
[0:0] -A IN_FedoraWorkstation -p icmp -j ACCEPT
[0:0] -A IN_FedoraWorkstation_allow -p udp -m udp --dport 137 -m conntrack --ctstate NEW -j ACCEPT
[0:0] -A IN_FedoraWorkstation_allow -p udp -m udp --dport 138 -m conntrack --ctstate NEW -j ACCEPT
[0:0] -A IN_FedoraWorkstation_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
[0:0] -A IN_FedoraWorkstation_allow -d 224.0.0.251/32 -p udp -m udp --dport 5353 -m conntrack --ctstate NEW -j ACCEPT
[0:0] -A IN_FedoraWorkstation_allow -p udp -m udp --dport 1025:65535 -m conntrack --ctstate NEW -j ACCEPT
[7:8] -A IN_FedoraWorkstation_allow -p tcp -m tcp --dport 1025:65535 -m conntrack --ctstate NEW -j ACCEPT
COMMIT
# Completed on Sat Feb 17 10:50:33 2018
iptables/tests/shell/testcases/ipt-save/dumps/ipt-save-filter.txt
0 → 100644
View file @
fe62f28a
# Generated by iptables-save v1.2.4 on Mon Mar 17 19:59:10 2003
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
:WLAN - [0:0]
:accept_log - [0:0]
:block - [0:0]
:in_icmp - [0:0]
:in_trusted - [0:0]
:reject_log - [0:0]
:wlanout - [0:0]
-A INPUT -i wlan0 -j WLAN
-A INPUT -s 127.0.0.1/32 -d 127.0.0.1/32 -i lo -j ACCEPT
-A INPUT -i ppp0 -p icmp -m limit --limit 1/sec -j in_icmp
-A INPUT -i ppp0 -p tcp -m tcp --dport 22 -j in_trusted
-A INPUT -j block
-A FORWARD -d 192.168.100.77/32 -i ppp0 -p udp -m udp --dport 4166 -j ACCEPT
-A FORWARD -d 192.168.100.77/32 -i ppp0 -p tcp -m tcp --dport 4180 -j ACCEPT
-A FORWARD -d 192.168.100.77/32 -i ppp0 -p tcp -m tcp --dport 4162 -j ACCEPT
-A FORWARD -d 192.168.100.77/32 -i ppp0 -p tcp -m tcp --dport 20376 -j ACCEPT
-A FORWARD -d 192.168.100.2/32 -i ppp0 -p tcp -m tcp --dport 10209 -j ACCEPT
-A FORWARD -d 192.168.100.2/32 -i ppp0 -p tcp -m tcp --dport 881 -j ACCEPT
-A FORWARD ! -s 192.168.0.0/24 -i eth2 -p icmp -j DROP
-A FORWARD ! -s 192.168.0.0/24 -i eth2 -p udp -j DROP
-A FORWARD ! -s 192.168.0.0/24 -i eth2 -p tcp -j DROP
-A FORWARD ! -s 192.168.100.0/24 -i eth1 -p icmp -j DROP
-A FORWARD ! -s 192.168.100.0/24 -i eth1 -p udp -j DROP
-A FORWARD ! -s 192.168.100.0/24 -i eth1 -p tcp -j DROP
-A FORWARD -o ppp0 -p udp -m udp --sport 137:139 -j DROP
-A FORWARD -o ppp0 -p udp -m udp --sport 445 -j DROP
-A FORWARD -o ppp0 -p tcp -m tcp --sport 137:139 -j DROP
-A FORWARD -o ppp0 -p tcp -m tcp --sport 445 -j DROP
-A FORWARD -i ppp0 -p udp -m udp --dport 137:139 -j DROP
-A FORWARD -i ppp0 -p udp -m udp --dport 445 -j DROP
-A FORWARD -i ppp0 -p tcp -m tcp --dport 137:139 -j DROP
-A FORWARD -i ppp0 -p tcp -m tcp --dport 445 -j DROP
-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
-A FORWARD -j block
-A OUTPUT -s 127.0.0.1/32 -d 127.0.0.1/32 -o lo -j ACCEPT
-A OUTPUT -o wlan0 -j wlanout
-A OUTPUT -j block
-A WLAN -s 192.168.200.4/32 -m mac --mac-source 00:00:F1:05:A0:E0 -j RETURN
-A WLAN -s 192.168.200.9/32 -m mac --mac-source 00:00:F1:05:99:85 -j RETURN
-A WLAN -m limit --limit 12/min -j LOG --log-prefix "UNKNOWN WLAN dropped:"
-A WLAN -j DROP
-A accept_log -i ppp0 -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -m limit --limit 1/sec -j LOG --log-prefix "TCPConnect on ppp0:"
-A accept_log -i ppp0 ! -p tcp -m limit --limit 1/sec -j LOG --log-prefix "Accepted Datagram on ppp0:"
-A accept_log -j ACCEPT
-A block -m state --state RELATED,ESTABLISHED -j ACCEPT
-A block ! -i ppp0 -m state --state NEW -j ACCEPT
-A block -p tcp -j reject_log
-A block -p udp -j reject_log
-A in_icmp -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A in_icmp -p icmp -m icmp --icmp-type 4 -j ACCEPT
-A in_icmp -p icmp -m icmp --icmp-type 1 -j ACCEPT
-A in_icmp -p icmp -m icmp --icmp-type 3 -j ACCEPT
-A in_icmp -p icmp -m icmp --icmp-type 11 -j ACCEPT
-A in_icmp -p icmp -m icmp --icmp-type 12 -j ACCEPT
-A in_trusted -s 10.230.173.148/32 -j ACCEPT
-A in_trusted -s 10.230.173.151/32 -j ACCEPT
-A reject_log -i ppp0 -p tcp -m tcp --dport 22:80 --tcp-flags SYN,RST,ACK SYN -m limit --limit 1/sec -j LOG --log-prefix "RejectTCPConnectReq on ppp0:"
-A reject_log -p tcp -j REJECT --reject-with tcp-reset
-A reject_log -p udp -j REJECT --reject-with icmp-port-unreachable
-A wlanout -d 192.168.200.4/32 -j RETURN
-A wlanout -d 192.168.200.9/32 -j RETURN
-A wlanout -j DROP
COMMIT
# Completed on Mon Mar 17 19:59:10 2003
iptables/tests/shell/testcases/ipt-save/dumps/policy-drop.txt
0 → 100644
View file @
fe62f28a
# Generated by xtables-save v1.6.2 on Tue Jun 26 22:28:41 2018
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
-A OUTPUT -j ACCEPT
COMMIT
# Completed on Tue Jun 26 22:28:41 2018
iptables/tests/shell/testcases/ipt-save/dumps/wireless.txt
0 → 100644
View file @
fe62f28a
# Generated by iptables-save v1.4.21 on Thu Jun 29 18:03:06 2017
*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:port_assignment - [0:0]
-A PREROUTING -j port_assignment
-A OUTPUT -j port_assignment
-A port_assignment -p tcp -m tcp --dport 1723 -j CT --helper pptp
COMMIT
# Completed on Thu Jun 29 18:03:06 2017
# Generated by iptables-save v1.4.21 on Thu Jun 29 18:03:06 2017
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:CUST_I15_IN - [0:0]
:CUST_I15_OUT - [0:0]
:CUST_I16_IN - [0:0]
:CUST_I16_OUT - [0:0]
:L_ACCEPT - [0:0]
:L_DROP - [0:0]
:L_REJECT - [0:0]
:VPN_USERS_IN - [0:0]
:VPN_USERS_OUT - [0:0]
-A INPUT -m conntrack --ctstate INVALID -j L_DROP
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j L_ACCEPT
-A INPUT -i lo -j L_ACCEPT
-A INPUT -s 10.78.129.130/32 -p tcp -m tcp --dport 5666 -j L_ACCEPT
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m multiport --dports 22,80,443,873,1723 -j L_ACCEPT
-A INPUT -p udp -m udp -m multiport --dports 500,1701,4500 -j L_ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j L_ACCEPT
-A INPUT -s 10.31.70.8/29 -i bond0.208 -p tcp -m tcp --dport 179 --tcp-flags FIN,SYN,RST,ACK SYN -j L_ACCEPT
-A INPUT -s 10.44.224.8/29 -i bond0.686 -p tcp -m tcp --dport 179 --tcp-flags FIN,SYN,RST,ACK SYN -j L_ACCEPT
-A INPUT -p esp -j L_ACCEPT
-A INPUT -s 168.209.255.75/32 -p gre -j L_ACCEPT
-A INPUT -s 168.209.255.106/32 -p gre -j L_ACCEPT
-A INPUT -s 10.35.167.46/32 -p gre -j L_ACCEPT
-A INPUT -s 10.35.167.45/32 -p gre -j L_ACCEPT
-A INPUT -i gre-wbcore -j L_ACCEPT
-A INPUT -i gre-davo-+ -j L_ACCEPT
-A INPUT -i bond0.208 -j L_DROP
-A INPUT -i bond0.686 -j L_DROP
-A INPUT -j L_ACCEPT
-A FORWARD -i bond0.10 -j ACCEPT
-A FORWARD -m conntrack --ctstate INVALID -j L_DROP
-A FORWARD -p tcp -m tcp --tcp-flags FIN,SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j L_ACCEPT
-A FORWARD -d 10.31.63.80/30 -o bond0.10 -j L_ACCEPT
-A FORWARD -o bond0.11 -j CUST_I16_IN
-A FORWARD -i bond0.11 -j CUST_I16_OUT
-A FORWARD -o bond0.12 -j CUST_I15_IN
-A FORWARD -i bond0.12 -j CUST_I15_OUT
-A FORWARD -s 192.168.255.0/24 -i ppp+ -o bond0.208 -j L_DROP
-A FORWARD -s 192.168.255.0/24 -i ppp+ -o bond0.686 -j L_DROP
-A FORWARD -j L_ACCEPT
-A CUST_I15_IN -p tcp -m tcp --dport 22 --tcp-flags FIN,SYN,RST,ACK SYN -j L_ACCEPT
-A CUST_I15_IN -p tcp -m tcp --dport 80 --tcp-flags FIN,SYN,RST,ACK SYN -j L_ACCEPT
-A CUST_I15_IN -p tcp -m tcp --dport 433 --tcp-flags FIN,SYN,RST,ACK SYN -j L_ACCEPT
-A CUST_I15_IN -p tcp -m tcp --dport 3306 --tcp-flags FIN,SYN,RST,ACK SYN -j L_ACCEPT
-A CUST_I15_IN -p tcp -m tcp --dport 3390 --tcp-flags FIN,SYN,RST,ACK SYN -j L_ACCEPT
-A CUST_I15_IN -j L_DROP
-A CUST_I15_OUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m multiport --dports 80,443 -j L_ACCEPT
-A CUST_I15_OUT -j L_DROP
-A CUST_I16_IN -p tcp -m tcp --dport 3390 --tcp-flags FIN,SYN,RST,ACK SYN -j L_ACCEPT
-A CUST_I16_IN -p tcp -m tcp --dport 21 --tcp-flags FIN,SYN,RST,ACK SYN -j L_ACCEPT
-A CUST_I16_IN -p icmp -m icmp --icmp-type 8 -j L_ACCEPT
-A CUST_I16_IN -j L_DROP
-A CUST_I16_OUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m multiport --dports 80,443 -j L_ACCEPT
-A CUST_I16_OUT -d 154.73.34.12/32 -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m multiport --dports 25 -j L_ACCEPT
-A CUST_I16_OUT -j L_DROP
-A L_ACCEPT -j NFLOG --nflog-group 1 --nflog-threshold 5
-A L_ACCEPT -j ACCEPT
-A L_DROP -j LOG --log-prefix "L_DROP: "
-A L_DROP -j NFLOG --nflog-group 2 --nflog-threshold 5
-A L_DROP -j DROP
-A L_REJECT -j NFLOG --nflog-group 3 --nflog-threshold 5
-A L_REJECT -j REJECT --reject-with icmp-port-unreachable
-A VPN_USERS_IN -i ppp0 -m comment --comment "User: " -j ACCEPT
-A VPN_USERS_OUT -o ppp0 -m comment --comment "User: " -j ACCEPT
COMMIT
# Completed on Thu Jun 29 18:03:06 2017
iptables/xshared.h
View file @
fe62f28a
...
@@ -48,8 +48,39 @@ struct xtables_afinfo {
...
@@ -48,8 +48,39 @@ struct xtables_afinfo {
int
so_rev_target
;
int
so_rev_target
;
};
};
/* trick for ebtables-compat, since watchers are targets */
struct
ebt_match
{
struct
ebt_match
*
next
;
union
{
struct
xtables_match
*
match
;
struct
xtables_target
*
watcher
;
}
u
;
bool
ismatch
;
};
/* Fake ebt_entry */
struct
ebt_entry
{
/* this needs to be the first field */
unsigned
int
bitmask
;
unsigned
int
invflags
;
uint16_t
ethproto
;
/* the physical in-dev */
char
in
[
IFNAMSIZ
];
/* the logical in-dev */
char
logical_in
[
IFNAMSIZ
];
/* the physical out-dev */
char
out
[
IFNAMSIZ
];
/* the logical out-dev */
char
logical_out
[
IFNAMSIZ
];
unsigned
char
sourcemac
[
6
];
unsigned
char
sourcemsk
[
6
];
unsigned
char
destmac
[
6
];
unsigned
char
destmsk
[
6
];
};
struct
iptables_command_state
{
struct
iptables_command_state
{
union
{
union
{
struct
ebt_entry
eb
;
struct
ipt_entry
fw
;
struct
ipt_entry
fw
;
struct
ip6t_entry
fw6
;
struct
ip6t_entry
fw6
;
};
};
...
@@ -57,6 +88,7 @@ struct iptables_command_state {
...
@@ -57,6 +88,7 @@ struct iptables_command_state {
int
c
;
int
c
;
unsigned
int
options
;
unsigned
int
options
;
struct
xtables_rule_match
*
matches
;
struct
xtables_rule_match
*
matches
;
struct
ebt_match
*
match_list
;
struct
xtables_target
*
target
;
struct
xtables_target
*
target
;
struct
xt_counters
counters
;
struct
xt_counters
counters
;
char
*
protocol
;
char
*
protocol
;
...
...
Prev
1
2
3
4
5
6
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