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
278668fa
Commit
278668fa
authored
Jul 10, 2018
by
Arturo Borrero Gonzalez
Browse files
New upstream version 1.8.0
parent
5beab31f
Changes
119
Hide whitespace changes
Inline
Side-by-side
iptables/nft-shared.c
View file @
278668fa
...
...
@@ -20,6 +20,7 @@
#include <xtables.h>
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter/xt_comment.h>
#include <libmnl/libmnl.h>
#include <libnftnl/rule.h>
...
...
@@ -83,7 +84,7 @@ void add_bitwise_u16(struct nftnl_rule *r, int mask, int xor)
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
;
uint32_t
xor
[
4
]
=
{
0
};
...
...
@@ -138,9 +139,10 @@ void add_iniface(struct nftnl_rule *r, char *iface, uint32_t op)
iface_len
=
strlen
(
iface
);
add_meta
(
r
,
NFT_META_IIFNAME
);
if
(
iface
[
iface_len
-
1
]
==
'+'
)
add_cmp_ptr
(
r
,
op
,
iface
,
iface_len
-
1
);
else
if
(
iface
[
iface_len
-
1
]
==
'+'
)
{
if
(
iface_len
>
1
)
add_cmp_ptr
(
r
,
op
,
iface
,
iface_len
-
1
);
}
else
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)
iface_len
=
strlen
(
iface
);
add_meta
(
r
,
NFT_META_OIFNAME
);
if
(
iface
[
iface_len
-
1
]
==
'+'
)
add_cmp_ptr
(
r
,
op
,
iface
,
iface_len
-
1
);
else
if
(
iface
[
iface_len
-
1
]
==
'+'
)
{
if
(
iface_len
>
1
)
add_cmp_ptr
(
r
,
op
,
iface
,
iface_len
-
1
);
}
else
add_cmp_ptr
(
r
,
op
,
iface
,
iface_len
+
1
);
}
void
add_addr
(
struct
nftnl_rule
*
r
,
int
offset
,
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_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
);
}
...
...
@@ -207,6 +220,30 @@ bool is_same_interfaces(const char *a_iniface, const char *a_outiface,
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
,
unsigned
char
*
iniface_mask
,
char
*
outiface
,
unsigned
char
*
outiface_mask
,
uint8_t
*
invflags
)
...
...
@@ -234,35 +271,21 @@ int parse_meta(struct nftnl_expr *e, uint8_t key, char *iniface,
memset
(
outiface_mask
,
0xff
,
strlen
(
outiface
)
+
1
);
break
;
case
NFT_META_BRI_IIFNAME
:
case
NFT_META_IIFNAME
:
ifname
=
nftnl_expr_get
(
e
,
NFTNL_EXPR_CMP_DATA
,
&
len
);
if
(
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_CMP_OP
)
==
NFT_CMP_NEQ
)
*
invflags
|=
IPT_INV_VIA_IN
;
memcpy
(
iniface
,
ifname
,
len
);
if
(
iniface
[
len
]
==
'\0'
)
memset
(
iniface_mask
,
0xff
,
len
);
else
{
iniface
[
len
]
=
'+'
;
iniface
[
len
+
1
]
=
'\0'
;
memset
(
iniface_mask
,
0xff
,
len
+
1
);
}
parse_ifname
(
ifname
,
len
,
iniface
,
iniface_mask
);
break
;
case
NFT_META_BRI_OIFNAME
:
case
NFT_META_OIFNAME
:
ifname
=
nftnl_expr_get
(
e
,
NFTNL_EXPR_CMP_DATA
,
&
len
);
if
(
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_CMP_OP
)
==
NFT_CMP_NEQ
)
*
invflags
|=
IPT_INV_VIA_OUT
;
memcpy
(
outiface
,
ifname
,
len
);
if
(
outiface
[
len
]
==
'\0'
)
memset
(
outiface_mask
,
0xff
,
len
);
else
{
outiface
[
len
]
=
'+'
;
outiface
[
len
+
1
]
=
'\0'
;
memset
(
outiface_mask
,
0xff
,
len
+
1
);
}
parse_ifname
(
ifname
,
len
,
outiface
,
outiface_mask
);
break
;
default:
return
-
1
;
...
...
@@ -276,11 +299,10 @@ static void *nft_get_data(struct nft_xt_ctx *ctx)
switch
(
ctx
->
family
)
{
case
NFPROTO_IPV4
:
case
NFPROTO_IPV6
:
case
NFPROTO_BRIDGE
:
return
ctx
->
state
.
cs
;
case
NFPROTO_ARP
:
return
ctx
->
state
.
cs_arp
;
case
NFPROTO_BRIDGE
:
return
ctx
->
state
.
cs_eb
;
default:
/* Should not happen */
return
NULL
;
...
...
@@ -333,10 +355,8 @@ void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
switch
(
ctx
->
family
)
{
case
NFPROTO_IPV4
:
case
NFPROTO_IPV6
:
matches
=
&
ctx
->
state
.
cs
->
matches
;
break
;
case
NFPROTO_BRIDGE
:
matches
=
&
ctx
->
state
.
cs
_eb
->
matches
;
matches
=
&
ctx
->
state
.
cs
->
matches
;
break
;
default:
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)
*
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
)
{
ctx
->
reg
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_META_DREG
);
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
;
}
...
...
@@ -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
)
{
int
verdict
=
nftnl_expr_get_u32
(
e
,
NFTNL_EXPR_IMM_VERDICT
);
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
=
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? */
switch
(
verdict
)
{
case
NF_ACCEPT
:
...
...
@@ -537,7 +618,8 @@ void nft_rule_to_iptables_command_state(struct nftnl_rule *r,
if
(
match
==
NULL
)
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
)
{
fprintf
(
stderr
,
"OOM"
);
exit
(
EXIT_FAILURE
);
...
...
@@ -838,7 +920,9 @@ bool compare_targets(struct xtables_target *tg1, struct xtables_target *tg2)
if
(
tg1
==
NULL
&&
tg2
==
NULL
)
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
;
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,
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 @
278668fa
...
...
@@ -43,13 +43,13 @@ enum {
NFT_XT_CTX_PAYLOAD
=
(
1
<<
0
),
NFT_XT_CTX_META
=
(
1
<<
1
),
NFT_XT_CTX_BITWISE
=
(
1
<<
2
),
NFT_XT_CTX_IMMEDIATE
=
(
1
<<
3
),
};
struct
nft_xt_ctx
{
union
{
struct
iptables_command_state
*
cs
;
struct
arptables_command_state
*
cs_arp
;
struct
ebtables_command_state
*
cs_eb
;
}
state
;
struct
nftnl_expr_iter
*
iter
;
int
family
;
...
...
@@ -63,6 +63,10 @@ struct nft_xt_ctx {
struct
{
uint32_t
key
;
}
meta
;
struct
{
uint32_t
data
[
4
];
uint32_t
len
,
reg
;
}
immediate
;
struct
{
uint32_t
mask
[
4
];
uint32_t
xor
[
4
];
...
...
@@ -107,6 +111,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_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
);
...
...
@@ -223,9 +228,9 @@ struct nft_xt_cmd_parse {
unsigned
int
command
;
unsigned
int
rulenum
;
char
*
table
;
char
*
chain
;
char
*
newname
;
char
*
policy
;
const
char
*
chain
;
const
char
*
newname
;
const
char
*
policy
;
bool
restore
;
int
verbose
;
};
...
...
@@ -245,17 +250,18 @@ 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
);
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
,
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
,
const
char
*
chain
,
const
char
*
policy
,
const
struct
xt_counters
*
counters
);
int
(
*
chain_user_add
)(
struct
nft_handle
*
h
,
const
char
*
chain
,
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
[],
char
**
table
,
bool
restore
);
...
...
@@ -269,4 +275,5 @@ void xtables_restore_parse(struct nft_handle *h,
struct
nft_xt_restore_cb
*
cb
,
int
argc
,
char
*
argv
[]);
void
nft_check_xt_legacy
(
int
family
,
bool
is_ipt_save
);
#endif
iptables/nft.c
View file @
278668fa
...
...
@@ -19,6 +19,7 @@
#include <time.h>
#include <stdarg.h>
#include <inttypes.h>
#include <assert.h>
#include <xtables.h>
#include <libiptc/libxtc.h>
...
...
@@ -44,6 +45,7 @@
#include <libnftnl/expr.h>
#include <libnftnl/set.h>
#include <libnftnl/udata.h>
#include <libnftnl/batch.h>
#include <netinet/in.h>
/* inet_ntoa */
#include <arpa/inet.h>
...
...
@@ -60,7 +62,7 @@ int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh,
void
*
data
)
{
int
ret
;
char
buf
[
MNL_SOCKET_BUFFER_SIZE
];
char
buf
[
16536
];
if
(
mnl_socket_sendto
(
h
->
nl
,
nlh
,
nlh
->
nlmsg_len
)
<
0
)
return
-
1
;
...
...
@@ -80,13 +82,7 @@ int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh,
return
0
;
}
static
LIST_HEAD
(
batch_page_list
);
static
int
batch_num_pages
;
struct
batch_page
{
struct
list_head
head
;
struct
mnl_nlmsg_batch
*
batch
;
};
#define NFT_NLMSG_MAXSIZE (UINT16_MAX + getpagesize())
/* selected batch page is 256 Kbytes long to load ruleset of
* half a million rules without hitting -EMSGSIZE due to large
...
...
@@ -94,44 +90,74 @@ struct batch_page {
*/
#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 */
buf
=
malloc
(
BATCH_PAGE_SIZE
+
getpagesize
());
if
(
buf
==
NULL
)
batch
=
nftnl_batch_alloc
(
BATCH_PAGE_SIZE
,
NFT_NLMSG_MAXSIZE
);
if
(
batch
==
NULL
)
return
NULL
;
return
mnl_nlmsg_batch_start
(
buf
,
BATCH_PAGE_SIZE
)
;
return
batch
;
}
static
struct
mnl_nlmsg_batch
*
mnl_nftnl_batch_page_add
(
struct
mnl_nlmsg_batch
*
batch
)
static
void
mnl_nft_batch_continue
(
struct
nftnl_batch
*
batch
)
{
struct
batch_page
*
batch_page
;
assert
(
nftnl_batch_update
(
batch
)
>=
0
);
}
batch_page
=
malloc
(
sizeof
(
struct
batch_page
));
if
(
batch_page
==
NULL
)
return
NULL
;
static
uint32_t
mnl_batch_begin
(
struct
nftnl_batch
*
batch
,
uint32_t
seqnum
)
{
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
;
list_add_tail
(
&
batch_page
->
head
,
&
batch_page_list
);
batch_num_pages
++
;
struct
mnl_err
{
struct
list_head
head
;
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
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
;
if
(
batch_num_pages
*
BATCH_PAGE_SIZE
<=
nlbuffsiz
)
if
(
nftnl_batch_iovec_len
(
batch
)
*
BATCH_PAGE_SIZE
<=
nlbuffsiz
)
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 */
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)
nlbuffsiz
=
newbuffsiz
;
}
static
void
mnl_nftnl_batch_reset
(
void
)
{
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
ssize_t
mnl_nft_socket_sendmsg
(
const
struct
mnl_socket
*
nf_sock
,
struct
nftnl_batch
*
batch
)
{
static
const
struct
sockaddr_nl
snl
=
{
.
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
=
{
.
msg_name
=
(
struct
sockaddr
*
)
&
snl
,
.
msg_namelen
=
sizeof
(
snl
),
.
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_
nftnl_batch_
reset
(
);
mnl_set_sndbuffer
(
nf_sock
,
batch
);
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
];
fd_set
readfds
;
struct
timeval
tv
=
{
...
...
@@ -200,7 +201,7 @@ static int mnl_nftnl_batch_talk(struct nft_handle *h)
};
int
err
=
0
;
ret
=
mnl_nft_socket_sendmsg
(
h
->
nl
);
ret
=
mnl_nft_socket_sendmsg
(
nf_sock
,
batch
);
if
(
ret
==
-
1
)
return
-
1
;
...
...
@@ -213,16 +214,18 @@ static int mnl_nftnl_batch_talk(struct nft_handle *h)
return
-
1
;
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
)
return
-
1
;
ret
=
mnl_cb_run
(
rcv_buf
,
ret
,
0
,
h
->
portid
,
NULL
,
NULL
);
/*
Annotate first error and continue
, make sure we get all
* acknoledgments.
*/
if
(
!
err
&&
ret
=
=
-
1
)
err
=
errno
;
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
);
err
=
-
1
;
}
ret
=
select
(
fd
+
1
,
&
readfds
,
NULL
,
NULL
,
&
tv
);
if
(
ret
==
-
1
)
...
...
@@ -231,29 +234,16 @@ static int mnl_nftnl_batch_talk(struct nft_handle *h)
FD_ZERO
(
&
readfds
);
FD_SET
(
fd
,
&
readfds
);
}
errno
=
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
);
return
err
;
}
enum
obj_update_type
{
NFT_COMPAT_TABLE_ADD
,
NFT_COMPAT_TABLE_FLUSH
,
NFT_COMPAT_CHAIN_ADD
,
NFT_COMPAT_CHAIN_USER_ADD
,
NFT_COMPAT_CHAIN_USER_DEL
,
NFT_COMPAT_CHAIN_USER_FLUSH
,
NFT_COMPAT_CHAIN_UPDATE
,
NFT_COMPAT_CHAIN_RENAME
,
NFT_COMPAT_RULE_APPEND
,
...
...
@@ -271,14 +261,83 @@ enum obj_action {
struct
obj_update
{
struct
list_head
head
;
enum
obj_update_type
type
;
unsigned
int
seq
;
union
{
struct
nftnl_table
*
table
;
struct
nftnl_chain
*
chain
;
struct
nftnl_rule
*
rule
;
struct
nftnl_rule
*
rule
;
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
)
{
struct
obj_update
*
obj
;
...
...
@@ -288,6 +347,7 @@ static int batch_add(struct nft_handle *h, enum obj_update_type type, void *ptr)
return
-
1
;
obj
->
ptr
=
ptr
;
obj
->
error
.
lineno
=
h
->
error
.
lineno
;
obj
->
type
=
type
;
list_add_tail
(
&
obj
->
head
,
&
h
->
obj_list
);
h
->
obj_list_num
++
;
...
...
@@ -455,12 +515,6 @@ struct builtin_table xtables_arp[TABLES_MAX] = {
.
prio
=
NF_IP_PRI_FILTER
,
.
hook
=
NF_ARP_IN
,
},
{
.
name
=
"FORWARD"
,
.
type
=
"filter"
,
.
prio
=
NF_IP_PRI_FILTER
,
.
hook
=
NF_ARP_FORWARD
,
},
{
.
name
=
"OUTPUT"
,
.
type
=
"filter"
,
...
...
@@ -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
,
struct
builtin_table
*
_t
)
{
...
...
@@ -561,13 +591,7 @@ static int nft_table_builtin_add(struct nft_handle *h,
nftnl_table_set
(
t
,
NFTNL_TABLE_NAME
,
(
char
*
)
_t
->
name
);
if
(
h
->
batch_support
)
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
;
ret
=
batch_table_add
(
h
,
NFT_COMPAT_TABLE_ADD
,
t
);
return
ret
;
}
...
...
@@ -592,29 +616,6 @@ nft_chain_builtin_alloc(struct builtin_table *table,
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
,
struct
builtin_table
*
table
,
struct
builtin_chain
*
chain
)
...
...
@@ -625,10 +626,7 @@ static void nft_chain_builtin_add(struct nft_handle *h,
if
(
c
==
NULL
)
return
;
if
(
h
->
batch_support
)
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_ADD
,
c
);
else
nft_chain_add
(
h
,
c
,
NLM_F_EXCL
);
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_ADD
,
c
);
}
/* find if built-in table already exists */
...
...
@@ -686,28 +684,27 @@ static void nft_chain_builtin_init(struct nft_handle *h,
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
)
{
int
ret
=
0
;
struct
builtin_table
*
t
;
t
=
nft_table_builtin_find
(
h
,
table
);
if
(
t
==
NULL
)
{
ret
=
-
1
;
goto
out
;
}
if
(
nft_table_builtin_add
(
h
,
t
)
<
0
)
{
/* Built-in table already initialized, skip. */
if
(
errno
==
EEXIST
)
goto
out
;
}
if
(
t
==
NULL
)
ret
urn
-
1
;
if
(
t
->
initialized
)
return
0
;
if
(
nft_table_builtin_add
(
h
,
t
)
<
0
)
return
-
1
;
nft_chain_builtin_init
(
h
,
t
);
out:
return
ret
;
t
->
initialized
=
true
;
return
0
;
}
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
;
}
static
bool
mnl_batch_supported
(
struct
nft_handle
*
h
)
static
int
nft_restart
(
struct
nft_handle
*
h
)
{
char
buf
[
MNL_SOCKET_BUFFER_SIZE
];
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_socket_close
(
h
->
nl
);
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
));
while
(
ret
>
0
)
{
ret
=
mnl_cb_run
(
buf
,
ret
,
0
,
mnl_socket_get_portid
(
h
->
nl
),
NULL
,
NULL
);
if
(
ret
<=
0
)
break
;
if
(
mnl_socket_bind
(
h
->
nl
,
0
,
MNL_SOCKET_AUTOPID
)
<
0
)
return
-
1
;
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
* 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
;
return
0
;
}
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
)
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
;
}
h
->
portid
=
mnl_socket_get_portid
(
h
->
nl
);
h
->
tables
=
t
;
INIT_LIST_HEAD
(
&
h
->
obj_list
);
INIT_LIST_HEAD
(
&
h
->
err_list
);
return
0
;
}
h
->
batch
=
mnl_nftnl_batch_alloc
();
h
->
batch_support
=
mnl_batch_supported
(
h
);
static
int
__flush_rule_cache
(
struct
nftnl_rule
*
r
,
void
*
data
)
{
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
;
}
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
)
return
;
nftnl_rule_list_free
(
h
->
rule_cache
);
h
->
rule_cache
=
NULL
;
if
(
tablename
)
{
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
)
{
flush_rule_cache
(
h
);
flush_chain_cache
(
h
,
NULL
);
flush_rule_cache
(
h
,
NULL
);
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
)
...
...
@@ -861,10 +873,7 @@ int nft_chain_set(struct nft_handle *h, const char *table,
if
(
c
==
NULL
)
return
0
;
if
(
h
->
batch_support
)
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_UPDATE
,
c
);
else
ret
=
nft_chain_add
(
h
,
c
,
0
);
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_UPDATE
,
c
);
/* the core expects 1 for success and 0 for error */
return
ret
==
0
?
1
:
0
;
...
...
@@ -920,11 +929,36 @@ static int __add_target(struct nftnl_expr *e, struct xt_entry_target *t)
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
)
{
struct
nftnl_expr
*
expr
;
int
ret
;
if
(
strcmp
(
t
->
u
.
user
.
name
,
"TRACE"
)
==
0
)
return
add_meta_nftrace
(
r
);
expr
=
nftnl_expr_alloc
(
"target"
);
if
(
expr
==
NULL
)
return
-
ENOMEM
;
...
...
@@ -1028,13 +1062,21 @@ enum udata_type {
int
add_comment
(
struct
nftnl_rule
*
r
,
const
char
*
comment
)
{
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
);
if
(
!
udata
)
return
-
ENOMEM
;
if
(
strnlen
(
comment
,
255
)
==
255
)
return
-
ENOSPC
;
if
(
!
nftnl_udata_put_strz
(
udata
,
UDATA_TYPE_COMMENT
,
comment
))
return
-
ENOMEM
;
nftnl_rule_set_data
(
r
,
NFTNL_RULE_USERDATA
,
nftnl_udata_buf_data
(
udata
),
nftnl_udata_buf_len
(
udata
));
...
...
@@ -1106,6 +1148,8 @@ err:
return
NULL
;
}
static
struct
nftnl_rule_list
*
nft_rule_list_get
(
struct
nft_handle
*
h
);
int
nft_rule_append
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
,
uint64_t
handle
,
bool
verbose
)
...
...
@@ -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
)
nftnl_rule_free
(
r
);
flush_rule_cache
(
h
);
nft_rule_list_get
(
h
);
nftnl_rule_list_add_tail
(
r
,
h
->
rule_cache
);
return
1
;
}
...
...
@@ -1188,10 +1235,14 @@ err:
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
nftnl_chain_list
*
list
;
int
ret
;
if
(
h
->
chain_cache
)
return
h
->
chain_cache
;
retry:
list
=
nftnl_chain_list_alloc
();
if
(
list
==
NULL
)
{
errno
=
ENOMEM
;
...
...
@@ -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
,
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
;
}
...
...
@@ -1262,7 +1320,6 @@ next:
}
nftnl_chain_list_iter_destroy
(
iter
);
nftnl_chain_list_free
(
list
);
return
1
;
}
...
...
@@ -1291,7 +1348,7 @@ err:
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
nftnl_rule_list
*
list
;
int
ret
;
...
...
@@ -1299,6 +1356,7 @@ static struct nftnl_rule_list *nft_rule_list_get(struct nft_handle *h)
if
(
h
->
rule_cache
)
return
h
->
rule_cache
;
retry:
list
=
nftnl_rule_list_alloc
();
if
(
list
==
NULL
)
return
0
;
...
...
@@ -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
);
if
(
ret
<
0
)
{
if
(
errno
==
EINTR
)
{
assert
(
nft_restart
(
h
)
>=
0
);
nftnl_rule_list_free
(
list
);
goto
retry
;
}
nftnl_rule_list_free
(
list
);
return
NULL
;
}
...
...
@@ -1370,6 +1434,55 @@ __nft_rule_flush(struct nft_handle *h, const char *table, const char *chain)
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
ret
;
...
...
@@ -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
*
c
;
if
(
nft_xtables_config_load
(
h
,
XTABLES_CONFIG_DEFAULT
,
0
)
<
0
)
nft_xt_builtin_init
(
h
,
table
);
nft_fn
=
nft_rule_flush
;
list
=
nftnl_chain_list_get
(
h
);
...
...
@@ -1409,12 +1525,9 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table)
next:
c
=
nftnl_chain_list_iter_next
(
iter
);
}
nftnl_chain_list_iter_destroy
(
iter
);
flush_rule_cache
(
h
);
flush_rule_cache
(
h
,
table
);
err:
nftnl_chain_list_free
(
list
);
/* the core expects 1 for success and 0 for error */
return
ret
==
0
?
1
:
0
;
}
...
...
@@ -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_NAME
,
(
char
*
)
chain
);
if
(
h
->
batch_support
)
{
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_USER_ADD
,
c
);
}
else
{
char
buf
[
MNL_SOCKET_BUFFER_SIZE
];
struct
nlmsghdr
*
nlh
;
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_USER_ADD
,
c
);
nlh
=
nftnl_chain_nlmsg_build_hdr
(
buf
,
NFT_MSG_NEWCHAIN
,
h
->
family
,
NLM_F_ACK
|
NLM_F_EXCL
,
h
->
seq
);
nftnl_chain_nlmsg_build_payload
(
nlh
,
c
);
nftnl_chain_free
(
c
);
ret
=
mnl_talk
(
h
,
nlh
,
NULL
,
NULL
);
}
nft_chain_dump
(
h
);
nftnl_chain_list_add
(
c
,
h
->
chain_cache
);
/* the core expects 1 for success and 0 for error */
return
ret
==
0
?
1
:
0
;
...
...
@@ -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 */
#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
)
{
struct
nftnl_chain_list
*
list
;
...
...
@@ -1480,6 +1573,8 @@ int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *tabl
int
ret
=
0
;
int
deleted_ctr
=
0
;
nft_fn
=
nft_chain_user_del
;
list
=
nftnl_chain_list_get
(
h
);
if
(
list
==
NULL
)
goto
err
;
...
...
@@ -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
)
goto
next
;
if
(
h
->
batch_support
)
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_USER_DEL
,
c
);
else
ret
=
__nft_chain_del
(
h
,
c
);
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_USER_DEL
,
c
);
if
(
ret
<
0
)
break
;
deleted_ctr
++
;
nftnl_chain_list_del
(
c
);
if
(
chain
!=
NULL
)
break
;
...
...
@@ -1523,11 +1616,9 @@ next:
nftnl_chain_list_iter_destroy
(
iter
);
err:
if
(
!
h
->
batch_support
)
nftnl_chain_list_free
(
list
);
/* chain not found */
if
(
deleted_ctr
==
0
)
{
if
(
chain
!=
NULL
&&
deleted_ctr
==
0
)
{
ret
=
-
1
;
errno
=
ENOENT
;
}
...
...
@@ -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_u64
(
c
,
NFTNL_CHAIN_HANDLE
,
handle
);
if
(
h
->
batch_support
)
{
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
);
}
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_RENAME
,
c
);
/* the core expects 1 for success and 0 for error */
return
ret
==
0
?
1
:
0
;
...
...
@@ -1655,10 +1734,12 @@ err:
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
nftnl_table_list
*
list
;
int
ret
;
retry:
list
=
nftnl_table_list_alloc
();
if
(
list
==
NULL
)
return
0
;
...
...
@@ -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
,
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
;
}
...
...
@@ -1707,20 +1793,17 @@ int nft_for_each_table(struct nft_handle *h,
int
(
*
func
)(
struct
nft_handle
*
h
,
const
char
*
tablename
,
bool
counters
),
bool
counters
)
{
int
ret
=
1
;
struct
nftnl_table_list
*
list
;
struct
nftnl_table_list_iter
*
iter
;
struct
nftnl_table
*
t
;
list
=
nftnl_table_list_get
(
h
);
if
(
list
==
NULL
)
{
ret
=
0
;
goto
err
;
}
if
(
list
==
NULL
)
return
-
1
;
iter
=
nftnl_table_list_iter_create
(
list
);
if
(
iter
==
NULL
)
return
0
;
return
-
1
;
t
=
nftnl_table_list_iter_next
(
iter
);
while
(
t
!=
NULL
)
{
...
...
@@ -1733,43 +1816,85 @@ int nft_for_each_table(struct nft_handle *h,
}
nftnl_table_list_free
(
list
);
return
0
;
}
err:
/* the core expects 1 for success and 0 for error */
return
ret
==
0
?
1
:
0
;
static
int
__nft_table_flush
(
struct
nft_handle
*
h
,
const
char
*
table
)
{
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
,
struct
nftnl_chain_list
*
chain_list
)
int
nft_table_flush
(
struct
nft_handle
*
h
,
const
char
*
table
)
{
struct
nftnl_chain_list_iter
*
iter
;
struct
nftnl_chain
*
chain_obj
;
struct
nftnl_table_list_iter
*
iter
;
struct
nftnl_table_list
*
list
;
struct
nftnl_table
*
t
;
int
ret
=
0
;
iter
=
nftnl_chain_list_iter_create
(
chain_list
);
if
(
iter
==
NULL
)
return
0
;
nft_fn
=
nft_table_flush
;
chain_obj
=
nftnl_chain_list_iter_next
(
iter
);
while
(
chain_obj
!=
NULL
)
{
const
char
*
table
=
nftnl_chain_get_str
(
chain_obj
,
NFTNL_CHAIN_TABLE
);
list
=
nftnl_table_list_get
(
h
);
if
(
list
==
NULL
)
{
ret
=
-
1
;
goto
err_out
;
}
if
(
strcmp
(
this_table
,
table
)
!=
0
)
goto
next
;
iter
=
nftnl_table_list_iter_create
(
list
);
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
;
if
(
__nft_chain_del
(
h
,
chain_obj
)
<
0
)
{
if
(
errno
!=
EBUSY
)
return
-
1
;
}
ret
=
__nft_table_flush
(
h
,
table
);
if
(
ret
<
0
)
goto
err_table_iter
;
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
,
...
...
@@ -1874,12 +1999,10 @@ int nft_rule_delete(struct nft_handle *h, const char *chain,
}
else
errno
=
ENOENT
;
flush_rule_cache
(
h
);
return
ret
;
}
static
int
static
struct
nftnl_rule
*
nft_rule_add
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
struct
iptables_command_state
*
cs
,
uint64_t
handle
,
bool
verbose
)
...
...
@@ -1888,25 +2011,24 @@ nft_rule_add(struct nft_handle *h, const char *chain,
r
=
nft_rule_new
(
h
,
chain
,
table
,
cs
);
if
(
r
==
NULL
)
return
0
;
return
NULL
;
if
(
handle
>
0
)
nftnl_rule_set_u64
(
r
,
NFTNL_RULE_POSITION
,
handle
);
if
(
batch_rule_add
(
h
,
NFT_COMPAT_RULE_INSERT
,
r
)
<
0
)
{
nftnl_rule_free
(
r
);
return
0
;
return
NULL
;
}
flush_rule_cache
(
h
);
return
1
;
return
r
;
}
int
nft_rule_insert
(
struct
nft_handle
*
h
,
const
char
*
chain
,
const
char
*
table
,
void
*
data
,
int
rulenum
,
bool
verbose
)
{
struct
nftnl_rule
*
r
,
*
new_rule
;
struct
nftnl_rule_list
*
list
;
struct
nftnl_rule
*
r
;
uint64_t
handle
=
0
;
/* 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,
*/
r
=
nft_rule_find
(
h
,
list
,
chain
,
table
,
data
,
rulenum
-
1
);
if
(
r
!=
NULL
)
{
flush_rule_cache
(
h
);
if
(
r
!=
NULL
)
return
nft_rule_append
(
h
,
chain
,
table
,
data
,
0
,
verbose
);
}
errno
=
ENOENT
;
goto
err
;
...
...
@@ -1939,13 +2059,21 @@ int nft_rule_insert(struct nft_handle *h, const char *chain,
handle
=
nftnl_rule_get_u64
(
r
,
NFTNL_RULE_HANDLE
);
DEBUGP
(
"adding after rule handle %"
PRIu64
"
\n
"
,
handle
);
flush
_rule_
cache
(
h
);
}
else
{
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:
flush_rule_cache
(
h
);
return
0
;
}
...
...
@@ -1973,8 +2101,6 @@ int nft_rule_delete_num(struct nft_handle *h, const char *chain,
}
else
errno
=
ENOENT
;
flush_rule_cache
(
h
);
return
ret
;
}
...
...
@@ -1997,14 +2123,14 @@ int nft_rule_replace(struct nft_handle *h, const char *chain,
(
unsigned
long
long
)
nftnl_rule_get_u64
(
r
,
NFTNL_RULE_HANDLE
));
nftnl_rule_list_del
(
r
);
ret
=
nft_rule_append
(
h
,
chain
,
table
,
data
,
nftnl_rule_get_u64
(
r
,
NFTNL_RULE_HANDLE
),
verbose
);
}
else
errno
=
ENOENT
;
flush_rule_cache
(
h
);
return
ret
;
}
...
...
@@ -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
);
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
)
{
__nft_rule_list
(
h
,
chain
,
table
,
rulenum
,
format
,
ops
->
print_firewall
);
...
...
@@ -2144,8 +2275,6 @@ next:
nftnl_chain_list_iter_destroy
(
iter
);
err:
nftnl_chain_list_free
(
list
);
return
1
;
}
...
...
@@ -2249,8 +2378,6 @@ next:
nftnl_chain_list_iter_destroy
(
iter
);
err:
nftnl_chain_list_free
(
list
);
return
ret
;
}
...
...
@@ -2284,8 +2411,6 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain,
false
);
error:
flush_rule_cache
(
h
);
return
ret
;
}
...
...
@@ -2295,10 +2420,9 @@ static void nft_compat_table_batch_add(struct nft_handle *h, uint16_t type,
{
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
);
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
,
...
...
@@ -2307,11 +2431,10 @@ static void nft_compat_chain_batch_add(struct nft_handle *h, uint16_t type,
{
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
);
nftnl_chain_nlmsg_build_payload
(
nlh
,
chain
);
nft_chain_print_debug
(
chain
,
nlh
);
nftnl_chain_free
(
chain
);
}
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
;
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
);
nftnl_rule_nlmsg_build_payload
(
nlh
,
rule
);
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
)
{
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
;
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
)
{
case
NFT_COMPAT_TABLE_ADD
:
nft_compat_table_batch_add
(
h
,
NFT_MSG_NEWTABLE
,
NLM_F_CREATE
,
seq
++
,
NLM_F_CREATE
,
n
->
seq
,
n
->
table
);
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
:
nft_compat_chain_batch_add
(
h
,
NFT_MSG_NEWCHAIN
,
NLM_F_CREATE
,
seq
++
,
NLM_F_CREATE
,
n
->
seq
,
n
->
chain
);
break
;
case
NFT_COMPAT_CHAIN_USER_ADD
:
nft_compat_chain_batch_add
(
h
,
NFT_MSG_NEWCHAIN
,
NLM_F_EXCL
,
seq
++
,
NLM_F_EXCL
,
n
->
seq
,
n
->
chain
);
break
;
case
NFT_COMPAT_CHAIN_USER_DEL
:
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
);
break
;
case
NFT_COMPAT_CHAIN_UPDATE
:
nft_compat_chain_batch_add
(
h
,
NFT_MSG_NEWCHAIN
,
h
->
restore
?
NLM_F_CREATE
:
0
,
seq
++
,
n
->
chain
);
n
->
seq
,
n
->
chain
);
break
;
case
NFT_COMPAT_CHAIN_RENAME
:
nft_compat_chain_batch_add
(
h
,
NFT_MSG_NEWCHAIN
,
0
,
seq
++
,
n
->
chain
);
n
->
seq
,
n
->
chain
);
break
;
case
NFT_COMPAT_RULE_APPEND
:
nft_compat_rule_batch_add
(
h
,
NFT_MSG_NEWRULE
,
NLM_F_CREATE
|
NLM_F_APPEND
,
seq
++
,
n
->
rule
);
n
->
seq
,
n
->
rule
);
break
;
case
NFT_COMPAT_RULE_INSERT
:
nft_compat_rule_batch_add
(
h
,
NFT_MSG_NEWRULE
,
NLM_F_CREATE
,
seq
++
,
NLM_F_CREATE
,
n
->
seq
,
n
->
rule
);
break
;
case
NFT_COMPAT_RULE_REPLACE
:
nft_compat_rule_batch_add
(
h
,
NFT_MSG_NEWRULE
,
NLM_F_CREATE
|
NLM_F_REPLACE
,
seq
++
,
n
->
rule
);
n
->
seq
,
n
->
rule
);
break
;
case
NFT_COMPAT_RULE_DELETE
:
case
NFT_COMPAT_RULE_FLUSH
:
nft_compat_rule_batch_add
(
h
,
NFT_MSG_DELRULE
,
0
,
seq
++
,
n
->
rule
);
n
->
seq
,
n
->
rule
);
break
;
}
h
->
obj_list_num
--
;
list_del
(
&
n
->
head
);
free
(
n
);
if
(
!
mnl_nlmsg_batch_next
(
h
->
batch
))
h
->
batch
=
mnl_nftnl_batch_page_add
(
h
->
batch
);
mnl_nft_batch_continue
(
h
->
batch
);
}
switch
(
action
)
{
case
NFT_COMPAT_COMMIT
:
mnl_
nftnl_
batch_end
(
h
->
batch
,
seq
++
);
mnl_batch_end
(
h
->
batch
,
seq
++
);
break
;
case
NFT_COMPAT_ABORT
:
break
;
}
if
(
!
mnl_nlmsg_batch_is_empty
(
h
->
batch
))
h
->
batch
=
mnl_nftnl_batch_page_add
(
h
->
batch
);
ret
=
mnl_batch_talk
(
h
->
nl
,
h
->
batch
,
&
h
->
err_list
);
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
;
}
...
...
@@ -2428,16 +2614,29 @@ int nft_abort(struct nft_handle *h)
int
nft_compatible_revision
(
const
char
*
name
,
uint8_t
rev
,
int
opt
)
{
struct
mnl_socket
*
nl
;
char
buf
[
MNL_SOCKET_BUFFER_SIZE
];
char
buf
[
16536
];
struct
nlmsghdr
*
nlh
;
uint32_t
portid
,
seq
,
type
;
uint32_t
portid
,
seq
,
type
=
0
;
uint32_t
pf
=
AF_INET
;
int
ret
=
0
;
if
(
opt
==
IPT_SO_GET_REVISION_MATCH
||
opt
==
IP6T_SO_GET_REVISION_MATCH
)
type
=
0
;
else
switch
(
opt
)
{
case
IPT_SO_GET_REVISION_MATCH
:
break
;
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
;
pf
=
AF_INET6
;
break
;
default:
/* No revision support (arp, ebtables), assume latest version ok */
return
1
;
}
nlh
=
mnl_nlmsg_put_header
(
buf
);
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)
nlh
->
nlmsg_seq
=
seq
=
time
(
NULL
);
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
->
res_id
=
0
;
...
...
@@ -2498,19 +2697,18 @@ const char *nft_strerror(int err)
{
nft_chain_user_del
,
EMLINK
,
"Can't delete chain with references left"
},
{
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_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_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 */
{
nft_rule_delete
,
ENOENT
,
"Bad rule (does a matching rule exist in that chain?)"
},
{
nft_chain_set
,
ENOENT
,
"Bad built-in chain name"
},
{
nft_chain_set
,
EINVAL
,
"Bad policy name"
},
{
NULL
,
ELOOP
,
"Loop found in table"
},
{
NULL
,
EPERM
,
"Permission denied (you must be root)"
},
{
NULL
,
0
,
"Incompatible with this kernel"
},
{
NULL
,
ENOPROTOOPT
,
"iptables who? (do you need to insmod?)"
},
...
...
@@ -2540,8 +2738,8 @@ static void xtables_config_perror(uint32_t flags, const char *fmt, ...)
va_end
(
args
);
}
int
nft_xtables_config_load
(
struct
nft_handle
*
h
,
const
char
*
filename
,
uint32_t
flags
)
static
int
__
nft_xtables_config_load
(
struct
nft_handle
*
h
,
const
char
*
filename
,
uint32_t
flags
)
{
struct
nftnl_table_list
*
table_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,
uint32_t
table_family
,
chain_family
;
bool
found
=
false
;
if
(
h
->
restore
)
return
0
;
table_list
=
nftnl_table_list_alloc
();
chain_list
=
nftnl_chain_list_alloc
();
...
...
@@ -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_free
(
chain_list
);
h
->
config_done
=
1
;
return
0
;
err:
...
...
@@ -2647,9 +2844,20 @@ err:
if
(
citer
!=
NULL
)
nftnl_chain_list_iter_destroy
(
citer
);
h
->
config_done
=
-
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
,
const
char
*
table
)
{
...
...
@@ -2684,18 +2892,7 @@ int nft_chain_zero_counters(struct nft_handle *h, const char *chain,
nftnl_chain_unset
(
c
,
NFTNL_CHAIN_HANDLE
);
if
(
h
->
batch_support
)
{
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
);
}
ret
=
batch_chain_add
(
h
,
NFT_COMPAT_CHAIN_ADD
,
c
);
if
(
chain
!=
NULL
)
break
;
...
...
@@ -2703,9 +2900,6 @@ next:
c
=
nftnl_chain_list_iter_next
(
iter
);
}
if
(
!
h
->
batch_support
)
nftnl_chain_list_free
(
list
);
nftnl_chain_list_iter_destroy
(
iter
);
err:
...
...
@@ -2747,15 +2941,15 @@ static int nft_is_expr_compatible(const char *name)
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
*
expr
;
int
ret
=
0
;
bool
compatible
=
false
;
iter
=
nftnl_expr_iter_create
(
rule
);
if
(
iter
==
NULL
)
return
-
1
;
return
false
;
expr
=
nftnl_expr_iter_next
(
iter
);
while
(
expr
!=
NULL
)
{
...
...
@@ -2766,37 +2960,51 @@ static int nft_is_rule_compatible(struct nftnl_rule *rule)
continue
;
}
ret
=
1
;
compatible
=
true
;
break
;
}
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
;
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
++
)
{
cur_table
=
x
tables
_ipv4
[
i
].
name
;
chains
=
x
tables
_ipv4
[
i
].
chains
;
cur_table
=
h
->
tables
[
i
].
name
;
chains
=
h
->
tables
[
i
].
chains
;
if
(
strcmp
(
table
,
cur_table
)
!=
0
)
if
(
!
cur_table
||
strcmp
(
table
,
cur_table
)
!=
0
)
continue
;
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
;
break
;
}
}
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_iter
*
iter
;
...
...
@@ -2816,101 +3024,55 @@ static int nft_are_chains_compatible(struct nft_handle *h)
if
(
!
nft_chain_builtin
(
chain
))
goto
next
;
const
char
*
table
=
nftnl_chain_get
(
chain
,
NFTNL_CHAIN_TABLE
);
const
char
*
name
=
nftnl_chain_get
(
chain
,
NFTNL_CHAIN_NAME
);
if
(
nft_is_chain_compatible
(
table
,
name
)
==
1
)
{
ret
=
1
;
ret
=
nft_is_chain_compatible
(
h
,
chain
);
if
(
ret
!=
0
)
break
;
}
next:
chain
=
nftnl_chain_list_iter_next
(
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
;
}
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_iter
*
iter
;
struct
nftnl_rule
*
rule
;
int
ret
=
0
;
int
ret
=
0
,
i
;
ret
=
nft_are_tables_compatible
(
h
);
if
(
ret
!=
0
)
return
ret
;
for
(
i
=
0
;
i
<
TABLES_MAX
;
i
++
)
{
if
(
!
h
->
tables
[
i
].
name
)
continue
;
if
(
strcmp
(
h
->
tables
[
i
].
name
,
tablename
)
==
0
)
break
;
}
if
(
i
==
TABLES_MAX
)
return
false
;
ret
=
nft_are_chains_compatible
(
h
);
ret
=
nft_are_chains_compatible
(
h
,
tablename
);
if
(
ret
!=
0
)
return
ret
;
return
false
;
list
=
nft_rule_list_get
(
h
);
if
(
list
==
NULL
)
return
-
1
;
return
true
;
iter
=
nftnl_rule_list_iter_create
(
list
);
if
(
iter
==
NULL
)
return
-
1
;
return
true
;
rule
=
nftnl_rule_list_iter_next
(
iter
);
while
(
rule
!=
NULL
)
{
ret
=
nft_is_rule_compatible
(
rule
);
if
(
ret
!=
0
)
break
;
rule
=
nftnl_rule_list_iter_next
(
iter
);
}
nftnl_rule_list_iter_destroy
(
iter
);
return
ret
;
return
ret
==
0
;
}
iptables/nft.h
View file @
278668fa
...
...
@@ -32,12 +32,19 @@ struct nft_handle {
uint32_t
seq
;
struct
list_head
obj_list
;
int
obj_list_num
;
struct
mnl_nlmsg_batch
*
batch
;
struct
nftnl_batch
*
batch
;
struct
list_head
err_list
;
struct
nft_family_ops
*
ops
;
struct
builtin_table
*
tables
;
struct
nftnl_chain_list
*
chain_cache
;
struct
nftnl_rule_list
*
rule_cache
;
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
];
...
...
@@ -56,23 +63,25 @@ void nft_fini(struct nft_handle *h);
struct
nftnl_table
;
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
);
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
);
void
nft_table_new
(
struct
nft_handle
*
h
,
const
char
*
table
);
/*
* Operations with chains.
*/
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
);
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
);
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_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_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,
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
iptables/tests/shell/run-tests.sh
0 → 100755
View file @
278668fa
#!/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 @
278668fa
#!/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 @
278668fa
#!/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 @
278668fa
#!/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 @
278668fa
#!/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 @
278668fa
#!/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 @
278668fa
#!/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 @
278668fa
*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 @
278668fa
#!/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 @
278668fa
#!/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 @
278668fa
# 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 @
278668fa
# 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 @
278668fa
# 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 @
278668fa
# 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 @
278668fa
# 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 @
278668fa
...
...
@@ -48,8 +48,39 @@ struct xtables_afinfo {
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
{
union
{
struct
ebt_entry
eb
;
struct
ipt_entry
fw
;
struct
ip6t_entry
fw6
;
};
...
...
@@ -57,6 +88,7 @@ struct iptables_command_state {
int
c
;
unsigned
int
options
;
struct
xtables_rule_match
*
matches
;
struct
ebt_match
*
match_list
;
struct
xtables_target
*
target
;
struct
xt_counters
counters
;
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