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
a8c28d05
Commit
a8c28d05
authored
Feb 10, 2010
by
Patrick McHardy
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
git://dev.medozas.de/linux
parents
d0b0268f
e3eaa991
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
348 additions
and
825 deletions
+348
-825
include/linux/netfilter/x_tables.h
include/linux/netfilter/x_tables.h
+4
-0
include/linux/netfilter_arp/arp_tables.h
include/linux/netfilter_arp/arp_tables.h
+1
-0
include/linux/netfilter_ipv4/ip_tables.h
include/linux/netfilter_ipv4/ip_tables.h
+1
-0
include/linux/netfilter_ipv6/ip6_tables.h
include/linux/netfilter_ipv6/ip6_tables.h
+1
-0
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/arp_tables.c
+7
-0
net/ipv4/netfilter/arptable_filter.c
net/ipv4/netfilter/arptable_filter.c
+21
-74
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ip_tables.c
+7
-0
net/ipv4/netfilter/iptable_filter.c
net/ipv4/netfilter/iptable_filter.c
+29
-93
net/ipv4/netfilter/iptable_mangle.c
net/ipv4/netfilter/iptable_mangle.c
+30
-124
net/ipv4/netfilter/iptable_raw.c
net/ipv4/netfilter/iptable_raw.c
+25
-69
net/ipv4/netfilter/iptable_security.c
net/ipv4/netfilter/iptable_security.c
+26
-89
net/ipv4/netfilter/nf_nat_rule.c
net/ipv4/netfilter/nf_nat_rule.c
+7
-32
net/ipv6/netfilter/ip6_tables.c
net/ipv6/netfilter/ip6_tables.c
+7
-0
net/ipv6/netfilter/ip6table_filter.c
net/ipv6/netfilter/ip6table_filter.c
+23
-88
net/ipv6/netfilter/ip6table_mangle.c
net/ipv6/netfilter/ip6table_mangle.c
+28
-103
net/ipv6/netfilter/ip6table_raw.c
net/ipv6/netfilter/ip6table_raw.c
+19
-65
net/ipv6/netfilter/ip6table_security.c
net/ipv6/netfilter/ip6table_security.c
+20
-87
net/netfilter/x_tables.c
net/netfilter/x_tables.c
+57
-1
net/netfilter/xt_repldata.h
net/netfilter/xt_repldata.h
+35
-0
No files found.
include/linux/netfilter/x_tables.h
View file @
a8c28d05
...
...
@@ -360,6 +360,7 @@ struct xt_table {
struct
module
*
me
;
u_int8_t
af
;
/* address/protocol family */
int
priority
;
/* hook order */
/* A unique name... */
const
char
name
[
XT_TABLE_MAXNAMELEN
];
...
...
@@ -521,6 +522,9 @@ static inline unsigned long ifname_compare_aligned(const char *_a,
return
ret
;
}
extern
struct
nf_hook_ops
*
xt_hook_link
(
const
struct
xt_table
*
,
nf_hookfn
*
);
extern
void
xt_hook_unlink
(
const
struct
xt_table
*
,
struct
nf_hook_ops
*
);
#ifdef CONFIG_COMPAT
#include <net/compat.h>
...
...
include/linux/netfilter_arp/arp_tables.h
View file @
a8c28d05
...
...
@@ -258,6 +258,7 @@ struct arpt_error {
.target.errorname = "ERROR", \
}
extern
void
*
arpt_alloc_initial_table
(
const
struct
xt_table
*
);
extern
struct
xt_table
*
arpt_register_table
(
struct
net
*
net
,
const
struct
xt_table
*
table
,
const
struct
arpt_replace
*
repl
);
...
...
include/linux/netfilter_ipv4/ip_tables.h
View file @
a8c28d05
...
...
@@ -282,6 +282,7 @@ struct ipt_error {
.target.errorname = "ERROR", \
}
extern
void
*
ipt_alloc_initial_table
(
const
struct
xt_table
*
);
extern
unsigned
int
ipt_do_table
(
struct
sk_buff
*
skb
,
unsigned
int
hook
,
const
struct
net_device
*
in
,
...
...
include/linux/netfilter_ipv6/ip6_tables.h
View file @
a8c28d05
...
...
@@ -297,6 +297,7 @@ ip6t_get_target(struct ip6t_entry *e)
#include <linux/init.h>
extern
void
ip6t_init
(
void
)
__init
;
extern
void
*
ip6t_alloc_initial_table
(
const
struct
xt_table
*
);
extern
struct
xt_table
*
ip6t_register_table
(
struct
net
*
net
,
const
struct
xt_table
*
table
,
const
struct
ip6t_replace
*
repl
);
...
...
net/ipv4/netfilter/arp_tables.c
View file @
a8c28d05
...
...
@@ -27,6 +27,7 @@
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_arp/arp_tables.h>
#include "../../netfilter/xt_repldata.h"
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"David S. Miller <davem@redhat.com>"
);
...
...
@@ -58,6 +59,12 @@ do { \
#define ARP_NF_ASSERT(x)
#endif
void
*
arpt_alloc_initial_table
(
const
struct
xt_table
*
info
)
{
return
xt_alloc_initial_table
(
arpt
,
ARPT
);
}
EXPORT_SYMBOL_GPL
(
arpt_alloc_initial_table
);
static
inline
int
arp_devaddr_compare
(
const
struct
arpt_devaddr_info
*
ap
,
const
char
*
hdr_addr
,
int
len
)
{
...
...
net/ipv4/netfilter/arptable_filter.c
View file @
a8c28d05
...
...
@@ -6,6 +6,7 @@
*/
#include <linux/module.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_arp/arp_tables.h>
MODULE_LICENSE
(
"GPL"
);
...
...
@@ -15,93 +16,37 @@ MODULE_DESCRIPTION("arptables filter table");
#define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT) | \
(1 << NF_ARP_FORWARD))
static
const
struct
{
struct
arpt_replace
repl
;
struct
arpt_standard
entries
[
3
];
struct
arpt_error
term
;
}
initial_table
__net_initdata
=
{
.
repl
=
{
.
name
=
"filter"
,
.
valid_hooks
=
FILTER_VALID_HOOKS
,
.
num_entries
=
4
,
.
size
=
sizeof
(
struct
arpt_standard
)
*
3
+
sizeof
(
struct
arpt_error
),
.
hook_entry
=
{
[
NF_ARP_IN
]
=
0
,
[
NF_ARP_OUT
]
=
sizeof
(
struct
arpt_standard
),
[
NF_ARP_FORWARD
]
=
2
*
sizeof
(
struct
arpt_standard
),
},
.
underflow
=
{
[
NF_ARP_IN
]
=
0
,
[
NF_ARP_OUT
]
=
sizeof
(
struct
arpt_standard
),
[
NF_ARP_FORWARD
]
=
2
*
sizeof
(
struct
arpt_standard
),
},
},
.
entries
=
{
ARPT_STANDARD_INIT
(
NF_ACCEPT
),
/* ARP_IN */
ARPT_STANDARD_INIT
(
NF_ACCEPT
),
/* ARP_OUT */
ARPT_STANDARD_INIT
(
NF_ACCEPT
),
/* ARP_FORWARD */
},
.
term
=
ARPT_ERROR_INIT
,
};
static
const
struct
xt_table
packet_filter
=
{
.
name
=
"filter"
,
.
valid_hooks
=
FILTER_VALID_HOOKS
,
.
me
=
THIS_MODULE
,
.
af
=
NFPROTO_ARP
,
.
priority
=
NF_IP_PRI_FILTER
,
};
/* The work comes in here from netfilter.c */
static
unsigned
int
arpt_in_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
static
unsigned
int
arptable_filter_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
arpt_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
in
)
->
ipv4
.
arptable_filter
);
}
const
struct
net
*
net
=
dev_net
((
in
!=
NULL
)
?
in
:
out
);
static
unsigned
int
arpt_out_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
arpt_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
out
)
->
ipv4
.
arptable_filter
);
return
arpt_do_table
(
skb
,
hook
,
in
,
out
,
net
->
ipv4
.
arptable_filter
);
}
static
struct
nf_hook_ops
arpt_ops
[]
__read_mostly
=
{
{
.
hook
=
arpt_in_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_ARP
,
.
hooknum
=
NF_ARP_IN
,
.
priority
=
NF_IP_PRI_FILTER
,
},
{
.
hook
=
arpt_out_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_ARP
,
.
hooknum
=
NF_ARP_OUT
,
.
priority
=
NF_IP_PRI_FILTER
,
},
{
.
hook
=
arpt_in_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_ARP
,
.
hooknum
=
NF_ARP_FORWARD
,
.
priority
=
NF_IP_PRI_FILTER
,
},
};
static
struct
nf_hook_ops
*
arpfilter_ops
__read_mostly
;
static
int
__net_init
arptable_filter_net_init
(
struct
net
*
net
)
{
/* Register table */
struct
arpt_replace
*
repl
;
repl
=
arpt_alloc_initial_table
(
&
packet_filter
);
if
(
repl
==
NULL
)
return
-
ENOMEM
;
net
->
ipv4
.
arptable_filter
=
arpt_register_table
(
net
,
&
packet_filter
,
&
initial_table
.
repl
);
arpt_register_table
(
net
,
&
packet_filter
,
repl
);
kfree
(
repl
);
if
(
IS_ERR
(
net
->
ipv4
.
arptable_filter
))
return
PTR_ERR
(
net
->
ipv4
.
arptable_filter
);
return
0
;
...
...
@@ -125,9 +70,11 @@ static int __init arptable_filter_init(void)
if
(
ret
<
0
)
return
ret
;
ret
=
nf_register_hooks
(
arpt_ops
,
ARRAY_SIZE
(
arpt_ops
));
if
(
ret
<
0
)
arpfilter_ops
=
xt_hook_link
(
&
packet_filter
,
arptable_filter_hook
);
if
(
IS_ERR
(
arpfilter_ops
))
{
ret
=
PTR_ERR
(
arpfilter_ops
);
goto
cleanup_table
;
}
return
ret
;
cleanup_table:
...
...
@@ -137,7 +84,7 @@ static int __init arptable_filter_init(void)
static
void
__exit
arptable_filter_fini
(
void
)
{
nf_unregister_hooks
(
arpt_ops
,
ARRAY_SIZE
(
arpt_ops
)
);
xt_hook_unlink
(
&
packet_filter
,
arpfilter_ops
);
unregister_pernet_subsys
(
&
arptable_filter_net_ops
);
}
...
...
net/ipv4/netfilter/ip_tables.c
View file @
a8c28d05
...
...
@@ -28,6 +28,7 @@
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <net/netfilter/nf_log.h>
#include "../../netfilter/xt_repldata.h"
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Netfilter Core Team <coreteam@netfilter.org>"
);
...
...
@@ -66,6 +67,12 @@ do { \
#define inline
#endif
void
*
ipt_alloc_initial_table
(
const
struct
xt_table
*
info
)
{
return
xt_alloc_initial_table
(
ipt
,
IPT
);
}
EXPORT_SYMBOL_GPL
(
ipt_alloc_initial_table
);
/*
We keep a set of rules for each CPU, so we can avoid write-locking
them in the softirq when updating the counters and therefore
...
...
net/ipv4/netfilter/iptable_filter.c
View file @
a8c28d05
...
...
@@ -23,104 +23,32 @@ MODULE_DESCRIPTION("iptables filter table");
(1 << NF_INET_FORWARD) | \
(1 << NF_INET_LOCAL_OUT))
static
struct
{
struct
ipt_replace
repl
;
struct
ipt_standard
entries
[
3
];
struct
ipt_error
term
;
}
initial_table
__net_initdata
=
{
.
repl
=
{
.
name
=
"filter"
,
.
valid_hooks
=
FILTER_VALID_HOOKS
,
.
num_entries
=
4
,
.
size
=
sizeof
(
struct
ipt_standard
)
*
3
+
sizeof
(
struct
ipt_error
),
.
hook_entry
=
{
[
NF_INET_LOCAL_IN
]
=
0
,
[
NF_INET_FORWARD
]
=
sizeof
(
struct
ipt_standard
),
[
NF_INET_LOCAL_OUT
]
=
sizeof
(
struct
ipt_standard
)
*
2
,
},
.
underflow
=
{
[
NF_INET_LOCAL_IN
]
=
0
,
[
NF_INET_FORWARD
]
=
sizeof
(
struct
ipt_standard
),
[
NF_INET_LOCAL_OUT
]
=
sizeof
(
struct
ipt_standard
)
*
2
,
},
},
.
entries
=
{
IPT_STANDARD_INIT
(
NF_ACCEPT
),
/* LOCAL_IN */
IPT_STANDARD_INIT
(
NF_ACCEPT
),
/* FORWARD */
IPT_STANDARD_INIT
(
NF_ACCEPT
),
/* LOCAL_OUT */
},
.
term
=
IPT_ERROR_INIT
,
/* ERROR */
};
static
const
struct
xt_table
packet_filter
=
{
.
name
=
"filter"
,
.
valid_hooks
=
FILTER_VALID_HOOKS
,
.
me
=
THIS_MODULE
,
.
af
=
NFPROTO_IPV4
,
.
priority
=
NF_IP_PRI_FILTER
,
};
/* The work comes in here from netfilter.c. */
static
unsigned
int
ipt_local_in_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
ipt_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
in
)
->
ipv4
.
iptable_filter
);
}
static
unsigned
int
ipt_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
iptable_filter_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
ipt_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
in
)
->
ipv4
.
iptable_filter
);
}
const
struct
net
*
net
;
static
unsigned
int
ipt_local_out_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
/* root is playing with raw sockets. */
if
(
skb
->
len
<
sizeof
(
struct
iphdr
)
||
ip_hdrlen
(
skb
)
<
sizeof
(
struct
iphdr
))
if
(
hook
==
NF_INET_LOCAL_OUT
&&
(
skb
->
len
<
sizeof
(
struct
iphdr
)
||
ip_hdrlen
(
skb
)
<
sizeof
(
struct
iphdr
)))
/* root is playing with raw sockets. */
return
NF_ACCEPT
;
return
ipt_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
out
)
->
ipv4
.
iptable_filter
);
net
=
dev_net
((
in
!=
NULL
)
?
in
:
out
);
return
ipt_do_table
(
skb
,
hook
,
in
,
out
,
net
->
ipv4
.
iptable_filter
);
}
static
struct
nf_hook_ops
ipt_ops
[]
__read_mostly
=
{
{
.
hook
=
ipt_local_in_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV4
,
.
hooknum
=
NF_INET_LOCAL_IN
,
.
priority
=
NF_IP_PRI_FILTER
,
},
{
.
hook
=
ipt_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV4
,
.
hooknum
=
NF_INET_FORWARD
,
.
priority
=
NF_IP_PRI_FILTER
,
},
{
.
hook
=
ipt_local_out_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV4
,
.
hooknum
=
NF_INET_LOCAL_OUT
,
.
priority
=
NF_IP_PRI_FILTER
,
},
};
static
struct
nf_hook_ops
*
filter_ops
__read_mostly
;
/* Default to forward because I got too much mail already. */
static
int
forward
=
NF_ACCEPT
;
...
...
@@ -128,9 +56,18 @@ module_param(forward, bool, 0000);
static
int
__net_init
iptable_filter_net_init
(
struct
net
*
net
)
{
/* Register table */
struct
ipt_replace
*
repl
;
repl
=
ipt_alloc_initial_table
(
&
packet_filter
);
if
(
repl
==
NULL
)
return
-
ENOMEM
;
/* Entry 1 is the FORWARD hook */
((
struct
ipt_standard
*
)
repl
->
entries
)[
1
].
target
.
verdict
=
-
forward
-
1
;
net
->
ipv4
.
iptable_filter
=
ipt_register_table
(
net
,
&
packet_filter
,
&
initial_table
.
repl
);
ipt_register_table
(
net
,
&
packet_filter
,
repl
);
kfree
(
repl
);
if
(
IS_ERR
(
net
->
ipv4
.
iptable_filter
))
return
PTR_ERR
(
net
->
ipv4
.
iptable_filter
);
return
0
;
...
...
@@ -155,17 +92,16 @@ static int __init iptable_filter_init(void)
return
-
EINVAL
;
}
/* Entry 1 is the FORWARD hook */
initial_table
.
entries
[
1
].
target
.
verdict
=
-
forward
-
1
;
ret
=
register_pernet_subsys
(
&
iptable_filter_net_ops
);
if
(
ret
<
0
)
return
ret
;
/* Register hooks */
ret
=
nf_register_hooks
(
ipt_ops
,
ARRAY_SIZE
(
ipt_ops
));
if
(
ret
<
0
)
filter_ops
=
xt_hook_link
(
&
packet_filter
,
iptable_filter_hook
);
if
(
IS_ERR
(
filter_ops
))
{
ret
=
PTR_ERR
(
filter_ops
);
goto
cleanup_table
;
}
return
ret
;
...
...
@@ -176,7 +112,7 @@ static int __init iptable_filter_init(void)
static
void
__exit
iptable_filter_fini
(
void
)
{
nf_unregister_hooks
(
ipt_ops
,
ARRAY_SIZE
(
ipt_ops
)
);
xt_hook_unlink
(
&
packet_filter
,
filter_ops
);
unregister_pernet_subsys
(
&
iptable_filter_net_ops
);
}
...
...
net/ipv4/netfilter/iptable_mangle.c
View file @
a8c28d05
...
...
@@ -27,95 +27,14 @@ MODULE_DESCRIPTION("iptables mangle table");
(1 << NF_INET_LOCAL_OUT) | \
(1 << NF_INET_POST_ROUTING))
/* Ouch - five different hooks? Maybe this should be a config option..... -- BC */
static
const
struct
{
struct
ipt_replace
repl
;
struct
ipt_standard
entries
[
5
];
struct
ipt_error
term
;
}
initial_table
__net_initdata
=
{
.
repl
=
{
.
name
=
"mangle"
,
.
valid_hooks
=
MANGLE_VALID_HOOKS
,
.
num_entries
=
6
,
.
size
=
sizeof
(
struct
ipt_standard
)
*
5
+
sizeof
(
struct
ipt_error
),
.
hook_entry
=
{
[
NF_INET_PRE_ROUTING
]
=
0
,
[
NF_INET_LOCAL_IN
]
=
sizeof
(
struct
ipt_standard
),
[
NF_INET_FORWARD
]
=
sizeof
(
struct
ipt_standard
)
*
2
,
[
NF_INET_LOCAL_OUT
]
=
sizeof
(
struct
ipt_standard
)
*
3
,
[
NF_INET_POST_ROUTING
]
=
sizeof
(
struct
ipt_standard
)
*
4
,
},
.
underflow
=
{
[
NF_INET_PRE_ROUTING
]
=
0
,
[
NF_INET_LOCAL_IN
]
=
sizeof
(
struct
ipt_standard
),
[
NF_INET_FORWARD
]
=
sizeof
(
struct
ipt_standard
)
*
2
,
[
NF_INET_LOCAL_OUT
]
=
sizeof
(
struct
ipt_standard
)
*
3
,
[
NF_INET_POST_ROUTING
]
=
sizeof
(
struct
ipt_standard
)
*
4
,
},
},
.
entries
=
{
IPT_STANDARD_INIT
(
NF_ACCEPT
),
/* PRE_ROUTING */
IPT_STANDARD_INIT
(
NF_ACCEPT
),
/* LOCAL_IN */
IPT_STANDARD_INIT
(
NF_ACCEPT
),
/* FORWARD */
IPT_STANDARD_INIT
(
NF_ACCEPT
),
/* LOCAL_OUT */
IPT_STANDARD_INIT
(
NF_ACCEPT
),
/* POST_ROUTING */
},
.
term
=
IPT_ERROR_INIT
,
/* ERROR */
};
static
const
struct
xt_table
packet_mangler
=
{
.
name
=
"mangle"
,
.
valid_hooks
=
MANGLE_VALID_HOOKS
,
.
me
=
THIS_MODULE
,
.
af
=
NFPROTO_IPV4
,
.
priority
=
NF_IP_PRI_MANGLE
,
};
/* The work comes in here from netfilter.c. */
static
unsigned
int
ipt_pre_routing_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
ipt_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
in
)
->
ipv4
.
iptable_mangle
);
}
static
unsigned
int
ipt_post_routing_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
ipt_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
out
)
->
ipv4
.
iptable_mangle
);
}
static
unsigned
int
ipt_local_in_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
ipt_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
in
)
->
ipv4
.
iptable_mangle
);
}
static
unsigned
int
ipt_forward_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
ipt_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
in
)
->
ipv4
.
iptable_mangle
);
}
static
unsigned
int
ipt_local_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
...
...
@@ -158,49 +77,34 @@ ipt_local_hook(unsigned int hook,
return
ret
;
}
static
struct
nf_hook_ops
ipt_ops
[]
__read_mostly
=
{
{
.
hook
=
ipt_pre_routing_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV4
,
.
hooknum
=
NF_INET_PRE_ROUTING
,
.
priority
=
NF_IP_PRI_MANGLE
,
},
{
.
hook
=
ipt_local_in_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV4
,
.
hooknum
=
NF_INET_LOCAL_IN
,
.
priority
=
NF_IP_PRI_MANGLE
,
},
{
.
hook
=
ipt_forward_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV4
,
.
hooknum
=
NF_INET_FORWARD
,
.
priority
=
NF_IP_PRI_MANGLE
,
},
{
.
hook
=
ipt_local_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV4
,
.
hooknum
=
NF_INET_LOCAL_OUT
,
.
priority
=
NF_IP_PRI_MANGLE
,
},
{
.
hook
=
ipt_post_routing_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV4
,
.
hooknum
=
NF_INET_POST_ROUTING
,
.
priority
=
NF_IP_PRI_MANGLE
,
},
};
/* The work comes in here from netfilter.c. */
static
unsigned
int
iptable_mangle_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
if
(
hook
==
NF_INET_LOCAL_OUT
)
return
ipt_local_hook
(
hook
,
skb
,
in
,
out
,
okfn
);
/* PREROUTING/INPUT/FORWARD: */
return
ipt_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
in
)
->
ipv4
.
iptable_mangle
);
}
static
struct
nf_hook_ops
*
mangle_ops
__read_mostly
;
static
int
__net_init
iptable_mangle_net_init
(
struct
net
*
net
)
{
/* Register table */
struct
ipt_replace
*
repl
;
repl
=
ipt_alloc_initial_table
(
&
packet_mangler
);
if
(
repl
==
NULL
)
return
-
ENOMEM
;
net
->
ipv4
.
iptable_mangle
=
ipt_register_table
(
net
,
&
packet_mangler
,
&
initial_table
.
repl
);
ipt_register_table
(
net
,
&
packet_mangler
,
repl
);
kfree
(
repl
);
if
(
IS_ERR
(
net
->
ipv4
.
iptable_mangle
))
return
PTR_ERR
(
net
->
ipv4
.
iptable_mangle
);
return
0
;
...
...
@@ -225,9 +129,11 @@ static int __init iptable_mangle_init(void)
return
ret
;
/* Register hooks */
ret
=
nf_register_hooks
(
ipt_ops
,
ARRAY_SIZE
(
ipt_ops
));
if
(
ret
<
0
)
mangle_ops
=
xt_hook_link
(
&
packet_mangler
,
iptable_mangle_hook
);
if
(
IS_ERR
(
mangle_ops
))
{
ret
=
PTR_ERR
(
mangle_ops
);
goto
cleanup_table
;
}
return
ret
;
...
...
@@ -238,7 +144,7 @@ static int __init iptable_mangle_init(void)
static
void
__exit
iptable_mangle_fini
(
void
)
{
nf_unregister_hooks
(
ipt_ops
,
ARRAY_SIZE
(
ipt_ops
)
);
xt_hook_unlink
(
&
packet_mangler
,
mangle_ops
);
unregister_pernet_subsys
(
&
iptable_mangle_net_ops
);
}
...
...
net/ipv4/netfilter/iptable_raw.c
View file @
a8c28d05
...
...
@@ -9,90 +9,44 @@
#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
static
const
struct
{
struct
ipt_replace
repl
;
struct
ipt_standard
entries
[
2
];
struct
ipt_error
term
;
}
initial_table
__net_initdata
=
{
.
repl
=
{
.
name
=
"raw"
,
.
valid_hooks
=
RAW_VALID_HOOKS
,
.
num_entries
=
3
,
.
size
=
sizeof
(
struct
ipt_standard
)
*
2
+
sizeof
(
struct
ipt_error
),
.
hook_entry
=
{
[
NF_INET_PRE_ROUTING
]
=
0
,
[
NF_INET_LOCAL_OUT
]
=
sizeof
(
struct
ipt_standard
)
},
.
underflow
=
{
[
NF_INET_PRE_ROUTING
]
=
0
,
[
NF_INET_LOCAL_OUT
]
=
sizeof
(
struct
ipt_standard
)
},
},
.
entries
=
{
IPT_STANDARD_INIT
(
NF_ACCEPT
),
/* PRE_ROUTING */
IPT_STANDARD_INIT
(
NF_ACCEPT
),
/* LOCAL_OUT */
},
.
term
=
IPT_ERROR_INIT
,
/* ERROR */
};
static
const
struct
xt_table
packet_raw
=
{
.
name
=
"raw"
,
.
valid_hooks
=
RAW_VALID_HOOKS
,
.
me
=
THIS_MODULE
,
.
af
=
NFPROTO_IPV4
,
.
priority
=
NF_IP_PRI_RAW
,
};
/* The work comes in here from netfilter.c. */
static
unsigned
int
ipt_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
iptable_raw_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
ipt_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
in
)
->
ipv4
.
iptable_raw
);
}
const
struct
net
*
net
;
static
unsigned
int
ipt_local_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
/* root is playing with raw sockets. */
if
(
skb
->
len
<
sizeof
(
struct
iphdr
)
||
ip_hdrlen
(
skb
)
<
sizeof
(
struct
iphdr
))
if
(
hook
==
NF_INET_LOCAL_OUT
&&
(
skb
->
len
<
sizeof
(
struct
iphdr
)
||
ip_hdrlen
(
skb
)
<
sizeof
(
struct
iphdr
)))
/* root is playing with raw sockets. */
return
NF_ACCEPT
;
return
ipt_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
out
)
->
ipv4
.
iptable_raw
);
net
=
dev_net
((
in
!=
NULL
)
?
in
:
out
);
return
ipt_do_table
(
skb
,
hook
,
in
,
out
,
net
->
ipv4
.
iptable_raw
);
}
/* 'raw' is the very first table. */
static
struct
nf_hook_ops
ipt_ops
[]
__read_mostly
=
{
{
.
hook
=
ipt_hook
,
.
pf
=
NFPROTO_IPV4
,
.
hooknum
=
NF_INET_PRE_ROUTING
,
.
priority
=
NF_IP_PRI_RAW
,
.
owner
=
THIS_MODULE
,
},
{
.
hook
=
ipt_local_hook
,
.
pf
=
NFPROTO_IPV4
,
.
hooknum
=
NF_INET_LOCAL_OUT
,
.
priority
=
NF_IP_PRI_RAW
,
.
owner
=
THIS_MODULE
,
},
};
static
struct
nf_hook_ops
*
rawtable_ops
__read_mostly
;
static
int
__net_init
iptable_raw_net_init
(
struct
net
*
net
)
{
/* Register table */
struct
ipt_replace
*
repl
;
repl
=
ipt_alloc_initial_table
(
&
packet_raw
);
if
(
repl
==
NULL
)
return
-
ENOMEM
;
net
->
ipv4
.
iptable_raw
=
ipt_register_table
(
net
,
&
packet_raw
,
&
initial_table
.
repl
);
ipt_register_table
(
net
,
&
packet_raw
,
repl
);
kfree
(
repl
);
if
(
IS_ERR
(
net
->
ipv4
.
iptable_raw
))
return
PTR_ERR
(
net
->
ipv4
.
iptable_raw
);
return
0
;
...
...
@@ -117,9 +71,11 @@ static int __init iptable_raw_init(void)
return
ret
;
/* Register hooks */
ret
=
nf_register_hooks
(
ipt_ops
,
ARRAY_SIZE
(
ipt_ops
));
if
(
ret
<
0
)
rawtable_ops
=
xt_hook_link
(
&
packet_raw
,
iptable_raw_hook
);
if
(
IS_ERR
(
rawtable_ops
))
{
ret
=
PTR_ERR
(
rawtable_ops
);
goto
cleanup_table
;
}
return
ret
;
...
...
@@ -130,7 +86,7 @@ static int __init iptable_raw_init(void)
static
void
__exit
iptable_raw_fini
(
void
)
{
nf_unregister_hooks
(
ipt_ops
,
ARRAY_SIZE
(
ipt_ops
)
);
xt_hook_unlink
(
&
packet_raw
,
rawtable_ops
);
unregister_pernet_subsys
(
&
iptable_raw_net_ops
);
}
...
...
net/ipv4/netfilter/iptable_security.c
View file @
a8c28d05
...
...
@@ -27,109 +27,44 @@ MODULE_DESCRIPTION("iptables security table, for MAC rules");
(1 << NF_INET_FORWARD) | \
(1 << NF_INET_LOCAL_OUT)
static
const
struct
{
struct
ipt_replace
repl
;
struct
ipt_standard
entries
[
3
];
struct
ipt_error
term
;
}
initial_table
__net_initdata
=
{
.
repl
=
{
.
name
=
"security"
,
.
valid_hooks
=
SECURITY_VALID_HOOKS
,
.
num_entries
=
4
,
.
size
=
sizeof
(
struct
ipt_standard
)
*
3
+
sizeof
(
struct
ipt_error
),
.
hook_entry
=
{
[
NF_INET_LOCAL_IN
]
=
0
,
[
NF_INET_FORWARD
]
=
sizeof
(
struct
ipt_standard
),
[
NF_INET_LOCAL_OUT
]
=
sizeof
(
struct
ipt_standard
)
*
2
,
},
.
underflow
=
{
[
NF_INET_LOCAL_IN
]
=
0
,
[
NF_INET_FORWARD
]
=
sizeof
(
struct
ipt_standard
),
[
NF_INET_LOCAL_OUT
]
=
sizeof
(
struct
ipt_standard
)
*
2
,
},
},
.
entries
=
{
IPT_STANDARD_INIT
(
NF_ACCEPT
),
/* LOCAL_IN */
IPT_STANDARD_INIT
(
NF_ACCEPT
),
/* FORWARD */
IPT_STANDARD_INIT
(
NF_ACCEPT
),
/* LOCAL_OUT */
},
.
term
=
IPT_ERROR_INIT
,
/* ERROR */
};
static
const
struct
xt_table
security_table
=
{
.
name
=
"security"
,
.
valid_hooks
=
SECURITY_VALID_HOOKS
,
.
me
=
THIS_MODULE
,
.
af
=
NFPROTO_IPV4
,
.
priority
=
NF_IP_PRI_SECURITY
,
};
static
unsigned
int
ipt_local_in_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
ipt_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
in
)
->
ipv4
.
iptable_security
);
}
static
unsigned
int
ipt_forward_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
iptable_security_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
ipt_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
in
)
->
ipv4
.
iptable_security
);
}
const
struct
net
*
net
;
static
unsigned
int
ipt_local_out_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
/* Somebody is playing with raw sockets. */
if
(
skb
->
len
<
sizeof
(
struct
iphdr
)
||
ip_hdrlen
(
skb
)
<
sizeof
(
struct
iphdr
))
if
(
hook
==
NF_INET_LOCAL_OUT
&&
(
skb
->
len
<
sizeof
(
struct
iphdr
)
||
ip_hdrlen
(
skb
)
<
sizeof
(
struct
iphdr
)))
/* Somebody is playing with raw sockets. */
return
NF_ACCEPT
;
return
ipt_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
out
)
->
ipv4
.
iptable_security
);
net
=
dev_net
((
in
!=
NULL
)
?
in
:
out
);
return
ipt_do_table
(
skb
,
hook
,
in
,
out
,
net
->
ipv4
.
iptable_security
);
}
static
struct
nf_hook_ops
ipt_ops
[]
__read_mostly
=
{
{
.
hook
=
ipt_local_in_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV4
,
.
hooknum
=
NF_INET_LOCAL_IN
,
.
priority
=
NF_IP_PRI_SECURITY
,
},
{
.
hook
=
ipt_forward_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV4
,
.
hooknum
=
NF_INET_FORWARD
,
.
priority
=
NF_IP_PRI_SECURITY
,
},
{
.
hook
=
ipt_local_out_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV4
,
.
hooknum
=
NF_INET_LOCAL_OUT
,
.
priority
=
NF_IP_PRI_SECURITY
,
},
};
static
struct
nf_hook_ops
*
sectbl_ops
__read_mostly
;
static
int
__net_init
iptable_security_net_init
(
struct
net
*
net
)
{
net
->
ipv4
.
iptable_security
=
ipt_register_table
(
net
,
&
security_table
,
&
initial_table
.
repl
);
struct
ipt_replace
*
repl
;
repl
=
ipt_alloc_initial_table
(
&
security_table
);
if
(
repl
==
NULL
)
return
-
ENOMEM
;
net
->
ipv4
.
iptable_security
=
ipt_register_table
(
net
,
&
security_table
,
repl
);
kfree
(
repl
);
if
(
IS_ERR
(
net
->
ipv4
.
iptable_security
))
return
PTR_ERR
(
net
->
ipv4
.
iptable_security
);
...
...
@@ -154,9 +89,11 @@ static int __init iptable_security_init(void)
if
(
ret
<
0
)
return
ret
;
ret
=
nf_register_hooks
(
ipt_ops
,
ARRAY_SIZE
(
ipt_ops
));
if
(
ret
<
0
)
sectbl_ops
=
xt_hook_link
(
&
security_table
,
iptable_security_hook
);
if
(
IS_ERR
(
sectbl_ops
))
{
ret
=
PTR_ERR
(
sectbl_ops
);
goto
cleanup_table
;
}
return
ret
;
...
...
@@ -167,7 +104,7 @@ static int __init iptable_security_init(void)
static
void
__exit
iptable_security_fini
(
void
)
{
nf_unregister_hooks
(
ipt_ops
,
ARRAY_SIZE
(
ipt_ops
)
);
xt_hook_unlink
(
&
security_table
,
sectbl_ops
);
unregister_pernet_subsys
(
&
iptable_security_net_ops
);
}
...
...
net/ipv4/netfilter/nf_nat_rule.c
View file @
a8c28d05
...
...
@@ -28,36 +28,6 @@
(1 << NF_INET_POST_ROUTING) | \
(1 << NF_INET_LOCAL_OUT))
static
const
struct
{
struct
ipt_replace
repl
;
struct
ipt_standard
entries
[
3
];
struct
ipt_error
term
;
}
nat_initial_table
__net_initdata
=
{
.
repl
=
{
.
name
=
"nat"
,
.
valid_hooks
=
NAT_VALID_HOOKS
,
.
num_entries
=
4
,
.
size
=
sizeof
(
struct
ipt_standard
)
*
3
+
sizeof
(
struct
ipt_error
),
.
hook_entry
=
{
[
NF_INET_PRE_ROUTING
]
=
0
,
[
NF_INET_POST_ROUTING
]
=
sizeof
(
struct
ipt_standard
),
[
NF_INET_LOCAL_OUT
]
=
sizeof
(
struct
ipt_standard
)
*
2
},
.
underflow
=
{
[
NF_INET_PRE_ROUTING
]
=
0
,
[
NF_INET_POST_ROUTING
]
=
sizeof
(
struct
ipt_standard
),
[
NF_INET_LOCAL_OUT
]
=
sizeof
(
struct
ipt_standard
)
*
2
},
},
.
entries
=
{
IPT_STANDARD_INIT
(
NF_ACCEPT
),
/* PRE_ROUTING */
IPT_STANDARD_INIT
(
NF_ACCEPT
),
/* POST_ROUTING */
IPT_STANDARD_INIT
(
NF_ACCEPT
),
/* LOCAL_OUT */
},
.
term
=
IPT_ERROR_INIT
,
/* ERROR */
};
static
const
struct
xt_table
nat_table
=
{
.
name
=
"nat"
,
.
valid_hooks
=
NAT_VALID_HOOKS
,
...
...
@@ -186,8 +156,13 @@ static struct xt_target ipt_dnat_reg __read_mostly = {
static
int
__net_init
nf_nat_rule_net_init
(
struct
net
*
net
)
{
net
->
ipv4
.
nat_table
=
ipt_register_table
(
net
,
&
nat_table
,
&
nat_initial_table
.
repl
);
struct
ipt_replace
*
repl
;
repl
=
ipt_alloc_initial_table
(
&
nat_table
);
if
(
repl
==
NULL
)
return
-
ENOMEM
;
net
->
ipv4
.
nat_table
=
ipt_register_table
(
net
,
&
nat_table
,
repl
);
kfree
(
repl
);
if
(
IS_ERR
(
net
->
ipv4
.
nat_table
))
return
PTR_ERR
(
net
->
ipv4
.
nat_table
);
return
0
;
...
...
net/ipv6/netfilter/ip6_tables.c
View file @
a8c28d05
...
...
@@ -29,6 +29,7 @@
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter/x_tables.h>
#include <net/netfilter/nf_log.h>
#include "../../netfilter/xt_repldata.h"
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Netfilter Core Team <coreteam@netfilter.org>"
);
...
...
@@ -67,6 +68,12 @@ do { \
#define inline
#endif
void
*
ip6t_alloc_initial_table
(
const
struct
xt_table
*
info
)
{
return
xt_alloc_initial_table
(
ip6t
,
IP6T
);
}
EXPORT_SYMBOL_GPL
(
ip6t_alloc_initial_table
);
/*
We keep a set of rules for each CPU, so we can avoid write-locking
them in the softirq when updating the counters and therefore
...
...
net/ipv6/netfilter/ip6table_filter.c
View file @
a8c28d05
...
...
@@ -21,99 +21,26 @@ MODULE_DESCRIPTION("ip6tables filter table");
(1 << NF_INET_FORWARD) | \
(1 << NF_INET_LOCAL_OUT))
static
struct
{
struct
ip6t_replace
repl
;
struct
ip6t_standard
entries
[
3
];
struct
ip6t_error
term
;
}
initial_table
__net_initdata
=
{
.
repl
=
{
.
name
=
"filter"
,
.
valid_hooks
=
FILTER_VALID_HOOKS
,
.
num_entries
=
4
,
.
size
=
sizeof
(
struct
ip6t_standard
)
*
3
+
sizeof
(
struct
ip6t_error
),
.
hook_entry
=
{
[
NF_INET_LOCAL_IN
]
=
0
,
[
NF_INET_FORWARD
]
=
sizeof
(
struct
ip6t_standard
),
[
NF_INET_LOCAL_OUT
]
=
sizeof
(
struct
ip6t_standard
)
*
2
},
.
underflow
=
{
[
NF_INET_LOCAL_IN
]
=
0
,
[
NF_INET_FORWARD
]
=
sizeof
(
struct
ip6t_standard
),
[
NF_INET_LOCAL_OUT
]
=
sizeof
(
struct
ip6t_standard
)
*
2
},
},
.
entries
=
{
IP6T_STANDARD_INIT
(
NF_ACCEPT
),
/* LOCAL_IN */
IP6T_STANDARD_INIT
(
NF_ACCEPT
),
/* FORWARD */
IP6T_STANDARD_INIT
(
NF_ACCEPT
),
/* LOCAL_OUT */
},
.
term
=
IP6T_ERROR_INIT
,
/* ERROR */
};
static
const
struct
xt_table
packet_filter
=
{
.
name
=
"filter"
,
.
valid_hooks
=
FILTER_VALID_HOOKS
,
.
me
=
THIS_MODULE
,
.
af
=
NFPROTO_IPV6
,
.
priority
=
NF_IP6_PRI_FILTER
,
};
/* The work comes in here from netfilter.c. */
static
unsigned
int
ip6t_in_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
ip6t_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
in
)
->
ipv6
.
ip6table_filter
);
}
static
unsigned
int
ip6t_local_out_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
ip6table_filter_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
#if 0
/* root is playing with raw sockets. */
if (skb->len < sizeof(struct iphdr) ||
ip_hdrlen(skb) < sizeof(struct iphdr)) {
if (net_ratelimit())
printk("ip6t_hook: happy cracking.\n");
return NF_ACCEPT;
}
#endif
const
struct
net
*
net
=
dev_net
((
in
!=
NULL
)
?
in
:
out
);
return
ip6t_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
out
)
->
ipv6
.
ip6table_filter
);
return
ip6t_do_table
(
skb
,
hook
,
in
,
out
,
net
->
ipv6
.
ip6table_filter
);
}
static
struct
nf_hook_ops
ip6t_ops
[]
__read_mostly
=
{
{
.
hook
=
ip6t_in_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV6
,
.
hooknum
=
NF_INET_LOCAL_IN
,
.
priority
=
NF_IP6_PRI_FILTER
,
},
{
.
hook
=
ip6t_in_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV6
,
.
hooknum
=
NF_INET_FORWARD
,
.
priority
=
NF_IP6_PRI_FILTER
,
},
{
.
hook
=
ip6t_local_out_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV6
,
.
hooknum
=
NF_INET_LOCAL_OUT
,
.
priority
=
NF_IP6_PRI_FILTER
,
},
};
static
struct
nf_hook_ops
*
filter_ops
__read_mostly
;
/* Default to forward because I got too much mail already. */
static
int
forward
=
NF_ACCEPT
;
...
...
@@ -121,9 +48,18 @@ module_param(forward, bool, 0000);
static
int
__net_init
ip6table_filter_net_init
(
struct
net
*
net
)
{
/* Register table */
struct
ip6t_replace
*
repl
;
repl
=
ip6t_alloc_initial_table
(
&
packet_filter
);
if
(
repl
==
NULL
)
return
-
ENOMEM
;
/* Entry 1 is the FORWARD hook */
((
struct
ip6t_standard
*
)
repl
->
entries
)[
1
].
target
.
verdict
=
-
forward
-
1
;
net
->
ipv6
.
ip6table_filter
=
ip6t_register_table
(
net
,
&
packet_filter
,
&
initial_table
.
repl
);
ip6t_register_table
(
net
,
&
packet_filter
,
repl
);
kfree
(
repl
);
if
(
IS_ERR
(
net
->
ipv6
.
ip6table_filter
))
return
PTR_ERR
(
net
->
ipv6
.
ip6table_filter
);
return
0
;
...
...
@@ -148,17 +84,16 @@ static int __init ip6table_filter_init(void)
return
-
EINVAL
;
}
/* Entry 1 is the FORWARD hook */
initial_table
.
entries
[
1
].
target
.
verdict
=
-
forward
-
1
;
ret
=
register_pernet_subsys
(
&
ip6table_filter_net_ops
);
if
(
ret
<
0
)
return
ret
;
/* Register hooks */
ret
=
nf_register_hooks
(
ip6t_ops
,
ARRAY_SIZE
(
ip6t_ops
));
if
(
ret
<
0
)
filter_ops
=
xt_hook_link
(
&
packet_filter
,
ip6table_filter_hook
);
if
(
IS_ERR
(
filter_ops
))
{
ret
=
PTR_ERR
(
filter_ops
);
goto
cleanup_table
;
}
return
ret
;
...
...
@@ -169,7 +104,7 @@ static int __init ip6table_filter_init(void)
static
void
__exit
ip6table_filter_fini
(
void
)
{
nf_unregister_hooks
(
ip6t_ops
,
ARRAY_SIZE
(
ip6t_ops
)
);
xt_hook_unlink
(
&
packet_filter
,
filter_ops
);
unregister_pernet_subsys
(
&
ip6table_filter_net_ops
);
}
...
...
net/ipv6/netfilter/ip6table_mangle.c
View file @
a8c28d05
...
...
@@ -21,76 +21,17 @@ MODULE_DESCRIPTION("ip6tables mangle table");
(1 << NF_INET_LOCAL_OUT) | \
(1 << NF_INET_POST_ROUTING))
static
const
struct
{
struct
ip6t_replace
repl
;
struct
ip6t_standard
entries
[
5
];
struct
ip6t_error
term
;
}
initial_table
__net_initdata
=
{
.
repl
=
{
.
name
=
"mangle"
,
.
valid_hooks
=
MANGLE_VALID_HOOKS
,
.
num_entries
=
6
,
.
size
=
sizeof
(
struct
ip6t_standard
)
*
5
+
sizeof
(
struct
ip6t_error
),
.
hook_entry
=
{
[
NF_INET_PRE_ROUTING
]
=
0
,
[
NF_INET_LOCAL_IN
]
=
sizeof
(
struct
ip6t_standard
),
[
NF_INET_FORWARD
]
=
sizeof
(
struct
ip6t_standard
)
*
2
,
[
NF_INET_LOCAL_OUT
]
=
sizeof
(
struct
ip6t_standard
)
*
3
,
[
NF_INET_POST_ROUTING
]
=
sizeof
(
struct
ip6t_standard
)
*
4
,
},
.
underflow
=
{
[
NF_INET_PRE_ROUTING
]
=
0
,
[
NF_INET_LOCAL_IN
]
=
sizeof
(
struct
ip6t_standard
),
[
NF_INET_FORWARD
]
=
sizeof
(
struct
ip6t_standard
)
*
2
,
[
NF_INET_LOCAL_OUT
]
=
sizeof
(
struct
ip6t_standard
)
*
3
,
[
NF_INET_POST_ROUTING
]
=
sizeof
(
struct
ip6t_standard
)
*
4
,
},
},
.
entries
=
{
IP6T_STANDARD_INIT
(
NF_ACCEPT
),
/* PRE_ROUTING */
IP6T_STANDARD_INIT
(
NF_ACCEPT
),
/* LOCAL_IN */
IP6T_STANDARD_INIT
(
NF_ACCEPT
),
/* FORWARD */
IP6T_STANDARD_INIT
(
NF_ACCEPT
),
/* LOCAL_OUT */
IP6T_STANDARD_INIT
(
NF_ACCEPT
),
/* POST_ROUTING */
},
.
term
=
IP6T_ERROR_INIT
,
/* ERROR */
};
static
const
struct
xt_table
packet_mangler
=
{
.
name
=
"mangle"
,
.
valid_hooks
=
MANGLE_VALID_HOOKS
,
.
me
=
THIS_MODULE
,
.
af
=
NFPROTO_IPV6
,
.
priority
=
NF_IP6_PRI_MANGLE
,
};
/* The work comes in here from netfilter.c. */
static
unsigned
int
ip6t_in_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
ip6t_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
in
)
->
ipv6
.
ip6table_mangle
);
}
static
unsigned
int
ip6t_post_routing_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
ip6t_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
out
)
->
ipv6
.
ip6table_mangle
);
}
static
unsigned
int
ip6t_local_out_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
...
...
@@ -119,7 +60,7 @@ ip6t_local_out_hook(unsigned int hook,
/* flowlabel and prio (includes version, which shouldn't change either */
flowlabel
=
*
((
u_int32_t
*
)
ipv6_hdr
(
skb
));
ret
=
ip6t_do_table
(
skb
,
hook
,
in
,
out
,
ret
=
ip6t_do_table
(
skb
,
hook
,
NULL
,
out
,
dev_net
(
out
)
->
ipv6
.
ip6table_mangle
);
if
(
ret
!=
NF_DROP
&&
ret
!=
NF_STOLEN
&&
...
...
@@ -132,49 +73,31 @@ ip6t_local_out_hook(unsigned int hook,
return
ret
;
}
static
struct
nf_hook_ops
ip6t_ops
[]
__read_mostly
=
{
{
.
hook
=
ip6t_in_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV6
,
.
hooknum
=
NF_INET_PRE_ROUTING
,
.
priority
=
NF_IP6_PRI_MANGLE
,
},
{
.
hook
=
ip6t_in_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV6
,
.
hooknum
=
NF_INET_LOCAL_IN
,
.
priority
=
NF_IP6_PRI_MANGLE
,
},
{
.
hook
=
ip6t_in_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV6
,
.
hooknum
=
NF_INET_FORWARD
,
.
priority
=
NF_IP6_PRI_MANGLE
,
},
{
.
hook
=
ip6t_local_out_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV6
,
.
hooknum
=
NF_INET_LOCAL_OUT
,
.
priority
=
NF_IP6_PRI_MANGLE
,
},
{
.
hook
=
ip6t_post_routing_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV6
,
.
hooknum
=
NF_INET_POST_ROUTING
,
.
priority
=
NF_IP6_PRI_MANGLE
,
},
};
/* The work comes in here from netfilter.c. */
static
unsigned
int
ip6table_mangle_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
if
(
hook
==
NF_INET_LOCAL_OUT
)
return
ip6t_local_out_hook
(
hook
,
skb
,
out
,
okfn
);
/* INPUT/FORWARD */
return
ip6t_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
in
)
->
ipv6
.
ip6table_mangle
);
}
static
struct
nf_hook_ops
*
mangle_ops
__read_mostly
;
static
int
__net_init
ip6table_mangle_net_init
(
struct
net
*
net
)
{
/* Register table */
struct
ip6t_replace
*
repl
;
repl
=
ip6t_alloc_initial_table
(
&
packet_mangler
);
if
(
repl
==
NULL
)
return
-
ENOMEM
;
net
->
ipv6
.
ip6table_mangle
=
ip6t_register_table
(
net
,
&
packet_mangler
,
&
initial_table
.
repl
);
ip6t_register_table
(
net
,
&
packet_mangler
,
repl
);
kfree
(
repl
);
if
(
IS_ERR
(
net
->
ipv6
.
ip6table_mangle
))
return
PTR_ERR
(
net
->
ipv6
.
ip6table_mangle
);
return
0
;
...
...
@@ -199,9 +122,11 @@ static int __init ip6table_mangle_init(void)
return
ret
;
/* Register hooks */
ret
=
nf_register_hooks
(
ip6t_ops
,
ARRAY_SIZE
(
ip6t_ops
));
if
(
ret
<
0
)
mangle_ops
=
xt_hook_link
(
&
packet_mangler
,
ip6table_mangle_hook
);
if
(
IS_ERR
(
mangle_ops
))
{
ret
=
PTR_ERR
(
mangle_ops
);
goto
cleanup_table
;
}
return
ret
;
...
...
@@ -212,7 +137,7 @@ static int __init ip6table_mangle_init(void)
static
void
__exit
ip6table_mangle_fini
(
void
)
{
nf_unregister_hooks
(
ip6t_ops
,
ARRAY_SIZE
(
ip6t_ops
)
);
xt_hook_unlink
(
&
packet_mangler
,
mangle_ops
);
unregister_pernet_subsys
(
&
ip6table_mangle_net_ops
);
}
...
...
net/ipv6/netfilter/ip6table_raw.c
View file @
a8c28d05
...
...
@@ -8,85 +8,37 @@
#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
static
const
struct
{
struct
ip6t_replace
repl
;
struct
ip6t_standard
entries
[
2
];
struct
ip6t_error
term
;
}
initial_table
__net_initdata
=
{
.
repl
=
{
.
name
=
"raw"
,
.
valid_hooks
=
RAW_VALID_HOOKS
,
.
num_entries
=
3
,
.
size
=
sizeof
(
struct
ip6t_standard
)
*
2
+
sizeof
(
struct
ip6t_error
),
.
hook_entry
=
{
[
NF_INET_PRE_ROUTING
]
=
0
,
[
NF_INET_LOCAL_OUT
]
=
sizeof
(
struct
ip6t_standard
)
},
.
underflow
=
{
[
NF_INET_PRE_ROUTING
]
=
0
,
[
NF_INET_LOCAL_OUT
]
=
sizeof
(
struct
ip6t_standard
)
},
},
.
entries
=
{
IP6T_STANDARD_INIT
(
NF_ACCEPT
),
/* PRE_ROUTING */
IP6T_STANDARD_INIT
(
NF_ACCEPT
),
/* LOCAL_OUT */
},
.
term
=
IP6T_ERROR_INIT
,
/* ERROR */
};
static
const
struct
xt_table
packet_raw
=
{
.
name
=
"raw"
,
.
valid_hooks
=
RAW_VALID_HOOKS
,
.
me
=
THIS_MODULE
,
.
af
=
NFPROTO_IPV6
,
.
priority
=
NF_IP6_PRI_FIRST
,
};
/* The work comes in here from netfilter.c. */
static
unsigned
int
ip6t_pre_routing_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
ip6table_raw_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
ip6t_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
in
)
->
ipv6
.
ip6table_raw
);
}
const
struct
net
*
net
=
dev_net
((
in
!=
NULL
)
?
in
:
out
);
static
unsigned
int
ip6t_local_out_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
ip6t_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
out
)
->
ipv6
.
ip6table_raw
);
return
ip6t_do_table
(
skb
,
hook
,
in
,
out
,
net
->
ipv6
.
ip6table_raw
);
}
static
struct
nf_hook_ops
ip6t_ops
[]
__read_mostly
=
{
{
.
hook
=
ip6t_pre_routing_hook
,
.
pf
=
NFPROTO_IPV6
,
.
hooknum
=
NF_INET_PRE_ROUTING
,
.
priority
=
NF_IP6_PRI_FIRST
,
.
owner
=
THIS_MODULE
,
},
{
.
hook
=
ip6t_local_out_hook
,
.
pf
=
NFPROTO_IPV6
,
.
hooknum
=
NF_INET_LOCAL_OUT
,
.
priority
=
NF_IP6_PRI_FIRST
,
.
owner
=
THIS_MODULE
,
},
};
static
struct
nf_hook_ops
*
rawtable_ops
__read_mostly
;
static
int
__net_init
ip6table_raw_net_init
(
struct
net
*
net
)
{
/* Register table */
struct
ip6t_replace
*
repl
;
repl
=
ip6t_alloc_initial_table
(
&
packet_raw
);
if
(
repl
==
NULL
)
return
-
ENOMEM
;
net
->
ipv6
.
ip6table_raw
=
ip6t_register_table
(
net
,
&
packet_raw
,
&
initial_table
.
repl
);
ip6t_register_table
(
net
,
&
packet_raw
,
repl
);
kfree
(
repl
);
if
(
IS_ERR
(
net
->
ipv6
.
ip6table_raw
))
return
PTR_ERR
(
net
->
ipv6
.
ip6table_raw
);
return
0
;
...
...
@@ -111,9 +63,11 @@ static int __init ip6table_raw_init(void)
return
ret
;
/* Register hooks */
ret
=
nf_register_hooks
(
ip6t_ops
,
ARRAY_SIZE
(
ip6t_ops
));
if
(
ret
<
0
)
rawtable_ops
=
xt_hook_link
(
&
packet_raw
,
ip6table_raw_hook
);
if
(
IS_ERR
(
rawtable_ops
))
{
ret
=
PTR_ERR
(
rawtable_ops
);
goto
cleanup_table
;
}
return
ret
;
...
...
@@ -124,7 +78,7 @@ static int __init ip6table_raw_init(void)
static
void
__exit
ip6table_raw_fini
(
void
)
{
nf_unregister_hooks
(
ip6t_ops
,
ARRAY_SIZE
(
ip6t_ops
)
);
xt_hook_unlink
(
&
packet_raw
,
rawtable_ops
);
unregister_pernet_subsys
(
&
ip6table_raw_net_ops
);
}
...
...
net/ipv6/netfilter/ip6table_security.c
View file @
a8c28d05
...
...
@@ -26,106 +26,37 @@ MODULE_DESCRIPTION("ip6tables security table, for MAC rules");
(1 << NF_INET_FORWARD) | \
(1 << NF_INET_LOCAL_OUT)
static
const
struct
{
struct
ip6t_replace
repl
;
struct
ip6t_standard
entries
[
3
];
struct
ip6t_error
term
;
}
initial_table
__net_initdata
=
{
.
repl
=
{
.
name
=
"security"
,
.
valid_hooks
=
SECURITY_VALID_HOOKS
,
.
num_entries
=
4
,
.
size
=
sizeof
(
struct
ip6t_standard
)
*
3
+
sizeof
(
struct
ip6t_error
),
.
hook_entry
=
{
[
NF_INET_LOCAL_IN
]
=
0
,
[
NF_INET_FORWARD
]
=
sizeof
(
struct
ip6t_standard
),
[
NF_INET_LOCAL_OUT
]
=
sizeof
(
struct
ip6t_standard
)
*
2
,
},
.
underflow
=
{
[
NF_INET_LOCAL_IN
]
=
0
,
[
NF_INET_FORWARD
]
=
sizeof
(
struct
ip6t_standard
),
[
NF_INET_LOCAL_OUT
]
=
sizeof
(
struct
ip6t_standard
)
*
2
,
},
},
.
entries
=
{
IP6T_STANDARD_INIT
(
NF_ACCEPT
),
/* LOCAL_IN */
IP6T_STANDARD_INIT
(
NF_ACCEPT
),
/* FORWARD */
IP6T_STANDARD_INIT
(
NF_ACCEPT
),
/* LOCAL_OUT */
},
.
term
=
IP6T_ERROR_INIT
,
/* ERROR */
};
static
const
struct
xt_table
security_table
=
{
.
name
=
"security"
,
.
valid_hooks
=
SECURITY_VALID_HOOKS
,
.
me
=
THIS_MODULE
,
.
af
=
NFPROTO_IPV6
,
.
priority
=
NF_IP6_PRI_SECURITY
,
};
static
unsigned
int
ip6t_local_in_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
ip6t_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
in
)
->
ipv6
.
ip6table_security
);
}
static
unsigned
int
ip6t_forward_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
ip6table_security_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
return
ip6t_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
in
)
->
ipv6
.
ip6table_security
);
}
const
struct
net
*
net
=
dev_net
((
in
!=
NULL
)
?
in
:
out
);
static
unsigned
int
ip6t_local_out_hook
(
unsigned
int
hook
,
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
int
(
*
okfn
)(
struct
sk_buff
*
))
{
/* TBD: handle short packets via raw socket */
return
ip6t_do_table
(
skb
,
hook
,
in
,
out
,
dev_net
(
out
)
->
ipv6
.
ip6table_security
);
return
ip6t_do_table
(
skb
,
hook
,
in
,
out
,
net
->
ipv6
.
ip6table_security
);
}
static
struct
nf_hook_ops
ip6t_ops
[]
__read_mostly
=
{
{
.
hook
=
ip6t_local_in_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV6
,
.
hooknum
=
NF_INET_LOCAL_IN
,
.
priority
=
NF_IP6_PRI_SECURITY
,
},
{
.
hook
=
ip6t_forward_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV6
,
.
hooknum
=
NF_INET_FORWARD
,
.
priority
=
NF_IP6_PRI_SECURITY
,
},
{
.
hook
=
ip6t_local_out_hook
,
.
owner
=
THIS_MODULE
,
.
pf
=
NFPROTO_IPV6
,
.
hooknum
=
NF_INET_LOCAL_OUT
,
.
priority
=
NF_IP6_PRI_SECURITY
,
},
};
static
struct
nf_hook_ops
*
sectbl_ops
__read_mostly
;
static
int
__net_init
ip6table_security_net_init
(
struct
net
*
net
)
{
net
->
ipv6
.
ip6table_security
=
ip6t_register_table
(
net
,
&
security_table
,
&
initial_table
.
repl
);
struct
ip6t_replace
*
repl
;
repl
=
ip6t_alloc_initial_table
(
&
security_table
);
if
(
repl
==
NULL
)
return
-
ENOMEM
;
net
->
ipv6
.
ip6table_security
=
ip6t_register_table
(
net
,
&
security_table
,
repl
);
kfree
(
repl
);
if
(
IS_ERR
(
net
->
ipv6
.
ip6table_security
))
return
PTR_ERR
(
net
->
ipv6
.
ip6table_security
);
...
...
@@ -150,9 +81,11 @@ static int __init ip6table_security_init(void)
if
(
ret
<
0
)
return
ret
;
ret
=
nf_register_hooks
(
ip6t_ops
,
ARRAY_SIZE
(
ip6t_ops
));
if
(
ret
<
0
)
sectbl_ops
=
xt_hook_link
(
&
security_table
,
ip6table_security_hook
);
if
(
IS_ERR
(
sectbl_ops
))
{
ret
=
PTR_ERR
(
sectbl_ops
);
goto
cleanup_table
;
}
return
ret
;
...
...
@@ -163,7 +96,7 @@ static int __init ip6table_security_init(void)
static
void
__exit
ip6table_security_fini
(
void
)
{
nf_unregister_hooks
(
ip6t_ops
,
ARRAY_SIZE
(
ip6t_ops
)
);
xt_hook_unlink
(
&
security_table
,
sectbl_ops
);
unregister_pernet_subsys
(
&
ip6table_security_net_ops
);
}
...
...
net/netfilter/x_tables.c
View file @
a8c28d05
...
...
@@ -26,7 +26,9 @@
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_arp.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter_arp/arp_tables.h>
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Harald Welte <laforge@netfilter.org>"
);
...
...
@@ -1091,6 +1093,60 @@ static const struct file_operations xt_target_ops = {
#endif
/* CONFIG_PROC_FS */
/**
* xt_hook_link - set up hooks for a new table
* @table: table with metadata needed to set up hooks
* @fn: Hook function
*
* This function will take care of creating and registering the necessary
* Netfilter hooks for XT tables.
*/
struct
nf_hook_ops
*
xt_hook_link
(
const
struct
xt_table
*
table
,
nf_hookfn
*
fn
)
{
unsigned
int
hook_mask
=
table
->
valid_hooks
;
uint8_t
i
,
num_hooks
=
hweight32
(
hook_mask
);
uint8_t
hooknum
;
struct
nf_hook_ops
*
ops
;
int
ret
;
ops
=
kmalloc
(
sizeof
(
*
ops
)
*
num_hooks
,
GFP_KERNEL
);
if
(
ops
==
NULL
)
return
ERR_PTR
(
-
ENOMEM
);
for
(
i
=
0
,
hooknum
=
0
;
i
<
num_hooks
&&
hook_mask
!=
0
;
hook_mask
>>=
1
,
++
hooknum
)
{
if
(
!
(
hook_mask
&
1
))
continue
;
ops
[
i
].
hook
=
fn
;
ops
[
i
].
owner
=
table
->
me
;
ops
[
i
].
pf
=
table
->
af
;
ops
[
i
].
hooknum
=
hooknum
;
ops
[
i
].
priority
=
table
->
priority
;
++
i
;
}
ret
=
nf_register_hooks
(
ops
,
num_hooks
);
if
(
ret
<
0
)
{
kfree
(
ops
);
return
ERR_PTR
(
ret
);
}
return
ops
;
}
EXPORT_SYMBOL_GPL
(
xt_hook_link
);
/**
* xt_hook_unlink - remove hooks for a table
* @ops: nf_hook_ops array as returned by nf_hook_link
* @hook_mask: the very same mask that was passed to nf_hook_link
*/
void
xt_hook_unlink
(
const
struct
xt_table
*
table
,
struct
nf_hook_ops
*
ops
)
{
nf_unregister_hooks
(
ops
,
hweight32
(
table
->
valid_hooks
));
kfree
(
ops
);
}
EXPORT_SYMBOL_GPL
(
xt_hook_unlink
);
int
xt_proto_init
(
struct
net
*
net
,
u_int8_t
af
)
{
#ifdef CONFIG_PROC_FS
...
...
net/netfilter/xt_repldata.h
0 → 100644
View file @
a8c28d05
/*
* Today's hack: quantum tunneling in structs
*
* 'entries' and 'term' are never anywhere referenced by word in code. In fact,
* they serve as the hanging-off data accessed through repl.data[].
*/
#define xt_alloc_initial_table(type, typ2) ({ \
unsigned int hook_mask = info->valid_hooks; \
unsigned int nhooks = hweight32(hook_mask); \
unsigned int bytes = 0, hooknum = 0, i = 0; \
struct { \
struct type##_replace repl; \
struct type##_standard entries[nhooks]; \
struct type##_error term; \
} *tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); \
if (tbl == NULL) \
return NULL; \
strncpy(tbl->repl.name, info->name, sizeof(tbl->repl.name)); \
tbl->term = (struct type##_error)typ2##_ERROR_INIT; \
tbl->repl.valid_hooks = hook_mask; \
tbl->repl.num_entries = nhooks + 1; \
tbl->repl.size = nhooks * sizeof(struct type##_standard) + \
sizeof(struct type##_error); \
for (; hook_mask != 0; hook_mask >>= 1, ++hooknum) { \
if (!(hook_mask & 1)) \
continue; \
tbl->repl.hook_entry[hooknum] = bytes; \
tbl->repl.underflow[hooknum] = bytes; \
tbl->entries[i++] = (struct type##_standard) \
typ2##_STANDARD_INIT(NF_ACCEPT); \
bytes += sizeof(struct type##_standard); \
} \
tbl; \
})
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