Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
8cc848fa
Commit
8cc848fa
authored
Jun 02, 2009
by
Patrick McHardy
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
git://dev.medozas.de/linux
parents
a17c8598
45185364
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
278 additions
and
235 deletions
+278
-235
net/bridge/netfilter/ebtables.c
net/bridge/netfilter/ebtables.c
+10
-6
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/arp_tables.c
+56
-53
net/ipv4/netfilter/ip_queue.c
net/ipv4/netfilter/ip_queue.c
+1
-1
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ip_tables.c
+86
-84
net/ipv6/netfilter/ip6_queue.c
net/ipv6/netfilter/ip6_queue.c
+1
-1
net/ipv6/netfilter/ip6_tables.c
net/ipv6/netfilter/ip6_tables.c
+84
-84
net/netfilter/nf_queue.c
net/netfilter/nf_queue.c
+2
-2
net/netfilter/x_tables.c
net/netfilter/x_tables.c
+38
-4
No files found.
net/bridge/netfilter/ebtables.c
View file @
8cc848fa
...
...
@@ -142,6 +142,12 @@ static inline int ebt_basic_match(struct ebt_entry *e, struct ethhdr *h,
return
0
;
}
static
inline
__pure
struct
ebt_entry
*
ebt_next_entry
(
const
struct
ebt_entry
*
entry
)
{
return
(
void
*
)
entry
+
entry
->
next_offset
;
}
/* Do some firewalling */
unsigned
int
ebt_do_table
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
...
...
@@ -249,8 +255,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
/* jump to a udc */
cs
[
sp
].
n
=
i
+
1
;
cs
[
sp
].
chaininfo
=
chaininfo
;
cs
[
sp
].
e
=
(
struct
ebt_entry
*
)
(((
char
*
)
point
)
+
point
->
next_offset
);
cs
[
sp
].
e
=
ebt_next_entry
(
point
);
i
=
0
;
chaininfo
=
(
struct
ebt_entries
*
)
(
base
+
verdict
);
#ifdef CONFIG_NETFILTER_DEBUG
...
...
@@ -266,8 +271,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
sp
++
;
continue
;
letscontinue:
point
=
(
struct
ebt_entry
*
)
(((
char
*
)
point
)
+
point
->
next_offset
);
point
=
ebt_next_entry
(
point
);
i
++
;
}
...
...
@@ -787,7 +791,7 @@ static int check_chainloops(struct ebt_entries *chain, struct ebt_cl_stack *cl_s
/* this can't be 0, so the loop test is correct */
cl_s
[
i
].
cs
.
n
=
pos
+
1
;
pos
=
0
;
cl_s
[
i
].
cs
.
e
=
((
void
*
)
e
+
e
->
next_offset
);
cl_s
[
i
].
cs
.
e
=
ebt_next_entry
(
e
);
e
=
(
struct
ebt_entry
*
)(
hlp2
->
data
);
nentries
=
hlp2
->
nentries
;
cl_s
[
i
].
from
=
chain_nr
;
...
...
@@ -797,7 +801,7 @@ static int check_chainloops(struct ebt_entries *chain, struct ebt_cl_stack *cl_s
continue
;
}
letscontinue:
e
=
(
void
*
)
e
+
e
->
next_offset
;
e
=
ebt_next_entry
(
e
)
;
pos
++
;
}
return
0
;
...
...
net/ipv4/netfilter/arp_tables.c
View file @
8cc848fa
...
...
@@ -231,6 +231,12 @@ static inline struct arpt_entry *get_entry(void *base, unsigned int offset)
return
(
struct
arpt_entry
*
)(
base
+
offset
);
}
static
inline
__pure
struct
arpt_entry
*
arpt_next_entry
(
const
struct
arpt_entry
*
entry
)
{
return
(
void
*
)
entry
+
entry
->
next_offset
;
}
unsigned
int
arpt_do_table
(
struct
sk_buff
*
skb
,
unsigned
int
hook
,
const
struct
net_device
*
in
,
...
...
@@ -267,67 +273,64 @@ unsigned int arpt_do_table(struct sk_buff *skb,
arp
=
arp_hdr
(
skb
);
do
{
if
(
arp_packet_match
(
arp
,
skb
->
dev
,
indev
,
outdev
,
&
e
->
arp
))
{
struct
arpt_entry_target
*
t
;
int
hdr_len
;
hdr_len
=
sizeof
(
*
arp
)
+
(
2
*
sizeof
(
struct
in_addr
))
+
(
2
*
skb
->
dev
->
addr_len
);
struct
arpt_entry_target
*
t
;
int
hdr_len
;
ADD_COUNTER
(
e
->
counters
,
hdr_len
,
1
);
if
(
!
arp_packet_match
(
arp
,
skb
->
dev
,
indev
,
outdev
,
&
e
->
arp
))
{
e
=
arpt_next_entry
(
e
);
continue
;
}
t
=
arpt_get_target
(
e
);
hdr_len
=
sizeof
(
*
arp
)
+
(
2
*
sizeof
(
struct
in_addr
))
+
(
2
*
skb
->
dev
->
addr_len
);
ADD_COUNTER
(
e
->
counters
,
hdr_len
,
1
);
/* Standard target? */
if
(
!
t
->
u
.
kernel
.
target
->
target
)
{
int
v
;
t
=
arpt_get_target
(
e
);
v
=
((
struct
arpt_standard_target
*
)
t
)
->
verdict
;
if
(
v
<
0
)
{
/* Pop from stack? */
if
(
v
!=
ARPT_RETURN
)
{
verdict
=
(
unsigned
)(
-
v
)
-
1
;
break
;
}
e
=
back
;
back
=
get_entry
(
table_base
,
back
->
comefrom
);
continue
;
}
if
(
table_base
+
v
!=
(
void
*
)
e
+
e
->
next_offset
)
{
/* Save old back ptr in next entry */
struct
arpt_entry
*
next
=
(
void
*
)
e
+
e
->
next_offset
;
next
->
comefrom
=
(
void
*
)
back
-
table_base
;
/* set back pointer to next entry */
back
=
next
;
}
/* Standard target? */
if
(
!
t
->
u
.
kernel
.
target
->
target
)
{
int
v
;
e
=
get_entry
(
table_base
,
v
);
}
else
{
/* Targets which reenter must return
* abs. verdicts
*/
tgpar
.
target
=
t
->
u
.
kernel
.
target
;
tgpar
.
targinfo
=
t
->
data
;
verdict
=
t
->
u
.
kernel
.
target
->
target
(
skb
,
&
tgpar
);
/* Target might have changed stuff. */
arp
=
arp_hdr
(
skb
);
if
(
verdict
==
ARPT_CONTINUE
)
e
=
(
void
*
)
e
+
e
->
next_offset
;
else
/* Verdict */
v
=
((
struct
arpt_standard_target
*
)
t
)
->
verdict
;
if
(
v
<
0
)
{
/* Pop from stack? */
if
(
v
!=
ARPT_RETURN
)
{
verdict
=
(
unsigned
)(
-
v
)
-
1
;
break
;
}
e
=
back
;
back
=
get_entry
(
table_base
,
back
->
comefrom
);
continue
;
}
}
else
{
e
=
(
void
*
)
e
+
e
->
next_offset
;
if
(
table_base
+
v
!=
arpt_next_entry
(
e
))
{
/* Save old back ptr in next entry */
struct
arpt_entry
*
next
=
arpt_next_entry
(
e
);
next
->
comefrom
=
(
void
*
)
back
-
table_base
;
/* set back pointer to next entry */
back
=
next
;
}
e
=
get_entry
(
table_base
,
v
);
continue
;
}
/* Targets which reenter must return
* abs. verdicts
*/
tgpar
.
target
=
t
->
u
.
kernel
.
target
;
tgpar
.
targinfo
=
t
->
data
;
verdict
=
t
->
u
.
kernel
.
target
->
target
(
skb
,
&
tgpar
);
/* Target might have changed stuff. */
arp
=
arp_hdr
(
skb
);
if
(
verdict
==
ARPT_CONTINUE
)
e
=
arpt_next_entry
(
e
);
else
/* Verdict */
break
;
}
while
(
!
hotdrop
);
xt_info_rdunlock_bh
();
...
...
net/ipv4/netfilter/ip_queue.c
View file @
8cc848fa
...
...
@@ -596,7 +596,7 @@ static int __init ip_queue_init(void)
#ifdef CONFIG_SYSCTL
ipq_sysctl_header
=
register_sysctl_paths
(
net_ipv4_ctl_path
,
ipq_table
);
#endif
status
=
nf_register_queue_handler
(
PF_INET
,
&
nfqh
);
status
=
nf_register_queue_handler
(
NFPROTO_IPV4
,
&
nfqh
);
if
(
status
<
0
)
{
printk
(
KERN_ERR
"ip_queue: failed to register queue handler
\n
"
);
goto
cleanup_sysctl
;
...
...
net/ipv4/netfilter/ip_tables.c
View file @
8cc848fa
...
...
@@ -238,8 +238,8 @@ static struct nf_loginfo trace_loginfo = {
/* Mildly perf critical (only if packet tracing is on) */
static
inline
int
get_chainname_rulenum
(
struct
ipt_entry
*
s
,
struct
ipt_entry
*
e
,
c
har
*
hookname
,
char
**
chainname
,
char
**
comment
,
unsigned
int
*
rulenum
)
c
onst
char
*
hookname
,
const
char
**
chainname
,
c
onst
c
har
**
comment
,
unsigned
int
*
rulenum
)
{
struct
ipt_standard_target
*
t
=
(
void
*
)
ipt_get_target
(
s
);
...
...
@@ -257,8 +257,8 @@ get_chainname_rulenum(struct ipt_entry *s, struct ipt_entry *e,
&&
unconditional
(
&
s
->
ip
))
{
/* Tail of chains: STANDARD target (return/policy) */
*
comment
=
*
chainname
==
hookname
?
(
char
*
)
comments
[
NF_IP_TRACE_COMMENT_POLICY
]
:
(
char
*
)
comments
[
NF_IP_TRACE_COMMENT_RETURN
];
?
comments
[
NF_IP_TRACE_COMMENT_POLICY
]
:
comments
[
NF_IP_TRACE_COMMENT_RETURN
];
}
return
1
;
}
else
...
...
@@ -277,14 +277,14 @@ static void trace_packet(struct sk_buff *skb,
{
void
*
table_base
;
const
struct
ipt_entry
*
root
;
char
*
hookname
,
*
chainname
,
*
comment
;
c
onst
c
har
*
hookname
,
*
chainname
,
*
comment
;
unsigned
int
rulenum
=
0
;
table_base
=
(
void
*
)
private
->
entries
[
smp_processor_id
()];
table_base
=
private
->
entries
[
smp_processor_id
()];
root
=
get_entry
(
table_base
,
private
->
hook_entry
[
hook
]);
hookname
=
chainname
=
(
char
*
)
hooknames
[
hook
];
comment
=
(
char
*
)
comments
[
NF_IP_TRACE_COMMENT_RULE
];
hookname
=
chainname
=
hooknames
[
hook
];
comment
=
comments
[
NF_IP_TRACE_COMMENT_RULE
];
IPT_ENTRY_ITERATE
(
root
,
private
->
size
-
private
->
hook_entry
[
hook
],
...
...
@@ -297,6 +297,12 @@ static void trace_packet(struct sk_buff *skb,
}
#endif
static
inline
__pure
struct
ipt_entry
*
ipt_next_entry
(
const
struct
ipt_entry
*
entry
)
{
return
(
void
*
)
entry
+
entry
->
next_offset
;
}
/* Returns one of the generic firewall policies, like NF_ACCEPT. */
unsigned
int
ipt_do_table
(
struct
sk_buff
*
skb
,
...
...
@@ -305,6 +311,8 @@ ipt_do_table(struct sk_buff *skb,
const
struct
net_device
*
out
,
struct
xt_table
*
table
)
{
#define tb_comefrom ((struct ipt_entry *)table_base)->comefrom
static
const
char
nulldevname
[
IFNAMSIZ
]
__attribute__
((
aligned
(
sizeof
(
long
))));
const
struct
iphdr
*
ip
;
u_int16_t
datalen
;
...
...
@@ -348,92 +356,84 @@ ipt_do_table(struct sk_buff *skb,
back
=
get_entry
(
table_base
,
private
->
underflow
[
hook
]);
do
{
struct
ipt_entry_target
*
t
;
IP_NF_ASSERT
(
e
);
IP_NF_ASSERT
(
back
);
if
(
ip_packet_match
(
ip
,
indev
,
outdev
,
&
e
->
ip
,
mtpar
.
fragoff
)
)
{
struct
ipt_entry_target
*
t
;
if
(
IPT_MATCH_ITERATE
(
e
,
do_match
,
skb
,
&
mtpar
)
!=
0
)
goto
no_match
;
if
(
!
ip_packet_match
(
ip
,
indev
,
outdev
,
&
e
->
ip
,
mtpar
.
fragoff
)
||
IPT_MATCH_ITERATE
(
e
,
do_match
,
skb
,
&
mtpar
)
!=
0
)
{
e
=
ipt_next_entry
(
e
);
continue
;
}
ADD_COUNTER
(
e
->
counters
,
ntohs
(
ip
->
tot_len
),
1
);
ADD_COUNTER
(
e
->
counters
,
ntohs
(
ip
->
tot_len
),
1
);
t
=
ipt_get_target
(
e
);
IP_NF_ASSERT
(
t
->
u
.
kernel
.
target
);
t
=
ipt_get_target
(
e
);
IP_NF_ASSERT
(
t
->
u
.
kernel
.
target
);
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
/* The packet is traced: log it */
if
(
unlikely
(
skb
->
nf_trace
))
trace_packet
(
skb
,
hook
,
in
,
out
,
table
->
name
,
private
,
e
);
/* The packet is traced: log it */
if
(
unlikely
(
skb
->
nf_trace
))
trace_packet
(
skb
,
hook
,
in
,
out
,
table
->
name
,
private
,
e
);
#endif
/* Standard target? */
if
(
!
t
->
u
.
kernel
.
target
->
target
)
{
int
v
;
v
=
((
struct
ipt_standard_target
*
)
t
)
->
verdict
;
if
(
v
<
0
)
{
/* Pop from stack? */
if
(
v
!=
IPT_RETURN
)
{
verdict
=
(
unsigned
)(
-
v
)
-
1
;
break
;
}
e
=
back
;
back
=
get_entry
(
table_base
,
back
->
comefrom
);
continue
;
}
if
(
table_base
+
v
!=
(
void
*
)
e
+
e
->
next_offset
&&
!
(
e
->
ip
.
flags
&
IPT_F_GOTO
))
{
/* Save old back ptr in next entry */
struct
ipt_entry
*
next
=
(
void
*
)
e
+
e
->
next_offset
;
next
->
comefrom
=
(
void
*
)
back
-
table_base
;
/* set back pointer to next entry */
back
=
next
;
/* Standard target? */
if
(
!
t
->
u
.
kernel
.
target
->
target
)
{
int
v
;
v
=
((
struct
ipt_standard_target
*
)
t
)
->
verdict
;
if
(
v
<
0
)
{
/* Pop from stack? */
if
(
v
!=
IPT_RETURN
)
{
verdict
=
(
unsigned
)(
-
v
)
-
1
;
break
;
}
e
=
back
;
back
=
get_entry
(
table_base
,
back
->
comefrom
);
continue
;
}
if
(
table_base
+
v
!=
ipt_next_entry
(
e
)
&&
!
(
e
->
ip
.
flags
&
IPT_F_GOTO
))
{
/* Save old back ptr in next entry */
struct
ipt_entry
*
next
=
ipt_next_entry
(
e
);
next
->
comefrom
=
(
void
*
)
back
-
table_base
;
/* set back pointer to next entry */
back
=
next
;
}
e
=
get_entry
(
table_base
,
v
);
continue
;
}
/* Targets which reenter must return
abs. verdicts */
tgpar
.
target
=
t
->
u
.
kernel
.
target
;
tgpar
.
targinfo
=
t
->
data
;
e
=
get_entry
(
table_base
,
v
);
}
else
{
/* Targets which reenter must return
abs. verdicts */
tgpar
.
target
=
t
->
u
.
kernel
.
target
;
tgpar
.
targinfo
=
t
->
data
;
#ifdef CONFIG_NETFILTER_DEBUG
((
struct
ipt_entry
*
)
table_base
)
->
comefrom
=
0xeeeeeeec
;
tb_comefrom
=
0xeeeeeeec
;
#endif
verdict
=
t
->
u
.
kernel
.
target
->
target
(
skb
,
&
tgpar
);
verdict
=
t
->
u
.
kernel
.
target
->
target
(
skb
,
&
tgpar
);
#ifdef CONFIG_NETFILTER_DEBUG
if
(((
struct
ipt_entry
*
)
table_base
)
->
comefrom
!=
0xeeeeeeec
&&
verdict
==
IPT_CONTINUE
)
{
printk
(
"Target %s reentered!
\n
"
,
t
->
u
.
kernel
.
target
->
name
);
verdict
=
NF_DROP
;
}
((
struct
ipt_entry
*
)
table_base
)
->
comefrom
=
0x57acc001
;
if
(
comefrom
!=
0xeeeeeeec
&&
verdict
==
IPT_CONTINUE
)
{
printk
(
"Target %s reentered!
\n
"
,
t
->
u
.
kernel
.
target
->
name
);
verdict
=
NF_DROP
;
}
tb_comefrom
=
0x57acc001
;
#endif
/* Target might have changed stuff. */
ip
=
ip_hdr
(
skb
);
datalen
=
skb
->
len
-
ip
->
ihl
*
4
;
if
(
verdict
==
IPT_CONTINUE
)
e
=
(
void
*
)
e
+
e
->
next_offset
;
else
/* Verdict */
break
;
}
}
else
{
/* Target might have changed stuff. */
ip
=
ip_hdr
(
skb
);
datalen
=
skb
->
len
-
ip
->
ihl
*
4
;
no_match:
e
=
(
void
*
)
e
+
e
->
next_offset
;
}
if
(
verdict
==
IPT_CONTINUE
)
e
=
ipt_next_entry
(
e
);
else
/* Verdict */
break
;
}
while
(
!
hotdrop
);
xt_info_rdunlock_bh
();
...
...
@@ -444,6 +444,8 @@ ipt_do_table(struct sk_buff *skb,
return
NF_DROP
;
else
return
verdict
;
#endif
#undef tb_comefrom
}
/* Figures out from what hook each rule can be called: returns 0 if
...
...
@@ -2158,7 +2160,7 @@ static bool icmp_checkentry(const struct xt_mtchk_param *par)
static
struct
xt_target
ipt_standard_target
__read_mostly
=
{
.
name
=
IPT_STANDARD_TARGET
,
.
targetsize
=
sizeof
(
int
),
.
family
=
AF_INET
,
.
family
=
NFPROTO_IPV4
,
#ifdef CONFIG_COMPAT
.
compatsize
=
sizeof
(
compat_int_t
),
.
compat_from_user
=
compat_standard_from_user
,
...
...
@@ -2170,7 +2172,7 @@ static struct xt_target ipt_error_target __read_mostly = {
.
name
=
IPT_ERROR_TARGET
,
.
target
=
ipt_error
,
.
targetsize
=
IPT_FUNCTION_MAXNAMELEN
,
.
family
=
AF_INET
,
.
family
=
NFPROTO_IPV4
,
};
static
struct
nf_sockopt_ops
ipt_sockopts
=
{
...
...
@@ -2196,17 +2198,17 @@ static struct xt_match icmp_matchstruct __read_mostly = {
.
matchsize
=
sizeof
(
struct
ipt_icmp
),
.
checkentry
=
icmp_checkentry
,
.
proto
=
IPPROTO_ICMP
,
.
family
=
AF_INET
,
.
family
=
NFPROTO_IPV4
,
};
static
int
__net_init
ip_tables_net_init
(
struct
net
*
net
)
{
return
xt_proto_init
(
net
,
AF_INET
);
return
xt_proto_init
(
net
,
NFPROTO_IPV4
);
}
static
void
__net_exit
ip_tables_net_exit
(
struct
net
*
net
)
{
xt_proto_fini
(
net
,
AF_INET
);
xt_proto_fini
(
net
,
NFPROTO_IPV4
);
}
static
struct
pernet_operations
ip_tables_net_ops
=
{
...
...
net/ipv6/netfilter/ip6_queue.c
View file @
8cc848fa
...
...
@@ -598,7 +598,7 @@ static int __init ip6_queue_init(void)
#ifdef CONFIG_SYSCTL
ipq_sysctl_header
=
register_sysctl_paths
(
net_ipv6_ctl_path
,
ipq_table
);
#endif
status
=
nf_register_queue_handler
(
PF_INET
6
,
&
nfqh
);
status
=
nf_register_queue_handler
(
NFPROTO_IPV
6
,
&
nfqh
);
if
(
status
<
0
)
{
printk
(
KERN_ERR
"ip6_queue: failed to register queue handler
\n
"
);
goto
cleanup_sysctl
;
...
...
net/ipv6/netfilter/ip6_tables.c
View file @
8cc848fa
...
...
@@ -270,8 +270,8 @@ static struct nf_loginfo trace_loginfo = {
/* Mildly perf critical (only if packet tracing is on) */
static
inline
int
get_chainname_rulenum
(
struct
ip6t_entry
*
s
,
struct
ip6t_entry
*
e
,
c
har
*
hookname
,
char
**
chainname
,
char
**
comment
,
unsigned
int
*
rulenum
)
c
onst
char
*
hookname
,
const
char
**
chainname
,
c
onst
c
har
**
comment
,
unsigned
int
*
rulenum
)
{
struct
ip6t_standard_target
*
t
=
(
void
*
)
ip6t_get_target
(
s
);
...
...
@@ -289,8 +289,8 @@ get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e,
&&
unconditional
(
&
s
->
ipv6
))
{
/* Tail of chains: STANDARD target (return/policy) */
*
comment
=
*
chainname
==
hookname
?
(
char
*
)
comments
[
NF_IP6_TRACE_COMMENT_POLICY
]
:
(
char
*
)
comments
[
NF_IP6_TRACE_COMMENT_RETURN
];
?
comments
[
NF_IP6_TRACE_COMMENT_POLICY
]
:
comments
[
NF_IP6_TRACE_COMMENT_RETURN
];
}
return
1
;
}
else
...
...
@@ -309,14 +309,14 @@ static void trace_packet(struct sk_buff *skb,
{
void
*
table_base
;
const
struct
ip6t_entry
*
root
;
char
*
hookname
,
*
chainname
,
*
comment
;
c
onst
c
har
*
hookname
,
*
chainname
,
*
comment
;
unsigned
int
rulenum
=
0
;
table_base
=
(
void
*
)
private
->
entries
[
smp_processor_id
()];
table_base
=
private
->
entries
[
smp_processor_id
()];
root
=
get_entry
(
table_base
,
private
->
hook_entry
[
hook
]);
hookname
=
chainname
=
(
char
*
)
hooknames
[
hook
];
comment
=
(
char
*
)
comments
[
NF_IP6_TRACE_COMMENT_RULE
];
hookname
=
chainname
=
hooknames
[
hook
];
comment
=
comments
[
NF_IP6_TRACE_COMMENT_RULE
];
IP6T_ENTRY_ITERATE
(
root
,
private
->
size
-
private
->
hook_entry
[
hook
],
...
...
@@ -329,6 +329,12 @@ static void trace_packet(struct sk_buff *skb,
}
#endif
static
inline
__pure
struct
ip6t_entry
*
ip6t_next_entry
(
const
struct
ip6t_entry
*
entry
)
{
return
(
void
*
)
entry
+
entry
->
next_offset
;
}
/* Returns one of the generic firewall policies, like NF_ACCEPT. */
unsigned
int
ip6t_do_table
(
struct
sk_buff
*
skb
,
...
...
@@ -337,6 +343,8 @@ ip6t_do_table(struct sk_buff *skb,
const
struct
net_device
*
out
,
struct
xt_table
*
table
)
{
#define tb_comefrom ((struct ip6t_entry *)table_base)->comefrom
static
const
char
nulldevname
[
IFNAMSIZ
]
__attribute__
((
aligned
(
sizeof
(
long
))));
bool
hotdrop
=
false
;
/* Initializing verdict to NF_DROP keeps gcc happy. */
...
...
@@ -375,96 +383,86 @@ ip6t_do_table(struct sk_buff *skb,
back
=
get_entry
(
table_base
,
private
->
underflow
[
hook
]);
do
{
struct
ip6t_entry_target
*
t
;
IP_NF_ASSERT
(
e
);
IP_NF_ASSERT
(
back
);
if
(
ip6_packet_match
(
skb
,
indev
,
outdev
,
&
e
->
ipv6
,
&
mtpar
.
thoff
,
&
mtpar
.
fragoff
,
&
hotdrop
))
{
struct
ip6t_entry_target
*
t
;
if
(
IP6T_MATCH_ITERATE
(
e
,
do_match
,
skb
,
&
mtpar
)
!=
0
)
goto
no_match
;
if
(
!
ip6_packet_match
(
skb
,
indev
,
outdev
,
&
e
->
ipv6
,
&
mtpar
.
thoff
,
&
mtpar
.
fragoff
,
&
hotdrop
)
||
IP6T_MATCH_ITERATE
(
e
,
do_match
,
skb
,
&
mtpar
)
!=
0
)
{
e
=
ip6t_next_entry
(
e
);
continue
;
}
ADD_COUNTER
(
e
->
counters
,
ntohs
(
ipv6_hdr
(
skb
)
->
payload_len
)
+
sizeof
(
struct
ipv6hdr
),
1
);
ADD_COUNTER
(
e
->
counters
,
ntohs
(
ipv6_hdr
(
skb
)
->
payload_len
)
+
sizeof
(
struct
ipv6hdr
),
1
);
t
=
ip6t_get_target
(
e
);
IP_NF_ASSERT
(
t
->
u
.
kernel
.
target
);
t
=
ip6t_get_target
(
e
);
IP_NF_ASSERT
(
t
->
u
.
kernel
.
target
);
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
/* The packet is traced: log it */
if
(
unlikely
(
skb
->
nf_trace
))
trace_packet
(
skb
,
hook
,
in
,
out
,
table
->
name
,
private
,
e
);
/* The packet is traced: log it */
if
(
unlikely
(
skb
->
nf_trace
))
trace_packet
(
skb
,
hook
,
in
,
out
,
table
->
name
,
private
,
e
);
#endif
/* Standard target? */
if
(
!
t
->
u
.
kernel
.
target
->
target
)
{
int
v
;
v
=
((
struct
ip6t_standard_target
*
)
t
)
->
verdict
;
if
(
v
<
0
)
{
/* Pop from stack? */
if
(
v
!=
IP6T_RETURN
)
{
verdict
=
(
unsigned
)(
-
v
)
-
1
;
break
;
}
e
=
back
;
back
=
get_entry
(
table_base
,
back
->
comefrom
);
continue
;
}
if
(
table_base
+
v
!=
(
void
*
)
e
+
e
->
next_offset
&&
!
(
e
->
ipv6
.
flags
&
IP6T_F_GOTO
))
{
/* Save old back ptr in next entry */
struct
ip6t_entry
*
next
=
(
void
*
)
e
+
e
->
next_offset
;
next
->
comefrom
=
(
void
*
)
back
-
table_base
;
/* set back pointer to next entry */
back
=
next
;
/* Standard target? */
if
(
!
t
->
u
.
kernel
.
target
->
target
)
{
int
v
;
v
=
((
struct
ip6t_standard_target
*
)
t
)
->
verdict
;
if
(
v
<
0
)
{
/* Pop from stack? */
if
(
v
!=
IP6T_RETURN
)
{
verdict
=
(
unsigned
)(
-
v
)
-
1
;
break
;
}
e
=
back
;
back
=
get_entry
(
table_base
,
back
->
comefrom
);
continue
;
}
if
(
table_base
+
v
!=
ip6t_next_entry
(
e
)
&&
!
(
e
->
ipv6
.
flags
&
IP6T_F_GOTO
))
{
/* Save old back ptr in next entry */
struct
ip6t_entry
*
next
=
ip6t_next_entry
(
e
);
next
->
comefrom
=
(
void
*
)
back
-
table_base
;
/* set back pointer to next entry */
back
=
next
;
}
e
=
get_entry
(
table_base
,
v
);
}
else
{
/* Targets which reenter must return
abs. verdicts */
tgpar
.
target
=
t
->
u
.
kernel
.
target
;
tgpar
.
targinfo
=
t
->
data
;
e
=
get_entry
(
table_base
,
v
);
continue
;
}
#ifdef CONFIG_NETFILTER_DEBUG
((
struct
ip6t_entry
*
)
table_base
)
->
comefrom
=
0xeeeeeeec
;
#endif
verdict
=
t
->
u
.
kernel
.
target
->
target
(
skb
,
&
tgpar
);
/* Targets which reenter must return
abs. verdicts */
tgpar
.
target
=
t
->
u
.
kernel
.
target
;
tgpar
.
targinfo
=
t
->
data
;
#ifdef CONFIG_NETFILTER_DEBUG
if
(((
struct
ip6t_entry
*
)
table_base
)
->
comefrom
!=
0xeeeeeeec
&&
verdict
==
IP6T_CONTINUE
)
{
printk
(
"Target %s reentered!
\n
"
,
t
->
u
.
kernel
.
target
->
name
);
verdict
=
NF_DROP
;
}
((
struct
ip6t_entry
*
)
table_base
)
->
comefrom
=
0x57acc001
;
tb_comefrom
=
0xeeeeeeec
;
#endif
if
(
verdict
==
IP6T_CONTINUE
)
e
=
(
void
*
)
e
+
e
->
next_offset
;
else
/* Verdict */
break
;
}
}
else
{
verdict
=
t
->
u
.
kernel
.
target
->
target
(
skb
,
&
tgpar
);
no_match:
e
=
(
void
*
)
e
+
e
->
next_offset
;
#ifdef CONFIG_NETFILTER_DEBUG
if
(
tb_comefrom
!=
0xeeeeeeec
&&
verdict
==
IP6T_CONTINUE
)
{
printk
(
"Target %s reentered!
\n
"
,
t
->
u
.
kernel
.
target
->
name
);
verdict
=
NF_DROP
;
}
tb_comefrom
=
0x57acc001
;
#endif
if
(
verdict
==
IP6T_CONTINUE
)
e
=
ip6t_next_entry
(
e
);
else
/* Verdict */
break
;
}
while
(
!
hotdrop
);
#ifdef CONFIG_NETFILTER_DEBUG
((
struct
ip6t_entry
*
)
table_base
)
->
comefrom
=
NETFILTER_LINK_POISON
;
tb_
comefrom
=
NETFILTER_LINK_POISON
;
#endif
xt_info_rdunlock_bh
();
...
...
@@ -475,6 +473,8 @@ ip6t_do_table(struct sk_buff *skb,
return
NF_DROP
;
else
return
verdict
;
#endif
#undef tb_comefrom
}
/* Figures out from what hook each rule can be called: returns 0 if
...
...
@@ -2191,7 +2191,7 @@ static bool icmp6_checkentry(const struct xt_mtchk_param *par)
static
struct
xt_target
ip6t_standard_target
__read_mostly
=
{
.
name
=
IP6T_STANDARD_TARGET
,
.
targetsize
=
sizeof
(
int
),
.
family
=
AF_INET
6
,
.
family
=
NFPROTO_IPV
6
,
#ifdef CONFIG_COMPAT
.
compatsize
=
sizeof
(
compat_int_t
),
.
compat_from_user
=
compat_standard_from_user
,
...
...
@@ -2203,7 +2203,7 @@ static struct xt_target ip6t_error_target __read_mostly = {
.
name
=
IP6T_ERROR_TARGET
,
.
target
=
ip6t_error
,
.
targetsize
=
IP6T_FUNCTION_MAXNAMELEN
,
.
family
=
AF_INET
6
,
.
family
=
NFPROTO_IPV
6
,
};
static
struct
nf_sockopt_ops
ip6t_sockopts
=
{
...
...
@@ -2229,17 +2229,17 @@ static struct xt_match icmp6_matchstruct __read_mostly = {
.
matchsize
=
sizeof
(
struct
ip6t_icmp
),
.
checkentry
=
icmp6_checkentry
,
.
proto
=
IPPROTO_ICMPV6
,
.
family
=
AF_INET
6
,
.
family
=
NFPROTO_IPV
6
,
};
static
int
__net_init
ip6_tables_net_init
(
struct
net
*
net
)
{
return
xt_proto_init
(
net
,
AF_INET
6
);
return
xt_proto_init
(
net
,
NFPROTO_IPV
6
);
}
static
void
__net_exit
ip6_tables_net_exit
(
struct
net
*
net
)
{
xt_proto_fini
(
net
,
AF_INET
6
);
xt_proto_fini
(
net
,
NFPROTO_IPV
6
);
}
static
struct
pernet_operations
ip6_tables_net_ops
=
{
...
...
net/netfilter/nf_queue.c
View file @
8cc848fa
...
...
@@ -204,10 +204,10 @@ int nf_queue(struct sk_buff *skb,
queuenum
);
switch
(
pf
)
{
case
AF_INET
:
case
NFPROTO_IPV4
:
skb
->
protocol
=
htons
(
ETH_P_IP
);
break
;
case
AF_INET
6
:
case
NFPROTO_IPV
6
:
skb
->
protocol
=
htons
(
ETH_P_IPV6
);
break
;
}
...
...
net/netfilter/x_tables.c
View file @
8cc848fa
...
...
@@ -329,6 +329,32 @@ int xt_find_revision(u8 af, const char *name, u8 revision, int target,
}
EXPORT_SYMBOL_GPL
(
xt_find_revision
);
static
char
*
textify_hooks
(
char
*
buf
,
size_t
size
,
unsigned
int
mask
)
{
static
const
char
*
const
names
[]
=
{
"PREROUTING"
,
"INPUT"
,
"FORWARD"
,
"OUTPUT"
,
"POSTROUTING"
,
"BROUTING"
,
};
unsigned
int
i
;
char
*
p
=
buf
;
bool
np
=
false
;
int
res
;
*
p
=
'\0'
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
names
);
++
i
)
{
if
(
!
(
mask
&
(
1
<<
i
)))
continue
;
res
=
snprintf
(
p
,
size
,
"%s%s"
,
np
?
"/"
:
""
,
names
[
i
]);
if
(
res
>
0
)
{
size
-=
res
;
p
+=
res
;
}
np
=
true
;
}
return
buf
;
}
int
xt_check_match
(
struct
xt_mtchk_param
*
par
,
unsigned
int
size
,
u_int8_t
proto
,
bool
inv_proto
)
{
...
...
@@ -351,9 +377,13 @@ int xt_check_match(struct xt_mtchk_param *par,
return
-
EINVAL
;
}
if
(
par
->
match
->
hooks
&&
(
par
->
hook_mask
&
~
par
->
match
->
hooks
)
!=
0
)
{
printk
(
"%s_tables: %s match: bad hook_mask %#x/%#x
\n
"
,
char
used
[
64
],
allow
[
64
];
printk
(
"%s_tables: %s match: used from hooks %s, but only "
"valid from %s
\n
"
,
xt_prefix
[
par
->
family
],
par
->
match
->
name
,
par
->
hook_mask
,
par
->
match
->
hooks
);
textify_hooks
(
used
,
sizeof
(
used
),
par
->
hook_mask
),
textify_hooks
(
allow
,
sizeof
(
allow
),
par
->
match
->
hooks
));
return
-
EINVAL
;
}
if
(
par
->
match
->
proto
&&
(
par
->
match
->
proto
!=
proto
||
inv_proto
))
{
...
...
@@ -497,9 +527,13 @@ int xt_check_target(struct xt_tgchk_param *par,
return
-
EINVAL
;
}
if
(
par
->
target
->
hooks
&&
(
par
->
hook_mask
&
~
par
->
target
->
hooks
)
!=
0
)
{
printk
(
"%s_tables: %s target: bad hook_mask %#x/%#x
\n
"
,
char
used
[
64
],
allow
[
64
];
printk
(
"%s_tables: %s target: used from hooks %s, but only "
"usable from %s
\n
"
,
xt_prefix
[
par
->
family
],
par
->
target
->
name
,
par
->
hook_mask
,
par
->
target
->
hooks
);
textify_hooks
(
used
,
sizeof
(
used
),
par
->
hook_mask
),
textify_hooks
(
allow
,
sizeof
(
allow
),
par
->
target
->
hooks
));
return
-
EINVAL
;
}
if
(
par
->
target
->
proto
&&
(
par
->
target
->
proto
!=
proto
||
inv_proto
))
{
...
...
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