Commit af0a2482 authored by David S. Miller's avatar David S. Miller

Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next

Pablo Neira Ayuso says:

====================
Netfilter updates for net-next

The following patchset contains Netfilter updates for net-next
to extend ctnetlink and the flowtable infrastructure:

1) Extend ctnetlink kernel side netlink dump filtering capabilities,
   from Romain Bellan.

2) Generalise the flowtable hook parser to take a hook list.

3) Pass a hook list to the flowtable hook registration/unregistration.

4) Add a helper function to release the flowtable hook list.

5) Update the flowtable event notifier to pass a flowtable hook list.

6) Allow users to add new devices to an existing flowtables.

7) Allow users to remove devices to an existing flowtables.

8) Allow for registering a flowtable with no initial devices.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a74d19ba 5b6743fb
...@@ -42,7 +42,8 @@ struct nf_conntrack_l4proto { ...@@ -42,7 +42,8 @@ struct nf_conntrack_l4proto {
/* Calculate tuple nlattr size */ /* Calculate tuple nlattr size */
unsigned int (*nlattr_tuple_size)(void); unsigned int (*nlattr_tuple_size)(void);
int (*nlattr_to_tuple)(struct nlattr *tb[], int (*nlattr_to_tuple)(struct nlattr *tb[],
struct nf_conntrack_tuple *t); struct nf_conntrack_tuple *t,
u_int32_t flags);
const struct nla_policy *nla_policy; const struct nla_policy *nla_policy;
struct { struct {
...@@ -152,7 +153,8 @@ const struct nf_conntrack_l4proto *nf_ct_l4proto_find(u8 l4proto); ...@@ -152,7 +153,8 @@ const struct nf_conntrack_l4proto *nf_ct_l4proto_find(u8 l4proto);
int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb, int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb,
const struct nf_conntrack_tuple *tuple); const struct nf_conntrack_tuple *tuple);
int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[], int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[],
struct nf_conntrack_tuple *t); struct nf_conntrack_tuple *t,
u_int32_t flags);
unsigned int nf_ct_port_nlattr_tuple_size(void); unsigned int nf_ct_port_nlattr_tuple_size(void);
extern const struct nla_policy nf_ct_port_nla_policy[]; extern const struct nla_policy nf_ct_port_nla_policy[];
......
...@@ -1002,6 +1002,7 @@ struct nft_stats { ...@@ -1002,6 +1002,7 @@ struct nft_stats {
struct nft_hook { struct nft_hook {
struct list_head list; struct list_head list;
bool inactive;
struct nf_hook_ops ops; struct nf_hook_ops ops;
struct rcu_head rcu; struct rcu_head rcu;
}; };
...@@ -1481,10 +1482,16 @@ struct nft_trans_obj { ...@@ -1481,10 +1482,16 @@ struct nft_trans_obj {
struct nft_trans_flowtable { struct nft_trans_flowtable {
struct nft_flowtable *flowtable; struct nft_flowtable *flowtable;
bool update;
struct list_head hook_list;
}; };
#define nft_trans_flowtable(trans) \ #define nft_trans_flowtable(trans) \
(((struct nft_trans_flowtable *)trans->data)->flowtable) (((struct nft_trans_flowtable *)trans->data)->flowtable)
#define nft_trans_flowtable_update(trans) \
(((struct nft_trans_flowtable *)trans->data)->update)
#define nft_trans_flowtable_hooks(trans) \
(((struct nft_trans_flowtable *)trans->data)->hook_list)
int __init nft_chain_filter_init(void); int __init nft_chain_filter_init(void);
void nft_chain_filter_fini(void); void nft_chain_filter_fini(void);
......
...@@ -55,6 +55,7 @@ enum ctattr_type { ...@@ -55,6 +55,7 @@ enum ctattr_type {
CTA_LABELS, CTA_LABELS,
CTA_LABELS_MASK, CTA_LABELS_MASK,
CTA_SYNPROXY, CTA_SYNPROXY,
CTA_FILTER,
__CTA_MAX __CTA_MAX
}; };
#define CTA_MAX (__CTA_MAX - 1) #define CTA_MAX (__CTA_MAX - 1)
...@@ -276,4 +277,12 @@ enum ctattr_expect_stats { ...@@ -276,4 +277,12 @@ enum ctattr_expect_stats {
}; };
#define CTA_STATS_EXP_MAX (__CTA_STATS_EXP_MAX - 1) #define CTA_STATS_EXP_MAX (__CTA_STATS_EXP_MAX - 1)
enum ctattr_filter {
CTA_FILTER_UNSPEC,
CTA_FILTER_ORIG_FLAGS,
CTA_FILTER_REPLY_FLAGS,
__CTA_FILTER_MAX
};
#define CTA_FILTER_MAX (__CTA_FILTER_MAX - 1)
#endif /* _IPCONNTRACK_NETLINK_H */ #endif /* _IPCONNTRACK_NETLINK_H */
...@@ -1974,13 +1974,22 @@ const struct nla_policy nf_ct_port_nla_policy[CTA_PROTO_MAX+1] = { ...@@ -1974,13 +1974,22 @@ const struct nla_policy nf_ct_port_nla_policy[CTA_PROTO_MAX+1] = {
EXPORT_SYMBOL_GPL(nf_ct_port_nla_policy); EXPORT_SYMBOL_GPL(nf_ct_port_nla_policy);
int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[], int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[],
struct nf_conntrack_tuple *t) struct nf_conntrack_tuple *t,
u_int32_t flags)
{ {
if (!tb[CTA_PROTO_SRC_PORT] || !tb[CTA_PROTO_DST_PORT]) if (flags & CTA_FILTER_FLAG(CTA_PROTO_SRC_PORT)) {
return -EINVAL; if (!tb[CTA_PROTO_SRC_PORT])
return -EINVAL;
t->src.u.tcp.port = nla_get_be16(tb[CTA_PROTO_SRC_PORT]);
}
t->src.u.tcp.port = nla_get_be16(tb[CTA_PROTO_SRC_PORT]); if (flags & CTA_FILTER_FLAG(CTA_PROTO_DST_PORT)) {
t->dst.u.tcp.port = nla_get_be16(tb[CTA_PROTO_DST_PORT]); if (!tb[CTA_PROTO_DST_PORT])
return -EINVAL;
t->dst.u.tcp.port = nla_get_be16(tb[CTA_PROTO_DST_PORT]);
}
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include <net/netfilter/nf_conntrack_zones.h> #include <net/netfilter/nf_conntrack_zones.h>
#include <net/netfilter/nf_log.h> #include <net/netfilter/nf_log.h>
#include "nf_internals.h"
static const unsigned int nf_ct_icmp_timeout = 30*HZ; static const unsigned int nf_ct_icmp_timeout = 30*HZ;
bool icmp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, bool icmp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
...@@ -271,20 +273,32 @@ static const struct nla_policy icmp_nla_policy[CTA_PROTO_MAX+1] = { ...@@ -271,20 +273,32 @@ static const struct nla_policy icmp_nla_policy[CTA_PROTO_MAX+1] = {
}; };
static int icmp_nlattr_to_tuple(struct nlattr *tb[], static int icmp_nlattr_to_tuple(struct nlattr *tb[],
struct nf_conntrack_tuple *tuple) struct nf_conntrack_tuple *tuple,
u_int32_t flags)
{ {
if (!tb[CTA_PROTO_ICMP_TYPE] || if (flags & CTA_FILTER_FLAG(CTA_PROTO_ICMP_TYPE)) {
!tb[CTA_PROTO_ICMP_CODE] || if (!tb[CTA_PROTO_ICMP_TYPE])
!tb[CTA_PROTO_ICMP_ID]) return -EINVAL;
return -EINVAL;
tuple->dst.u.icmp.type = nla_get_u8(tb[CTA_PROTO_ICMP_TYPE]);
tuple->dst.u.icmp.type = nla_get_u8(tb[CTA_PROTO_ICMP_TYPE]); if (tuple->dst.u.icmp.type >= sizeof(invmap) ||
tuple->dst.u.icmp.code = nla_get_u8(tb[CTA_PROTO_ICMP_CODE]); !invmap[tuple->dst.u.icmp.type])
tuple->src.u.icmp.id = nla_get_be16(tb[CTA_PROTO_ICMP_ID]); return -EINVAL;
}
if (tuple->dst.u.icmp.type >= sizeof(invmap) ||
!invmap[tuple->dst.u.icmp.type]) if (flags & CTA_FILTER_FLAG(CTA_PROTO_ICMP_CODE)) {
return -EINVAL; if (!tb[CTA_PROTO_ICMP_CODE])
return -EINVAL;
tuple->dst.u.icmp.code = nla_get_u8(tb[CTA_PROTO_ICMP_CODE]);
}
if (flags & CTA_FILTER_FLAG(CTA_PROTO_ICMP_ID)) {
if (!tb[CTA_PROTO_ICMP_ID])
return -EINVAL;
tuple->src.u.icmp.id = nla_get_be16(tb[CTA_PROTO_ICMP_ID]);
}
return 0; return 0;
} }
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include <net/netfilter/nf_conntrack_zones.h> #include <net/netfilter/nf_conntrack_zones.h>
#include <net/netfilter/nf_log.h> #include <net/netfilter/nf_log.h>
#include "nf_internals.h"
static const unsigned int nf_ct_icmpv6_timeout = 30*HZ; static const unsigned int nf_ct_icmpv6_timeout = 30*HZ;
bool icmpv6_pkt_to_tuple(const struct sk_buff *skb, bool icmpv6_pkt_to_tuple(const struct sk_buff *skb,
...@@ -193,21 +195,33 @@ static const struct nla_policy icmpv6_nla_policy[CTA_PROTO_MAX+1] = { ...@@ -193,21 +195,33 @@ static const struct nla_policy icmpv6_nla_policy[CTA_PROTO_MAX+1] = {
}; };
static int icmpv6_nlattr_to_tuple(struct nlattr *tb[], static int icmpv6_nlattr_to_tuple(struct nlattr *tb[],
struct nf_conntrack_tuple *tuple) struct nf_conntrack_tuple *tuple,
u_int32_t flags)
{ {
if (!tb[CTA_PROTO_ICMPV6_TYPE] || if (flags & CTA_FILTER_FLAG(CTA_PROTO_ICMPV6_TYPE)) {
!tb[CTA_PROTO_ICMPV6_CODE] || if (!tb[CTA_PROTO_ICMPV6_TYPE])
!tb[CTA_PROTO_ICMPV6_ID]) return -EINVAL;
return -EINVAL;
tuple->dst.u.icmp.type = nla_get_u8(tb[CTA_PROTO_ICMPV6_TYPE]);
tuple->dst.u.icmp.type = nla_get_u8(tb[CTA_PROTO_ICMPV6_TYPE]); if (tuple->dst.u.icmp.type < 128 ||
tuple->dst.u.icmp.code = nla_get_u8(tb[CTA_PROTO_ICMPV6_CODE]); tuple->dst.u.icmp.type - 128 >= sizeof(invmap) ||
tuple->src.u.icmp.id = nla_get_be16(tb[CTA_PROTO_ICMPV6_ID]); !invmap[tuple->dst.u.icmp.type - 128])
return -EINVAL;
if (tuple->dst.u.icmp.type < 128 || }
tuple->dst.u.icmp.type - 128 >= sizeof(invmap) ||
!invmap[tuple->dst.u.icmp.type - 128]) if (flags & CTA_FILTER_FLAG(CTA_PROTO_ICMPV6_CODE)) {
return -EINVAL; if (!tb[CTA_PROTO_ICMPV6_CODE])
return -EINVAL;
tuple->dst.u.icmp.code = nla_get_u8(tb[CTA_PROTO_ICMPV6_CODE]);
}
if (flags & CTA_FILTER_FLAG(CTA_PROTO_ICMPV6_ID)) {
if (!tb[CTA_PROTO_ICMPV6_ID])
return -EINVAL;
tuple->src.u.icmp.id = nla_get_be16(tb[CTA_PROTO_ICMPV6_ID]);
}
return 0; return 0;
} }
......
...@@ -6,6 +6,23 @@ ...@@ -6,6 +6,23 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
/* nf_conntrack_netlink.c: applied on tuple filters */
#define CTA_FILTER_F_CTA_IP_SRC (1 << 0)
#define CTA_FILTER_F_CTA_IP_DST (1 << 1)
#define CTA_FILTER_F_CTA_TUPLE_ZONE (1 << 2)
#define CTA_FILTER_F_CTA_PROTO_NUM (1 << 3)
#define CTA_FILTER_F_CTA_PROTO_SRC_PORT (1 << 4)
#define CTA_FILTER_F_CTA_PROTO_DST_PORT (1 << 5)
#define CTA_FILTER_F_CTA_PROTO_ICMP_TYPE (1 << 6)
#define CTA_FILTER_F_CTA_PROTO_ICMP_CODE (1 << 7)
#define CTA_FILTER_F_CTA_PROTO_ICMP_ID (1 << 8)
#define CTA_FILTER_F_CTA_PROTO_ICMPV6_TYPE (1 << 9)
#define CTA_FILTER_F_CTA_PROTO_ICMPV6_CODE (1 << 10)
#define CTA_FILTER_F_CTA_PROTO_ICMPV6_ID (1 << 11)
#define CTA_FILTER_F_MAX (1 << 12)
#define CTA_FILTER_F_ALL (CTA_FILTER_F_MAX-1)
#define CTA_FILTER_FLAG(ctattr) CTA_FILTER_F_ ## ctattr
/* nf_queue.c */ /* nf_queue.c */
void nf_queue_nf_hook_drop(struct net *net); void nf_queue_nf_hook_drop(struct net *net);
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment