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
290749d4
Commit
290749d4
authored
Dec 03, 2019
by
Arturo Borrero Gonzalez
Browse files
New upstream version 1.8.4
parent
89c92f0c
Changes
87
Hide whitespace changes
Inline
Side-by-side
iptables/nft-cache.h
0 → 100644
View file @
290749d4
#ifndef _NFT_CACHE_H_
#define _NFT_CACHE_H_
struct
nft_handle
;
void
nft_fake_cache
(
struct
nft_handle
*
h
);
void
nft_build_cache
(
struct
nft_handle
*
h
,
struct
nftnl_chain
*
c
);
void
nft_rebuild_cache
(
struct
nft_handle
*
h
);
void
nft_release_cache
(
struct
nft_handle
*
h
);
void
flush_chain_cache
(
struct
nft_handle
*
h
,
const
char
*
tablename
);
int
flush_rule_cache
(
struct
nft_handle
*
h
,
const
char
*
table
,
struct
nftnl_chain
*
c
);
struct
nftnl_chain_list
*
nft_chain_list_get
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
);
struct
nftnl_set_list
*
nft_set_list_get
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
set
);
struct
nftnl_table_list
*
nftnl_table_list_get
(
struct
nft_handle
*
h
);
#endif
/* _NFT_CACHE_H_ */
iptables/nft-ipv4.c
View file @
290749d4
...
...
@@ -26,7 +26,7 @@
#include "nft.h"
#include "nft-shared.h"
static
int
nft_ipv4_add
(
struct
nftnl_rule
*
r
,
void
*
data
)
static
int
nft_ipv4_add
(
struct
nft_handle
*
h
,
struct
nftnl_rule
*
r
,
void
*
data
)
{
struct
iptables_command_state
*
cs
=
data
;
struct
xtables_rule_match
*
matchp
;
...
...
@@ -77,7 +77,7 @@ static int nft_ipv4_add(struct nftnl_rule *r, void *data)
add_compat
(
r
,
cs
->
fw
.
ip
.
proto
,
cs
->
fw
.
ip
.
invflags
&
XT_INV_PROTO
);
for
(
matchp
=
cs
->
matches
;
matchp
;
matchp
=
matchp
->
next
)
{
ret
=
add_match
(
r
,
matchp
->
match
->
m
);
ret
=
add_match
(
h
,
r
,
matchp
->
match
->
m
);
if
(
ret
<
0
)
return
ret
;
}
...
...
@@ -261,12 +261,12 @@ static void print_fragment(unsigned int flags, unsigned int invflags,
fputc
(
' '
,
stdout
);
}
static
void
nft_ipv4_print_rule
(
struct
nft
nl_ru
le
*
r
,
unsigned
int
num
,
unsigned
int
format
)
static
void
nft_ipv4_print_rule
(
struct
nft
_hand
le
*
h
,
struct
nftnl_rule
*
r
,
unsigned
int
num
,
unsigned
int
format
)
{
struct
iptables_command_state
cs
=
{};
nft_rule_to_iptables_command_state
(
r
,
&
cs
);
nft_rule_to_iptables_command_state
(
h
,
r
,
&
cs
);
print_rule_details
(
&
cs
,
cs
.
jumpto
,
cs
.
fw
.
ip
.
flags
,
cs
.
fw
.
ip
.
invflags
,
cs
.
fw
.
ip
.
proto
,
num
,
format
);
...
...
iptables/nft-ipv6.c
View file @
290749d4
...
...
@@ -25,7 +25,7 @@
#include "nft.h"
#include "nft-shared.h"
static
int
nft_ipv6_add
(
struct
nftnl_rule
*
r
,
void
*
data
)
static
int
nft_ipv6_add
(
struct
nft_handle
*
h
,
struct
nftnl_rule
*
r
,
void
*
data
)
{
struct
iptables_command_state
*
cs
=
data
;
struct
xtables_rule_match
*
matchp
;
...
...
@@ -66,7 +66,7 @@ static int nft_ipv6_add(struct nftnl_rule *r, void *data)
add_compat
(
r
,
cs
->
fw6
.
ipv6
.
proto
,
cs
->
fw6
.
ipv6
.
invflags
&
XT_INV_PROTO
);
for
(
matchp
=
cs
->
matches
;
matchp
;
matchp
=
matchp
->
next
)
{
ret
=
add_match
(
r
,
matchp
->
match
->
m
);
ret
=
add_match
(
h
,
r
,
matchp
->
match
->
m
);
if
(
ret
<
0
)
return
ret
;
}
...
...
@@ -187,12 +187,12 @@ static void nft_ipv6_parse_immediate(const char *jumpto, bool nft_goto,
cs
->
fw6
.
ipv6
.
flags
|=
IP6T_F_GOTO
;
}
static
void
nft_ipv6_print_rule
(
struct
nft
nl_ru
le
*
r
,
unsigned
int
num
,
unsigned
int
format
)
static
void
nft_ipv6_print_rule
(
struct
nft
_hand
le
*
h
,
struct
nftnl_rule
*
r
,
unsigned
int
num
,
unsigned
int
format
)
{
struct
iptables_command_state
cs
=
{};
nft_rule_to_iptables_command_state
(
r
,
&
cs
);
nft_rule_to_iptables_command_state
(
h
,
r
,
&
cs
);
print_rule_details
(
&
cs
,
cs
.
jumpto
,
cs
.
fw6
.
ipv6
.
flags
,
cs
.
fw6
.
ipv6
.
invflags
,
cs
.
fw6
.
ipv6
.
proto
,
...
...
iptables/nft-shared.c
View file @
290749d4
...
...
@@ -69,7 +69,7 @@ void add_payload(struct nftnl_rule *r, int offset, int len, uint32_t base)
}
/* bitwise operation is = sreg & mask ^ xor */
void
add_bitwise_u16
(
struct
nftnl_rule
*
r
,
int
mask
,
int
xor
)
void
add_bitwise_u16
(
struct
nftnl_rule
*
r
,
u
int
16_t
mask
,
u
int
16_t
xor
)
{
struct
nftnl_expr
*
expr
;
...
...
@@ -310,7 +310,6 @@ static void nft_parse_target(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
struct
xtables_target
*
target
;
struct
xt_entry_target
*
t
;
size_t
size
;
struct
nft_family_ops
*
ops
;
void
*
data
=
ctx
->
cs
;
target
=
xtables_find_target
(
targname
,
XTF_TRY_LOAD
);
...
...
@@ -327,8 +326,7 @@ static void nft_parse_target(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
target
->
t
=
t
;
ops
=
nft_family_ops_lookup
(
ctx
->
family
);
ops
->
parse_target
(
target
,
data
);
ctx
->
h
->
ops
->
parse_target
(
target
,
data
);
}
static
void
nft_parse_match
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
)
...
...
@@ -339,9 +337,8 @@ static void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
struct
xtables_match
*
match
;
struct
xtables_rule_match
**
matches
;
struct
xt_entry_match
*
m
;
struct
nft_family_ops
*
ops
;
switch
(
ctx
->
family
)
{
switch
(
ctx
->
h
->
family
)
{
case
NFPROTO_IPV4
:
case
NFPROTO_IPV6
:
case
NFPROTO_BRIDGE
:
...
...
@@ -349,7 +346,7 @@ static void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
break
;
default:
fprintf
(
stderr
,
"BUG: nft_parse_match() unknown family %d
\n
"
,
ctx
->
family
);
ctx
->
h
->
family
);
exit
(
EXIT_FAILURE
);
}
...
...
@@ -365,9 +362,8 @@ static void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
match
->
m
=
m
;
ops
=
nft_family_ops_lookup
(
ctx
->
family
);
if
(
ops
->
parse_match
!=
NULL
)
ops
->
parse_match
(
match
,
ctx
->
cs
);
if
(
ctx
->
h
->
ops
->
parse_match
!=
NULL
)
ctx
->
h
->
ops
->
parse_match
(
match
,
ctx
->
cs
);
}
void
print_proto
(
uint16_t
proto
,
int
invert
)
...
...
@@ -400,7 +396,6 @@ void get_cmp_data(struct nftnl_expr *e, void *data, size_t dlen, bool *inv)
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
;
...
...
@@ -429,8 +424,7 @@ static void nft_meta_set_to_target(struct nft_xt_ctx *ctx)
target
->
t
=
t
;
ops
=
nft_family_ops_lookup
(
ctx
->
family
);
ops
->
parse_target
(
target
,
ctx
->
cs
);
ctx
->
h
->
ops
->
parse_target
(
target
,
ctx
->
cs
);
}
static
void
nft_parse_meta
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
)
...
...
@@ -451,8 +445,16 @@ static void nft_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
static
void
nft_parse_payload
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
)
{
if
(
ctx
->
flags
&
NFT_XT_CTX_PAYLOAD
)
{
memcpy
(
&
ctx
->
prev_payload
,
&
ctx
->
payload
,
sizeof
(
ctx
->
prev_payload
));
ctx
->
flags
|=
NFT_XT_CTX_PREV_PAYLOAD
;
}
ctx
->
reg
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_META_DREG
);
ctx
->
payload
.
base
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_PAYLOAD_BASE
);
ctx
->
payload
.
offset
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_PAYLOAD_OFFSET
);
ctx
->
payload
.
len
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_PAYLOAD_LEN
);
ctx
->
flags
|=
NFT_XT_CTX_PAYLOAD
;
}
...
...
@@ -474,7 +476,6 @@ static void nft_parse_bitwise(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
static
void
nft_parse_cmp
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
)
{
struct
nft_family_ops
*
ops
=
nft_family_ops_lookup
(
ctx
->
family
);
void
*
data
=
ctx
->
cs
;
uint32_t
reg
;
...
...
@@ -483,12 +484,12 @@ static void nft_parse_cmp(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
return
;
if
(
ctx
->
flags
&
NFT_XT_CTX_META
)
{
ops
->
parse_meta
(
ctx
,
e
,
data
);
ctx
->
h
->
ops
->
parse_meta
(
ctx
,
e
,
data
);
ctx
->
flags
&=
~
NFT_XT_CTX_META
;
}
/* bitwise context is interpreted from payload */
if
(
ctx
->
flags
&
NFT_XT_CTX_PAYLOAD
)
{
ops
->
parse_payload
(
ctx
,
e
,
data
);
ctx
->
h
->
ops
->
parse_payload
(
ctx
,
e
,
data
);
ctx
->
flags
&=
~
NFT_XT_CTX_PAYLOAD
;
}
}
...
...
@@ -502,7 +503,6 @@ static void nft_parse_counter(struct nftnl_expr *e, struct xt_counters *counters
static
void
nft_parse_immediate
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
)
{
const
char
*
chain
=
nftnl_expr_get_str
(
e
,
NFTNL_EXPR_IMM_CHAIN
);
struct
nft_family_ops
*
ops
;
const
char
*
jumpto
=
NULL
;
bool
nft_goto
=
false
;
void
*
data
=
ctx
->
cs
;
...
...
@@ -544,8 +544,7 @@ static void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
break
;
}
ops
=
nft_family_ops_lookup
(
ctx
->
family
);
ops
->
parse_immediate
(
jumpto
,
nft_goto
,
data
);
ctx
->
h
->
ops
->
parse_immediate
(
jumpto
,
nft_goto
,
data
);
}
static
void
nft_parse_limit
(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
)
...
...
@@ -555,19 +554,18 @@ static void nft_parse_limit(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
__u64
rate
=
nftnl_expr_get_u64
(
e
,
NFTNL_EXPR_LIMIT_RATE
);
struct
xtables_rule_match
**
matches
;
struct
xtables_match
*
match
;
struct
nft_family_ops
*
ops
;
struct
xt_rateinfo
*
rinfo
;
size_t
size
;
switch
(
ctx
->
family
)
{
switch
(
ctx
->
h
->
family
)
{
case
NFPROTO_IPV4
:
case
NFPROTO_IPV6
:
case
NFPROTO_BRIDGE
:
matches
=
&
ctx
->
cs
->
matches
;
break
;
default:
fprintf
(
stderr
,
"BUG: nft_parse_
match
() unknown family %d
\n
"
,
ctx
->
family
);
fprintf
(
stderr
,
"BUG: nft_parse_
limit
() unknown family %d
\n
"
,
ctx
->
h
->
family
);
exit
(
EXIT_FAILURE
);
}
...
...
@@ -586,20 +584,27 @@ static void nft_parse_limit(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
rinfo
->
avg
=
XT_LIMIT_SCALE
*
unit
/
rate
;
rinfo
->
burst
=
burst
;
ops
=
nft_family_ops_lookup
(
ctx
->
family
);
if
(
ops
->
parse_match
!=
NULL
)
ops
->
parse_match
(
match
,
ctx
->
cs
);
if
(
ctx
->
h
->
ops
->
parse_match
!=
NULL
)
ctx
->
h
->
ops
->
parse_match
(
match
,
ctx
->
cs
);
}
static
void
nft_parse_lookup
(
struct
nft_xt_ctx
*
ctx
,
struct
nft_handle
*
h
,
struct
nftnl_expr
*
e
)
{
if
(
ctx
->
h
->
ops
->
parse_lookup
)
ctx
->
h
->
ops
->
parse_lookup
(
ctx
,
e
,
NULL
);
}
void
nft_rule_to_iptables_command_state
(
const
struct
nftnl_rule
*
r
,
void
nft_rule_to_iptables_command_state
(
struct
nft_handle
*
h
,
const
struct
nftnl_rule
*
r
,
struct
iptables_command_state
*
cs
)
{
struct
nftnl_expr_iter
*
iter
;
struct
nftnl_expr
*
expr
;
int
family
=
nftnl_rule_get_u32
(
r
,
NFTNL_RULE_FAMILY
);
struct
nft_xt_ctx
ctx
=
{
.
cs
=
cs
,
.
family
=
family
,
.
h
=
h
,
.
table
=
nftnl_rule_get_str
(
r
,
NFTNL_RULE_TABLE
),
};
iter
=
nftnl_expr_iter_create
(
r
);
...
...
@@ -630,6 +635,8 @@ void nft_rule_to_iptables_command_state(const struct nftnl_rule *r,
nft_parse_target
(
&
ctx
,
expr
);
else
if
(
strcmp
(
name
,
"limit"
)
==
0
)
nft_parse_limit
(
&
ctx
,
expr
);
else
if
(
strcmp
(
name
,
"lookup"
)
==
0
)
nft_parse_lookup
(
&
ctx
,
h
,
expr
);
expr
=
nftnl_expr_iter_next
(
iter
);
}
...
...
@@ -982,19 +989,18 @@ void nft_ipv46_parse_target(struct xtables_target *t, void *data)
cs
->
target
=
t
;
}
bool
nft_ipv46_rule_find
(
struct
nft_family_ops
*
ops
,
struct
nftnl_rule
*
r
,
void
*
data
)
bool
nft_ipv46_rule_find
(
struct
nft_handle
*
h
,
struct
nftnl_rule
*
r
,
void
*
data
)
{
struct
iptables_command_state
*
cs
=
data
,
this
=
{};
bool
ret
=
false
;
nft_rule_to_iptables_command_state
(
r
,
&
this
);
nft_rule_to_iptables_command_state
(
h
,
r
,
&
this
);
DEBUGP
(
"comparing with... "
);
#ifdef DEBUG_DEL
nft_rule_print_save
(
r
,
NFT_RULE_APPEND
,
0
);
#endif
if
(
!
ops
->
is_same
(
cs
,
&
this
))
if
(
!
h
->
ops
->
is_same
(
cs
,
&
this
))
goto
out
;
if
(
!
compare_matches
(
cs
->
matches
,
this
.
matches
))
{
...
...
@@ -1014,7 +1020,7 @@ bool nft_ipv46_rule_find(struct nft_family_ops *ops,
ret
=
true
;
out:
ops
->
clear_cs
(
&
this
);
h
->
ops
->
clear_cs
(
&
this
);
return
ret
;
}
...
...
iptables/nft-shared.h
View file @
290749d4
...
...
@@ -35,6 +35,7 @@
#define FMT(tab,notab) ((format) & FMT_NOTABLE ? (notab) : (tab))
struct
xtables_args
;
struct
nft_handle
;
struct
xt_xlate
;
enum
{
...
...
@@ -42,19 +43,22 @@ enum {
NFT_XT_CTX_META
=
(
1
<<
1
),
NFT_XT_CTX_BITWISE
=
(
1
<<
2
),
NFT_XT_CTX_IMMEDIATE
=
(
1
<<
3
),
NFT_XT_CTX_PREV_PAYLOAD
=
(
1
<<
4
),
};
struct
nft_xt_ctx
{
struct
iptables_command_state
*
cs
;
struct
nftnl_expr_iter
*
iter
;
int
family
;
struct
nft_handle
*
h
;
uint32_t
flags
;
const
char
*
table
;
uint32_t
reg
;
struct
{
uint32_t
base
;
uint32_t
offset
;
uint32_t
len
;
}
payload
;
}
payload
,
prev_
payload
;
struct
{
uint32_t
key
;
}
meta
;
...
...
@@ -69,7 +73,7 @@ struct nft_xt_ctx {
};
struct
nft_family_ops
{
int
(
*
add
)(
struct
nftnl_rule
*
r
,
void
*
data
);
int
(
*
add
)(
struct
nft_handle
*
h
,
struct
nftnl_rule
*
r
,
void
*
data
);
bool
(
*
is_same
)(
const
void
*
data_a
,
const
void
*
data_b
);
void
(
*
print_payload
)(
struct
nftnl_expr
*
e
,
...
...
@@ -82,6 +86,8 @@ struct nft_family_ops {
void
*
data
);
void
(
*
parse_cmp
)(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
,
void
*
data
);
void
(
*
parse_lookup
)(
struct
nft_xt_ctx
*
ctx
,
struct
nftnl_expr
*
e
,
void
*
data
);
void
(
*
parse_immediate
)(
const
char
*
jumpto
,
bool
nft_goto
,
void
*
data
);
void
(
*
print_table_header
)(
const
char
*
tablename
);
...
...
@@ -89,8 +95,8 @@ struct nft_family_ops {
const
char
*
pol
,
const
struct
xt_counters
*
counters
,
bool
basechain
,
uint32_t
refs
,
uint32_t
entries
);
void
(
*
print_rule
)(
struct
nft
nl_ru
le
*
r
,
unsigned
int
num
,
unsigned
int
format
);
void
(
*
print_rule
)(
struct
nft
_hand
le
*
h
,
struct
nftnl_rule
*
r
,
unsigned
int
num
,
unsigned
int
format
);
void
(
*
save_rule
)(
const
void
*
data
,
unsigned
int
format
);
void
(
*
save_counters
)(
const
void
*
data
);
void
(
*
save_chain
)(
const
struct
nftnl_chain
*
c
,
const
char
*
policy
);
...
...
@@ -100,10 +106,10 @@ struct nft_family_ops {
struct
xtables_args
*
args
);
void
(
*
parse_match
)(
struct
xtables_match
*
m
,
void
*
data
);
void
(
*
parse_target
)(
struct
xtables_target
*
t
,
void
*
data
);
void
(
*
rule_to_cs
)(
const
struct
nftnl_rule
*
r
,
void
(
*
rule_to_cs
)(
struct
nft_handle
*
h
,
const
struct
nftnl_rule
*
r
,
struct
iptables_command_state
*
cs
);
void
(
*
clear_cs
)(
struct
iptables_command_state
*
cs
);
bool
(
*
rule_find
)(
struct
nft_
family_ops
*
ops
,
struct
nftnl_rule
*
r
,
bool
(
*
rule_find
)(
struct
nft_
handle
*
h
,
struct
nftnl_rule
*
r
,
void
*
data
);
int
(
*
xlate
)(
const
void
*
data
,
struct
xt_xlate
*
xl
);
};
...
...
@@ -111,7 +117,7 @@ struct nft_family_ops {
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_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
,
u
int
16_t
mask
,
u
int
16_t
xor
);
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_u16
(
struct
nftnl_rule
*
r
,
uint16_t
val
,
uint32_t
op
);
...
...
@@ -137,7 +143,8 @@ int parse_meta(struct nftnl_expr *e, uint8_t key, char *iniface,
unsigned
char
*
outiface_mask
,
uint8_t
*
invflags
);
void
print_proto
(
uint16_t
proto
,
int
invert
);
void
get_cmp_data
(
struct
nftnl_expr
*
e
,
void
*
data
,
size_t
dlen
,
bool
*
inv
);
void
nft_rule_to_iptables_command_state
(
const
struct
nftnl_rule
*
r
,
void
nft_rule_to_iptables_command_state
(
struct
nft_handle
*
h
,
const
struct
nftnl_rule
*
r
,
struct
iptables_command_state
*
cs
);
void
nft_clear_iptables_command_state
(
struct
iptables_command_state
*
cs
);
void
print_header
(
unsigned
int
format
,
const
char
*
chain
,
const
char
*
pol
,
...
...
@@ -163,9 +170,8 @@ void save_matches_and_target(const struct iptables_command_state *cs,
struct
nft_family_ops
*
nft_family_ops_lookup
(
int
family
);
struct
nft_handle
;
void
nft_ipv46_parse_target
(
struct
xtables_target
*
t
,
void
*
data
);
bool
nft_ipv46_rule_find
(
struct
nft_
family_ops
*
ops
,
struct
nftnl_rule
*
r
,
bool
nft_ipv46_rule_find
(
struct
nft_
handle
*
h
,
struct
nftnl_rule
*
r
,
void
*
data
);
bool
compare_matches
(
struct
xtables_rule_match
*
mt1
,
struct
xtables_rule_match
*
mt2
);
...
...
@@ -199,23 +205,6 @@ struct xtables_args {
unsigned
long
long
pcnt_cnt
,
bcnt_cnt
;
};
#define CMD_NONE 0x0000U
#define CMD_INSERT 0x0001U
#define CMD_DELETE 0x0002U
#define CMD_DELETE_NUM 0x0004U
#define CMD_REPLACE 0x0008U
#define CMD_APPEND 0x0010U
#define CMD_LIST 0x0020U
#define CMD_FLUSH 0x0040U
#define CMD_ZERO 0x0080U
#define CMD_NEW_CHAIN 0x0100U
#define CMD_DELETE_CHAIN 0x0200U
#define CMD_SET_POLICY 0x0400U
#define CMD_RENAME_CHAIN 0x0800U
#define CMD_LIST_RULES 0x1000U
#define CMD_ZERO_NUM 0x2000U
#define CMD_CHECK 0x4000U
struct
nft_xt_cmd_parse
{
unsigned
int
command
;
unsigned
int
rulenum
;
...
...
@@ -232,19 +221,10 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
struct
nft_xt_cmd_parse
*
p
,
struct
iptables_command_state
*
cs
,
struct
xtables_args
*
args
);
struct
nft_xt_restore_parse
{
FILE
*
in
;
int
testing
;
const
char
*
tablename
;
bool
commit
;
};
struct
nftnl_chain_list
;
struct
nft_xt_restore_cb
{
void
(
*
table_new
)(
struct
nft_handle
*
h
,
const
char
*
table
);
struct
nftnl_chain_list
*
(
*
chain_list
)(
struct
nft_handle
*
h
,
const
char
*
table
);
int
(
*
chain_set
)(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
,
const
char
*
policy
,
const
struct
xt_counters
*
counters
);
...
...
@@ -260,10 +240,16 @@ struct nft_xt_restore_cb {
int
(
*
abort
)(
struct
nft_handle
*
h
);
};
struct
nft_xt_restore_parse
{
FILE
*
in
;
int
testing
;
const
char
*
tablename
;
bool
commit
;
const
struct
nft_xt_restore_cb
*
cb
;
};
void
xtables_restore_parse
(
struct
nft_handle
*
h
,
struct
nft_xt_restore_parse
*
p
,
struct
nft_xt_restore_cb
*
cb
,
int
argc
,
char
*
argv
[]);
const
struct
nft_xt_restore_parse
*
p
);
void
nft_check_xt_legacy
(
int
family
,
bool
is_ipt_save
);
#endif
iptables/nft.c
View file @
290749d4
...
...
@@ -55,48 +55,18 @@
#include "nft.h"
#include "xshared.h"
/* proto_to_name */
#include "nft-cache.h"
#include "nft-shared.h"
#include "nft-bridge.h"
/* EBT_NOPROTO */
#include "xtables-config-parser.h"
static
void
*
nft_fn
;
static
int
genid_cb
(
const
struct
nlmsghdr
*
nlh
,
void
*
data
)
{
uint32_t
*
genid
=
data
;
struct
nftnl_gen
*
gen
;
gen
=
nftnl_gen_alloc
();
if
(
!
gen
)
return
MNL_CB_ERROR
;
if
(
nftnl_gen_nlmsg_parse
(
nlh
,
gen
)
<
0
)
goto
out
;
*
genid
=
nftnl_gen_get_u32
(
gen
,
NFTNL_GEN_ID
);
nftnl_gen_free
(
gen
);
return
MNL_CB_STOP
;
out:
nftnl_gen_free
(
gen
);
return
MNL_CB_ERROR
;
}
static
int
mnl_genid_get
(
struct
nft_handle
*
h
,
uint32_t
*
genid
)
{
char
buf
[
MNL_SOCKET_BUFFER_SIZE
];
struct
nlmsghdr
*
nlh
;
nlh
=
nftnl_nlmsg_build_hdr
(
buf
,
NFT_MSG_GETGEN
,
0
,
0
,
h
->
seq
);
return
mnl_talk
(
h
,
nlh
,
genid_cb
,
genid
);
}
int
mnl_talk
(
struct
nft_handle
*
h
,
struct
nlmsghdr
*
nlh
,
int
(
*
cb
)(
const
struct
nlmsghdr
*
nlh
,
void
*
data
),
void
*
data
)
{
int
ret
;
char
buf
[
16536
];
char
buf
[
32768
];
if
(
mnl_socket_sendto
(
h
->
nl
,
nlh
,
nlh
->
nlmsg_len
)
<
0
)
return
-
1
;
...
...
@@ -186,33 +156,42 @@ static void mnl_err_list_free(struct mnl_err *err)
free
(
err
);
}
static
int
nlbuffsiz
;
static
void
mnl_set_sndbuffer
(
const
struct
mnl_socket
*
nl
,
struct
nftnl_batch
*
batch
)
static
void
mnl_set_sndbuffer
(
struct
nft_handle
*
h
)
{
int
newbuffsiz
;
int
newbuffsiz
=
nftnl_batch_iovec_len
(
h
->
batch
)
*
BATCH_PAGE_SIZE
;
if
(
n
ftnl_batch_iovec_len
(
batch
)
*
BATCH_PAGE_SIZE
<=
nl
buffsiz
)
if
(
n
ewbuffsiz
<=
h
->
nlsnd
buffsiz
)
return
;
newbuffsiz
=
nftnl_batch_iovec_len
(
batch
)
*
BATCH_PAGE_SIZE
;
/* 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
(
h
->
nl
),
SOL_SOCKET
,
SO_SNDBUFFORCE
,
&
newbuffsiz
,
sizeof
(
socklen_t
))
<
0
)
return
;
h
->
nlsndbuffsiz
=
newbuffsiz
;
}
static
void
mnl_set_rcvbuffer
(
struct
nft_handle
*
h
,
int
numcmds
)
{
int
newbuffsiz
=
getpagesize
()
*
numcmds
;
if
(
newbuffsiz
<=
h
->
nlrcvbuffsiz
)
return
;
/* Rise receiver buffer length to avoid hitting -ENOBUFS */
if
(
setsockopt
(
mnl_socket_get_fd
(
h
->
nl
),
SOL_SOCKET
,
SO_RCVBUFFORCE
,
&
newbuffsiz
,
sizeof
(
socklen_t
))
<
0
)
return
;
nl
buffsiz
=
newbuffsiz
;
h
->
nlrcv
buffsiz
=
newbuffsiz
;
}
static
ssize_t
mnl_nft_socket_sendmsg
(
const
struct
mnl_socket
*
nf_sock
,
struct
nftnl_batch
*
batch
)
static
ssize_t
mnl_nft_socket_sendmsg
(
struct
nft_handle
*
h
,
int
numcmds
)
{
static
const
struct
sockaddr_nl
snl
=
{
.
nl_family
=
AF_NETLINK
};
uint32_t
iov_len
=
nftnl_batch_iovec_len
(
batch
);
uint32_t
iov_len
=
nftnl_batch_iovec_len
(
h
->
batch
);
struct
iovec
iov
[
iov_len
];
struct
msghdr
msg
=
{
.
msg_name
=
(
struct
sockaddr
*
)
&
snl
,
...
...
@@ -221,16 +200,16 @@ static ssize_t mnl_nft_socket_sendmsg(const struct mnl_socket *nf_sock,
.
msg_iovlen
=
iov_len
,
};
mnl_set_sndbuffer
(
nf_sock
,
batch
);
nftnl_batch_iovec
(
batch
,
iov
,
iov_len
);
mnl_set_sndbuffer
(
h
);
mnl_set_rcvbuffer
(
h
,
numcmds
);
nftnl_batch_iovec
(
h
->
batch
,
iov
,
iov_len
);
return
sendmsg
(
mnl_socket_get_fd
(
nf_sock
),
&
msg
,
0
);
return
sendmsg
(
mnl_socket_get_fd
(
h
->
nl
),
&
msg
,
0
);
}
static
int
mnl_batch_talk
(
const
struct
mnl_socket
*
nf_sock
,
struct
nftnl_batch
*
batch
,
struct
list_head
*
err_list
)
static
int
mnl_batch_talk
(
struct
nft_handle
*
h
,
int
numcmds
)
{
const
struct
mnl_socket
*
nl
=
nf_sock
;
const
struct
mnl_socket
*
nl
=
h
->
nl
;
int
ret
,
fd
=
mnl_socket_get_fd
(
nl
),
portid
=
mnl_socket_get_portid
(
nl
);
char
rcv_buf
[
MNL_SOCKET_BUFFER_SIZE
];
fd_set
readfds
;
...
...
@@ -240,7 +219,7 @@ static int mnl_batch_talk(const struct mnl_socket *nf_sock,
};
int
err
=
0
;
ret
=
mnl_nft_socket_sendmsg
(
nf_sock
,
batch
);
ret
=
mnl_nft_socket_sendmsg
(
h
,
numcmds
);
if
(
ret
==
-
1
)
return
-
1
;
...
...
@@ -262,7 +241,8 @@ static int mnl_batch_talk(const struct mnl_socket *nf_sock,
ret
=
mnl_cb_run
(
rcv_buf
,
ret
,
0
,
portid
,
NULL
,
NULL
);
/* Continue on error, make sure we get all acknowledgments */
if
(
ret
==
-
1
)
{
mnl_err_list_node_add
(
err_list
,
errno
,
nlh
->
nlmsg_seq
);
mnl_err_list_node_add
(
&
h
->
err_list
,
errno
,
nlh
->
nlmsg_seq
);
err
=
-
1
;
}
...
...
@@ -291,6 +271,7 @@ enum obj_update_type {
NFT_COMPAT_RULE_REPLACE
,
NFT_COMPAT_RULE_DELETE
,
NFT_COMPAT_RULE_FLUSH
,
NFT_COMPAT_SET_ADD
,
};
enum
obj_action
{
...
...
@@ -308,6 +289,7 @@ struct obj_update {
struct
nftnl_table
*
table
;
struct
nftnl_chain
*
chain
;
struct
nftnl_rule
*
rule
;
struct
nftnl_set
*
set
;
void
*
ptr
;
};
struct
{
...
...
@@ -335,6 +317,7 @@ static int mnl_append_error(const struct nft_handle *h,
[
NFT_COMPAT_RULE_REPLACE
]
=
"RULE_REPLACE"
,
[
NFT_COMPAT_RULE_DELETE
]
=
"RULE_DELETE"
,
[
NFT_COMPAT_RULE_FLUSH
]
=
"RULE_FLUSH"
,
[
NFT_COMPAT_SET_ADD
]
=
"SET_ADD"
,
};
char
errmsg
[
256
];
char
tcr
[
128
];
...
...
@@ -371,10 +354,14 @@ static int mnl_append_error(const struct nft_handle *h,
nftnl_rule_get_str
(
o
->
rule
,
NFTNL_RULE_CHAIN
));
#if 0
{
nft_rule_print_save(o->rule, NFT_RULE_APPEND, FMT_NOCOUNTS);
nft_rule_print_save(
h,
o->rule, NFT_RULE_APPEND, FMT_NOCOUNTS);
}
#endif
break
;
case
NFT_COMPAT_SET_ADD
:
snprintf
(
tcr
,
sizeof
(
tcr
),
"set %s"
,
nftnl_set_get_str
(
o
->
set
,
NFTNL_SET_NAME
));
break
;
}
return
snprintf
(
buf
,
len
,
"%s: %s"
,
errmsg
,
tcr
);
...
...
@@ -404,6 +391,13 @@ batch_table_add(struct nft_handle *h, enum obj_update_type type,
return
batch_add
(
h
,
type
,
t
);
}
static
struct
obj_update
*
batch_set_add
(
struct
nft_handle
*
h
,
enum
obj_update_type
type
,
struct
nftnl_set
*
s
)
{
return
batch_add
(
h
,
type
,
s
);
}
static
int
batch_chain_add
(
struct
nft_handle
*
h
,
enum
obj_update_type
type
,
struct
nftnl_chain
*
c
)
{
...
...
@@ -647,7 +641,7 @@ static int nft_table_builtin_add(struct nft_handle *h,
if
(
t
==
NULL
)
return
-
1
;
nftnl_table_set
(
t
,
NFTNL_TABLE_NAME
,
(
char
*
)
_t
->
name
);
nftnl_table_set
_str
(
t
,
NFTNL_TABLE_NAME
,
_t
->
name
);
ret
=
batch_table_add
(
h
,
NFT_COMPAT_TABLE_ADD
,
t
)
?
0
:
-
1
;
...
...
@@ -664,12 +658,12 @@ nft_chain_builtin_alloc(const struct builtin_table *table,
if
(
c
==
NULL
)
return
NULL
;
nftnl_chain_set
(
c
,
NFTNL_CHAIN_TABLE
,
(
char
*
)
table
->
name
);
nftnl_chain_set
(
c
,
NFTNL_CHAIN_NAME
,
(
char
*
)
chain
->
name
);
nftnl_chain_set
_str
(
c
,
NFTNL_CHAIN_TABLE
,
table
->
name
);
nftnl_chain_set
_str
(
c
,
NFTNL_CHAIN_NAME
,
chain
->
name
);
nftnl_chain_set_u32
(
c
,
NFTNL_CHAIN_HOOKNUM
,
chain
->
hook
);
nftnl_chain_set_u32
(
c
,
NFTNL_CHAIN_PRIO
,
chain
->
prio
);
nftnl_chain_set_u32
(
c
,
NFTNL_CHAIN_POLICY
,
policy
);
nftnl_chain_set
(
c
,
NFTNL_CHAIN_TYPE
,
(
char
*
)
chain
->
type
);
nftnl_chain_set
_str
(
c
,
NFTNL_CHAIN_TYPE
,
chain
->
type
);
return
c
;
}
...
...
@@ -688,31 +682,25 @@ static void nft_chain_builtin_add(struct nft_handle *h,
nftnl_chain_list_add_tail
(
c
,
h
->
cache
->
table
[
table
->
type
].
chains
);
}
static
const
struct
builtin_table
*
__nft_table_builtin_find
(
const
struct
builtin_table
*
tables
,
const
char
*
table
)
/* find if built-in table already exists */
const
struct
builtin_table
*
nft_table_builtin_find
(
struct
nft_handle
*
h
,
const
char
*
table
)
{
int
i
;
bool
found
=
false
;
for
(
i
=
0
;
i
<
NFT_TABLE_MAX
;
i
++
)
{
if
(
tables
[
i
].
name
==
NULL
)
if
(
h
->
tables
[
i
].
name
==
NULL
)
continue
;
if
(
strcmp
(
tables
[
i
].
name
,
table
)
!=
0
)
if
(
strcmp
(
h
->
tables
[
i
].
name
,
table
)
!=
0
)
continue
;
found
=
true
;
break
;
}
return
found
?
&
tables
[
i
]
:
NULL
;
}
/* find if built-in table already exists */
const
struct
builtin_table
*
nft_table_builtin_find
(
struct
nft_handle
*
h
,
const
char
*
table
)
{
return
__nft_table_builtin_find
(
h
->
tables
,
table
);
return
found
?
&
h
->
tables
[
i
]
:
NULL
;
}
/* find if built-in chain already exists */
...
...
@@ -735,15 +723,16 @@ nft_chain_builtin_find(const struct builtin_table *t, const char *chain)
static
void
nft_chain_builtin_init
(
struct
nft_handle
*
h
,
const
struct
builtin_table
*
table
)
{
struct
nftnl_chain_list
*
list
=
nft_chain_list_get
(
h
,
table
->
name
)
;
struct
nftnl_chain_list
*
list
;
struct
nftnl_chain
*
c
;
int
i
;
if
(
!
list
)
return
;
/* Initialize built-in chains if they don't exist yet */
for
(
i
=
0
;
i
<
NF_INET_NUMHOOKS
&&
table
->
chains
[
i
].
name
!=
NULL
;
i
++
)
{
list
=
nft_chain_list_get
(
h
,
table
->
name
,
table
->
chains
[
i
].
name
);
if
(
!
list
)
continue
;
c
=
nftnl_chain_list_lookup_byname
(
list
,
table
->
chains
[
i
].
name
);
if
(
c
!=
NULL
)
...
...
@@ -782,7 +771,7 @@ static bool nft_chain_builtin(struct nftnl_chain *c)
return
nftnl_chain_get
(
c
,
NFTNL_CHAIN_HOOKNUM
)
!=
NULL
;
}
static
int
nft_restart
(
struct
nft_handle
*
h
)
int
nft_restart
(
struct
nft_handle
*
h
)
{
mnl_socket_close
(
h
->
nl
);
...
...
@@ -794,7 +783,8 @@ static int nft_restart(struct nft_handle *h)
return
-
1
;
h
->
portid
=
mnl_socket_get_portid
(
h
->
nl
);
nlbuffsiz
=
0
;
h
->
nlsndbuffsiz
=
0
;
h
->
nlrcvbuffsiz
=
0
;
return
0
;
}
...
...
@@ -820,67 +810,6 @@ int nft_init(struct nft_handle *h, const struct builtin_table *t)
return
0
;
}
static
int
__flush_rule_cache
(
struct
nftnl_rule
*
r
,
void
*
data
)
{
nftnl_rule_list_del
(
r
);
nftnl_rule_free
(
r
);
return
0
;
}
static
void
flush_rule_cache
(
struct
nftnl_chain
*
c
)
{
nftnl_rule_foreach
(
c
,
__flush_rule_cache
,
NULL
);
}
static
int
__flush_chain_cache
(
struct
nftnl_chain
*
c
,
void
*
data
)
{
nftnl_chain_list_del
(
c
);
nftnl_chain_free
(
c
);
return
0
;
}
static
int
flush_cache
(
struct
nft_cache
*
c
,
const
struct
builtin_table
*
tables
,
const
char
*
tablename
)
{
const
struct
builtin_table
*
table
;
int
i
;
if
(
tablename
)
{
table
=
__nft_table_builtin_find
(
tables
,
tablename
);
if
(
!
table
||
!
c
->
table
[
table
->
type
].
chains
)
return
0
;
nftnl_chain_list_foreach
(
c
->
table
[
table
->
type
].
chains
,
__flush_chain_cache
,
NULL
);
return
0
;
}
for
(
i
=
0
;
i
<
NFT_TABLE_MAX
;
i
++
)
{
if
(
tables
[
i
].
name
==
NULL
)
continue
;
if
(
!
c
->
table
[
i
].
chains
)
continue
;
nftnl_chain_list_free
(
c
->
table
[
i
].
chains
);
c
->
table
[
i
].
chains
=
NULL
;
}
nftnl_table_list_free
(
c
->
tables
);
c
->
tables
=
NULL
;
return
1
;
}
static
void
flush_chain_cache
(
struct
nft_handle
*
h
,
const
char
*
tablename
)
{
if
(
!
h
->
have_cache
)
return
;
if
(
flush_cache
(
h
->
cache
,
h
->
tables
,
tablename
))
h
->
have_cache
=
false
;
}
void
nft_fini
(
struct
nft_handle
*
h
)
{
flush_chain_cache
(
h
,
NULL
);
...
...
@@ -1015,13 +944,163 @@ static int add_nft_limit(struct nftnl_rule *r, struct xt_entry_match *m)
return
0
;
}
int
add_match
(
struct
nftnl_rule
*
r
,
struct
xt_entry_match
*
m
)
static
struct
nftnl_set
*
add_anon_set
(
struct
nft_handle
*
h
,
const
char
*
table
,
uint32_t
flags
,
uint32_t
key_type
,
uint32_t
key_len
,
uint32_t
size
)
{
static
uint32_t
set_id
=
0
;
struct
nftnl_set
*
s
;
s
=
nftnl_set_alloc
();
if
(
!
s
)
return
NULL
;
nftnl_set_set_u32
(
s
,
NFTNL_SET_FAMILY
,
h
->
family
);
nftnl_set_set_str
(
s
,
NFTNL_SET_TABLE
,
table
);
nftnl_set_set_str
(
s
,
NFTNL_SET_NAME
,
"__set%d"
);
nftnl_set_set_u32
(
s
,
NFTNL_SET_ID
,
++
set_id
);
nftnl_set_set_u32
(
s
,
NFTNL_SET_FLAGS
,
NFT_SET_ANONYMOUS
|
NFT_SET_CONSTANT
|
flags
);
nftnl_set_set_u32
(
s
,
NFTNL_SET_KEY_TYPE
,
key_type
);
nftnl_set_set_u32
(
s
,
NFTNL_SET_KEY_LEN
,
key_len
);
nftnl_set_set_u32
(
s
,
NFTNL_SET_DESC_SIZE
,
size
);
return
batch_set_add
(
h
,
NFT_COMPAT_SET_ADD
,
s
)
?
s
:
NULL
;
}
static
struct
nftnl_expr
*
gen_payload
(
uint32_t
base
,
uint32_t
offset
,
uint32_t
len
,
uint32_t
dreg
)
{
struct
nftnl_expr
*
e
=
nftnl_expr_alloc
(
"payload"
);
if
(
!
e
)
return
NULL
;
nftnl_expr_set_u32
(
e
,
NFTNL_EXPR_PAYLOAD_BASE
,
base
);
nftnl_expr_set_u32
(
e
,
NFTNL_EXPR_PAYLOAD_OFFSET
,
offset
);
nftnl_expr_set_u32
(
e
,
NFTNL_EXPR_PAYLOAD_LEN
,
len
);
nftnl_expr_set_u32
(
e
,
NFTNL_EXPR_PAYLOAD_DREG
,
dreg
);
return
e
;
}
static
struct
nftnl_expr
*
gen_lookup
(
uint32_t
sreg
,
const
char
*
set_name
,
uint32_t
set_id
,
uint32_t
flags
)
{
struct
nftnl_expr
*
e
=
nftnl_expr_alloc
(
"lookup"
);
if
(
!
e
)
return
NULL
;
nftnl_expr_set_u32
(
e
,
NFTNL_EXPR_LOOKUP_SREG
,
sreg
);
nftnl_expr_set_str
(
e
,
NFTNL_EXPR_LOOKUP_SET
,
set_name
);
nftnl_expr_set_u32
(
e
,
NFTNL_EXPR_LOOKUP_SET_ID
,
set_id
);
nftnl_expr_set_u32
(
e
,
NFTNL_EXPR_LOOKUP_FLAGS
,
flags
);
return
e
;
}
/* simplified nftables:include/netlink.h, netlink_padded_len() */
#define NETLINK_ALIGN 4
/* from nftables:include/datatype.h, TYPE_BITS */
#define CONCAT_TYPE_BITS 6
/* from nftables:include/datatype.h, enum datatypes */
#define NFT_DATATYPE_IPADDR 7
#define NFT_DATATYPE_ETHERADDR 9
static
int
__add_nft_among
(
struct
nft_handle
*
h
,
const
char
*
table
,
struct
nftnl_rule
*
r
,
struct
nft_among_pair
*
pairs
,
int
cnt
,
bool
dst
,
bool
inv
,
bool
ip
)
{
uint32_t
set_id
,
type
=
NFT_DATATYPE_ETHERADDR
,
len
=
ETH_ALEN
;
/* { !dst, dst } */
static
const
int
eth_addr_off
[]
=
{
offsetof
(
struct
ether_header
,
ether_shost
),
offsetof
(
struct
ether_header
,
ether_dhost
)
};
static
const
int
ip_addr_off
[]
=
{
offsetof
(
struct
iphdr
,
saddr
),
offsetof
(
struct
iphdr
,
daddr
)
};
struct
nftnl_expr
*
e
;
struct
nftnl_set
*
s
;
int
idx
=
0
;
if
(
ip
)
{
type
=
type
<<
CONCAT_TYPE_BITS
|
NFT_DATATYPE_IPADDR
;
len
+=
sizeof
(
struct
in_addr
)
+
NETLINK_ALIGN
-
1
;
len
&=
~
(
NETLINK_ALIGN
-
1
);
}
s
=
add_anon_set
(
h
,
table
,
0
,
type
,
len
,
cnt
);
if
(
!
s
)
return
-
ENOMEM
;
set_id
=
nftnl_set_get_u32
(
s
,
NFTNL_SET_ID
);
for
(
idx
=
0
;
idx
<
cnt
;
idx
++
)
{
struct
nftnl_set_elem
*
elem
=
nftnl_set_elem_alloc
();
if
(
!
elem
)
return
-
ENOMEM
;
nftnl_set_elem_set
(
elem
,
NFTNL_SET_ELEM_KEY
,
&
pairs
[
idx
],
len
);
nftnl_set_elem_add
(
s
,
elem
);
}
e
=
gen_payload
(
NFT_PAYLOAD_LL_HEADER
,
eth_addr_off
[
dst
],
ETH_ALEN
,
NFT_REG_1
);
if
(
!
e
)
return
-
ENOMEM
;
nftnl_rule_add_expr
(
r
,
e
);
if
(
ip
)
{
e
=
gen_payload
(
NFT_PAYLOAD_NETWORK_HEADER
,
ip_addr_off
[
dst
],
sizeof
(
struct
in_addr
),
NFT_REG32_02
);
if
(
!
e
)
return
-
ENOMEM
;
nftnl_rule_add_expr
(
r
,
e
);
}
e
=
gen_lookup
(
NFT_REG_1
,
"__set%d"
,
set_id
,
inv
);
if
(
!
e
)
return
-
ENOMEM
;
nftnl_rule_add_expr
(
r
,
e
);
return
0
;
}
static
int
add_nft_among
(
struct
nft_handle
*
h
,
struct
nftnl_rule
*
r
,
struct
xt_entry_match
*
m
)
{
struct
nft_among_data
*
data
=
(
struct
nft_among_data
*
)
m
->
data
;
const
char
*
table
=
nftnl_rule_get
(
r
,
NFTNL_RULE_TABLE
);
if
((
data
->
src
.
cnt
&&
data
->
src
.
ip
)
||
(
data
->
dst
.
cnt
&&
data
->
dst
.
ip
))
{
uint16_t
eth_p_ip
=
htons
(
ETH_P_IP
);
add_meta
(
r
,
NFT_META_PROTOCOL
);
add_cmp_ptr
(
r
,
NFT_CMP_EQ
,
&
eth_p_ip
,
2
);
}
if
(
data
->
src
.
cnt
)
__add_nft_among
(
h
,
table
,
r
,
data
->
pairs
,
data
->
src
.
cnt
,
false
,
data
->
src
.
inv
,
data
->
src
.
ip
);
if
(
data
->
dst
.
cnt
)
__add_nft_among
(
h
,
table
,
r
,
data
->
pairs
+
data
->
src
.
cnt
,
data
->
dst
.
cnt
,
true
,
data
->
dst
.
inv
,
data
->
dst
.
ip
);
return
0
;
}
int
add_match
(
struct
nft_handle
*
h
,
struct
nftnl_rule
*
r
,
struct
xt_entry_match
*
m
)
{
struct
nftnl_expr
*
expr
;
int
ret
;
if
(
!
strcmp
(
m
->
u
.
user
.
name
,
"limit"
))
return
add_nft_limit
(
r
,
m
);
else
if
(
!
strcmp
(
m
->
u
.
user
.
name
,
"among"
))
return
add_nft_among
(
h
,
r
,
m
);
expr
=
nftnl_expr_alloc
(
"match"
);
if
(
expr
==
NULL
)
...
...
@@ -1234,10 +1313,10 @@ nft_rule_new(struct nft_handle *h, const char *chain, const char *table,
return
NULL
;
nftnl_rule_set_u32
(
r
,
NFTNL_RULE_FAMILY
,
h
->
family
);
nftnl_rule_set
(
r
,
NFTNL_RULE_TABLE
,
(
char
*
)
table
);
nftnl_rule_set
(
r
,
NFTNL_RULE_CHAIN
,
(
char
*
)
chain
);
nftnl_rule_set
_str
(
r
,
NFTNL_RULE_TABLE
,
table
);
nftnl_rule_set
_str
(
r
,
NFTNL_RULE_CHAIN
,
chain
);
if
(
h
->
ops
->
add
(
r
,
data
)
<
0
)
if
(
h
->
ops
->
add
(
h
,
r
,
data
)
<
0
)
goto
err
;
return
r
;
...
...
@@ -1257,9 +1336,15 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
struct
nftnl_rule
*
r
;
int
type
;
/* If built-in chains don't exist for this table, create them */
if
(
nft_xtables_config_load
(
h
,
XTABLES_CONFIG_DEFAULT
,
0
)
<
0
)
nft_xt_builtin_init
(
h
,
table
);
nft_xt_builtin_init
(
h
,
table
);
/* Since ebtables user-defined chain policies are implemented as last
* rule in nftables, rule cache is required here to treat them right. */
if
(
h
->
family
==
NFPROTO_BRIDGE
)
{
c
=
nft_chain_find
(
h
,
table
,
chain
);
if
(
c
&&
!
nft_chain_builtin
(
c
))
nft_build_cache
(
h
,
c
);
}
nft_fn
=
nft_rule_append
;
...
...
@@ -1280,7 +1365,7 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
}
if
(
verbose
)
h
->
ops
->
print_rule
(
r
,
0
,
FMT_PRINT_RULE
);
h
->
ops
->
print_rule
(
h
,
r
,
0
,
FMT_PRINT_RULE
);
if
(
ref
)
{
nftnl_chain_rule_insert_at
(
r
,
ref
);
...
...
@@ -1298,16 +1383,14 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
}
void
nft_rule_print_save
(
const
struct
nftnl_rule
*
r
,
enum
nft_rule_print
type
,
unsigned
int
format
)
nft_rule_print_save
(
struct
nft_handle
*
h
,
const
struct
nftnl_rule
*
r
,
enum
nft_rule_print
type
,
unsigned
int
format
)
{
const
char
*
chain
=
nftnl_rule_get_str
(
r
,
NFTNL_RULE_CHAIN
);
int
family
=
nftnl_rule_get_u32
(
r
,
NFTNL_RULE_FAMILY
);
struct
iptables_command_state
cs
=
{};
struct
nft_family_ops
*
ops
;
struct
nft_family_ops
*
ops
=
h
->
ops
;
ops
=
nft_family_ops_lookup
(
family
);
ops
->
rule_to_cs
(
r
,
&
cs
);
ops
->
rule_to_cs
(
h
,
r
,
&
cs
);
if
(
!
(
format
&
(
FMT_NOCOUNTS
|
FMT_C_COUNTS
))
&&
ops
->
save_counters
)
ops
->
save_counters
(
&
cs
);
...
...
@@ -1329,106 +1412,6 @@ nft_rule_print_save(const struct nftnl_rule *r, enum nft_rule_print type,
ops
->
clear_cs
(
&
cs
);
}
static
int
nftnl_chain_list_cb
(
const
struct
nlmsghdr
*
nlh
,
void
*
data
)
{
struct
nft_handle
*
h
=
data
;
const
struct
builtin_table
*
t
;
struct
nftnl_chain
*
c
;
c
=
nftnl_chain_alloc
();
if
(
c
==
NULL
)
goto
err
;
if
(
nftnl_chain_nlmsg_parse
(
nlh
,
c
)
<
0
)
goto
out
;
t
=
nft_table_builtin_find
(
h
,
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_TABLE
));
if
(
!
t
)
goto
out
;
nftnl_chain_list_add_tail
(
c
,
h
->
cache
->
table
[
t
->
type
].
chains
);
return
MNL_CB_OK
;
out:
nftnl_chain_free
(
c
);
err:
return
MNL_CB_OK
;
}
static
int
nftnl_table_list_cb
(
const
struct
nlmsghdr
*
nlh
,
void
*
data
)
{
struct
nftnl_table
*
t
;
struct
nftnl_table_list
*
list
=
data
;
t
=
nftnl_table_alloc
();
if
(
t
==
NULL
)
goto
err
;
if
(
nftnl_table_nlmsg_parse
(
nlh
,
t
)
<
0
)
goto
out
;
nftnl_table_list_add_tail
(
t
,
list
);
return
MNL_CB_OK
;
out:
nftnl_table_free
(
t
);
err:
return
MNL_CB_OK
;
}
static
int
fetch_table_cache
(
struct
nft_handle
*
h
)
{
char
buf
[
16536
];
struct
nlmsghdr
*
nlh
;
struct
nftnl_table_list
*
list
;
int
ret
;
list
=
nftnl_table_list_alloc
();
if
(
list
==
NULL
)
return
0
;
nlh
=
nftnl_rule_nlmsg_build_hdr
(
buf
,
NFT_MSG_GETTABLE
,
h
->
family
,
NLM_F_DUMP
,
h
->
seq
);
ret
=
mnl_talk
(
h
,
nlh
,
nftnl_table_list_cb
,
list
);
if
(
ret
<
0
&&
errno
==
EINTR
)
assert
(
nft_restart
(
h
)
>=
0
);
h
->
cache
->
tables
=
list
;
return
1
;
}
static
int
fetch_chain_cache
(
struct
nft_handle
*
h
)
{
char
buf
[
16536
];
struct
nlmsghdr
*
nlh
;
int
i
,
ret
;
fetch_table_cache
(
h
);
for
(
i
=
0
;
i
<
NFT_TABLE_MAX
;
i
++
)
{
enum
nft_table_type
type
=
h
->
tables
[
i
].
type
;
if
(
!
h
->
tables
[
i
].
name
)
continue
;
h
->
cache
->
table
[
type
].
chains
=
nftnl_chain_list_alloc
();
if
(
!
h
->
cache
->
table
[
type
].
chains
)
return
-
1
;
}
nlh
=
nftnl_chain_nlmsg_build_hdr
(
buf
,
NFT_MSG_GETCHAIN
,
h
->
family
,
NLM_F_DUMP
,
h
->
seq
);
ret
=
mnl_talk
(
h
,
nlh
,
nftnl_chain_list_cb
,
h
);
if
(
ret
<
0
&&
errno
==
EINTR
)
assert
(
nft_restart
(
h
)
>=
0
);
return
ret
;
}
static
bool
nft_rule_is_policy_rule
(
struct
nftnl_rule
*
r
)
{
const
struct
nftnl_udata
*
tb
[
UDATA_TYPE_MAX
+
1
]
=
{};
...
...
@@ -1467,8 +1450,8 @@ static struct nftnl_rule *nft_chain_last_rule(struct nftnl_chain *c)
return
last
;
}
static
void
nft_bridge_chain_postprocess
(
struct
nft_handle
*
h
,
struct
nftnl_chain
*
c
)
void
nft_bridge_chain_postprocess
(
struct
nft_handle
*
h
,
struct
nftnl_chain
*
c
)
{
struct
nftnl_rule
*
last
=
nft_chain_last_rule
(
c
);
struct
nftnl_expr_iter
*
iter
;
...
...
@@ -1509,138 +1492,6 @@ static void nft_bridge_chain_postprocess(struct nft_handle *h,
out_iter:
nftnl_expr_iter_destroy
(
iter
);
}
static
int
nftnl_rule_list_cb
(
const
struct
nlmsghdr
*
nlh
,
void
*
data
)
{
struct
nftnl_chain
*
c
=
data
;
struct
nftnl_rule
*
r
;
r
=
nftnl_rule_alloc
();
if
(
r
==
NULL
)
return
MNL_CB_OK
;
if
(
nftnl_rule_nlmsg_parse
(
nlh
,
r
)
<
0
)
{
nftnl_rule_free
(
r
);
return
MNL_CB_OK
;
}
nftnl_chain_rule_add_tail
(
r
,
c
);
return
MNL_CB_OK
;
}
static
int
nft_rule_list_update
(
struct
nftnl_chain
*
c
,
void
*
data
)
{
struct
nft_handle
*
h
=
data
;
char
buf
[
16536
];
struct
nlmsghdr
*
nlh
;
struct
nftnl_rule
*
rule
;
int
ret
;
rule
=
nftnl_rule_alloc
();
if
(
!
rule
)
return
-
1
;
nftnl_rule_set_str
(
rule
,
NFTNL_RULE_TABLE
,
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_TABLE
));
nftnl_rule_set_str
(
rule
,
NFTNL_RULE_CHAIN
,
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_NAME
));
nlh
=
nftnl_rule_nlmsg_build_hdr
(
buf
,
NFT_MSG_GETRULE
,
h
->
family
,
NLM_F_DUMP
,
h
->
seq
);
nftnl_rule_nlmsg_build_payload
(
nlh
,
rule
);
ret
=
mnl_talk
(
h
,
nlh
,
nftnl_rule_list_cb
,
c
);
if
(
ret
<
0
&&
errno
==
EINTR
)
assert
(
nft_restart
(
h
)
>=
0
);
nftnl_rule_free
(
rule
);
if
(
h
->
family
==
NFPROTO_BRIDGE
)
nft_bridge_chain_postprocess
(
h
,
c
);
return
0
;
}
static
int
fetch_rule_cache
(
struct
nft_handle
*
h
)
{
int
i
;
for
(
i
=
0
;
i
<
NFT_TABLE_MAX
;
i
++
)
{
enum
nft_table_type
type
=
h
->
tables
[
i
].
type
;
if
(
!
h
->
tables
[
i
].
name
)
continue
;
if
(
nftnl_chain_list_foreach
(
h
->
cache
->
table
[
type
].
chains
,
nft_rule_list_update
,
h
))
return
-
1
;
}
return
0
;
}
static
void
__nft_build_cache
(
struct
nft_handle
*
h
)
{
uint32_t
genid_start
,
genid_stop
;
retry:
mnl_genid_get
(
h
,
&
genid_start
);
fetch_chain_cache
(
h
);
fetch_rule_cache
(
h
);
h
->
have_cache
=
true
;
mnl_genid_get
(
h
,
&
genid_stop
);
if
(
genid_start
!=
genid_stop
)
{
flush_chain_cache
(
h
,
NULL
);
goto
retry
;
}
h
->
nft_genid
=
genid_start
;
}
void
nft_build_cache
(
struct
nft_handle
*
h
)
{
if
(
!
h
->
have_cache
)
__nft_build_cache
(
h
);
}
static
void
__nft_flush_cache
(
struct
nft_handle
*
h
)
{
if
(
!
h
->
cache_index
)
{
h
->
cache_index
++
;
h
->
cache
=
&
h
->
__cache
[
h
->
cache_index
];
}
else
{
flush_chain_cache
(
h
,
NULL
);
}
}
static
void
nft_rebuild_cache
(
struct
nft_handle
*
h
)
{
if
(
h
->
have_cache
)
__nft_flush_cache
(
h
);
__nft_build_cache
(
h
);
}
static
void
nft_release_cache
(
struct
nft_handle
*
h
)
{
if
(
h
->
cache_index
)
flush_cache
(
&
h
->
__cache
[
0
],
h
->
tables
,
NULL
);
}
struct
nftnl_chain_list
*
nft_chain_list_get
(
struct
nft_handle
*
h
,
const
char
*
table
)
{
const
struct
builtin_table
*
t
;
t
=
nft_table_builtin_find
(
h
,
table
);
if
(
!
t
)
return
NULL
;
nft_build_cache
(
h
);
return
h
->
cache
->
table
[
t
->
type
].
chains
;
}
static
const
char
*
policy_name
[
NF_ACCEPT
+
1
]
=
{
[
NF_DROP
]
=
"DROP"
,
[
NF_ACCEPT
]
=
"ACCEPT"
,
...
...
@@ -1648,12 +1499,10 @@ static const char *policy_name[NF_ACCEPT+1] = {
int
nft_chain_save
(
struct
nft_handle
*
h
,
struct
nftnl_chain_list
*
list
)
{
struct
nft_family_ops
*
ops
=
h
->
ops
;
struct
nftnl_chain_list_iter
*
iter
;
struct
nft_family_ops
*
ops
;
struct
nftnl_chain
*
c
;
ops
=
nft_family_ops_lookup
(
h
->
family
);
iter
=
nftnl_chain_list_iter_create
(
list
);
if
(
iter
==
NULL
)
return
0
;
...
...
@@ -1702,7 +1551,7 @@ static int nft_chain_save_rules(struct nft_handle *h,
r
=
nftnl_rule_iter_next
(
iter
);
while
(
r
!=
NULL
)
{
nft_rule_print_save
(
r
,
NFT_RULE_APPEND
,
format
);
nft_rule_print_save
(
h
,
r
,
NFT_RULE_APPEND
,
format
);
r
=
nftnl_rule_iter_next
(
iter
);
}
...
...
@@ -1717,7 +1566,7 @@ int nft_rule_save(struct nft_handle *h, const char *table, unsigned int format)
struct
nftnl_chain
*
c
;
int
ret
=
0
;
list
=
nft_chain_list_get
(
h
,
table
);
list
=
nft_chain_list_get
(
h
,
table
,
NULL
);
if
(
!
list
)
return
0
;
...
...
@@ -1727,6 +1576,7 @@ int nft_rule_save(struct nft_handle *h, const char *table, unsigned int format)
c
=
nftnl_chain_list_iter_next
(
iter
);
while
(
c
)
{
nft_build_cache
(
h
,
c
);
ret
=
nft_chain_save_rules
(
h
,
c
,
format
);
if
(
ret
!=
0
)
break
;
...
...
@@ -1747,15 +1597,16 @@ __nft_rule_flush(struct nft_handle *h, const char *table,
struct
obj_update
*
obj
;
struct
nftnl_rule
*
r
;
if
(
verbose
)
if
(
verbose
&&
chain
)
fprintf
(
stdout
,
"Flushing chain `%s'
\n
"
,
chain
);
r
=
nftnl_rule_alloc
();
if
(
r
==
NULL
)
return
;
nftnl_rule_set
(
r
,
NFTNL_RULE_TABLE
,
(
char
*
)
table
);
nftnl_rule_set
(
r
,
NFTNL_RULE_CHAIN
,
(
char
*
)
chain
);
nftnl_rule_set_str
(
r
,
NFTNL_RULE_TABLE
,
table
);
if
(
chain
)
nftnl_rule_set_str
(
r
,
NFTNL_RULE_CHAIN
,
chain
);
obj
=
batch_rule_add
(
h
,
NFT_COMPAT_RULE_FLUSH
,
r
);
if
(
!
obj
)
{
...
...
@@ -1769,29 +1620,34 @@ __nft_rule_flush(struct nft_handle *h, const char *table,
int
nft_rule_flush
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
bool
verbose
)
{
int
ret
=
0
;
struct
nftnl_chain_list
*
list
;
struct
nftnl_chain_list_iter
*
iter
;
struct
nftnl_chain
*
c
;
struct
nftnl_chain_list
*
list
;
struct
nftnl_chain
*
c
=
NULL
;
int
ret
=
0
;
if
(
nft_xtables_config_load
(
h
,
XTABLES_CONFIG_DEFAULT
,
0
)
<
0
)
nft_xt_builtin_init
(
h
,
table
);
nft_xt_builtin_init
(
h
,
table
);
nft_fn
=
nft_rule_flush
;
list
=
nft_chain_list_get
(
h
,
table
);
if
(
list
==
NULL
)
{
ret
=
1
;
goto
err
;
if
(
chain
||
verbose
)
{
list
=
nft_chain_list_get
(
h
,
table
,
chain
);
if
(
list
==
NULL
)
{
ret
=
1
;
goto
err
;
}
}
if
(
chain
)
{
c
=
nftnl_chain_list_lookup_byname
(
list
,
chain
);
if
(
!
c
)
if
(
!
c
)
{
errno
=
ENOENT
;
return
0
;
}
}
if
(
chain
||
!
verbose
)
{
__nft_rule_flush
(
h
,
table
,
chain
,
verbose
,
false
);
flush_rule_cache
(
c
);
flush_rule_cache
(
h
,
table
,
c
);
return
1
;
}
...
...
@@ -1803,11 +1659,10 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table,
c
=
nftnl_chain_list_iter_next
(
iter
);
while
(
c
!=
NULL
)
{
const
char
*
chain_name
=
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_NAME
);
chain
=
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_NAME
);
__nft_rule_flush
(
h
,
table
,
chain
_name
,
verbose
,
false
);
flush_rule_cache
(
c
);
__nft_rule_flush
(
h
,
table
,
chain
,
verbose
,
false
);
flush_rule_cache
(
h
,
table
,
c
);
c
=
nftnl_chain_list_iter_next
(
iter
);
}
nftnl_chain_list_iter_destroy
(
iter
);
...
...
@@ -1824,9 +1679,7 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl
nft_fn
=
nft_chain_user_add
;
/* If built-in chains don't exist for this table, create them */
if
(
nft_xtables_config_load
(
h
,
XTABLES_CONFIG_DEFAULT
,
0
)
<
0
)
nft_xt_builtin_init
(
h
,
table
);
nft_xt_builtin_init
(
h
,
table
);
if
(
nft_chain_exists
(
h
,
table
,
chain
))
{
errno
=
EEXIST
;
...
...
@@ -1837,14 +1690,14 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl
if
(
c
==
NULL
)
return
0
;
nftnl_chain_set
(
c
,
NFTNL_CHAIN_TABLE
,
(
char
*
)
table
);
nftnl_chain_set
(
c
,
NFTNL_CHAIN_NAME
,
(
char
*
)
chain
);
nftnl_chain_set
_str
(
c
,
NFTNL_CHAIN_TABLE
,
table
);
nftnl_chain_set
_str
(
c
,
NFTNL_CHAIN_NAME
,
chain
);
if
(
h
->
family
==
NFPROTO_BRIDGE
)
nftnl_chain_set_u32
(
c
,
NFTNL_CHAIN_POLICY
,
NF_ACCEPT
);
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_USER_ADD
,
c
);
list
=
nft_chain_list_get
(
h
,
table
);
list
=
nft_chain_list_get
(
h
,
table
,
chain
);
if
(
list
)
nftnl_chain_list_add
(
c
,
list
);
...
...
@@ -1871,8 +1724,8 @@ int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table
if
(
!
c
)
return
-
1
;
nftnl_chain_set
(
c
,
NFTNL_CHAIN_TABLE
,
(
char
*
)
table
);
nftnl_chain_set
(
c
,
NFTNL_CHAIN_NAME
,
(
char
*
)
chain
);
nftnl_chain_set
_str
(
c
,
NFTNL_CHAIN_TABLE
,
table
);
nftnl_chain_set
_str
(
c
,
NFTNL_CHAIN_NAME
,
chain
);
created
=
true
;
}
...
...
@@ -1884,7 +1737,7 @@ int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_USER_ADD
,
c
);
list
=
nft_chain_list_get
(
h
,
table
);
list
=
nft_chain_list_get
(
h
,
table
,
chain
);
if
(
list
)
nftnl_chain_list_add
(
c
,
list
);
...
...
@@ -1916,6 +1769,10 @@ static int __nft_chain_user_del(struct nftnl_chain *c, void *data)
fprintf
(
stdout
,
"Deleting chain `%s'
\n
"
,
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_NAME
));
/* This triggers required policy rule deletion. */
if
(
h
->
family
==
NFPROTO_BRIDGE
)
nft_build_cache
(
h
,
c
);
/* XXX This triggers a fast lookup from the kernel. */
nftnl_chain_unset
(
c
,
NFTNL_CHAIN_HANDLE
);
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_USER_DEL
,
c
);
...
...
@@ -1939,7 +1796,7 @@ int nft_chain_user_del(struct nft_handle *h, const char *chain,
nft_fn
=
nft_chain_user_del
;
list
=
nft_chain_list_get
(
h
,
table
);
list
=
nft_chain_list_get
(
h
,
table
,
chain
);
if
(
list
==
NULL
)
return
0
;
...
...
@@ -1967,7 +1824,7 @@ nft_chain_find(struct nft_handle *h, const char *table, const char *chain)
{
struct
nftnl_chain_list
*
list
;
list
=
nft_chain_list_get
(
h
,
table
);
list
=
nft_chain_list_get
(
h
,
table
,
chain
);
if
(
list
==
NULL
)
return
NULL
;
...
...
@@ -2003,9 +1860,7 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain,
return
0
;
}
/* If built-in chains don't exist for this table, create them */
if
(
nft_xtables_config_load
(
h
,
XTABLES_CONFIG_DEFAULT
,
0
)
<
0
)
nft_xt_builtin_init
(
h
,
table
);
nft_xt_builtin_init
(
h
,
table
);
/* Config load changed errno. Ensure genuine info for our callers. */
errno
=
0
;
...
...
@@ -2023,8 +1878,8 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain,
if
(
c
==
NULL
)
return
0
;
nftnl_chain_set
(
c
,
NFTNL_CHAIN_TABLE
,
(
char
*
)
table
);
nftnl_chain_set
(
c
,
NFTNL_CHAIN_NAME
,
(
char
*
)
newname
);
nftnl_chain_set
_str
(
c
,
NFTNL_CHAIN_TABLE
,
table
);
nftnl_chain_set
_str
(
c
,
NFTNL_CHAIN_NAME
,
newname
);
nftnl_chain_set_u64
(
c
,
NFTNL_CHAIN_HANDLE
,
handle
);
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_RENAME
,
c
);
...
...
@@ -2033,13 +1888,6 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain,
return
ret
==
0
?
1
:
0
;
}
static
struct
nftnl_table_list
*
nftnl_table_list_get
(
struct
nft_handle
*
h
)
{
nft_build_cache
(
h
);
return
h
->
cache
->
tables
;
}
bool
nft_table_find
(
struct
nft_handle
*
h
,
const
char
*
tablename
)
{
struct
nftnl_table_list_iter
*
iter
;
...
...
@@ -2075,8 +1923,8 @@ err:
}
int
nft_for_each_table
(
struct
nft_handle
*
h
,
int
(
*
func
)(
struct
nft_handle
*
h
,
const
char
*
tablename
,
bool
counters
),
bool
counters
)
int
(
*
func
)(
struct
nft_handle
*
h
,
const
char
*
tablename
,
void
*
data
),
void
*
data
)
{
struct
nftnl_table_list
*
list
;
struct
nftnl_table_list_iter
*
iter
;
...
...
@@ -2095,7 +1943,7 @@ int nft_for_each_table(struct nft_handle *h,
const
char
*
tablename
=
nftnl_table_get
(
t
,
NFTNL_TABLE_NAME
);
func
(
h
,
tablename
,
counters
);
func
(
h
,
tablename
,
data
);
t
=
nftnl_table_list_iter_next
(
iter
);
}
...
...
@@ -2179,8 +2027,7 @@ err_out:
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
);
nft_xt_builtin_init
(
h
,
table
);
}
static
int
__nft_rule_del
(
struct
nft_handle
*
h
,
struct
nftnl_rule
*
r
)
...
...
@@ -2189,6 +2036,9 @@ static int __nft_rule_del(struct nft_handle *h, struct nftnl_rule *r)
nftnl_rule_list_del
(
r
);
if
(
!
nftnl_rule_get_u64
(
r
,
NFTNL_RULE_HANDLE
))
nftnl_rule_set_u32
(
r
,
NFTNL_RULE_ID
,
++
h
->
rule_id
);
obj
=
batch_rule_add
(
h
,
NFT_COMPAT_RULE_DELETE
,
r
);
if
(
!
obj
)
{
nftnl_rule_free
(
r
);
...
...
@@ -2204,6 +2054,8 @@ nft_rule_find(struct nft_handle *h, struct nftnl_chain *c, void *data, int rulen
struct
nftnl_rule_iter
*
iter
;
bool
found
=
false
;
nft_build_cache
(
h
,
c
);
if
(
rulenum
>=
0
)
/* Delete by rule number case */
return
nftnl_rule_lookup_byindex
(
c
,
rulenum
);
...
...
@@ -2214,7 +2066,7 @@ nft_rule_find(struct nft_handle *h, struct nftnl_chain *c, void *data, int rulen
r
=
nftnl_rule_iter_next
(
iter
);
while
(
r
!=
NULL
)
{
found
=
h
->
ops
->
rule_find
(
h
->
ops
,
r
,
data
);
found
=
h
->
ops
->
rule_find
(
h
,
r
,
data
);
if
(
found
)
break
;
r
=
nftnl_rule_iter_next
(
iter
);
...
...
@@ -2242,7 +2094,7 @@ int nft_rule_check(struct nft_handle *h, const char *chain,
goto
fail_enoent
;
if
(
verbose
)
h
->
ops
->
print_rule
(
r
,
0
,
FMT_PRINT_RULE
);
h
->
ops
->
print_rule
(
h
,
r
,
0
,
FMT_PRINT_RULE
);
return
1
;
fail_enoent:
...
...
@@ -2271,7 +2123,7 @@ int nft_rule_delete(struct nft_handle *h, const char *chain,
if
(
ret
<
0
)
errno
=
ENOMEM
;
if
(
verbose
)
h
->
ops
->
print_rule
(
r
,
0
,
FMT_PRINT_RULE
);
h
->
ops
->
print_rule
(
h
,
r
,
0
,
FMT_PRINT_RULE
);
}
else
errno
=
ENOENT
;
...
...
@@ -2312,7 +2164,7 @@ nft_rule_add(struct nft_handle *h, const char *chain,
}
if
(
verbose
)
h
->
ops
->
print_rule
(
r
,
0
,
FMT_PRINT_RULE
);
h
->
ops
->
print_rule
(
h
,
r
,
0
,
FMT_PRINT_RULE
);
return
r
;
}
...
...
@@ -2323,9 +2175,7 @@ int nft_rule_insert(struct nft_handle *h, const char *chain,
struct
nftnl_rule
*
r
=
NULL
,
*
new_rule
;
struct
nftnl_chain
*
c
;
/* If built-in chains don't exist for this table, create them */
if
(
nft_xtables_config_load
(
h
,
XTABLES_CONFIG_DEFAULT
,
0
)
<
0
)
nft_xt_builtin_init
(
h
,
table
);
nft_xt_builtin_init
(
h
,
table
);
nft_fn
=
nft_rule_insert
;
...
...
@@ -2423,8 +2273,8 @@ int nft_rule_replace(struct nft_handle *h, const char *chain,
static
int
__nft_rule_list
(
struct
nft_handle
*
h
,
struct
nftnl_chain
*
c
,
int
rulenum
,
unsigned
int
format
,
void
(
*
cb
)(
struct
nft
nl_ru
le
*
r
,
unsigned
int
num
,
unsigned
int
format
))
void
(
*
cb
)(
struct
nft
_hand
le
*
h
,
struct
nftnl_rule
*
r
,
unsigned
int
num
,
unsigned
int
format
))
{
struct
nftnl_rule_iter
*
iter
;
struct
nftnl_rule
*
r
;
...
...
@@ -2437,7 +2287,7 @@ __nft_rule_list(struct nft_handle *h, struct nftnl_chain *c,
* valid chain but invalid rule number
*/
return
1
;
cb
(
r
,
rulenum
,
format
);
cb
(
h
,
r
,
rulenum
,
format
);
return
1
;
}
...
...
@@ -2447,7 +2297,7 @@ __nft_rule_list(struct nft_handle *h, struct nftnl_chain *c,
r
=
nftnl_rule_iter_next
(
iter
);
while
(
r
!=
NULL
)
{
cb
(
r
,
++
rule_ctr
,
format
);
cb
(
h
,
r
,
++
rule_ctr
,
format
);
r
=
nftnl_rule_iter_next
(
iter
);
}
...
...
@@ -2476,7 +2326,6 @@ static int nft_rule_count(struct nft_handle *h, struct nftnl_chain *c)
}
static
void
__nft_print_header
(
struct
nft_handle
*
h
,
const
struct
nft_family_ops
*
ops
,
struct
nftnl_chain
*
c
,
unsigned
int
format
)
{
const
char
*
chain_name
=
nftnl_chain_get_str
(
c
,
NFTNL_CHAIN_NAME
);
...
...
@@ -2492,31 +2341,23 @@ static void __nft_print_header(struct nft_handle *h,
if
(
nftnl_chain_is_set
(
c
,
NFTNL_CHAIN_POLICY
))
pname
=
policy_name
[
nftnl_chain_get_u32
(
c
,
NFTNL_CHAIN_POLICY
)];
ops
->
print_header
(
format
,
chain_name
,
pname
,
h
->
ops
->
print_header
(
format
,
chain_name
,
pname
,
&
ctrs
,
basechain
,
refs
-
entries
,
entries
);
}
int
nft_rule_list
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
int
rulenum
,
unsigned
int
format
)
{
const
struct
nft_family_ops
*
ops
;
const
struct
nft_family_ops
*
ops
=
h
->
ops
;
struct
nftnl_chain_list
*
list
;
struct
nftnl_chain_list_iter
*
iter
;
struct
nftnl_chain
*
c
;
bool
found
=
false
;
/* If built-in chains don't exist for this table, create them */
if
(
nft_xtables_config_load
(
h
,
XTABLES_CONFIG_DEFAULT
,
0
)
<
0
)
nft_xt_builtin_init
(
h
,
table
);
nft_xt_builtin_init
(
h
,
table
);
nft_assert_table_compatible
(
h
,
table
,
chain
);
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
;
}
list
=
nft_chain_list_get
(
h
,
table
);
list
=
nft_chain_list_get
(
h
,
table
,
chain
);
if
(
!
list
)
return
0
;
...
...
@@ -2528,7 +2369,7 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
if
(
!
rulenum
)
{
if
(
ops
->
print_table_header
)
ops
->
print_table_header
(
table
);
__nft_print_header
(
h
,
ops
,
c
,
format
);
__nft_print_header
(
h
,
c
,
format
);
}
__nft_rule_list
(
h
,
c
,
rulenum
,
format
,
ops
->
print_rule
);
return
1
;
...
...
@@ -2546,7 +2387,7 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
if
(
found
)
printf
(
"
\n
"
);
__nft_print_header
(
h
,
ops
,
c
,
format
);
__nft_print_header
(
h
,
c
,
format
);
__nft_rule_list
(
h
,
c
,
rulenum
,
format
,
ops
->
print_rule
);
found
=
true
;
...
...
@@ -2557,9 +2398,10 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
}
static
void
list_save
(
struct
nftnl_rule
*
r
,
unsigned
int
num
,
unsigned
int
format
)
list_save
(
struct
nft_handle
*
h
,
struct
nftnl_rule
*
r
,
unsigned
int
num
,
unsigned
int
format
)
{
nft_rule_print_save
(
r
,
NFT_RULE_APPEND
,
format
);
nft_rule_print_save
(
h
,
r
,
NFT_RULE_APPEND
,
format
);
}
static
int
__nftnl_rule_list_chain_save
(
struct
nftnl_chain
*
c
,
void
*
data
)
...
...
@@ -2612,16 +2454,10 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain,
struct
nftnl_chain
*
c
;
int
ret
=
0
;
/* If built-in chains don't exist for this table, create them */
if
(
nft_xtables_config_load
(
h
,
XTABLES_CONFIG_DEFAULT
,
0
)
<
0
)
nft_xt_builtin_init
(
h
,
table
);
nft_xt_builtin_init
(
h
,
table
);
nft_assert_table_compatible
(
h
,
table
,
chain
);
if
(
!
nft_is_table_compatible
(
h
,
table
))
{
xtables_error
(
OTHER_PROBLEM
,
"table `%s' is incompatible, use 'nft' tool.
\n
"
,
table
);
return
0
;
}
list
=
nft_chain_list_get
(
h
,
table
);
list
=
nft_chain_list_get
(
h
,
table
,
chain
);
if
(
!
list
)
return
0
;
...
...
@@ -2677,7 +2513,7 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain,
goto
error
;
}
nft_rule_to_iptables_command_state
(
r
,
&
cs
);
nft_rule_to_iptables_command_state
(
h
,
r
,
&
cs
);
cs
.
counters
.
pcnt
=
cs
.
counters
.
bcnt
=
0
;
...
...
@@ -2698,6 +2534,39 @@ static void nft_compat_table_batch_add(struct nft_handle *h, uint16_t type,
nftnl_table_nlmsg_build_payload
(
nlh
,
table
);
}
static
void
nft_compat_set_batch_add
(
struct
nft_handle
*
h
,
uint16_t
type
,
uint16_t
flags
,
uint32_t
seq
,
struct
nftnl_set
*
set
)
{
struct
nlmsghdr
*
nlh
;
nlh
=
nftnl_nlmsg_build_hdr
(
nftnl_batch_buffer
(
h
->
batch
),
type
,
h
->
family
,
flags
,
seq
);
nftnl_set_nlmsg_build_payload
(
nlh
,
set
);
}
static
void
nft_compat_setelem_batch_add
(
struct
nft_handle
*
h
,
uint16_t
type
,
uint16_t
flags
,
uint32_t
*
seq
,
struct
nftnl_set
*
set
)
{
struct
nftnl_set_elems_iter
*
iter
;
struct
nlmsghdr
*
nlh
;
iter
=
nftnl_set_elems_iter_create
(
set
);
if
(
!
iter
)
return
;
while
(
nftnl_set_elems_iter_cur
(
iter
))
{
(
*
seq
)
++
;
mnl_nft_batch_continue
(
h
->
batch
);
nlh
=
nftnl_nlmsg_build_hdr
(
nftnl_batch_buffer
(
h
->
batch
),
type
,
h
->
family
,
flags
,
*
seq
);
if
(
nftnl_set_elems_nlmsg_build_payload_iter
(
nlh
,
iter
)
<=
0
)
break
;
}
nftnl_set_elems_iter_destroy
(
iter
);
}
static
void
nft_compat_chain_batch_add
(
struct
nft_handle
*
h
,
uint16_t
type
,
uint16_t
flags
,
uint32_t
seq
,
struct
nftnl_chain
*
chain
)
...
...
@@ -2747,6 +2616,9 @@ static void batch_obj_del(struct nft_handle *h, struct obj_update *o)
case
NFT_COMPAT_RULE_FLUSH
:
nftnl_rule_free
(
o
->
rule
);
break
;
case
NFT_COMPAT_SET_ADD
:
nftnl_set_free
(
o
->
set
);
break
;
}
h
->
obj_list_num
--
;
list_del
(
&
o
->
head
);
...
...
@@ -2813,6 +2685,7 @@ static void nft_refresh_transaction(struct nft_handle *h)
case
NFT_COMPAT_RULE_REPLACE
:
case
NFT_COMPAT_RULE_DELETE
:
case
NFT_COMPAT_RULE_FLUSH
:
case
NFT_COMPAT_SET_ADD
:
break
;
}
}
...
...
@@ -2903,6 +2776,13 @@ retry:
nft_compat_rule_batch_add
(
h
,
NFT_MSG_DELRULE
,
0
,
n
->
seq
,
n
->
rule
);
break
;
case
NFT_COMPAT_SET_ADD
:
nft_compat_set_batch_add
(
h
,
NFT_MSG_NEWSET
,
NLM_F_CREATE
,
n
->
seq
,
n
->
set
);
nft_compat_setelem_batch_add
(
h
,
NFT_MSG_NEWSETELEM
,
NLM_F_CREATE
,
&
n
->
seq
,
n
->
set
);
seq
=
n
->
seq
;
break
;
}
mnl_nft_batch_continue
(
h
->
batch
);
...
...
@@ -2917,7 +2797,7 @@ retry:
}
errno
=
0
;
ret
=
mnl_batch_talk
(
h
->
nl
,
h
->
batch
,
&
h
->
err_list
);
ret
=
mnl_batch_talk
(
h
,
seq
);
if
(
ret
&&
errno
==
ERESTART
)
{
nft_rebuild_cache
(
h
);
...
...
@@ -3039,6 +2919,8 @@ int ebt_set_user_chain_policy(struct nft_handle *h, const char *table,
else
return
0
;
nft_build_cache
(
h
,
c
);
nftnl_chain_set_u32
(
c
,
NFTNL_CHAIN_POLICY
,
pval
);
return
1
;
}
...
...
@@ -3065,11 +2947,15 @@ static void nft_bridge_commit_prepare(struct nft_handle *h)
int
nft_commit
(
struct
nft_handle
*
h
)
{
if
(
h
->
family
==
NFPROTO_BRIDGE
)
nft_bridge_commit_prepare
(
h
);
return
nft_action
(
h
,
NFT_COMPAT_COMMIT
);
}
int
nft_bridge_commit
(
struct
nft_handle
*
h
)
{
nft_bridge_commit_prepare
(
h
);
return
nft_commit
(
h
);
}
int
nft_abort
(
struct
nft_handle
*
h
)
{
return
nft_action
(
h
,
NFT_COMPAT_ABORT
);
...
...
@@ -3204,7 +3090,7 @@ const char *nft_strerror(int err)
{
NULL
,
ENOENT
,
"No chain/target/match by that name"
},
};
for
(
i
=
0
;
i
<
sizeof
(
table
)
/
sizeof
(
struct
table_struct
);
i
++
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
table
);
i
++
)
{
if
((
!
table
[
i
].
fn
||
table
[
i
].
fn
==
nft_fn
)
&&
table
[
i
].
err
==
err
)
return
table
[
i
].
message
;
...
...
@@ -3213,136 +3099,42 @@ const char *nft_strerror(int err)
return
strerror
(
err
);
}
static
void
xtables_config_perror
(
uint32_t
flags
,
const
char
*
fmt
,
...)
{
va_list
args
;
va_start
(
args
,
fmt
);
if
(
flags
&
NFT_LOAD_VERBOSE
)
vfprintf
(
stderr
,
fmt
,
args
);
va_end
(
args
);
}
static
int
__nft_xtables_config_load
(
struct
nft_handle
*
h
,
const
char
*
filename
,
uint32_t
flags
)
static
int
recover_rule_compat
(
struct
nftnl_rule
*
r
)
{
struct
nftnl_table_list
*
table_list
=
NULL
;
struct
nftnl_chain_list
*
chain_list
=
NULL
;
struct
nftnl_table_list_iter
*
titer
=
NULL
;
struct
nftnl_chain_list_iter
*
citer
=
NULL
;
struct
nftnl_table
*
table
;
struct
nftnl_chain
*
chain
;
uint32_t
table_family
,
chain_family
;
bool
found
=
false
;
table_list
=
nftnl_table_list_alloc
();
chain_list
=
nftnl_chain_list_alloc
();
if
(
xtables_config_parse
(
filename
,
table_list
,
chain_list
)
<
0
)
{
if
(
errno
==
ENOENT
)
{
xtables_config_perror
(
flags
,
"configuration file `%s' does not exists
\n
"
,
filename
);
}
else
{
xtables_config_perror
(
flags
,
"Fatal error parsing config file: %s
\n
"
,
strerror
(
errno
));
}
goto
err
;
}
/* Stage 1) create tables */
titer
=
nftnl_table_list_iter_create
(
table_list
);
while
((
table
=
nftnl_table_list_iter_next
(
titer
))
!=
NULL
)
{
table_family
=
nftnl_table_get_u32
(
table
,
NFTNL_TABLE_FAMILY
);
if
(
h
->
family
!=
table_family
)
continue
;
found
=
true
;
if
(
batch_table_add
(
h
,
NFT_COMPAT_TABLE_ADD
,
table
)
<
0
)
{
if
(
errno
==
EEXIST
)
{
xtables_config_perror
(
flags
,
"table `%s' already exists, skipping
\n
"
,
(
char
*
)
nftnl_table_get
(
table
,
NFTNL_TABLE_NAME
));
}
else
{
xtables_config_perror
(
flags
,
"table `%s' cannot be create, reason `%s'. Exitting
\n
"
,
(
char
*
)
nftnl_table_get
(
table
,
NFTNL_TABLE_NAME
),
strerror
(
errno
));
goto
err
;
}
continue
;
}
xtables_config_perror
(
flags
,
"table `%s' has been created
\n
"
,
(
char
*
)
nftnl_table_get
(
table
,
NFTNL_TABLE_NAME
));
}
nftnl_table_list_iter_destroy
(
titer
);
nftnl_table_list_free
(
table_list
);
if
(
!
found
)
goto
err
;
/* Stage 2) create chains */
citer
=
nftnl_chain_list_iter_create
(
chain_list
);
while
((
chain
=
nftnl_chain_list_iter_next
(
citer
))
!=
NULL
)
{
chain_family
=
nftnl_chain_get_u32
(
chain
,
NFTNL_CHAIN_TABLE
);
if
(
h
->
family
!=
chain_family
)
continue
;
if
(
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_ADD
,
chain
)
<
0
)
{
if
(
errno
==
EEXIST
)
{
xtables_config_perror
(
flags
,
"chain `%s' already exists in table `%s', skipping
\n
"
,
(
char
*
)
nftnl_chain_get
(
chain
,
NFTNL_CHAIN_NAME
),
(
char
*
)
nftnl_chain_get
(
chain
,
NFTNL_CHAIN_TABLE
));
}
else
{
xtables_config_perror
(
flags
,
"chain `%s' cannot be create, reason `%s'. Exitting
\n
"
,
(
char
*
)
nftnl_chain_get
(
chain
,
NFTNL_CHAIN_NAME
),
strerror
(
errno
));
goto
err
;
}
continue
;
}
xtables_config_perror
(
flags
,
"chain `%s' in table `%s' has been created
\n
"
,
(
char
*
)
nftnl_chain_get
(
chain
,
NFTNL_CHAIN_NAME
),
(
char
*
)
nftnl_chain_get
(
chain
,
NFTNL_CHAIN_TABLE
));
}
nftnl_chain_list_iter_destroy
(
citer
);
nftnl_chain_list_free
(
chain_list
);
h
->
config_done
=
1
;
struct
nftnl_expr_iter
*
iter
;
struct
nftnl_expr
*
e
;
uint32_t
reg
;
int
ret
=
-
1
;
return
0
;
iter
=
nftnl_expr_iter_create
(
r
);
if
(
!
iter
)
return
-
1
;
err:
nftnl_table_list_free
(
table_list
);
nftnl_chain_list_free
(
chain_list
);
next_expr:
e
=
nftnl_expr_iter_next
(
iter
);
if
(
!
e
)
goto
out
;
if
(
titer
!=
NULL
)
nftnl_table_list_iter_destroy
(
titer
);
if
(
citer
!=
NULL
)
nftnl_chain_list_iter_destroy
(
citer
);
if
(
strcmp
(
"meta"
,
nftnl_expr_get_str
(
e
,
NFTNL_EXPR_NAME
))
||
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_META_KEY
)
!=
NFT_META_L4PROTO
)
goto
next_expr
;
h
->
config_done
=
-
1
;
reg
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_META_DREG
)
;
return
-
1
;
}
e
=
nftnl_expr_iter_next
(
iter
);
if
(
!
e
)
goto
out
;
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
);
if
(
strcmp
(
"cmp"
,
nftnl_expr_get_str
(
e
,
NFTNL_EXPR_NAME
))
||
reg
!=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_CMP_SREG
))
goto
next_expr
;
return
h
->
config_done
;
add_compat
(
r
,
nftnl_expr_get_u8
(
e
,
NFTNL_EXPR_CMP_DATA
),
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_CMP_OP
)
==
NFT_CMP_NEQ
);
ret
=
0
;
out:
nftnl_expr_iter_destroy
(
iter
);
return
ret
;
}
struct
chain_zero_data
{
...
...
@@ -3370,6 +3162,8 @@ static int __nft_chain_zero_counters(struct nftnl_chain *c, void *data)
return
-
1
;
}
nft_build_cache
(
h
,
c
);
iter
=
nftnl_rule_iter_create
(
c
);
if
(
iter
==
NULL
)
return
-
1
;
...
...
@@ -3407,6 +3201,7 @@ static int __nft_chain_zero_counters(struct nftnl_chain *c, void *data)
* Unset RULE_POSITION for older kernels, we want to replace
* rule based on its handle only.
*/
recover_rule_compat
(
r
);
nftnl_rule_unset
(
r
,
NFTNL_RULE_POSITION
);
if
(
!
batch_rule_add
(
h
,
NFT_COMPAT_RULE_REPLACE
,
r
))
{
nftnl_rule_iter_destroy
(
iter
);
...
...
@@ -3431,7 +3226,7 @@ int nft_chain_zero_counters(struct nft_handle *h, const char *chain,
struct
nftnl_chain
*
c
;
int
ret
=
0
;
list
=
nft_chain_list_get
(
h
,
table
);
list
=
nft_chain_list_get
(
h
,
table
,
chain
);
if
(
list
==
NULL
)
goto
err
;
...
...
@@ -3460,9 +3255,7 @@ uint32_t nft_invflags2cmp(uint32_t invflags, uint32_t flag)
return
NFT_CMP_EQ
;
}
#define NFT_COMPAT_EXPR_MAX 8
static
const
char
*
supported_exprs
[
NFT_COMPAT_EXPR_MAX
]
=
{
static
const
char
*
supported_exprs
[]
=
{
"match"
,
"target"
,
"payload"
,
...
...
@@ -3470,7 +3263,8 @@ static const char *supported_exprs[NFT_COMPAT_EXPR_MAX] = {
"cmp"
,
"bitwise"
,
"counter"
,
"immediate"
"immediate"
,
"lookup"
,
};
...
...
@@ -3479,7 +3273,7 @@ static int nft_is_expr_compatible(struct nftnl_expr *expr, void *data)
const
char
*
name
=
nftnl_expr_get_str
(
expr
,
NFTNL_EXPR_NAME
);
int
i
;
for
(
i
=
0
;
i
<
NFT_COMPAT_EXPR_MAX
;
i
++
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
supported_exprs
)
;
i
++
)
{
if
(
strcmp
(
supported_exprs
[
i
],
name
)
==
0
)
return
0
;
}
...
...
@@ -3506,6 +3300,8 @@ static int nft_is_chain_compatible(struct nftnl_chain *c, void *data)
enum
nf_inet_hooks
hook
;
int
prio
;
nft_build_cache
(
h
,
c
);
if
(
nftnl_rule_foreach
(
c
,
nft_is_rule_compatible
,
NULL
))
return
-
1
;
...
...
@@ -3533,11 +3329,12 @@ static int nft_is_chain_compatible(struct nftnl_chain *c, void *data)
return
0
;
}
bool
nft_is_table_compatible
(
struct
nft_handle
*
h
,
const
char
*
tablename
)
bool
nft_is_table_compatible
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
)
{
struct
nftnl_chain_list
*
clist
;
clist
=
nft_chain_list_get
(
h
,
table
name
);
clist
=
nft_chain_list_get
(
h
,
table
,
chain
);
if
(
clist
==
NULL
)
return
false
;
...
...
@@ -3546,3 +3343,22 @@ bool nft_is_table_compatible(struct nft_handle *h, const char *tablename)
return
true
;
}
void
nft_assert_table_compatible
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
)
{
const
char
*
pfx
=
""
,
*
sfx
=
""
;
if
(
nft_is_table_compatible
(
h
,
table
,
chain
))
return
;
if
(
chain
)
{
pfx
=
"chain `"
;
sfx
=
"' in "
;
}
else
{
chain
=
""
;
}
xtables_error
(
OTHER_PROBLEM
,
"%s%s%stable `%s' is incompatible, use 'nft' tool.
\n
"
,
pfx
,
chain
,
sfx
,
table
);
}
iptables/nft.h
View file @
290749d4
...
...
@@ -27,10 +27,19 @@ struct builtin_table {
struct
builtin_chain
chains
[
NF_INET_NUMHOOKS
];
};
enum
nft_cache_level
{
NFT_CL_NONE
,
NFT_CL_TABLES
,
NFT_CL_CHAINS
,
NFT_CL_SETS
,
NFT_CL_RULES
};
struct
nft_cache
{
struct
nftnl_table_list
*
tables
;
struct
{
struct
nftnl_chain_list
*
chains
;
struct
nftnl_set_list
*
sets
;
bool
initialized
;
}
table
[
NFT_TABLE_MAX
];
};
...
...
@@ -38,6 +47,8 @@ struct nft_cache {
struct
nft_handle
{
int
family
;
struct
mnl_socket
*
nl
;
int
nlsndbuffsiz
;
int
nlrcvbuffsiz
;
uint32_t
portid
;
uint32_t
seq
;
uint32_t
nft_genid
;
...
...
@@ -51,7 +62,7 @@ struct nft_handle {
unsigned
int
cache_index
;
struct
nft_cache
__cache
[
2
];
struct
nft_cache
*
cache
;
bool
have_cache
;
enum
nft_cache_level
cache_level
;
bool
restore
;
bool
noflush
;
int8_t
config_done
;
...
...
@@ -71,7 +82,7 @@ int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh,
void
*
data
);
int
nft_init
(
struct
nft_handle
*
h
,
const
struct
builtin_table
*
t
);
void
nft_fini
(
struct
nft_handle
*
h
);
void
nft_
build_cache
(
struct
nft_handle
*
h
);
int
nft_
restart
(
struct
nft_handle
*
h
);
/*
* Operations with tables.
...
...
@@ -79,7 +90,7 @@ void nft_build_cache(struct nft_handle *h);
struct
nftnl_table
;
struct
nftnl_chain_list
;
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
,
void
*
data
),
void
*
data
);
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_flush
(
struct
nft_handle
*
h
,
const
char
*
table
);
...
...
@@ -92,8 +103,6 @@ const struct builtin_table *nft_table_builtin_find(struct nft_handle *h, const c
struct
nftnl_chain
;
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_list_get
(
struct
nft_handle
*
h
,
const
char
*
table
);
int
nft_chain_save
(
struct
nft_handle
*
h
,
struct
nftnl_chain_list
*
list
);
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
,
bool
verbose
);
...
...
@@ -102,6 +111,9 @@ int nft_chain_user_rename(struct nft_handle *h, const char *chain, const char *t
int
nft_chain_zero_counters
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
bool
verbose
);
const
struct
builtin_chain
*
nft_chain_builtin_find
(
const
struct
builtin_table
*
t
,
const
char
*
chain
);
bool
nft_chain_exists
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
);
void
nft_bridge_chain_postprocess
(
struct
nft_handle
*
h
,
struct
nftnl_chain
*
c
);
/*
* Operations with rule-set.
...
...
@@ -125,7 +137,7 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain, const char *
*/
int
add_counters
(
struct
nftnl_rule
*
r
,
uint64_t
packets
,
uint64_t
bytes
);
int
add_verdict
(
struct
nftnl_rule
*
r
,
int
verdict
);
int
add_match
(
struct
nftnl_rule
*
r
,
struct
xt_entry_match
*
m
);
int
add_match
(
struct
nft_handle
*
h
,
struct
nftnl_rule
*
r
,
struct
xt_entry_match
*
m
);
int
add_target
(
struct
nftnl_rule
*
r
,
struct
xt_entry_target
*
t
);
int
add_jumpto
(
struct
nftnl_rule
*
r
,
const
char
*
name
,
int
verdict
);
int
add_action
(
struct
nftnl_rule
*
r
,
struct
iptables_command_state
*
cs
,
bool
goto_set
);
...
...
@@ -136,8 +148,8 @@ enum nft_rule_print {
NFT_RULE_DEL
,
};
void
nft_rule_print_save
(
const
struct
nftnl_rule
*
r
,
enum
nft_rule_print
type
,
unsigned
int
format
);
void
nft_rule_print_save
(
struct
nft_handle
*
h
,
const
struct
nftnl_rule
*
r
,
enum
nft_rule_print
type
,
unsigned
int
format
);
uint32_t
nft_invflags2cmp
(
uint32_t
invflags
,
uint32_t
flag
);
...
...
@@ -145,6 +157,7 @@ uint32_t nft_invflags2cmp(uint32_t invflags, uint32_t flag);
* global commit and abort
*/
int
nft_commit
(
struct
nft_handle
*
h
);
int
nft_bridge_commit
(
struct
nft_handle
*
h
);
int
nft_abort
(
struct
nft_handle
*
h
);
int
nft_abort_policy_rule
(
struct
nft_handle
*
h
,
const
char
*
table
);
...
...
@@ -168,22 +181,6 @@ int nft_init_eb(struct nft_handle *h, const char *pname);
int
ebt_get_current_chain
(
const
char
*
chain
);
int
do_commandeb
(
struct
nft_handle
*
h
,
int
argc
,
char
*
argv
[],
char
**
table
,
bool
restore
);
/*
* Parse config for tables and chain helper functions
*/
#define XTABLES_CONFIG_DEFAULT "/etc/xtables.conf"
struct
nftnl_table_list
;
struct
nftnl_chain_list
;
extern
int
xtables_config_parse
(
const
char
*
filename
,
struct
nftnl_table_list
*
table_list
,
struct
nftnl_chain_list
*
chain_list
);
enum
{
NFT_LOAD_VERBOSE
=
(
1
<<
0
),
};
int
nft_xtables_config_load
(
struct
nft_handle
*
h
,
const
char
*
filename
,
uint32_t
flags
);
/*
* Translation from iptables to nft
*/
...
...
@@ -211,7 +208,10 @@ 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
);
bool
nft_is_table_compatible
(
struct
nft_handle
*
h
,
const
char
*
name
);
bool
nft_is_table_compatible
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
);
void
nft_assert_table_compatible
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
);
int
ebt_set_user_chain_policy
(
struct
nft_handle
*
h
,
const
char
*
table
,
const
char
*
chain
,
const
char
*
policy
);
...
...
iptables/tests/shell/run-tests.sh
View file @
290749d4
...
...
@@ -38,6 +38,14 @@ while [ -n "$1" ]; do
HOST
=
y
shift
;;
-l
|
--legacy
)
LEGACY_ONLY
=
y
shift
;;
-n
|
--nft
)
NFT_ONLY
=
y
shift
;;
*${
RETURNCODE_SEPARATOR
}
+
([
0-9]
)
)
SINGLE+
=
"
$1
"
VERBOSE
=
y
...
...
@@ -98,19 +106,23 @@ do_test() {
}
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
))
"
if
[
"
$NFT_ONLY
"
!=
"y"
]
;
then
for
testfile
in
$(
find_tests
)
;
do
do_test
"
$testfile
"
"
$XTABLES_LEGACY_MULTI
"
done
msg_info
"legacy results: [OK]
$ok
[FAILED]
$failed
[TOTAL]
$((
ok+failed
))
"
fi
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
))
"
if
[
"
$LEGACY_ONLY
"
!=
"y"
]
;
then
for
testfile
in
$(
find_tests
)
;
do
do_test
"
$testfile
"
"
$XTABLES_NFT_MULTI
"
done
msg_info
"nft results: [OK]
$ok
[FAILED]
$failed
[TOTAL]
$((
ok+failed
))
"
fi
ok
=
$((
legacy_ok+ok
))
failed
=
$((
legacy_fail+failed
))
...
...
iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0
View file @
290749d4
...
...
@@ -50,13 +50,12 @@ DUMP='*filter
-A foo -j MARK --set-mark 12345
-A foo -j ACCEPT --opcode 1
-A foo -j ACCEPT --proto-type 0x800
-A foo -j ACCEPT -i lo --opcode 1 --proto-type 0x800
'
-A foo -j ACCEPT -i lo --opcode 1 --proto-type 0x800'
diff
-u
<
(
echo
-e
"
$DUMP
"
)
<
(
$XT_MULTI
arptables-save
)
diff
-u
<
(
echo
-e
"
$DUMP
"
)
<
(
$XT_MULTI
arptables-save
|
grep
-v
"^#"
)
# make sure dump can be restored and check it didn't change
$XT_MULTI
arptables
-F
$XT_MULTI
arptables-restore
<<<
$DUMP
diff
-u
<
(
echo
-e
"
$DUMP
"
)
<
(
$XT_MULTI
arptables-save
)
diff
-u
<
(
echo
-e
"
$DUMP
"
)
<
(
$XT_MULTI
arptables-save
|
grep
-v
"^#"
)
iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0
View file @
290749d4
...
...
@@ -11,8 +11,7 @@ set -e
DUMP
=
'*filter
:OUTPUT ACCEPT
-A OUTPUT -j mangle --mangle-ip-s 10.0.0.1
-A OUTPUT -j mangle --mangle-ip-d 10.0.0.2
'
-A OUTPUT -j mangle --mangle-ip-d 10.0.0.2'
# note how mangle-ip-s is unset in second rule
...
...
@@ -20,8 +19,7 @@ EXPECT='*filter
:INPUT ACCEPT
:OUTPUT ACCEPT
-A OUTPUT -j mangle --mangle-ip-s 10.0.0.1
-A OUTPUT -j mangle --mangle-ip-d 10.0.0.2
'
-A OUTPUT -j mangle --mangle-ip-d 10.0.0.2'
$XT_MULTI
arptables
-F
$XT_MULTI
arptables-restore
<<<
$DUMP
...
...
iptables/tests/shell/testcases/arptables/0003-arptables-verbose-output_0
View file @
290749d4
...
...
@@ -58,7 +58,6 @@ EXPECT='*filter
-A INPUT -j MARK -i eth23 --set-mark 42
-A OUTPUT -j CLASSIFY -o eth23 --set-class 23:42
-A OUTPUT -j foo -o eth23
-A foo -j mangle -o eth23 --mangle-ip-s 10.0.0.1
'
-A foo -j mangle -o eth23 --mangle-ip-s 10.0.0.1'
diff
-u
-Z
<
(
echo
-e
"
$EXPECT
"
)
<
(
$XT_MULTI
arptables-save
)
diff
-u
-Z
<
(
echo
-e
"
$EXPECT
"
)
<
(
$XT_MULTI
arptables-save
|
grep
-v
'^#'
)
iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0
View file @
290749d4
#!/bin/sh
get_entries_count
()
{
# (chain)
$XT_MULTI
ebtables
-L
$1
|
sed
-n
's/.*entries: \([0-9]*\).*/\1/p'
}
set
-x
case
"
$XT_MULTI
"
in
*
/xtables-nft-multi
)
...
...
@@ -28,32 +32,32 @@ case "$XT_MULTI" in
exit
1
fi
$XT_MULTI
ebtables
-L
FOO |
grep
-q
'entries: 0'
if
[
$
?
-ne
0
]
;
then
echo
"Unexpected entries count in empty unreferenced chain"
entries
=
$(
get_entries_count FOO
)
if
[
$
entries
-ne
0
]
;
then
echo
"Unexpected entries count in empty unreferenced chain
(expected 0, have
$entries
)
"
$XT_MULTI
ebtables
-L
exit
1
fi
$XT_MULTI
ebtables
-A
FORWARD
-j
FOO
$XT_MULTI
ebtables
-L
FORWARD |
grep
-q
'entries: 1'
if
[
$
?
-ne
0
]
;
then
echo
"Unexpected entries count in FORWARD chain"
entries
=
$(
get_entries_count FORWARD
)
if
[
$
entries
-ne
1
]
;
then
echo
"Unexpected entries count in FORWARD chain
(expected 1, have
$entries
)
"
$XT_MULTI
ebtables
-L
exit
1
fi
$XT_MULTI
ebtables
-L
FOO |
grep
-q
'entries: 0'
if
[
$
?
-ne
0
]
;
then
echo
"Unexpected entries count in empty referenced chain"
entries
=
$(
get_entries_count FOO
)
if
[
$
entries
-ne
0
]
;
then
echo
"Unexpected entries count in empty referenced chain
(expected 0, have
$entries
)
"
$XT_MULTI
ebtables
-L
exit
1
fi
$XT_MULTI
ebtables
-A
FOO
-j
ACCEPT
$XT_MULTI
ebtables
-L
FOO |
grep
-q
'entries: 1'
if
[
$
?
-ne
0
]
;
then
echo
"Unexpected entries count in non-empty referenced chain"
entries
=
$(
get_entries_count FOO
)
if
[
$
entries
-ne
1
]
;
then
echo
"Unexpected entries count in non-empty referenced chain
(expected 1, have
$entries
)
"
$XT_MULTI
ebtables
-L
exit
1
fi
...
...
iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0
View file @
290749d4
...
...
@@ -99,7 +99,6 @@ DUMP='*filter
-A foo --802_3-sap 0x23 --limit 100/sec --limit-burst 5 -j ACCEPT
-A foo --pkttype-type multicast --log-level notice --log-prefix "" -j CONTINUE
-A foo --pkttype-type multicast --limit 100/sec --limit-burst 5 -j ACCEPT
*nat
:PREROUTING ACCEPT
:OUTPUT DROP
...
...
@@ -107,8 +106,7 @@ DUMP='*filter
:nat_foo DROP
-A PREROUTING -j redirect
-A OUTPUT -j ACCEPT
-A POSTROUTING -j ACCEPT
'
-A POSTROUTING -j ACCEPT'
diff
-u
<
(
echo
-e
"
$DUMP
"
)
<
(
$XT_MULTI
ebtables-save |
grep
-v
'^#'
)
...
...
iptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_0
View file @
290749d4
...
...
@@ -13,8 +13,7 @@ DUMP='*filter
-A FORWARD --limit 100 --limit-burst 42 -j ACCEPT
-A FORWARD --limit 1000 -j ACCEPT
-A FORWARD --log --log-prefix "foobar"
-A FORWARD --log
'
-A FORWARD --log'
# note how limit-burst is 5 in second rule and log-prefix empty in fourth one
...
...
@@ -25,8 +24,7 @@ EXPECT='*filter
-A FORWARD --limit 100/sec --limit-burst 42 -j ACCEPT
-A FORWARD --limit 1000/sec --limit-burst 5 -j ACCEPT
-A FORWARD --log-level notice --log-prefix "foobar" -j CONTINUE
-A FORWARD --log-level notice --log-prefix "" -j CONTINUE
'
-A FORWARD --log-level notice --log-prefix "" -j CONTINUE'
$XT_MULTI
ebtables
--init-table
$XT_MULTI
ebtables-restore
<<<
$DUMP
...
...
iptables/tests/shell/testcases/ebtables/0004-save-counters_0
0 → 100755
View file @
290749d4
#!/bin/bash
set
-e
# there is no legacy backend to test
[[
$XT_MULTI
==
*
/xtables-nft-multi
]]
||
{
echo
"skip
$XT_MULTI
"
;
exit
0
;
}
$XT_MULTI
ebtables
--init-table
$XT_MULTI
ebtables
-A
FORWARD
-i
nodev123
-o
nodev432
-j
ACCEPT
$XT_MULTI
ebtables
-A
FORWARD
-i
nodev432
-o
nodev123
-j
ACCEPT
EXPECT
=
'Bridge table: filter
Bridge chain: FORWARD, entries: 2, policy: ACCEPT
-i nodev123 -o nodev432 -j ACCEPT
-i nodev432 -o nodev123 -j ACCEPT'
echo
"ebtables -L FORWARD"
diff
-u
<
(
echo
-e
"
$EXPECT
"
)
<
(
$XT_MULTI
ebtables
-L
FORWARD
)
EXPECT
=
'Bridge table: filter
Bridge chain: FORWARD, entries: 2, policy: ACCEPT
-i nodev123 -o nodev432 -j ACCEPT , pcnt = 0 -- bcnt = 0
-i nodev432 -o nodev123 -j ACCEPT , pcnt = 0 -- bcnt = 0'
echo
"ebtables -L FORWARD --Lc"
diff
-u
<
(
echo
-e
"
$EXPECT
"
)
<
(
$XT_MULTI
ebtables
-L
FORWARD
--Lc
)
EXPECT
=
'*filter
:INPUT ACCEPT
:FORWARD ACCEPT
:OUTPUT ACCEPT
-A FORWARD -i nodev123 -o nodev432 -j ACCEPT
-A FORWARD -i nodev432 -o nodev123 -j ACCEPT'
echo
"ebtables-save"
diff
-u
<
(
echo
-e
"
$EXPECT
"
)
<
(
$XT_MULTI
ebtables-save |
grep
-v
'^#'
)
EXPECT
=
'*filter
:INPUT ACCEPT
:FORWARD ACCEPT
:OUTPUT ACCEPT
[0:0] -A FORWARD -i nodev123 -o nodev432 -j ACCEPT
[0:0] -A FORWARD -i nodev432 -o nodev123 -j ACCEPT'
echo
"ebtables-save -c"
diff
-u
<
(
echo
-e
"
$EXPECT
"
)
<
(
$XT_MULTI
ebtables-save
-c
|
grep
-v
'^#'
)
export
EBTABLES_SAVE_COUNTER
=
yes
# -c flag overrides EBTABLES_SAVE_COUNTER variable
echo
"EBTABLES_SAVE_COUNTER=yes ebtables-save -c"
diff
-u
<
(
echo
-e
"
$EXPECT
"
)
<
(
$XT_MULTI
ebtables-save
-c
|
grep
-v
'^#'
)
EXPECT
=
'*filter
:INPUT ACCEPT
:FORWARD ACCEPT
:OUTPUT ACCEPT
-A FORWARD -i nodev123 -o nodev432 -j ACCEPT -c 0 0
-A FORWARD -i nodev432 -o nodev123 -j ACCEPT -c 0 0'
echo
"EBTABLES_SAVE_COUNTER=yes ebtables-save"
diff
-u
<
(
echo
-e
"
$EXPECT
"
)
<
(
$XT_MULTI
ebtables-save |
grep
-v
'^#'
)
iptables/tests/shell/testcases/ebtables/0005-ifnamechecks_0
0 → 100755
View file @
290749d4
#!/bin/bash
set
-e
# there is no legacy backend to test
[[
$XT_MULTI
==
*
/xtables-nft-multi
]]
||
{
echo
"skip
$XT_MULTI
"
;
exit
0
;
}
EXPECT
=
'*filter
:INPUT ACCEPT
:FORWARD ACCEPT
:OUTPUT ACCEPT
:PVEFW-FORWARD ACCEPT
:PVEFW-FWBR-OUT ACCEPT
-A FORWARD -j PVEFW-FORWARD
-A PVEFW-FORWARD -p IPv4 -j ACCEPT
-A PVEFW-FORWARD -p IPv6 -j ACCEPT
-A PVEFW-FORWARD -i fwln+ -j ACCEPT
-A PVEFW-FORWARD -o fwln+ -j PVEFW-FWBR-OUT'
$XT_MULTI
ebtables-restore
<<<
$EXPECT
exec
diff
-u
<
(
echo
-e
"
$EXPECT
"
)
<
(
$XT_MULTI
ebtables-save |
grep
-v
'^#'
)
iptables/tests/shell/testcases/ipt-restore/0003-restore-ordering_0
View file @
290749d4
...
...
@@ -14,7 +14,7 @@ ipt_show() {
$XT_MULTI
iptables-restore
<<
EOF
*filter
-A FORWARD -m comment --comment "
appended
rule" -j ACCEPT
-A FORWARD -m comment --comment "rule
4
" -j ACCEPT
-I FORWARD 1 -m comment --comment "rule 1" -j ACCEPT
-I FORWARD 2 -m comment --comment "rule 2" -j ACCEPT
-I FORWARD 3 -m comment --comment "rule 3" -j ACCEPT
...
...
@@ -24,7 +24,7 @@ EOF
EXPECT
=
'-A FORWARD -m comment --comment "rule 1" -j ACCEPT
-A FORWARD -m comment --comment "rule 2" -j ACCEPT
-A FORWARD -m comment --comment "rule 3" -j ACCEPT
-A FORWARD -m comment --comment "
appended
rule" -j ACCEPT'
-A FORWARD -m comment --comment "rule
4
" -j ACCEPT'
diff
-u
-Z
<
(
echo
-e
"
$EXPECT
"
)
<
(
ipt_show
)
...
...
@@ -32,11 +32,14 @@ diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
$XT_MULTI
iptables-restore
--noflush
<<
EOF
*filter
-A FORWARD -m comment --comment "rule 5" -j ACCEPT
-I FORWARD 1 -m comment --comment "rule 0.5" -j ACCEPT
-I FORWARD 3 -m comment --comment "rule 1.5" -j ACCEPT
-I FORWARD 5 -m comment --comment "rule 2.5" -j ACCEPT
-I FORWARD 7 -m comment --comment "rule 3.5" -j ACCEPT
-I FORWARD 9 -m comment --comment "appended rule 2" -j ACCEPT
-I FORWARD 9 -m comment --comment "rule 4.5" -j ACCEPT
-I FORWARD 11 -m comment --comment "rule 5.5" -j ACCEPT
-A FORWARD -m comment --comment "rule 6" -j ACCEPT
COMMIT
EOF
...
...
@@ -47,8 +50,11 @@ EXPECT='-A FORWARD -m comment --comment "rule 0.5" -j ACCEPT
-A FORWARD -m comment --comment "rule 2.5" -j ACCEPT
-A FORWARD -m comment --comment "rule 3" -j ACCEPT
-A FORWARD -m comment --comment "rule 3.5" -j ACCEPT
-A FORWARD -m comment --comment "appended rule" -j ACCEPT
-A FORWARD -m comment --comment "appended rule 2" -j ACCEPT'
-A FORWARD -m comment --comment "rule 4" -j ACCEPT
-A FORWARD -m comment --comment "rule 4.5" -j ACCEPT
-A FORWARD -m comment --comment "rule 5" -j ACCEPT
-A FORWARD -m comment --comment "rule 5.5" -j ACCEPT
-A FORWARD -m comment --comment "rule 6" -j ACCEPT'
diff
-u
-Z
<
(
echo
-e
"
$EXPECT
"
)
<
(
ipt_show
)
...
...
@@ -78,6 +84,8 @@ diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
$XT_MULTI
iptables-restore
--noflush
<<
EOF
*filter
-A FORWARD -m comment --comment "appended rule 4" -j ACCEPT
-D FORWARD 7
-D FORWARD -m comment --comment "appended rule 1" -j ACCEPT
-D FORWARD 3
-I FORWARD 3 -m comment --comment "manually replaced rule 2" -j ACCEPT
...
...
iptables/tests/shell/testcases/ipt-restore/0004-restore-race_0
View file @
290749d4
...
...
@@ -24,7 +24,7 @@ clean_tempfile()
trap
clean_tempfile EXIT
ENTRY_NUM
=
$((
RANDOM%10
0
))
ENTRY_NUM
=
$((
RANDOM%10
))
UCHAIN_NUM
=
$((
RANDOM%10
))
get_target
()
...
...
@@ -87,7 +87,7 @@ fi
case
"
$XT_MULTI
"
in
*
/xtables-nft-multi
)
attempts
=
$((
RANDOM%
20
0
))
attempts
=
$((
RANDOM%
1
0
))
attempts
=
$((
attempts+1
))
;;
*
)
...
...
iptables/tests/shell/testcases/ipt-restore/0005-ipt-6_0
0 → 100755
View file @
290749d4
#!/bin/bash
# Make sure iptables-restore simply ignores
# rules starting with -6
set
-e
# show rules, drop uninteresting policy settings
ipt_show
()
{
$XT_MULTI
iptables
-S
|
grep
-v
'^-P'
}
# issue reproducer for iptables-restore
$XT_MULTI
iptables-restore
<<
EOF
*filter
-A FORWARD -m comment --comment any -j ACCEPT
-4 -A FORWARD -m comment --comment ipv4 -j ACCEPT
-6 -A FORWARD -m comment --comment ipv6 -j ACCEPT
COMMIT
EOF
EXPECT
=
'-A FORWARD -m comment --comment any -j ACCEPT
-A FORWARD -m comment --comment ipv4 -j ACCEPT'
diff
-u
-Z
<
(
echo
-e
"
$EXPECT
"
)
<
(
ipt_show
)
iptables/tests/shell/testcases/ipt-restore/0006-ip6t-4_0
0 → 100755
View file @
290749d4
#!/bin/bash
# Make sure ip6tables-restore simply ignores
# rules starting with -4
set
-e
# show rules, drop uninteresting policy settings
ipt_show
()
{
$XT_MULTI
ip6tables
-S
|
grep
-v
'^-P'
}
# issue reproducer for ip6tables-restore
$XT_MULTI
ip6tables-restore
<<
EOF
*filter
-A FORWARD -m comment --comment any -j ACCEPT
-4 -A FORWARD -m comment --comment ipv4 -j ACCEPT
-6 -A FORWARD -m comment --comment ipv6 -j ACCEPT
COMMIT
EOF
EXPECT
=
'-A FORWARD -m comment --comment any -j ACCEPT
-A FORWARD -m comment --comment ipv6 -j ACCEPT'
diff
-u
-Z
<
(
echo
-e
"
$EXPECT
"
)
<
(
ipt_show
)
Prev
1
2
3
4
5
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment