netfilter: nf_tables: nft_compat: release cached matches/targets
Subsystems (2)
[email protected]
maintainerPATCH 1/7 netfilter: nf_tables: nft_compat: release cached matches/targets
From: Pablo Neira Ayuso <[email protected]>
Release existing targets/matches that are cached in our lists.
--- net/netfilter/nft_compat.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
net/netfilter/nft_compat.c +18 -0
@@ -517,6 +517,14 @@ nft_match_select_ops(const struct nft_ctx *ctx,return &nft_match->ops; } +static void nft_match_release (void ) +{ +struct nft_xt *nft_match; + +list_for_each_entry (nft_match, &nft_match_list, head) +kfree (nft_match); +} +static struct nft_expr_type nft_match_type__read_mostly = { .name ="match" , .select_ops = nft_match_select_ops,
@@ -579,6 +587,14 @@ nft_target_select_ops(const struct nft_ctx *ctx,return &nft_target->ops; } +static void nft_target_release (void ) +{ +struct nft_xt *nft_target; + +list_for_each_entry (nft_target, &nft_target_list, head) +kfree (nft_target); +} +static struct nft_expr_type nft_target_type__read_mostly = { .name ="target" , .select_ops = nft_target_select_ops,
@@ -621,6 +637,8 @@ void nft_compat_module_exit(void)nfnetlink_subsys_unregister (&nfnl_compat_subsys);nft_unregister_expr (&nft_target_type);nft_unregister_expr (&nft_match_type); +nft_match_release (); +nft_target_release (); }MODULE_ALIAS_NFNL_SUBSYS (NFNL_SUBSYS_NFTA_COMPAT );
Signature · 1 line
1.7.10.4
[email protected]
maintainerPATCH 2/7 netfilter: nf_tables: move filter chain definition to layer 3 modules
From: Pablo Neira Ayuso <[email protected]>
This patch moves the definition of the filter_ipv4 and filter_ipv6 default filter chains to where they belong.
--- net/ipv4/netfilter/nf_tables_ipv4.c | 23 +++++++++++++++++++- net/ipv6/netfilter/nf_tables_ipv6.c | 23 +++++++++++++++++++- net/netfilter/nf_tables_api.c | 41 ----------------------------------- 3 files changed, 44 insertions(+), 43 deletions(-)
net/ipv4/netfilter/nf_tables_ipv4.c +22 -1
@@ -1,5 +1,6 @@/* * Copyright (c) 2008 Patrick McHardy <[email protected]> +* Copyright (c) 2012-2013 Pablo Neira Ayuso <[email protected]> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as
@@ -70,14 +71,34 @@ static struct pernet_operations nf_tables_ipv4_net_ops = { .exit = nf_tables_ipv4_exit_net, }; +static struct nf_chain_type filter_ipv4 = { + .family =NFPROTO_IPV4 , + .name ="filter" , + .type =NFT_CHAIN_T_DEFAULT , + .hook_mask = (1 <<NF_INET_LOCAL_IN ) | + (1 <<NF_INET_LOCAL_OUT ) | + (1 <<NF_INET_FORWARD ) | + (1 <<NF_INET_PRE_ROUTING ) | + (1 <<NF_INET_POST_ROUTING ), + .fn = { + [NF_INET_LOCAL_IN ] = nft_do_chain, + [NF_INET_LOCAL_OUT ] = nft_do_chain, + [NF_INET_FORWARD ] = nft_do_chain, + [NF_INET_PRE_ROUTING ] = nft_do_chain, + [NF_INET_POST_ROUTING ] = nft_do_chain, + }, +}; +static int __init nf_tables_ipv4_init (void ) { +nft_register_chain_type (&filter_ipv4);return register_pernet_subsys (&nf_tables_ipv4_net_ops); } static void __exit nf_tables_ipv4_exit(void) { -return unregister_pernet_subsys (&nf_tables_ipv4_net_ops); +unregister_pernet_subsys (&nf_tables_ipv4_net_ops); +nft_unregister_chain_type (&filter_ipv4); }module_init (nf_tables_ipv4_init);
net/ipv6/netfilter/nf_tables_ipv6.c +22 -1
@@ -1,5 +1,6 @@/* * Copyright (c) 2008 Patrick McHardy <[email protected]> +* Copyright (c) 2012-2013 Pablo Neira Ayuso <[email protected]> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as
@@ -67,14 +68,34 @@ static struct pernet_operations nf_tables_ipv6_net_ops = { .exit = nf_tables_ipv6_exit_net, }; +static struct nf_chain_type filter_ipv6 = { + .family =NFPROTO_IPV6 , + .name ="filter" , + .type =NFT_CHAIN_T_DEFAULT , + .hook_mask = (1 <<NF_INET_LOCAL_IN ) | + (1 <<NF_INET_LOCAL_OUT ) | + (1 <<NF_INET_FORWARD ) | + (1 <<NF_INET_PRE_ROUTING ) | + (1 <<NF_INET_POST_ROUTING ), + .fn = { + [NF_INET_LOCAL_IN ] = nft_do_chain, + [NF_INET_LOCAL_OUT ] = nft_do_chain, + [NF_INET_FORWARD ] = nft_do_chain, + [NF_INET_PRE_ROUTING ] = nft_do_chain, + [NF_INET_POST_ROUTING ] = nft_do_chain, + }, +}; +static int __init nf_tables_ipv6_init (void ) { +nft_register_chain_type (&filter_ipv6);return register_pernet_subsys (&nf_tables_ipv6_net_ops); } static void __exit nf_tables_ipv6_exit(void) { -return unregister_pernet_subsys (&nf_tables_ipv6_net_ops); +unregister_pernet_subsys (&nf_tables_ipv6_net_ops); +nft_unregister_chain_type (&filter_ipv6); }module_init (nf_tables_ipv6_init);
net/netfilter/nf_tables_api.c +0 -41
59 lines not on this page · raw message
Signature · 1 line
1.7.10.4
Re: [PATCH 2/7] netfilter: nf_tables: move filter chain definition to layer 3 modules
Quoted 34 lines · On Thu, Jan 10, 2013 at 04:28:36PM +0100, [email protected] wrote:
From: Pablo Neira Ayuso <[email protected]>
This patch moves the definition of the
filter_ipv4andfilter_ipv6default filter chains to where they belong.Signed-off-by Pablo Neira Ayuso <[email protected]>--- net/ipv4/netfilter/nf_tables_ipv4.c | 23 +++++++++++++++++++- net/ipv6/netfilter/nf_tables_ipv6.c | 23 +++++++++++++++++++- net/netfilter/nf_tables_api.c | 41 ----------------------------------- 3 files changed, 44 insertions(+), 43 deletions(-)net/ipv4/netfilter/nf_tables_ipv4.c +8
-0@@ -1,5 +1,6 @@/* * Copyright (c) 2008 Patrick McHardy <[email protected]> +* Copyright (c) 2012-2013 Pablo Neira Ayuso <[email protected]> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -70,14 +71,34 @@ static struct pernet_operations nf_tables_ipv4_net_ops = { .exit = nf_tables_ipv4_exit_net, }; +static struct nf_chain_type filter_ipv4 = { + .family =NFPROTO_IPV4 , + .name ="filter" , + .type =NFT_CHAIN_T_DEFAULT , + .hook_mask = (1 <<NF_INET_LOCAL_IN ) | + (1 <<NF_INET_LOCAL_OUT ) | + (1 << NF_INET_FORWARD) |
net/ipv4/netfilter/nf_tables_ipv4.c static struct pernet_operations nf_tables_ipv4_net_ops = { · line 90
Quoted 10 lines
net/ipv4/netfilter/nf_tables_ipv4.c +10
-0+ (1 <<NF_INET_PRE_ROUTING ) | + (1 << NF_INET_POST_ROUTING), + .fn = { + [NF_INET_LOCAL_IN] = nft_do_chain, + [NF_INET_LOCAL_OUT] = nft_do_chain, + [NF_INET_FORWARD] = nft_do_chain, + [NF_INET_PRE_ROUTING] = nft_do_chain, + [NF_INET_POST_ROUTING] = nft_do_chain, + }, +};
I'm still thinking about how to rework this, the chain types currently break the LOCAL_OUT check for short SOCK_RAW packets and setting of the transport layer header pointer before invoking nft_do_chain(). I'll also need some additional overloading for multi family tables, so I think we need to rethink this scheme.
Feel free to apply your patch, but I'll probably will rework this very soon anyway.
[email protected]
maintainerPATCH 3/7 netfilter: nf_tables: remove hook definitions from struct nft_af_info
In reply to [email protected]From: Pablo Neira Ayuso <[email protected]>
They are now included in the filter chain definition.
--- include/net/netfilter/nf_tables.h | 2 -- net/ipv4/netfilter/nf_tables_ipv4.c | 5 +---- net/ipv6/netfilter/nf_tables_ipv6.c | 5 +---- net/netfilter/nf_tables_api.c | 2 -- 4 files changed, 2 insertions(+), 12 deletions(-)
include/net/netfilter/nf_tables.h +0 -2
@@ -430,7 +430,6 @@ struct nft_table {* @nhooks: number of hooks in this family * @owner: module owner * @tables: used internally -* @hooks: hookfn overrides for packet validation */ struct nft_af_info {struct list_head list;
@@ -438,7 +437,6 @@ struct nft_af_info {unsigned int nhooks;struct module *owner;struct list_head tables; -nf_hookfn *hooks[NF_MAX_HOOKS ]; };extern int nft_register_afinfo (struct net *,struct nft_af_info *);
net/ipv4/netfilter/nf_tables_ipv4.c +1 -4
@@ -38,9 +38,6 @@ static struct nft_af_info nft_af_ipv4 __read_mostly = { .family = NFPROTO_IPV4, .nhooks = NF_INET_NUMHOOKS, .owner = THIS_MODULE, - .hooks = { - [NF_INET_LOCAL_OUT] = nft_ipv4_output, - }, };static int nf_tables_ipv4_init_net (struct net *net)
@@ -82,7 +79,7 @@ static struct nf_chain_type filter_ipv4 = { (1 << NF_INET_POST_ROUTING), .fn = { [NF_INET_LOCAL_IN] = nft_do_chain, - [NF_INET_LOCAL_OUT] = nft_do_chain, + [NF_INET_LOCAL_OUT] = nft_ipv4_output, [NF_INET_FORWARD] = nft_do_chain, [NF_INET_PRE_ROUTING] = nft_do_chain, [NF_INET_POST_ROUTING] = nft_do_chain,
net/ipv6/netfilter/nf_tables_ipv6.c +1 -4
@@ -35,9 +35,6 @@ static struct nft_af_info nft_af_ipv6 __read_mostly = { .family = NFPROTO_IPV6, .nhooks = NF_INET_NUMHOOKS, .owner = THIS_MODULE, - .hooks = { - [NF_INET_LOCAL_OUT] = nft_ipv6_output, - }, };static int nf_tables_ipv6_init_net (struct net *net)
@@ -79,7 +76,7 @@ static struct nf_chain_type filter_ipv6 = { (1 << NF_INET_POST_ROUTING), .fn = { [NF_INET_LOCAL_IN] = nft_do_chain, - [NF_INET_LOCAL_OUT] = nft_do_chain, + [NF_INET_LOCAL_OUT] = nft_ipv6_output, [NF_INET_FORWARD] = nft_do_chain, [NF_INET_PRE_ROUTING] = nft_do_chain, [NF_INET_POST_ROUTING] = nft_do_chain,
net/netfilter/nf_tables_api.c +0 -2
@@ -842,8 +842,6 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb, ops->priority =ntohl (nla_get_be32 (ha[NFTA_HOOK_PRIORITY ])); ops->priv = chain; ops->hook = hookfn; -if (afi->hooks[ops->hooknum]) - ops->hook = afi->hooks[ops->hooknum]; chain->flags |=NFT_BASE_CHAIN ;
Signature · 1 line
1.7.10.4
Re: [PATCH 3/7] netfilter: nf_tables: remove hook definitions from struct nft_af_info
Quoted 4 lines · On Thu, Jan 10, 2013 at 04:28:37PM +0100, [email protected] wrote:
From: Pablo Neira Ayuso <[email protected]>
They are now included in the filter chain definition.
Ok should have looked at the entire series before responding. I do still need the table hooks for the multi family tables, so I'd suggest to keep the current state until I've come up with a scheme that accomodates all our needs.
Pablo Neira Ayuso
maintainerRe: [PATCH 3/7] netfilter: nf_tables: remove hook definitions from struct nft_af_info
Quoted 10 lines · Patrick McHardy
Quoted 4 lines · On Thu, Jan 10, 2013 at 04:28:37PM +0100, [email protected] wrote:
From: Pablo Neira Ayuso <[email protected]>
They are now included in the filter chain definition.
Ok should have looked at the entire series before responding. I do still need the table hooks for the multi family tables, so I'd suggest to keep the current state until I've come up with a scheme that accomodates all our needs.
OK, I'll rework this patch to fix the output path of filter. I will keep the table hooks so you can still use it.
Thanks Patrick.
[email protected]
maintainerPATCH 4/7 netfilter: nf_tables: move specific layer 3 compat code to nf_tables_ipv[4|6]
In reply to [email protected]From: Pablo Neira Ayuso <[email protected]>
This patch moves the struct xt_action_param to struct nft_pktinfo and that structure is filled at the beginning of the every chain.
The specific code to handle IPv4 and IPv6 now resides in nf_tables_ipv[4|6].
--- include/net/netfilter/nf_tables.h | 24 +++++++--- include/net/netfilter/nf_tables_ipv4.h | 23 ++++++++++ include/net/netfilter/nf_tables_ipv6.h | 29 ++++++++++++ include/net/netns/nftables.h | 3 +- net/ipv4/netfilter/nf_tables_ipv4.c | 30 ++++++++++--- net/ipv4/netfilter/nft_chain_nat_ipv4.c | 6 ++- net/ipv4/netfilter/nft_chain_route_ipv4.c | 6 ++- net/ipv6/netfilter/nf_tables_ipv6.c | 31 ++++++++++--- net/ipv6/netfilter/nft_chain_nat_ipv6.c | 6 ++- net/ipv6/netfilter/nft_chain_route_ipv6.c | 7 ++- net/netfilter/nf_tables_core.c | 19 +++----- net/netfilter/nft_compat.c | 69 +++-------------------------- 12 files changed, 154 insertions(+), 99 deletions(-) create mode 100644 include/net/netfilter/nf_tables_ipv4.h create mode 100644 include/net/netfilter/nf_tables_ipv6.h
include/net/netfilter/nf_tables.h +17 -7
@@ -3,6 +3,7 @@#include <linux/list.h> #include <linux/netfilter.h> +#include <linux/netfilter/x_tables.h> #include <linux/netfilter/nf_tables.h> #include <net/netlink.h>
@@ -16,10 +17,22 @@ struct nft_pktinfo {u8 nhoff;u8 thoff;/* for x_tables compatibility */ -bool compat_set; -u16 fragoff; +struct xt_action_param xt; }; +static inline void nft_set_pktinfo (struct nft_pktinfo *pkt, +const struct nf_hook_ops *ops, +struct sk_buff *skb, +const struct net_device *in, +const struct net_device *out) +{ + pkt->skb = skb; + pkt->in = pkt->xt.in = in; + pkt->out = pkt->xt.out = out; + pkt->hooknum = pkt->xt.hooknum = ops->hooknum; + pkt->xt.family = ops->pf; +} + struct nft_data { union { u32 data[4];
@@ -397,11 +410,8 @@ static inline struct nft_base_chain *nft_base_chain(const struct nft_chain *chai return container_of(chain, struct nft_base_chain, chain); } -extern unsigned int nft_do_chain (const struct nf_hook_ops *ops, -struct sk_buff *skb, -const struct net_device *in, -const struct net_device *out, -int (*okfn)(struct sk_buff *)); +extern unsigned int nft_do_chain_pktinfo (struct nft_pktinfo *pkt, +const struct nf_hook_ops *ops);/** * struct nft_table - nf_tables table
include/net/netfilter/nf_tables_ipv4.h new file +23 -0
@@ -0,0 +1,23 @@ +#ifndef _NF_TABLES_IPV4_H_ +#define _NF_TABLES_IPV4_H_ + +#include <net/netfilter/nf_tables.h> +#include <net/ip.h> + +static inline void +nft_set_pktinfo_ipv4 (struct nft_pktinfo *pkt, +const struct nf_hook_ops *ops, +struct sk_buff *skb, +const struct net_device *in, +const struct net_device *out) +{ +struct iphdr *ip; + +nft_set_pktinfo (pkt, ops, skb, in, out); + + pkt->xt.thoff =ip_hdrlen (pkt->skb); + ip =ip_hdr (pkt->skb); + pkt->xt.fragoff =ntohs (ip->frag_off) &IP_OFFSET ; +} + +#endif
include/net/netfilter/nf_tables_ipv6.h new file +29 -0
@@ -0,0 +1,29 @@ +#ifndef _NF_TABLES_IPV6_H_ +#define _NF_TABLES_IPV6_H_ + +#include <linux/netfilter_ipv6/ip6_tables.h> + +static inline int +nft_set_pktinfo_ipv6 (struct nft_pktinfo *pkt, +const struct nf_hook_ops *ops, +struct sk_buff *skb, +const struct net_device *in, +const struct net_device *out) +{ +int protohdr, thoff =0 ; +unsigned short frag_off; + +nft_set_pktinfo (pkt, ops, skb, in, out); + + protohdr =ipv6_find_hdr (pkt->skb, &thoff,-1 , &frag_off,NULL ); +/* If malformed, drop it */ +if (protohdr <0 ) +return -1 ; + + pkt->xt.thoff = thoff; + pkt->xt.fragoff = frag_off; + +return 0 ; +} + +#endif
include/net/netns/nftables.h +2 -1
@@ -2,7 +2,8 @@#define _NETNS_NFTABLES_H_#include <linux/list.h> -#include <net/netfilter/nf_tables.h> + +struct nft_af_info ;struct netns_nftables {struct list_head af_info;
net/ipv4/netfilter/nf_tables_ipv4.c +24 -6
@@ -15,7 +15,7 @@#include <linux/netfilter_ipv4.h> #include <net/netfilter/nf_tables.h> #include <net/net_namespace.h> -#include <net/ip.h> +#include <net/netfilter/nf_tables_ipv4.h> static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops, struct sk_buff *skb,
@@ -23,6 +23,8 @@ static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops, const struct net_device *out, int (*okfn)(struct sk_buff *)) { + struct nft_pktinfo pkt; +if (unlikely (skb->len <sizeof (struct iphdr ) ||ip_hdr (skb)->ihl <sizeof (struct iphdr ) /4 )) {if (net_ratelimit ())
@@ -30,8 +32,9 @@ static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops, "packet\n");return NF_ACCEPT ; } +nft_set_pktinfo_ipv4 (&pkt, ops, skb, in, out); -return nft_do_chain (ops, skb, in, out, okfn); +return nft_do_chain_pktinfo (&pkt, ops); }static struct nft_af_info nft_af_ipv4__read_mostly = {
@@ -68,6 +71,20 @@ static struct pernet_operations nf_tables_ipv4_net_ops = { .exit = nf_tables_ipv4_exit_net, }; +static unsigned int +nft_do_chain_ipv4 (const struct nf_hook_ops *ops, +struct sk_buff *skb, +const struct net_device *in, +const struct net_device *out, +int (*okfn)(struct sk_buff *)) +{ +struct nft_pktinfo pkt; + +nft_set_pktinfo_ipv4 (&pkt, ops, skb, in, out); + +return nft_do_chain_pktinfo (&pkt, ops); +} +static struct nf_chain_type filter_ipv4 = { .family =NFPROTO_IPV4 , .name ="filter" ,
@@ -78,11 +95,12 @@ static struct nf_chain_type filter_ipv4 = { (1 <<NF_INET_PRE_ROUTING ) | (1 << NF_INET_POST_ROUTING), .fn = { - [NF_INET_LOCAL_IN] = nft_do_chain, + [NF_INET_LOCAL_IN] = nft_do_chain_ipv4, [NF_INET_LOCAL_OUT] = nft_ipv4_output, - [NF_INET_FORWARD] = nft_do_chain, - [NF_INET_PRE_ROUTING] = nft_do_chain, - [NF_INET_POST_ROUTING] = nft_do_chain, + [NF_INET_LOCAL_OUT] = nft_do_chain_ipv4, + [NF_INET_FORWARD] = nft_do_chain_ipv4, + [NF_INET_PRE_ROUTING] = nft_do_chain_ipv4, + [NF_INET_POST_ROUTING] = nft_do_chain_ipv4, }, };
net/ipv4/netfilter/nft_chain_nat_ipv4.c +5 -1
@@ -22,6 +22,7 @@#include <net/netfilter/nf_nat.h> #include <net/netfilter/nf_nat_core.h> #include <net/netfilter/nf_tables.h> +#include <net/netfilter/nf_tables_ipv4.h> #include <net/netfilter/nf_nat_l3proto.h> #include <net/ip.h>
@@ -39,6 +40,7 @@ static unsigned int nf_nat_fn(const struct nf_hook_ops *ops,struct nf_conn *ct =nf_ct_get (skb, &ctinfo);struct nf_conn_nat *nat;enum nf_nat_manip_type maniptype =HOOK2MANIP (ops->hooknum); +struct nft_pktinfo pkt;unsigned int ret;if (ct ==NULL ||nf_ct_is_untracked (ct))
@@ -71,7 +73,9 @@ static unsigned int nf_nat_fn(const struct nf_hook_ops *ops,if (nf_nat_initialized (ct, maniptype))break ; - ret =nft_do_chain (ops, skb, in, out, okfn); +nft_set_pktinfo_ipv4 (&pkt, ops, skb, in, out); + + ret =nft_do_chain_pktinfo (&pkt, ops);if (ret !=NF_ACCEPT )return ret;if (!nf_nat_initialized (ct, maniptype)) {
net/ipv4/netfilter/nft_chain_route_ipv4.c +5 -1
@@ -17,6 +17,7 @@#include <linux/netfilter/nfnetlink.h> #include <linux/netfilter/nf_tables.h> #include <net/netfilter/nf_tables.h> +#include <net/netfilter/nf_tables_ipv4.h> #include <net/route.h> static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
@@ -26,11 +27,14 @@ static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops, int (*okfn)(struct sk_buff *)) {unsigned int ret; +struct nft_pktinfo pkt;u32 mark; +nft_set_pktinfo_ipv4 (&pkt, ops, skb, in, out); +// FIXME: length validation mark = skb->mark; - ret =nft_do_chain (ops, skb, in, out, okfn); + ret =nft_do_chain_pktinfo (&pkt, ops);if (ret !=NF_DROP && ret !=NF_QUEUE ) {if (skb->mark != mark &&ip_route_me_harder (skb,RTN_UNSPEC )) ret =NF_DROP ;
net/ipv6/netfilter/nf_tables_ipv6.c +26 -5
@@ -14,6 +14,7 @@#include <linux/ipv6.h> #include <linux/netfilter_ipv6.h> #include <net/netfilter/nf_tables.h> +#include <net/netfilter/nf_tables_ipv6.h> static unsigned int nft_ipv6_output(const struct nf_hook_ops *ops, struct sk_buff *skb,
@@ -21,14 +22,18 @@ static unsigned int nft_ipv6_output(const struct nf_hook_ops *ops, const struct net_device *out, int (*okfn)(struct sk_buff *)) { + struct nft_pktinfo pkt; +if (unlikely (skb->len <sizeof (struct ipv6hdr ))) {if (net_ratelimit ())pr_info ("nf_tables_ipv6: ignoring short SOCK_RAW " "packet\n" );return NF_ACCEPT ; } +if (nft_set_pktinfo_ipv6 (&pkt, ops, skb, in, out) <0 ) +return NF_DROP ; - return nft_do_chain(ops, skb, in, out, okfn); +return nft_do_chain_pktinfo (&pkt, ops); } static struct nft_af_info nft_af_ipv6 __read_mostly = {
@@ -65,6 +70,22 @@ static struct pernet_operations nf_tables_ipv6_net_ops = { .exit = nf_tables_ipv6_exit_net, }; +static unsigned int +nft_do_chain_ipv6 (const struct nf_hook_ops *ops, +struct sk_buff *skb, +const struct net_device *in, +const struct net_device *out, +int (*okfn)(struct sk_buff *)) +{ +struct nft_pktinfo pkt; + +/* malformed packet, drop it */ +if (nft_set_pktinfo_ipv6 (&pkt, ops, skb, in, out) <0 ) +return NF_DROP ; + +return nft_do_chain_pktinfo (&pkt, ops); +} +static struct nf_chain_type filter_ipv6 = { .family =NFPROTO_IPV6 , .name ="filter" ,
@@ -75,11 +96,11 @@ static struct nf_chain_type filter_ipv6 = { (1 <<NF_INET_PRE_ROUTING ) | (1 << NF_INET_POST_ROUTING), .fn = { - [NF_INET_LOCAL_IN] = nft_do_chain, + [NF_INET_LOCAL_IN] = nft_do_chain_ipv6, [NF_INET_LOCAL_OUT] = nft_ipv6_output, - [NF_INET_FORWARD] = nft_do_chain, - [NF_INET_PRE_ROUTING] = nft_do_chain, - [NF_INET_POST_ROUTING] = nft_do_chain, + [NF_INET_FORWARD] = nft_do_chain_ipv6, + [NF_INET_PRE_ROUTING] = nft_do_chain_ipv6, + [NF_INET_POST_ROUTING] = nft_do_chain_ipv6, }, };
net/ipv6/netfilter/nft_chain_nat_ipv6.c +5 -1
@@ -20,6 +20,7 @@#include <net/netfilter/nf_nat.h> #include <net/netfilter/nf_nat_core.h> #include <net/netfilter/nf_tables.h> +#include <net/netfilter/nf_tables_ipv6.h> #include <net/netfilter/nf_nat_l3proto.h> #include <net/ipv6.h>
@@ -40,6 +41,7 @@ static unsigned int nf_nat_ipv6_fn(const struct nf_hook_ops *ops,__be16 frag_off;int hdrlen;u8 nexthdr; +struct nft_pktinfo pkt;unsigned int ret;if (ct ==NULL ||nf_ct_is_untracked (ct))
@@ -75,7 +77,9 @@ static unsigned int nf_nat_ipv6_fn(const struct nf_hook_ops *ops,if (nf_nat_initialized (ct, maniptype))break ; - ret =nft_do_chain (ops, skb, in, out, okfn); +nft_set_pktinfo_ipv6 (&pkt, ops, skb, in, out); + + ret =nft_do_chain_pktinfo (&pkt, ops);if (ret !=NF_ACCEPT )return ret;if (!nf_nat_initialized (ct, maniptype)) {
net/ipv6/netfilter/nft_chain_route_ipv6.c +6 -1
@@ -19,6 +19,7 @@#include <linux/netfilter/nfnetlink.h> #include <linux/netfilter/nf_tables.h> #include <net/netfilter/nf_tables.h> +#include <net/netfilter/nf_tables_ipv6.h> #include <net/route.h> static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
@@ -28,10 +29,14 @@ static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops, int (*okfn)(struct sk_buff *)) {unsigned int ret; +struct nft_pktinfo pkt;u32 mark; +if (nft_set_pktinfo_ipv6 (&pkt, ops, skb, in, out) <0 ) +return NF_DROP ; + mark = skb->mark; - ret =nft_do_chain (ops, skb, in, out, okfn); + ret =nft_do_chain_pktinfo (&pkt, ops);if (ret !=NF_DROP && ret !=NF_QUEUE ) {if (skb->mark != mark &&ip6_route_me_harder (skb)) ret =NF_DROP ;
net/netfilter/nf_tables_core.c +5 -14
@@ -60,22 +60,13 @@ static bool nft_payload_fast_eval(const struct nft_expr *expr,return true; } -unsigned int nft_do_chain (const struct nf_hook_ops *ops, -struct sk_buff *skb, -const struct net_device *in, -const struct net_device *out, -int (*okfn)(struct sk_buff *)) +unsigned int +nft_do_chain_pktinfo (struct nft_pktinfo *pkt,const struct nf_hook_ops *ops) {const struct nft_chain *chain = ops->priv;const struct nft_rule *rule;const struct nft_expr *expr, *last;struct nft_data data[NFT_REG_MAX +1 ]; -const struct nft_pktinfo pkt = { - .skb = skb, - .in = in, - .out = out, - .hooknum = ops->hooknum, - };unsigned int stackptr =0 ;struct {const struct nft_chain *chain;
@@ -91,8 +82,8 @@ next_rule:if (expr->ops == &nft_cmp_fast_ops)nft_cmp_fast_eval (expr, data);else if (expr->ops != &nft_payload_fast_ops || - !nft_payload_fast_eval (expr, data, &pkt)) - expr->ops->eval (expr, data, &pkt); + !nft_payload_fast_eval (expr, data, pkt)) + expr->ops->eval (expr, data, pkt);if (data[NFT_REG_VERDICT ].verdict !=NFT_CONTINUE )break ;
@@ -138,7 +129,7 @@ next_rule:return nft_base_chain (chain)->policy; } -EXPORT_SYMBOL_GPL (nft_do_chain); +EXPORT_SYMBOL_GPL (nft_do_chain_pktinfo);int __init nf_tables_core_module_init (void ) {
net/netfilter/nft_compat.c +7 -62
104 lines not on this page · raw message
Signature · 1 line
1.7.10.4
Re: [PATCH 4/7] netfilter: nf_tables: move specific layer 3 compat code to nf_tables_ipv[4|6]
include/net/netfilter/nf_tables.h static inline struct nft_base_chain *nft_base_chain(const struct nft_chain *chai · line 414
Quoted 10 lines · On Thu, Jan 10, 2013 at 04:28:38PM +0100, [email protected] wrote:
From: Pablo Neira Ayuso <[email protected]>
This patch moves the struct
xt_action_paramto structnft_pktinfoand that structure is filled at the beginning of the every chain.The specific code to handle IPv4 and IPv6 now resides in nf_tables_ipv[4|6].
include/net/netfilter/nf_tables.h +2
-0+extern unsigned int nft_do_chain_pktinfo (struct nft_pktinfo *pkt, +const struct nf_hook_ops *ops);
Passing the pktinfo is something I also need to fix the transport layer parsing. I don't like that function name at all though, just keep nft_do_chain()?
Pablo Neira Ayuso
maintainerRe: [PATCH 4/7] netfilter: nf_tables: move specific layer 3 compat code to nf_tables_ipv[4|6]
Quoted 9 lines · Patrick McHardy
Quoted 8 lines · On Thu, Jan 10, 2013 at 04:28:38PM +0100, [email protected] wrote:
From: Pablo Neira Ayuso <[email protected]>
This patch moves the struct
xt_action_paramto structnft_pktinfoand that structure is filled at the beginning of the every chain.The specific code to handle IPv4 and IPv6 now resides in nf_tables_ipv[4|6].
Quoted 6 lines
include/net/netfilter/nf_tables.h static inline struct nft_base_chain *nft_base_chain(const struct nft_chain *chai · line 414
Quoted 2 lines
include/net/netfilter/nf_tables.h +2
-0+extern unsigned int nft_do_chain_pktinfo (struct nft_pktinfo *pkt, +const struct nf_hook_ops *ops);Passing the pktinfo is something I also need to fix the transport layer parsing. I don't like that function name at all though, just keep
nft_do_chain()?
Will change it back to use nft_do_chain.
[email protected]
maintainerPATCH 5/7 netfilter: nf_tables: x_tables support as a compile time option
In reply to [email protected]From: Pablo Neira Ayuso <[email protected]>
Restore Make x_tables over nf_tables as optional module at compile time. The main reason for this is the dependency on x_tables symbols.
--- include/net/netfilter/nf_tables_core.h | 3 --- net/netfilter/Kconfig | 9 +++++++++ net/netfilter/Makefile | 3 ++- net/netfilter/nf_tables_core.c | 6 ------ net/netfilter/nft_compat.c | 12 ++++++++++-- 5 files changed, 21 insertions(+), 12 deletions(-)
include/net/netfilter/nf_tables_core.h +0 -3
@@ -39,7 +39,4 @@ extern const struct nft_expr_ops nft_payload_fast_ops;extern int nft_payload_module_init (void );extern void nft_payload_module_exit (void ); -extern int nft_compat_module_init (void ); -extern void nft_compat_module_exit (void ); -#endif /* _NET_NF_TABLES_CORE_H */
net/netfilter/Kconfig +9 -0
@@ -474,6 +474,15 @@ config NFT_NAT depends on NF_CONNTRACK tristate "Netfilter nf_tables nat module" +config NFT_COMPAT + depends on NF_TABLES + select NETFILTER_XTABLES + tristate "Netfilter x_tables over nf_tables module" + help + This is required if you intend to use any of existing + x_tables match/target extensions over the nf_tables + framework. + if NETFILTER_XTABLES comment "Xtables combined modules"
net/netfilter/Makefile +2 -1
@@ -64,11 +64,12 @@ obj-$(CONFIG_NF_NAT_TFTP) += nf_nat_tftp.o obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o # nf_tables -nf_tables-objs += nf_tables_core.o nf_tables_api.o nft_compat.o +nf_tables-objs += nf_tables_core.o nf_tables_api.o nf_tables-objs += nft_immediate.o nft_cmp.o nft_lookup.o nf_tables-objs += nft_bitwise.o nft_byteorder.o nft_payload.o obj-$(CONFIG_NF_TABLES) += nf_tables.o +obj-$(CONFIG_NFT_COMPAT) += nft_compat.o obj-$(CONFIG_NFT_EXTHDR) += nft_exthdr.o obj-$(CONFIG_NFT_META) += nft_meta.o obj-$(CONFIG_NFT_CT) += nft_ct.o
net/netfilter/nf_tables_core.c +0 -6
@@ -159,13 +159,8 @@ int __init nf_tables_core_module_init(void)if (err <0 ) goto err6; - err =nft_compat_module_init (); -if (err <0 ) - goto err7; -return 0 ; -err7:nft_payload_module_exit (); err6:nft_byteorder_module_exit ();
@@ -183,7 +178,6 @@ err1:void nf_tables_core_module_exit (void ) { -nft_compat_module_exit ();nft_payload_module_exit ();nft_byteorder_module_exit ();nft_bitwise_module_exit ();
net/netfilter/nft_compat.c +10 -2
@@ -548,7 +548,7 @@ static struct nft_expr_type nft_target_type __read_mostly = { .owner = THIS_MODULE, }; -int __init nft_compat_module_init (void ) +static int __init nft_compat_module_init (void ) {int ret;
@@ -577,7 +577,7 @@ err_match:return ret; } -void nft_compat_module_exit (void ) +static void __exit nft_compat_module_exit(void) {nfnetlink_subsys_unregister (&nfnl_compat_subsys);nft_unregister_expr (&nft_target_type);
@@ -587,3 +587,11 @@ void nft_compat_module_exit(void) }MODULE_ALIAS_NFNL_SUBSYS (NFNL_SUBSYS_NFTA_COMPAT ); + +module_init (nft_compat_module_init); +module_exit (nft_compat_module_exit); + +MODULE_LICENSE ("GPL" ); +MODULE_AUTHOR ("Pablo Neira Ayuso <[email protected]>" ); +MODULE_ALIAS_NFT_EXPR ("match" ); +MODULE_ALIAS_NFT_EXPR ("target" );
Signature · 1 line
1.7.10.4
[email protected]
maintainerPATCH 6/7 netfilter: nf_tables: support 32bits-64bits x_tables compat
In reply to [email protected]From: Pablo Neira Ayuso <[email protected]>
This patch adds support for existing compat infrastructure in matches/targets.
This adds a new callback compat_to_blob that uses memcpy instead of copy_to_user.
The standard target has no compat_to_blob since user-space is using the native immediate expression to issue verdicts.
--- include/linux/netfilter/x_tables.h | 2 + net/ipv4/netfilter/ipt_ULOG.c | 14 ++++++ net/netfilter/nft_compat.c | 83 ++++++++++++++++++++++++++++++++---- net/netfilter/xt_limit.c | 16 +++++++ 4 files changed, 107 insertions(+), 8 deletions(-)
include/linux/netfilter/x_tables.h +2 -0
@@ -307,6 +307,7 @@ struct xt_match {/* Called when userspace align differs from kernel space one */ void (*compat_from_user)(void *dst,const void *src);int (*compat_to_user)(void __user *dst,const void *src); +void (*compat_to_blob)(void *dst,const void *src);#endif /* Set this to THIS_MODULE if you are a module, otherwise NULL */ struct module *me;
@@ -347,6 +348,7 @@ struct xt_target {/* Called when userspace align differs from kernel space one */ void (*compat_from_user)(void *dst,const void *src);int (*compat_to_user)(void __user *dst,const void *src); +void (*compat_to_blob)(void *dst,const void *src);#endif /* Set this to THIS_MODULE if you are a module, otherwise NULL */ struct module *me;
net/ipv4/netfilter/ipt_ULOG.c +14 -0
@@ -356,6 +356,19 @@ static int ulog_tg_compat_to_user(void __user *dst, const void *src)memcpy (cl.prefix, l->prefix,sizeof (cl.prefix));return copy_to_user (dst, &cl,sizeof (cl)) ? -EFAULT :0 ; } + +static void ulog_tg_compat_to_blob (void *dst,const void *src) +{ +const struct ipt_ulog_info *l = src; +struct compat_ipt_ulog_info cl = { + .nl_group = l->nl_group, + .copy_range = l->copy_range, + .qthreshold = l->qthreshold, + }; + +memcpy (cl.prefix, l->prefix,sizeof (cl.prefix)); +memcpy (dst, &cl,sizeof (cl)); +}#endif /* CONFIG_COMPAT */ static struct xt_target ulog_tg_reg__read_mostly = {
@@ -368,6 +381,7 @@ static struct xt_target ulog_tg_reg __read_mostly = { .compatsize = sizeof(struct compat_ipt_ulog_info), .compat_from_user = ulog_tg_compat_from_user, .compat_to_user = ulog_tg_compat_to_user, + .compat_to_blob = ulog_tg_compat_to_blob, #endif .me = THIS_MODULE, };
net/netfilter/nft_compat.c +75 -8
147 lines not on this page · raw message
net/netfilter/xt_limit.c +16 -0
@@ -177,6 +177,21 @@ static int limit_mt_compat_to_user(void __user *dst, const void *src) };return copy_to_user (dst, &cm,sizeof (cm)) ? -EFAULT :0 ; } + +static void limit_mt_compat_to_blob (void *dst,const void *src) +{ +const struct xt_rateinfo *m = src; +struct compat_xt_rateinfo cm = { + .avg = m->avg, + .burst = m->burst, + .prev = m->prev, + .credit = m->credit, + .credit_cap = m->credit_cap, + .cost = m->cost, + .master = m->prev >>32 , + }; +memcpy (dst, &cm,sizeof (cm)); +}#endif /* CONFIG_COMPAT */ static struct xt_match limit_mt_reg__read_mostly = {
@@ -191,6 +206,7 @@ static struct xt_match limit_mt_reg __read_mostly = { .compatsize = sizeof(struct compat_xt_rateinfo), .compat_from_user = limit_mt_compat_from_user, .compat_to_user = limit_mt_compat_to_user, + .compat_to_blob = limit_mt_compat_to_blob, #endif .me = THIS_MODULE, };
Signature · 1 line
1.7.10.4
Re: [PATCH 6/7] netfilter: nf_tables: support 32bits-64bits x_tables compat
Quoted 8 lines · On Thu, Jan 10, 2013 at 04:28:40PM +0100, [email protected] wrote:
From: Pablo Neira Ayuso <[email protected]>
This patch adds support for existing compat infrastructure in matches/targets.
This adds a new callback
compat_to_blobthat uses memcpy instead ofcopy_to_user.
Alternatively we could use the existing compat callbacks and set_fs() to avoid duplicating all of them.
[email protected]
maintainerPATCH 7/7 netfilter: nf_tables: fix alias for xtables over nftables module
In reply to [email protected]From: Pablo Neira Ayuso <[email protected]>
modinfo nft_compat
[...]
alias: nfnetlink-subsys-NFNL_SUBSYS_NFTA_COMPAT
--- net/netfilter/nft_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/nft_compat.c +1 -1
@@ -653,7 +653,7 @@ static void __exit nft_compat_module_exit(void)nft_target_release (); } -MODULE_ALIAS_NFNL_SUBSYS (NFNL_SUBSYS_NFTA_COMPAT ); +MODULE_ALIAS_NFNL_SUBSYS (NFNL_SUBSYS_NFT_COMPAT );module_init (nft_compat_module_init);module_exit (nft_compat_module_exit);
Signature · 1 line
1.7.10.4