提交 371f1c7e 编写于 作者: D David S. Miller

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

Pablo Neira Ayuso says:

====================
Netfilter/IPVS updates for net-next

The following patchset contains Netfilter/IPVS updates for your net-next
tree. Most relevantly, updates for the nfnetlink_log to integrate with
conntrack, fixes for cttimeout and improvements for nf_queue core, they are:

1) Remove useless ifdef around static inline function in IPVS, from
   Eric W. Biederman.

2) Simplify the conntrack support for nfnetlink_queue: Merge
   nfnetlink_queue_ct.c file into nfnetlink_queue_core.c, then rename it back
   to nfnetlink_queue.c

3) Use y2038 safe timestamp from nfnetlink_queue.

4) Get rid of dead function definition in nf_conntrack, from Flavio
   Leitner.

5) Attach conntrack support for nfnetlink_log.c, from Ken-ichirou MATSUZAWA.
   This adds a new NETFILTER_NETLINK_GLUE_CT Kconfig switch that
   controls enabling both nfqueue and nflog integration with conntrack.
   The userspace application can request this via NFULNL_CFG_F_CONNTRACK
   configuration flag.

6) Remove unused netns variables in IPVS, from Eric W. Biederman and
   Simon Horman.

7) Don't put back the refcount on the cttimeout object from xt_CT on success.

8) Fix crash on cttimeout policy object removal. We have to flush out
   the cttimeout extension area of the conntrack not to refer to an unexisting
   object that was just removed.

9) Make sure rcu_callback completion before removing nfnetlink_cttimeout
   module removal.

10) Fix compilation warning in br_netfilter when no nf_defrag_ipv4 and
    nf_defrag_ipv6 are enabled. Patch from Arnd Bergmann.

11) Autoload ctnetlink dependencies when NFULNL_CFG_F_CONNTRACK is
    requested. Again from Ken-ichirou MATSUZAWA.

12) Don't use pointer to previous hook when reinjecting traffic via
    nf_queue with NF_REPEAT verdict since it may be already gone. This
    also avoids a deadloop if the userspace application keeps returning
    NF_REPEAT.

13) A bunch of cleanups for netfilter IPv4 and IPv6 code from Ian Morris.

14) Consolidate logger instance existence check in nfulnl_recv_config().

15) Fix broken atomicity when applying configuration updates to logger
    instances in nfnetlink_log.

16) Get rid of the .owner attribute in our hook object. We don't need
    this anymore since we're dropping pending packets that have escaped
    from the kernel when unremoving the hook. Patch from Florian Westphal.

17) Remove unnecessary rcu_read_lock() from nf_reinject code, we always
    assume RCU read side lock from .call_rcu in nfnetlink. Also from Florian.

18) Use static inline function instead of macros to define NF_HOOK() and
    NF_HOOK_COND() when no netfilter support in on, from Arnd Bergmann.
====================
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
...@@ -90,7 +90,6 @@ struct nf_hook_ops { ...@@ -90,7 +90,6 @@ struct nf_hook_ops {
/* User fills in from here down. */ /* User fills in from here down. */
nf_hookfn *hook; nf_hookfn *hook;
struct net_device *dev; struct net_device *dev;
struct module *owner;
void *priv; void *priv;
u_int8_t pf; u_int8_t pf;
unsigned int hooknum; unsigned int hooknum;
...@@ -347,8 +346,23 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family) ...@@ -347,8 +346,23 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
} }
#else /* !CONFIG_NETFILTER */ #else /* !CONFIG_NETFILTER */
#define NF_HOOK(pf, hook, net, sk, skb, indev, outdev, okfn) (okfn)(net, sk, skb) static inline int
#define NF_HOOK_COND(pf, hook, net, sk, skb, indev, outdev, okfn, cond) (okfn)(net, sk, skb) NF_HOOK_COND(uint8_t pf, unsigned int hook, struct net *net, struct sock *sk,
struct sk_buff *skb, struct net_device *in, struct net_device *out,
int (*okfn)(struct net *, struct sock *, struct sk_buff *),
bool cond)
{
return okfn(net, sk, skb);
}
static inline int
NF_HOOK(uint8_t pf, unsigned int hook, struct net *net, struct sock *sk,
struct sk_buff *skb, struct net_device *in, struct net_device *out,
int (*okfn)(struct net *, struct sock *, struct sk_buff *))
{
return okfn(net, sk, skb);
}
static inline int nf_hook(u_int8_t pf, unsigned int hook, struct net *net, static inline int nf_hook(u_int8_t pf, unsigned int hook, struct net *net,
struct sock *sk, struct sk_buff *skb, struct sock *sk, struct sk_buff *skb,
struct net_device *indev, struct net_device *outdev, struct net_device *indev, struct net_device *outdev,
...@@ -369,24 +383,28 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family) ...@@ -369,24 +383,28 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
extern void (*ip_ct_attach)(struct sk_buff *, const struct sk_buff *) __rcu; extern void (*ip_ct_attach)(struct sk_buff *, const struct sk_buff *) __rcu;
void nf_ct_attach(struct sk_buff *, const struct sk_buff *); void nf_ct_attach(struct sk_buff *, const struct sk_buff *);
extern void (*nf_ct_destroy)(struct nf_conntrack *) __rcu; extern void (*nf_ct_destroy)(struct nf_conntrack *) __rcu;
#else
static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
#endif
struct nf_conn; struct nf_conn;
enum ip_conntrack_info; enum ip_conntrack_info;
struct nlattr; struct nlattr;
struct nfq_ct_hook { struct nfnl_ct_hook {
struct nf_conn *(*get_ct)(const struct sk_buff *skb,
enum ip_conntrack_info *ctinfo);
size_t (*build_size)(const struct nf_conn *ct); size_t (*build_size)(const struct nf_conn *ct);
int (*build)(struct sk_buff *skb, struct nf_conn *ct); int (*build)(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
u_int16_t ct_attr, u_int16_t ct_info_attr);
int (*parse)(const struct nlattr *attr, struct nf_conn *ct); int (*parse)(const struct nlattr *attr, struct nf_conn *ct);
int (*attach_expect)(const struct nlattr *attr, struct nf_conn *ct, int (*attach_expect)(const struct nlattr *attr, struct nf_conn *ct,
u32 portid, u32 report); u32 portid, u32 report);
void (*seq_adjust)(struct sk_buff *skb, struct nf_conn *ct, void (*seq_adjust)(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo, s32 off); enum ip_conntrack_info ctinfo, s32 off);
}; };
extern struct nfq_ct_hook __rcu *nfq_ct_hook; extern struct nfnl_ct_hook __rcu *nfnl_ct_hook;
#else
static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
#endif
/** /**
* nf_skb_duplicated - TEE target has sent a packet * nf_skb_duplicated - TEE target has sent a packet
......
...@@ -183,10 +183,6 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls); ...@@ -183,10 +183,6 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls);
void nf_ct_free_hashtable(void *hash, unsigned int size); void nf_ct_free_hashtable(void *hash, unsigned int size);
struct nf_conntrack_tuple_hash *
__nf_conntrack_find(struct net *net, u16 zone,
const struct nf_conntrack_tuple *tuple);
int nf_conntrack_hash_check_insert(struct nf_conn *ct); int nf_conntrack_hash_check_insert(struct nf_conn *ct);
bool nf_ct_delete(struct nf_conn *ct, u32 pid, int report); bool nf_ct_delete(struct nf_conn *ct, u32 pid, int report);
......
...@@ -20,10 +20,20 @@ struct ctnl_timeout { ...@@ -20,10 +20,20 @@ struct ctnl_timeout {
}; };
struct nf_conn_timeout { struct nf_conn_timeout {
struct ctnl_timeout *timeout; struct ctnl_timeout __rcu *timeout;
}; };
#define NF_CT_TIMEOUT_EXT_DATA(__t) (unsigned int *) &((__t)->timeout->data) static inline unsigned int *
nf_ct_timeout_data(struct nf_conn_timeout *t)
{
struct ctnl_timeout *timeout;
timeout = rcu_dereference(t->timeout);
if (timeout == NULL)
return NULL;
return (unsigned int *)timeout->data;
}
static inline static inline
struct nf_conn_timeout *nf_ct_timeout_find(const struct nf_conn *ct) struct nf_conn_timeout *nf_ct_timeout_find(const struct nf_conn *ct)
...@@ -47,7 +57,7 @@ struct nf_conn_timeout *nf_ct_timeout_ext_add(struct nf_conn *ct, ...@@ -47,7 +57,7 @@ struct nf_conn_timeout *nf_ct_timeout_ext_add(struct nf_conn *ct,
if (timeout_ext == NULL) if (timeout_ext == NULL)
return NULL; return NULL;
timeout_ext->timeout = timeout; rcu_assign_pointer(timeout_ext->timeout, timeout);
return timeout_ext; return timeout_ext;
#else #else
...@@ -64,10 +74,13 @@ nf_ct_timeout_lookup(struct net *net, struct nf_conn *ct, ...@@ -64,10 +74,13 @@ nf_ct_timeout_lookup(struct net *net, struct nf_conn *ct,
unsigned int *timeouts; unsigned int *timeouts;
timeout_ext = nf_ct_timeout_find(ct); timeout_ext = nf_ct_timeout_find(ct);
if (timeout_ext) if (timeout_ext) {
timeouts = NF_CT_TIMEOUT_EXT_DATA(timeout_ext); timeouts = nf_ct_timeout_data(timeout_ext);
else if (unlikely(!timeouts))
timeouts = l4proto->get_timeouts(net);
} else {
timeouts = l4proto->get_timeouts(net); timeouts = l4proto->get_timeouts(net);
}
return timeouts; return timeouts;
#else #else
......
...@@ -32,7 +32,7 @@ void nf_register_queue_handler(const struct nf_queue_handler *qh); ...@@ -32,7 +32,7 @@ void nf_register_queue_handler(const struct nf_queue_handler *qh);
void nf_unregister_queue_handler(void); void nf_unregister_queue_handler(void);
void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict); void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
bool nf_queue_entry_get_refs(struct nf_queue_entry *entry); void nf_queue_entry_get_refs(struct nf_queue_entry *entry);
void nf_queue_entry_release_refs(struct nf_queue_entry *entry); void nf_queue_entry_release_refs(struct nf_queue_entry *entry);
static inline void init_hashrandom(u32 *jhash_initval) static inline void init_hashrandom(u32 *jhash_initval)
......
#ifndef _NET_NFNL_QUEUE_H_
#define _NET_NFNL_QUEUE_H_
#include <linux/netfilter/nf_conntrack_common.h>
struct nf_conn;
#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT
struct nf_conn *nfqnl_ct_get(struct sk_buff *entskb, size_t *size,
enum ip_conntrack_info *ctinfo);
struct nf_conn *nfqnl_ct_parse(const struct sk_buff *skb,
const struct nlattr *attr,
enum ip_conntrack_info *ctinfo);
int nfqnl_ct_put(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo);
void nfqnl_ct_seq_adjust(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo, int diff);
int nfqnl_attach_expect(struct nf_conn *ct, const struct nlattr *attr,
u32 portid, u32 report);
#else
inline struct nf_conn *
nfqnl_ct_get(struct sk_buff *entskb, size_t *size, enum ip_conntrack_info *ctinfo)
{
return NULL;
}
inline struct nf_conn *nfqnl_ct_parse(const struct sk_buff *skb,
const struct nlattr *attr,
enum ip_conntrack_info *ctinfo)
{
return NULL;
}
inline int
nfqnl_ct_put(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo)
{
return 0;
}
inline void nfqnl_ct_seq_adjust(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo, int diff)
{
}
inline int nfqnl_attach_expect(struct nf_conn *ct, const struct nlattr *attr,
u32 portid, u32 report)
{
return 0;
}
#endif /* NF_CONNTRACK */
#endif
...@@ -51,6 +51,8 @@ enum nfulnl_attr_type { ...@@ -51,6 +51,8 @@ enum nfulnl_attr_type {
NFULA_HWTYPE, /* hardware type */ NFULA_HWTYPE, /* hardware type */
NFULA_HWHEADER, /* hardware header */ NFULA_HWHEADER, /* hardware header */
NFULA_HWLEN, /* hardware header length */ NFULA_HWLEN, /* hardware header length */
NFULA_CT, /* nf_conntrack_netlink.h */
NFULA_CT_INFO, /* enum ip_conntrack_info */
__NFULA_MAX __NFULA_MAX
}; };
...@@ -93,5 +95,6 @@ enum nfulnl_attr_config { ...@@ -93,5 +95,6 @@ enum nfulnl_attr_config {
#define NFULNL_CFG_F_SEQ 0x0001 #define NFULNL_CFG_F_SEQ 0x0001
#define NFULNL_CFG_F_SEQ_GLOBAL 0x0002 #define NFULNL_CFG_F_SEQ_GLOBAL 0x0002
#define NFULNL_CFG_F_CONNTRACK 0x0004
#endif /* _NFNETLINK_LOG_H */ #endif /* _NFNETLINK_LOG_H */
...@@ -111,7 +111,6 @@ static inline __be16 pppoe_proto(const struct sk_buff *skb) ...@@ -111,7 +111,6 @@ static inline __be16 pppoe_proto(const struct sk_buff *skb)
/* largest possible L2 header, see br_nf_dev_queue_xmit() */ /* largest possible L2 header, see br_nf_dev_queue_xmit() */
#define NF_BRIDGE_MAX_MAC_HEADER_LENGTH (PPPOE_SES_HLEN + ETH_HLEN) #define NF_BRIDGE_MAX_MAC_HEADER_LENGTH (PPPOE_SES_HLEN + ETH_HLEN)
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) || IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
struct brnf_frag_data { struct brnf_frag_data {
char mac[NF_BRIDGE_MAX_MAC_HEADER_LENGTH]; char mac[NF_BRIDGE_MAX_MAC_HEADER_LENGTH];
u8 encap_size; u8 encap_size;
...@@ -121,7 +120,6 @@ struct brnf_frag_data { ...@@ -121,7 +120,6 @@ struct brnf_frag_data {
}; };
static DEFINE_PER_CPU(struct brnf_frag_data, brnf_frag_data_storage); static DEFINE_PER_CPU(struct brnf_frag_data, brnf_frag_data_storage);
#endif
static void nf_bridge_info_free(struct sk_buff *skb) static void nf_bridge_info_free(struct sk_buff *skb)
{ {
...@@ -666,7 +664,6 @@ static unsigned int br_nf_forward_arp(void *priv, ...@@ -666,7 +664,6 @@ static unsigned int br_nf_forward_arp(void *priv,
return NF_STOLEN; return NF_STOLEN;
} }
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) || IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
static int br_nf_push_frag_xmit(struct net *net, struct sock *sk, struct sk_buff *skb) static int br_nf_push_frag_xmit(struct net *net, struct sock *sk, struct sk_buff *skb)
{ {
struct brnf_frag_data *data; struct brnf_frag_data *data;
...@@ -691,9 +688,7 @@ static int br_nf_push_frag_xmit(struct net *net, struct sock *sk, struct sk_buff ...@@ -691,9 +688,7 @@ static int br_nf_push_frag_xmit(struct net *net, struct sock *sk, struct sk_buff
nf_bridge_info_free(skb); nf_bridge_info_free(skb);
return br_dev_queue_push_xmit(net, sk, skb); return br_dev_queue_push_xmit(net, sk, skb);
} }
#endif
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
static int static int
br_nf_ip_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, br_nf_ip_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
int (*output)(struct net *, struct sock *, struct sk_buff *)) int (*output)(struct net *, struct sock *, struct sk_buff *))
...@@ -711,7 +706,6 @@ br_nf_ip_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, ...@@ -711,7 +706,6 @@ br_nf_ip_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
return ip_do_fragment(net, sk, skb, output); return ip_do_fragment(net, sk, skb, output);
} }
#endif
static unsigned int nf_bridge_mtu_reduction(const struct sk_buff *skb) static unsigned int nf_bridge_mtu_reduction(const struct sk_buff *skb)
{ {
...@@ -734,11 +728,11 @@ static int br_nf_dev_queue_xmit(struct net *net, struct sock *sk, struct sk_buff ...@@ -734,11 +728,11 @@ static int br_nf_dev_queue_xmit(struct net *net, struct sock *sk, struct sk_buff
nf_bridge = nf_bridge_info_get(skb); nf_bridge = nf_bridge_info_get(skb);
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
/* This is wrong! We should preserve the original fragment /* This is wrong! We should preserve the original fragment
* boundaries by preserving frag_list rather than refragmenting. * boundaries by preserving frag_list rather than refragmenting.
*/ */
if (skb->protocol == htons(ETH_P_IP)) { if (IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) &&
skb->protocol == htons(ETH_P_IP)) {
struct brnf_frag_data *data; struct brnf_frag_data *data;
if (br_validate_ipv4(net, skb)) if (br_validate_ipv4(net, skb))
...@@ -760,9 +754,8 @@ static int br_nf_dev_queue_xmit(struct net *net, struct sock *sk, struct sk_buff ...@@ -760,9 +754,8 @@ static int br_nf_dev_queue_xmit(struct net *net, struct sock *sk, struct sk_buff
return br_nf_ip_fragment(net, sk, skb, br_nf_push_frag_xmit); return br_nf_ip_fragment(net, sk, skb, br_nf_push_frag_xmit);
} }
#endif if (IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) &&
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) skb->protocol == htons(ETH_P_IPV6)) {
if (skb->protocol == htons(ETH_P_IPV6)) {
const struct nf_ipv6_ops *v6ops = nf_get_ipv6_ops(); const struct nf_ipv6_ops *v6ops = nf_get_ipv6_ops();
struct brnf_frag_data *data; struct brnf_frag_data *data;
...@@ -786,7 +779,6 @@ static int br_nf_dev_queue_xmit(struct net *net, struct sock *sk, struct sk_buff ...@@ -786,7 +779,6 @@ static int br_nf_dev_queue_xmit(struct net *net, struct sock *sk, struct sk_buff
kfree_skb(skb); kfree_skb(skb);
return -EMSGSIZE; return -EMSGSIZE;
} }
#endif
nf_bridge_info_free(skb); nf_bridge_info_free(skb);
return br_dev_queue_push_xmit(net, sk, skb); return br_dev_queue_push_xmit(net, sk, skb);
drop: drop:
...@@ -904,49 +896,42 @@ EXPORT_SYMBOL_GPL(br_netfilter_enable); ...@@ -904,49 +896,42 @@ EXPORT_SYMBOL_GPL(br_netfilter_enable);
static struct nf_hook_ops br_nf_ops[] __read_mostly = { static struct nf_hook_ops br_nf_ops[] __read_mostly = {
{ {
.hook = br_nf_pre_routing, .hook = br_nf_pre_routing,
.owner = THIS_MODULE,
.pf = NFPROTO_BRIDGE, .pf = NFPROTO_BRIDGE,
.hooknum = NF_BR_PRE_ROUTING, .hooknum = NF_BR_PRE_ROUTING,
.priority = NF_BR_PRI_BRNF, .priority = NF_BR_PRI_BRNF,
}, },
{ {
.hook = br_nf_local_in, .hook = br_nf_local_in,
.owner = THIS_MODULE,
.pf = NFPROTO_BRIDGE, .pf = NFPROTO_BRIDGE,
.hooknum = NF_BR_LOCAL_IN, .hooknum = NF_BR_LOCAL_IN,
.priority = NF_BR_PRI_BRNF, .priority = NF_BR_PRI_BRNF,
}, },
{ {
.hook = br_nf_forward_ip, .hook = br_nf_forward_ip,
.owner = THIS_MODULE,
.pf = NFPROTO_BRIDGE, .pf = NFPROTO_BRIDGE,
.hooknum = NF_BR_FORWARD, .hooknum = NF_BR_FORWARD,
.priority = NF_BR_PRI_BRNF - 1, .priority = NF_BR_PRI_BRNF - 1,
}, },
{ {
.hook = br_nf_forward_arp, .hook = br_nf_forward_arp,
.owner = THIS_MODULE,
.pf = NFPROTO_BRIDGE, .pf = NFPROTO_BRIDGE,
.hooknum = NF_BR_FORWARD, .hooknum = NF_BR_FORWARD,
.priority = NF_BR_PRI_BRNF, .priority = NF_BR_PRI_BRNF,
}, },
{ {
.hook = br_nf_post_routing, .hook = br_nf_post_routing,
.owner = THIS_MODULE,
.pf = NFPROTO_BRIDGE, .pf = NFPROTO_BRIDGE,
.hooknum = NF_BR_POST_ROUTING, .hooknum = NF_BR_POST_ROUTING,
.priority = NF_BR_PRI_LAST, .priority = NF_BR_PRI_LAST,
}, },
{ {
.hook = ip_sabotage_in, .hook = ip_sabotage_in,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_PRE_ROUTING, .hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_FIRST, .priority = NF_IP_PRI_FIRST,
}, },
{ {
.hook = ip_sabotage_in, .hook = ip_sabotage_in,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_PRE_ROUTING, .hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP6_PRI_FIRST, .priority = NF_IP6_PRI_FIRST,
......
...@@ -73,21 +73,18 @@ ebt_out_hook(void *priv, struct sk_buff *skb, ...@@ -73,21 +73,18 @@ ebt_out_hook(void *priv, struct sk_buff *skb,
static struct nf_hook_ops ebt_ops_filter[] __read_mostly = { static struct nf_hook_ops ebt_ops_filter[] __read_mostly = {
{ {
.hook = ebt_in_hook, .hook = ebt_in_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_BRIDGE, .pf = NFPROTO_BRIDGE,
.hooknum = NF_BR_LOCAL_IN, .hooknum = NF_BR_LOCAL_IN,
.priority = NF_BR_PRI_FILTER_BRIDGED, .priority = NF_BR_PRI_FILTER_BRIDGED,
}, },
{ {
.hook = ebt_in_hook, .hook = ebt_in_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_BRIDGE, .pf = NFPROTO_BRIDGE,
.hooknum = NF_BR_FORWARD, .hooknum = NF_BR_FORWARD,
.priority = NF_BR_PRI_FILTER_BRIDGED, .priority = NF_BR_PRI_FILTER_BRIDGED,
}, },
{ {
.hook = ebt_out_hook, .hook = ebt_out_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_BRIDGE, .pf = NFPROTO_BRIDGE,
.hooknum = NF_BR_LOCAL_OUT, .hooknum = NF_BR_LOCAL_OUT,
.priority = NF_BR_PRI_FILTER_OTHER, .priority = NF_BR_PRI_FILTER_OTHER,
......
...@@ -73,21 +73,18 @@ ebt_nat_out(void *priv, struct sk_buff *skb, ...@@ -73,21 +73,18 @@ ebt_nat_out(void *priv, struct sk_buff *skb,
static struct nf_hook_ops ebt_ops_nat[] __read_mostly = { static struct nf_hook_ops ebt_ops_nat[] __read_mostly = {
{ {
.hook = ebt_nat_out, .hook = ebt_nat_out,
.owner = THIS_MODULE,
.pf = NFPROTO_BRIDGE, .pf = NFPROTO_BRIDGE,
.hooknum = NF_BR_LOCAL_OUT, .hooknum = NF_BR_LOCAL_OUT,
.priority = NF_BR_PRI_NAT_DST_OTHER, .priority = NF_BR_PRI_NAT_DST_OTHER,
}, },
{ {
.hook = ebt_nat_out, .hook = ebt_nat_out,
.owner = THIS_MODULE,
.pf = NFPROTO_BRIDGE, .pf = NFPROTO_BRIDGE,
.hooknum = NF_BR_POST_ROUTING, .hooknum = NF_BR_POST_ROUTING,
.priority = NF_BR_PRI_NAT_SRC, .priority = NF_BR_PRI_NAT_SRC,
}, },
{ {
.hook = ebt_nat_in, .hook = ebt_nat_in,
.owner = THIS_MODULE,
.pf = NFPROTO_BRIDGE, .pf = NFPROTO_BRIDGE,
.hooknum = NF_BR_PRE_ROUTING, .hooknum = NF_BR_PRE_ROUTING,
.priority = NF_BR_PRI_NAT_DST_BRIDGED, .priority = NF_BR_PRI_NAT_DST_BRIDGED,
......
...@@ -789,9 +789,7 @@ static int dn_forward(struct sk_buff *skb) ...@@ -789,9 +789,7 @@ static int dn_forward(struct sk_buff *skb)
struct dn_dev *dn_db = rcu_dereference(dst->dev->dn_ptr); struct dn_dev *dn_db = rcu_dereference(dst->dev->dn_ptr);
struct dn_route *rt; struct dn_route *rt;
int header_len; int header_len;
#ifdef CONFIG_NETFILTER
struct net_device *dev = skb->dev; struct net_device *dev = skb->dev;
#endif
if (skb->pkt_type != PACKET_HOST) if (skb->pkt_type != PACKET_HOST)
goto drop; goto drop;
......
...@@ -186,7 +186,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr, ...@@ -186,7 +186,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
if (FWINV(ret != 0, ARPT_INV_VIA_IN)) { if (FWINV(ret != 0, ARPT_INV_VIA_IN)) {
dprintf("VIA in mismatch (%s vs %s).%s\n", dprintf("VIA in mismatch (%s vs %s).%s\n",
indev, arpinfo->iniface, indev, arpinfo->iniface,
arpinfo->invflags&ARPT_INV_VIA_IN ?" (INV)":""); arpinfo->invflags & ARPT_INV_VIA_IN ? " (INV)" : "");
return 0; return 0;
} }
...@@ -195,7 +195,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr, ...@@ -195,7 +195,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
if (FWINV(ret != 0, ARPT_INV_VIA_OUT)) { if (FWINV(ret != 0, ARPT_INV_VIA_OUT)) {
dprintf("VIA out mismatch (%s vs %s).%s\n", dprintf("VIA out mismatch (%s vs %s).%s\n",
outdev, arpinfo->outiface, outdev, arpinfo->outiface,
arpinfo->invflags&ARPT_INV_VIA_OUT ?" (INV)":""); arpinfo->invflags & ARPT_INV_VIA_OUT ? " (INV)" : "");
return 0; return 0;
} }
...@@ -468,7 +468,7 @@ static int mark_source_chains(const struct xt_table_info *newinfo, ...@@ -468,7 +468,7 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
pos = newpos; pos = newpos;
} }
} }
next: next:
duprintf("Finished chain %u\n", hook); duprintf("Finished chain %u\n", hook);
} }
return 1; return 1;
...@@ -632,7 +632,7 @@ static inline void cleanup_entry(struct arpt_entry *e) ...@@ -632,7 +632,7 @@ static inline void cleanup_entry(struct arpt_entry *e)
* newinfo). * newinfo).
*/ */
static int translate_table(struct xt_table_info *newinfo, void *entry0, static int translate_table(struct xt_table_info *newinfo, void *entry0,
const struct arpt_replace *repl) const struct arpt_replace *repl)
{ {
struct arpt_entry *iter; struct arpt_entry *iter;
unsigned int i; unsigned int i;
...@@ -892,7 +892,7 @@ static int compat_table_info(const struct xt_table_info *info, ...@@ -892,7 +892,7 @@ static int compat_table_info(const struct xt_table_info *info,
#endif #endif
static int get_info(struct net *net, void __user *user, static int get_info(struct net *net, void __user *user,
const int *len, int compat) const int *len, int compat)
{ {
char name[XT_TABLE_MAXNAMELEN]; char name[XT_TABLE_MAXNAMELEN];
struct xt_table *t; struct xt_table *t;
...@@ -1069,7 +1069,7 @@ static int __do_replace(struct net *net, const char *name, ...@@ -1069,7 +1069,7 @@ static int __do_replace(struct net *net, const char *name,
} }
static int do_replace(struct net *net, const void __user *user, static int do_replace(struct net *net, const void __user *user,
unsigned int len) unsigned int len)
{ {
int ret; int ret;
struct arpt_replace tmp; struct arpt_replace tmp;
......
...@@ -102,7 +102,7 @@ ip_packet_match(const struct iphdr *ip, ...@@ -102,7 +102,7 @@ ip_packet_match(const struct iphdr *ip,
if (FWINV(ret != 0, IPT_INV_VIA_IN)) { if (FWINV(ret != 0, IPT_INV_VIA_IN)) {
dprintf("VIA in mismatch (%s vs %s).%s\n", dprintf("VIA in mismatch (%s vs %s).%s\n",
indev, ipinfo->iniface, indev, ipinfo->iniface,
ipinfo->invflags&IPT_INV_VIA_IN ?" (INV)":""); ipinfo->invflags & IPT_INV_VIA_IN ? " (INV)" : "");
return false; return false;
} }
...@@ -111,7 +111,7 @@ ip_packet_match(const struct iphdr *ip, ...@@ -111,7 +111,7 @@ ip_packet_match(const struct iphdr *ip,
if (FWINV(ret != 0, IPT_INV_VIA_OUT)) { if (FWINV(ret != 0, IPT_INV_VIA_OUT)) {
dprintf("VIA out mismatch (%s vs %s).%s\n", dprintf("VIA out mismatch (%s vs %s).%s\n",
outdev, ipinfo->outiface, outdev, ipinfo->outiface,
ipinfo->invflags&IPT_INV_VIA_OUT ?" (INV)":""); ipinfo->invflags & IPT_INV_VIA_OUT ? " (INV)" : "");
return false; return false;
} }
...@@ -120,7 +120,7 @@ ip_packet_match(const struct iphdr *ip, ...@@ -120,7 +120,7 @@ ip_packet_match(const struct iphdr *ip,
FWINV(ip->protocol != ipinfo->proto, IPT_INV_PROTO)) { FWINV(ip->protocol != ipinfo->proto, IPT_INV_PROTO)) {
dprintf("Packet protocol %hi does not match %hi.%s\n", dprintf("Packet protocol %hi does not match %hi.%s\n",
ip->protocol, ipinfo->proto, ip->protocol, ipinfo->proto,
ipinfo->invflags&IPT_INV_PROTO ? " (INV)":""); ipinfo->invflags & IPT_INV_PROTO ? " (INV)" : "");
return false; return false;
} }
...@@ -431,8 +431,8 @@ ipt_do_table(struct sk_buff *skb, ...@@ -431,8 +431,8 @@ ipt_do_table(struct sk_buff *skb,
} while (!acpar.hotdrop); } while (!acpar.hotdrop);
pr_debug("Exiting %s; sp at %u\n", __func__, stackidx); pr_debug("Exiting %s; sp at %u\n", __func__, stackidx);
xt_write_recseq_end(addend); xt_write_recseq_end(addend);
local_bh_enable(); local_bh_enable();
#ifdef DEBUG_ALLOW_ALL #ifdef DEBUG_ALLOW_ALL
return NF_ACCEPT; return NF_ACCEPT;
...@@ -484,7 +484,7 @@ mark_source_chains(const struct xt_table_info *newinfo, ...@@ -484,7 +484,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
unsigned int oldpos, size; unsigned int oldpos, size;
if ((strcmp(t->target.u.user.name, if ((strcmp(t->target.u.user.name,
XT_STANDARD_TARGET) == 0) && XT_STANDARD_TARGET) == 0) &&
t->verdict < -NF_MAX_VERDICT - 1) { t->verdict < -NF_MAX_VERDICT - 1) {
duprintf("mark_source_chains: bad " duprintf("mark_source_chains: bad "
"negative verdict (%i)\n", "negative verdict (%i)\n",
...@@ -549,7 +549,7 @@ mark_source_chains(const struct xt_table_info *newinfo, ...@@ -549,7 +549,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
pos = newpos; pos = newpos;
} }
} }
next: next:
duprintf("Finished chain %u\n", hook); duprintf("Finished chain %u\n", hook);
} }
return 1; return 1;
...@@ -804,7 +804,7 @@ cleanup_entry(struct ipt_entry *e, struct net *net) ...@@ -804,7 +804,7 @@ cleanup_entry(struct ipt_entry *e, struct net *net)
newinfo) */ newinfo) */
static int static int
translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0, translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
const struct ipt_replace *repl) const struct ipt_replace *repl)
{ {
struct ipt_entry *iter; struct ipt_entry *iter;
unsigned int i; unsigned int i;
...@@ -1078,7 +1078,7 @@ static int compat_table_info(const struct xt_table_info *info, ...@@ -1078,7 +1078,7 @@ static int compat_table_info(const struct xt_table_info *info,
#endif #endif
static int get_info(struct net *net, void __user *user, static int get_info(struct net *net, void __user *user,
const int *len, int compat) const int *len, int compat)
{ {
char name[XT_TABLE_MAXNAMELEN]; char name[XT_TABLE_MAXNAMELEN];
struct xt_table *t; struct xt_table *t;
...@@ -1304,7 +1304,7 @@ do_replace(struct net *net, const void __user *user, unsigned int len) ...@@ -1304,7 +1304,7 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
static int static int
do_add_counters(struct net *net, const void __user *user, do_add_counters(struct net *net, const void __user *user,
unsigned int len, int compat) unsigned int len, int compat)
{ {
unsigned int i; unsigned int i;
struct xt_counters_info tmp; struct xt_counters_info tmp;
......
...@@ -492,14 +492,14 @@ static void arp_print(struct arp_payload *payload) ...@@ -492,14 +492,14 @@ static void arp_print(struct arp_payload *payload)
{ {
#define HBUFFERLEN 30 #define HBUFFERLEN 30
char hbuffer[HBUFFERLEN]; char hbuffer[HBUFFERLEN];
int j,k; int j, k;
for (k=0, j=0; k < HBUFFERLEN-3 && j < ETH_ALEN; j++) { for (k = 0, j = 0; k < HBUFFERLEN - 3 && j < ETH_ALEN; j++) {
hbuffer[k++] = hex_asc_hi(payload->src_hw[j]); hbuffer[k++] = hex_asc_hi(payload->src_hw[j]);
hbuffer[k++] = hex_asc_lo(payload->src_hw[j]); hbuffer[k++] = hex_asc_lo(payload->src_hw[j]);
hbuffer[k++]=':'; hbuffer[k++] = ':';
} }
hbuffer[--k]='\0'; hbuffer[--k] = '\0';
pr_debug("src %pI4@%s, dst %pI4\n", pr_debug("src %pI4@%s, dst %pI4\n",
&payload->src_ip, hbuffer, &payload->dst_ip); &payload->src_ip, hbuffer, &payload->dst_ip);
......
...@@ -231,7 +231,7 @@ synproxy_send_client_ack(const struct synproxy_net *snet, ...@@ -231,7 +231,7 @@ synproxy_send_client_ack(const struct synproxy_net *snet,
synproxy_build_options(nth, opts); synproxy_build_options(nth, opts);
synproxy_send_tcp(snet, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY, synproxy_send_tcp(snet, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY,
niph, nth, tcp_hdr_size); niph, nth, tcp_hdr_size);
} }
static bool static bool
...@@ -437,14 +437,12 @@ static struct xt_target synproxy_tg4_reg __read_mostly = { ...@@ -437,14 +437,12 @@ static struct xt_target synproxy_tg4_reg __read_mostly = {
static struct nf_hook_ops ipv4_synproxy_ops[] __read_mostly = { static struct nf_hook_ops ipv4_synproxy_ops[] __read_mostly = {
{ {
.hook = ipv4_synproxy_hook, .hook = ipv4_synproxy_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_IN, .hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
}, },
{ {
.hook = ipv4_synproxy_hook, .hook = ipv4_synproxy_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_POST_ROUTING, .hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
......
...@@ -25,7 +25,7 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert) ...@@ -25,7 +25,7 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
bool r; bool r;
pr_debug("spi_match:%c 0x%x <= 0x%x <= 0x%x\n", pr_debug("spi_match:%c 0x%x <= 0x%x <= 0x%x\n",
invert ? '!' : ' ', min, spi, max); invert ? '!' : ' ', min, spi, max);
r=(spi >= min && spi <= max) ^ invert; r = (spi >= min && spi <= max) ^ invert;
pr_debug(" result %s\n", r ? "PASS" : "FAILED"); pr_debug(" result %s\n", r ? "PASS" : "FAILED");
return r; return r;
} }
......
...@@ -68,7 +68,6 @@ static struct nf_hook_ops nf_nat_ipv4_ops[] __read_mostly = { ...@@ -68,7 +68,6 @@ static struct nf_hook_ops nf_nat_ipv4_ops[] __read_mostly = {
/* Before packet filtering, change destination */ /* Before packet filtering, change destination */
{ {
.hook = iptable_nat_ipv4_in, .hook = iptable_nat_ipv4_in,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_PRE_ROUTING, .hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_NAT_DST, .priority = NF_IP_PRI_NAT_DST,
...@@ -76,7 +75,6 @@ static struct nf_hook_ops nf_nat_ipv4_ops[] __read_mostly = { ...@@ -76,7 +75,6 @@ static struct nf_hook_ops nf_nat_ipv4_ops[] __read_mostly = {
/* After packet filtering, change source */ /* After packet filtering, change source */
{ {
.hook = iptable_nat_ipv4_out, .hook = iptable_nat_ipv4_out,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_POST_ROUTING, .hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP_PRI_NAT_SRC, .priority = NF_IP_PRI_NAT_SRC,
...@@ -84,7 +82,6 @@ static struct nf_hook_ops nf_nat_ipv4_ops[] __read_mostly = { ...@@ -84,7 +82,6 @@ static struct nf_hook_ops nf_nat_ipv4_ops[] __read_mostly = {
/* Before packet filtering, change destination */ /* Before packet filtering, change destination */
{ {
.hook = iptable_nat_ipv4_local_fn, .hook = iptable_nat_ipv4_local_fn,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_OUT, .hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_NAT_DST, .priority = NF_IP_PRI_NAT_DST,
...@@ -92,7 +89,6 @@ static struct nf_hook_ops nf_nat_ipv4_ops[] __read_mostly = { ...@@ -92,7 +89,6 @@ static struct nf_hook_ops nf_nat_ipv4_ops[] __read_mostly = {
/* After packet filtering, change source */ /* After packet filtering, change source */
{ {
.hook = iptable_nat_ipv4_fn, .hook = iptable_nat_ipv4_fn,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_IN, .hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_NAT_SRC, .priority = NF_IP_PRI_NAT_SRC,
......
...@@ -79,7 +79,7 @@ static int __init iptable_security_init(void) ...@@ -79,7 +79,7 @@ static int __init iptable_security_init(void)
int ret; int ret;
ret = register_pernet_subsys(&iptable_security_net_ops); ret = register_pernet_subsys(&iptable_security_net_ops);
if (ret < 0) if (ret < 0)
return ret; return ret;
sectbl_ops = xt_hook_link(&security_table, iptable_security_hook); sectbl_ops = xt_hook_link(&security_table, iptable_security_hook);
......
...@@ -166,42 +166,36 @@ static unsigned int ipv4_conntrack_local(void *priv, ...@@ -166,42 +166,36 @@ static unsigned int ipv4_conntrack_local(void *priv,
static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = { static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
{ {
.hook = ipv4_conntrack_in, .hook = ipv4_conntrack_in,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_PRE_ROUTING, .hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_CONNTRACK, .priority = NF_IP_PRI_CONNTRACK,
}, },
{ {
.hook = ipv4_conntrack_local, .hook = ipv4_conntrack_local,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_OUT, .hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_CONNTRACK, .priority = NF_IP_PRI_CONNTRACK,
}, },
{ {
.hook = ipv4_helper, .hook = ipv4_helper,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_POST_ROUTING, .hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP_PRI_CONNTRACK_HELPER, .priority = NF_IP_PRI_CONNTRACK_HELPER,
}, },
{ {
.hook = ipv4_confirm, .hook = ipv4_confirm,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_POST_ROUTING, .hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP_PRI_CONNTRACK_CONFIRM, .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
}, },
{ {
.hook = ipv4_helper, .hook = ipv4_helper,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_IN, .hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_CONNTRACK_HELPER, .priority = NF_IP_PRI_CONNTRACK_HELPER,
}, },
{ {
.hook = ipv4_confirm, .hook = ipv4_confirm,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_IN, .hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_CONNTRACK_CONFIRM, .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
......
...@@ -95,14 +95,12 @@ static unsigned int ipv4_conntrack_defrag(void *priv, ...@@ -95,14 +95,12 @@ static unsigned int ipv4_conntrack_defrag(void *priv,
static struct nf_hook_ops ipv4_defrag_ops[] = { static struct nf_hook_ops ipv4_defrag_ops[] = {
{ {
.hook = ipv4_conntrack_defrag, .hook = ipv4_conntrack_defrag,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_PRE_ROUTING, .hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_CONNTRACK_DEFRAG, .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
}, },
{ {
.hook = ipv4_conntrack_defrag, .hook = ipv4_conntrack_defrag,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_OUT, .hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_CONNTRACK_DEFRAG, .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
......
...@@ -1156,7 +1156,7 @@ static int snmp_parse_mangle(unsigned char *msg, ...@@ -1156,7 +1156,7 @@ static int snmp_parse_mangle(unsigned char *msg,
} }
if (obj->type == SNMP_IPADDR) if (obj->type == SNMP_IPADDR)
mangle_address(ctx.begin, ctx.pointer - 4 , map, check); mangle_address(ctx.begin, ctx.pointer - 4, map, check);
kfree(obj->id); kfree(obj->id);
kfree(obj); kfree(obj);
......
...@@ -117,7 +117,7 @@ ip6_packet_match(const struct sk_buff *skb, ...@@ -117,7 +117,7 @@ ip6_packet_match(const struct sk_buff *skb,
if (FWINV(ret != 0, IP6T_INV_VIA_IN)) { if (FWINV(ret != 0, IP6T_INV_VIA_IN)) {
dprintf("VIA in mismatch (%s vs %s).%s\n", dprintf("VIA in mismatch (%s vs %s).%s\n",
indev, ip6info->iniface, indev, ip6info->iniface,
ip6info->invflags&IP6T_INV_VIA_IN ?" (INV)":""); ip6info->invflags & IP6T_INV_VIA_IN ? " (INV)" : "");
return false; return false;
} }
...@@ -126,14 +126,14 @@ ip6_packet_match(const struct sk_buff *skb, ...@@ -126,14 +126,14 @@ ip6_packet_match(const struct sk_buff *skb,
if (FWINV(ret != 0, IP6T_INV_VIA_OUT)) { if (FWINV(ret != 0, IP6T_INV_VIA_OUT)) {
dprintf("VIA out mismatch (%s vs %s).%s\n", dprintf("VIA out mismatch (%s vs %s).%s\n",
outdev, ip6info->outiface, outdev, ip6info->outiface,
ip6info->invflags&IP6T_INV_VIA_OUT ?" (INV)":""); ip6info->invflags & IP6T_INV_VIA_OUT ? " (INV)" : "");
return false; return false;
} }
/* ... might want to do something with class and flowlabel here ... */ /* ... might want to do something with class and flowlabel here ... */
/* look for the desired protocol header */ /* look for the desired protocol header */
if((ip6info->flags & IP6T_F_PROTO)) { if (ip6info->flags & IP6T_F_PROTO) {
int protohdr; int protohdr;
unsigned short _frag_off; unsigned short _frag_off;
...@@ -151,9 +151,9 @@ ip6_packet_match(const struct sk_buff *skb, ...@@ -151,9 +151,9 @@ ip6_packet_match(const struct sk_buff *skb,
ip6info->proto); ip6info->proto);
if (ip6info->proto == protohdr) { if (ip6info->proto == protohdr) {
if(ip6info->invflags & IP6T_INV_PROTO) { if (ip6info->invflags & IP6T_INV_PROTO)
return false; return false;
}
return true; return true;
} }
...@@ -443,8 +443,8 @@ ip6t_do_table(struct sk_buff *skb, ...@@ -443,8 +443,8 @@ ip6t_do_table(struct sk_buff *skb,
break; break;
} while (!acpar.hotdrop); } while (!acpar.hotdrop);
xt_write_recseq_end(addend); xt_write_recseq_end(addend);
local_bh_enable(); local_bh_enable();
#ifdef DEBUG_ALLOW_ALL #ifdef DEBUG_ALLOW_ALL
return NF_ACCEPT; return NF_ACCEPT;
...@@ -561,7 +561,7 @@ mark_source_chains(const struct xt_table_info *newinfo, ...@@ -561,7 +561,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
pos = newpos; pos = newpos;
} }
} }
next: next:
duprintf("Finished chain %u\n", hook); duprintf("Finished chain %u\n", hook);
} }
return 1; return 1;
...@@ -816,7 +816,7 @@ static void cleanup_entry(struct ip6t_entry *e, struct net *net) ...@@ -816,7 +816,7 @@ static void cleanup_entry(struct ip6t_entry *e, struct net *net)
newinfo) */ newinfo) */
static int static int
translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0, translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
const struct ip6t_replace *repl) const struct ip6t_replace *repl)
{ {
struct ip6t_entry *iter; struct ip6t_entry *iter;
unsigned int i; unsigned int i;
...@@ -1090,7 +1090,7 @@ static int compat_table_info(const struct xt_table_info *info, ...@@ -1090,7 +1090,7 @@ static int compat_table_info(const struct xt_table_info *info,
#endif #endif
static int get_info(struct net *net, void __user *user, static int get_info(struct net *net, void __user *user,
const int *len, int compat) const int *len, int compat)
{ {
char name[XT_TABLE_MAXNAMELEN]; char name[XT_TABLE_MAXNAMELEN];
struct xt_table *t; struct xt_table *t;
...@@ -1152,7 +1152,7 @@ static int get_info(struct net *net, void __user *user, ...@@ -1152,7 +1152,7 @@ static int get_info(struct net *net, void __user *user,
static int static int
get_entries(struct net *net, struct ip6t_get_entries __user *uptr, get_entries(struct net *net, struct ip6t_get_entries __user *uptr,
const int *len) const int *len)
{ {
int ret; int ret;
struct ip6t_get_entries get; struct ip6t_get_entries get;
......
...@@ -244,7 +244,7 @@ synproxy_send_client_ack(const struct synproxy_net *snet, ...@@ -244,7 +244,7 @@ synproxy_send_client_ack(const struct synproxy_net *snet,
synproxy_build_options(nth, opts); synproxy_build_options(nth, opts);
synproxy_send_tcp(snet, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY, synproxy_send_tcp(snet, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY,
niph, nth, tcp_hdr_size); niph, nth, tcp_hdr_size);
} }
static bool static bool
...@@ -458,14 +458,12 @@ static struct xt_target synproxy_tg6_reg __read_mostly = { ...@@ -458,14 +458,12 @@ static struct xt_target synproxy_tg6_reg __read_mostly = {
static struct nf_hook_ops ipv6_synproxy_ops[] __read_mostly = { static struct nf_hook_ops ipv6_synproxy_ops[] __read_mostly = {
{ {
.hook = ipv6_synproxy_hook, .hook = ipv6_synproxy_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN, .hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
}, },
{ {
.hook = ipv6_synproxy_hook, .hook = ipv6_synproxy_hook,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_POST_ROUTING, .hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
......
...@@ -70,7 +70,6 @@ static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = { ...@@ -70,7 +70,6 @@ static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = {
/* Before packet filtering, change destination */ /* Before packet filtering, change destination */
{ {
.hook = ip6table_nat_in, .hook = ip6table_nat_in,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_PRE_ROUTING, .hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP6_PRI_NAT_DST, .priority = NF_IP6_PRI_NAT_DST,
...@@ -78,7 +77,6 @@ static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = { ...@@ -78,7 +77,6 @@ static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = {
/* After packet filtering, change source */ /* After packet filtering, change source */
{ {
.hook = ip6table_nat_out, .hook = ip6table_nat_out,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_POST_ROUTING, .hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP6_PRI_NAT_SRC, .priority = NF_IP6_PRI_NAT_SRC,
...@@ -86,7 +84,6 @@ static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = { ...@@ -86,7 +84,6 @@ static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = {
/* Before packet filtering, change destination */ /* Before packet filtering, change destination */
{ {
.hook = ip6table_nat_local_fn, .hook = ip6table_nat_local_fn,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT, .hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_NAT_DST, .priority = NF_IP6_PRI_NAT_DST,
...@@ -94,7 +91,6 @@ static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = { ...@@ -94,7 +91,6 @@ static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = {
/* After packet filtering, change source */ /* After packet filtering, change source */
{ {
.hook = ip6table_nat_fn, .hook = ip6table_nat_fn,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN, .hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP6_PRI_NAT_SRC, .priority = NF_IP6_PRI_NAT_SRC,
......
...@@ -187,42 +187,36 @@ static unsigned int ipv6_conntrack_local(void *priv, ...@@ -187,42 +187,36 @@ static unsigned int ipv6_conntrack_local(void *priv,
static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
{ {
.hook = ipv6_conntrack_in, .hook = ipv6_conntrack_in,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_PRE_ROUTING, .hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP6_PRI_CONNTRACK, .priority = NF_IP6_PRI_CONNTRACK,
}, },
{ {
.hook = ipv6_conntrack_local, .hook = ipv6_conntrack_local,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT, .hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_CONNTRACK, .priority = NF_IP6_PRI_CONNTRACK,
}, },
{ {
.hook = ipv6_helper, .hook = ipv6_helper,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_POST_ROUTING, .hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP6_PRI_CONNTRACK_HELPER, .priority = NF_IP6_PRI_CONNTRACK_HELPER,
}, },
{ {
.hook = ipv6_confirm, .hook = ipv6_confirm,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_POST_ROUTING, .hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP6_PRI_LAST, .priority = NF_IP6_PRI_LAST,
}, },
{ {
.hook = ipv6_helper, .hook = ipv6_helper,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN, .hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP6_PRI_CONNTRACK_HELPER, .priority = NF_IP6_PRI_CONNTRACK_HELPER,
}, },
{ {
.hook = ipv6_confirm, .hook = ipv6_confirm,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN, .hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP6_PRI_LAST-1, .priority = NF_IP6_PRI_LAST-1,
......
...@@ -57,12 +57,12 @@ static const u_int8_t invmap[] = { ...@@ -57,12 +57,12 @@ static const u_int8_t invmap[] = {
[ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1, [ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1,
[ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1, [ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1,
[ICMPV6_NI_QUERY - 128] = ICMPV6_NI_REPLY + 1, [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_REPLY + 1,
[ICMPV6_NI_REPLY - 128] = ICMPV6_NI_QUERY +1 [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_QUERY + 1
}; };
static const u_int8_t noct_valid_new[] = { static const u_int8_t noct_valid_new[] = {
[ICMPV6_MGM_QUERY - 130] = 1, [ICMPV6_MGM_QUERY - 130] = 1,
[ICMPV6_MGM_REPORT -130] = 1, [ICMPV6_MGM_REPORT - 130] = 1,
[ICMPV6_MGM_REDUCTION - 130] = 1, [ICMPV6_MGM_REDUCTION - 130] = 1,
[NDISC_ROUTER_SOLICITATION - 130] = 1, [NDISC_ROUTER_SOLICITATION - 130] = 1,
[NDISC_ROUTER_ADVERTISEMENT - 130] = 1, [NDISC_ROUTER_ADVERTISEMENT - 130] = 1,
......
...@@ -59,7 +59,7 @@ struct nf_ct_frag6_skb_cb ...@@ -59,7 +59,7 @@ struct nf_ct_frag6_skb_cb
struct sk_buff *orig; struct sk_buff *orig;
}; };
#define NFCT_FRAG6_CB(skb) ((struct nf_ct_frag6_skb_cb*)((skb)->cb)) #define NFCT_FRAG6_CB(skb) ((struct nf_ct_frag6_skb_cb *)((skb)->cb))
static struct inet_frags nf_frags; static struct inet_frags nf_frags;
...@@ -445,7 +445,7 @@ nf_ct_frag6_reasm(struct frag_queue *fq, struct net_device *dev) ...@@ -445,7 +445,7 @@ nf_ct_frag6_reasm(struct frag_queue *fq, struct net_device *dev)
skb_reset_transport_header(head); skb_reset_transport_header(head);
skb_push(head, head->data - skb_network_header(head)); skb_push(head, head->data - skb_network_header(head));
for (fp=head->next; fp; fp = fp->next) { for (fp = head->next; fp; fp = fp->next) {
head->data_len += fp->len; head->data_len += fp->len;
head->len += fp->len; head->len += fp->len;
if (head->ip_summed != fp->ip_summed) if (head->ip_summed != fp->ip_summed)
......
...@@ -85,14 +85,12 @@ static unsigned int ipv6_defrag(void *priv, ...@@ -85,14 +85,12 @@ static unsigned int ipv6_defrag(void *priv,
static struct nf_hook_ops ipv6_defrag_ops[] = { static struct nf_hook_ops ipv6_defrag_ops[] = {
{ {
.hook = ipv6_defrag, .hook = ipv6_defrag,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_PRE_ROUTING, .hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP6_PRI_CONNTRACK_DEFRAG, .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
}, },
{ {
.hook = ipv6_defrag, .hook = ipv6_defrag,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT, .hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_CONNTRACK_DEFRAG, .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
......
...@@ -26,7 +26,7 @@ const struct tcphdr *nf_reject_ip6_tcphdr_get(struct sk_buff *oldskb, ...@@ -26,7 +26,7 @@ const struct tcphdr *nf_reject_ip6_tcphdr_get(struct sk_buff *oldskb,
int tcphoff; int tcphoff;
proto = oip6h->nexthdr; proto = oip6h->nexthdr;
tcphoff = ipv6_skip_exthdr(oldskb, ((u8*)(oip6h+1) - oldskb->data), tcphoff = ipv6_skip_exthdr(oldskb, ((u8 *)(oip6h + 1) - oldskb->data),
&proto, &frag_off); &proto, &frag_off);
if ((tcphoff < 0) || (tcphoff > oldskb->len)) { if ((tcphoff < 0) || (tcphoff > oldskb->len)) {
...@@ -224,7 +224,7 @@ static bool reject6_csum_ok(struct sk_buff *skb, int hook) ...@@ -224,7 +224,7 @@ static bool reject6_csum_ok(struct sk_buff *skb, int hook)
return true; return true;
proto = ip6h->nexthdr; proto = ip6h->nexthdr;
thoff = ipv6_skip_exthdr(skb, ((u8*)(ip6h+1) - skb->data), &proto, &fo); thoff = ipv6_skip_exthdr(skb, ((u8 *)(ip6h + 1) - skb->data), &proto, &fo);
if (thoff < 0 || thoff >= skb->len || (fo & htons(~0x7)) != 0) if (thoff < 0 || thoff >= skb->len || (fo & htons(~0x7)) != 0)
return false; return false;
......
...@@ -61,11 +61,11 @@ static const struct nf_chain_type nft_chain_route_ipv6 = { ...@@ -61,11 +61,11 @@ static const struct nf_chain_type nft_chain_route_ipv6 = {
.name = "route", .name = "route",
.type = NFT_CHAIN_T_ROUTE, .type = NFT_CHAIN_T_ROUTE,
.family = NFPROTO_IPV6, .family = NFPROTO_IPV6,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.hook_mask = (1 << NF_INET_LOCAL_OUT), .hook_mask = (1 << NF_INET_LOCAL_OUT),
.hooks = { .hooks = {
[NF_INET_LOCAL_OUT] = nf_route_table_hook, [NF_INET_LOCAL_OUT] = nf_route_table_hook,
}, },
}; };
static int __init nft_chain_route_init(void) static int __init nft_chain_route_init(void)
......
...@@ -354,7 +354,7 @@ config NF_CT_NETLINK_HELPER ...@@ -354,7 +354,7 @@ config NF_CT_NETLINK_HELPER
select NETFILTER_NETLINK select NETFILTER_NETLINK
depends on NF_CT_NETLINK depends on NF_CT_NETLINK
depends on NETFILTER_NETLINK_QUEUE depends on NETFILTER_NETLINK_QUEUE
depends on NETFILTER_NETLINK_QUEUE_CT depends on NETFILTER_NETLINK_GLUE_CT
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
help help
This option enables the user-space connection tracking helpers This option enables the user-space connection tracking helpers
...@@ -362,13 +362,14 @@ config NF_CT_NETLINK_HELPER ...@@ -362,13 +362,14 @@ config NF_CT_NETLINK_HELPER
If unsure, say `N'. If unsure, say `N'.
config NETFILTER_NETLINK_QUEUE_CT config NETFILTER_NETLINK_GLUE_CT
bool "NFQUEUE integration with Connection Tracking" bool "NFQUEUE and NFLOG integration with Connection Tracking"
default n default n
depends on NETFILTER_NETLINK_QUEUE depends on (NETFILTER_NETLINK_QUEUE || NETFILTER_NETLINK_LOG) && NF_CT_NETLINK
help help
If this option is enabled, NFQUEUE can include Connection Tracking If this option is enabled, NFQUEUE and NFLOG can include
information together with the packet is the enqueued via NFNETLINK. Connection Tracking information together with the packet is
the enqueued via NFNETLINK.
config NF_NAT config NF_NAT
tristate tristate
......
...@@ -10,8 +10,6 @@ obj-$(CONFIG_NETFILTER) = netfilter.o ...@@ -10,8 +10,6 @@ obj-$(CONFIG_NETFILTER) = netfilter.o
obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o
obj-$(CONFIG_NETFILTER_NETLINK_ACCT) += nfnetlink_acct.o obj-$(CONFIG_NETFILTER_NETLINK_ACCT) += nfnetlink_acct.o
nfnetlink_queue-y := nfnetlink_queue_core.o
nfnetlink_queue-$(CONFIG_NETFILTER_NETLINK_QUEUE_CT) += nfnetlink_queue_ct.o
obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o
obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o
......
...@@ -313,8 +313,6 @@ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state) ...@@ -313,8 +313,6 @@ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state)
int err = nf_queue(skb, elem, state, int err = nf_queue(skb, elem, state,
verdict >> NF_VERDICT_QBITS); verdict >> NF_VERDICT_QBITS);
if (err < 0) { if (err < 0) {
if (err == -ECANCELED)
goto next_hook;
if (err == -ESRCH && if (err == -ESRCH &&
(verdict & NF_VERDICT_FLAG_QUEUE_BYPASS)) (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
goto next_hook; goto next_hook;
...@@ -348,6 +346,12 @@ int skb_make_writable(struct sk_buff *skb, unsigned int writable_len) ...@@ -348,6 +346,12 @@ int skb_make_writable(struct sk_buff *skb, unsigned int writable_len)
} }
EXPORT_SYMBOL(skb_make_writable); EXPORT_SYMBOL(skb_make_writable);
/* This needs to be compiled in any case to avoid dependencies between the
* nfnetlink_queue code and nf_conntrack.
*/
struct nfnl_ct_hook __rcu *nfnl_ct_hook __read_mostly;
EXPORT_SYMBOL_GPL(nfnl_ct_hook);
#if IS_ENABLED(CONFIG_NF_CONNTRACK) #if IS_ENABLED(CONFIG_NF_CONNTRACK)
/* This does not belong here, but locally generated errors need it if connection /* This does not belong here, but locally generated errors need it if connection
tracking in use: without this, connection may not be in hash table, and hence tracking in use: without this, connection may not be in hash table, and hence
...@@ -385,9 +389,6 @@ void nf_conntrack_destroy(struct nf_conntrack *nfct) ...@@ -385,9 +389,6 @@ void nf_conntrack_destroy(struct nf_conntrack *nfct)
} }
EXPORT_SYMBOL(nf_conntrack_destroy); EXPORT_SYMBOL(nf_conntrack_destroy);
struct nfq_ct_hook __rcu *nfq_ct_hook __read_mostly;
EXPORT_SYMBOL_GPL(nfq_ct_hook);
/* Built-in default zone used e.g. by modules. */ /* Built-in default zone used e.g. by modules. */
const struct nf_conntrack_zone nf_ct_zone_dflt = { const struct nf_conntrack_zone nf_ct_zone_dflt = {
.id = NF_CT_DEFAULT_ZONE_ID, .id = NF_CT_DEFAULT_ZONE_ID,
......
...@@ -1347,23 +1347,20 @@ static void ip_vs_conn_flush(struct netns_ipvs *ipvs) ...@@ -1347,23 +1347,20 @@ static void ip_vs_conn_flush(struct netns_ipvs *ipvs)
*/ */
int __net_init ip_vs_conn_net_init(struct netns_ipvs *ipvs) int __net_init ip_vs_conn_net_init(struct netns_ipvs *ipvs)
{ {
struct net *net = ipvs->net;
atomic_set(&ipvs->conn_count, 0); atomic_set(&ipvs->conn_count, 0);
proc_create("ip_vs_conn", 0, net->proc_net, &ip_vs_conn_fops); proc_create("ip_vs_conn", 0, ipvs->net->proc_net, &ip_vs_conn_fops);
proc_create("ip_vs_conn_sync", 0, net->proc_net, &ip_vs_conn_sync_fops); proc_create("ip_vs_conn_sync", 0, ipvs->net->proc_net,
&ip_vs_conn_sync_fops);
return 0; return 0;
} }
void __net_exit ip_vs_conn_net_cleanup(struct netns_ipvs *ipvs) void __net_exit ip_vs_conn_net_cleanup(struct netns_ipvs *ipvs)
{ {
struct net *net = ipvs->net;
/* flush all the connection entries first */ /* flush all the connection entries first */
ip_vs_conn_flush(ipvs); ip_vs_conn_flush(ipvs);
remove_proc_entry("ip_vs_conn", net->proc_net); remove_proc_entry("ip_vs_conn", ipvs->net->proc_net);
remove_proc_entry("ip_vs_conn_sync", net->proc_net); remove_proc_entry("ip_vs_conn_sync", ipvs->net->proc_net);
} }
int __init ip_vs_conn_init(void) int __init ip_vs_conn_init(void)
......
...@@ -547,7 +547,6 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, ...@@ -547,7 +547,6 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
return cp; return cp;
} }
#ifdef CONFIG_SYSCTL
static inline int ip_vs_addr_is_unicast(struct net *net, int af, static inline int ip_vs_addr_is_unicast(struct net *net, int af,
union nf_inet_addr *addr) union nf_inet_addr *addr)
{ {
...@@ -557,7 +556,6 @@ static inline int ip_vs_addr_is_unicast(struct net *net, int af, ...@@ -557,7 +556,6 @@ static inline int ip_vs_addr_is_unicast(struct net *net, int af,
#endif #endif
return (inet_addr_type(net, addr->ip) == RTN_UNICAST); return (inet_addr_type(net, addr->ip) == RTN_UNICAST);
} }
#endif
/* /*
* Pass or drop the packet. * Pass or drop the packet.
...@@ -1174,7 +1172,6 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, ...@@ -1174,7 +1172,6 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
static unsigned int static unsigned int
ip_vs_out(struct netns_ipvs *ipvs, unsigned int hooknum, struct sk_buff *skb, int af) ip_vs_out(struct netns_ipvs *ipvs, unsigned int hooknum, struct sk_buff *skb, int af)
{ {
struct net *net = ipvs->net;
struct ip_vs_iphdr iph; struct ip_vs_iphdr iph;
struct ip_vs_protocol *pp; struct ip_vs_protocol *pp;
struct ip_vs_proto_data *pd; struct ip_vs_proto_data *pd;
...@@ -1274,7 +1271,7 @@ ip_vs_out(struct netns_ipvs *ipvs, unsigned int hooknum, struct sk_buff *skb, in ...@@ -1274,7 +1271,7 @@ ip_vs_out(struct netns_ipvs *ipvs, unsigned int hooknum, struct sk_buff *skb, in
#ifdef CONFIG_IP_VS_IPV6 #ifdef CONFIG_IP_VS_IPV6
if (af == AF_INET6) { if (af == AF_INET6) {
if (!skb->dev) if (!skb->dev)
skb->dev = net->loopback_dev; skb->dev = ipvs->net->loopback_dev;
icmpv6_send(skb, icmpv6_send(skb,
ICMPV6_DEST_UNREACH, ICMPV6_DEST_UNREACH,
ICMPV6_PORT_UNREACH, ICMPV6_PORT_UNREACH,
...@@ -1926,7 +1923,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { ...@@ -1926,7 +1923,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
/* After packet filtering, change source only for VS/NAT */ /* After packet filtering, change source only for VS/NAT */
{ {
.hook = ip_vs_reply4, .hook = ip_vs_reply4,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_IN, .hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_NAT_SRC - 2, .priority = NF_IP_PRI_NAT_SRC - 2,
...@@ -1936,7 +1932,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { ...@@ -1936,7 +1932,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
* applied to IPVS. */ * applied to IPVS. */
{ {
.hook = ip_vs_remote_request4, .hook = ip_vs_remote_request4,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_IN, .hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_NAT_SRC - 1, .priority = NF_IP_PRI_NAT_SRC - 1,
...@@ -1944,7 +1939,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { ...@@ -1944,7 +1939,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
/* Before ip_vs_in, change source only for VS/NAT */ /* Before ip_vs_in, change source only for VS/NAT */
{ {
.hook = ip_vs_local_reply4, .hook = ip_vs_local_reply4,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_OUT, .hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_NAT_DST + 1, .priority = NF_IP_PRI_NAT_DST + 1,
...@@ -1952,7 +1946,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { ...@@ -1952,7 +1946,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
/* After mangle, schedule and forward local requests */ /* After mangle, schedule and forward local requests */
{ {
.hook = ip_vs_local_request4, .hook = ip_vs_local_request4,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_OUT, .hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_NAT_DST + 2, .priority = NF_IP_PRI_NAT_DST + 2,
...@@ -1961,7 +1954,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { ...@@ -1961,7 +1954,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
* destined for 0.0.0.0/0, which is for incoming IPVS connections */ * destined for 0.0.0.0/0, which is for incoming IPVS connections */
{ {
.hook = ip_vs_forward_icmp, .hook = ip_vs_forward_icmp,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_FORWARD, .hooknum = NF_INET_FORWARD,
.priority = 99, .priority = 99,
...@@ -1969,7 +1961,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { ...@@ -1969,7 +1961,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
/* After packet filtering, change source only for VS/NAT */ /* After packet filtering, change source only for VS/NAT */
{ {
.hook = ip_vs_reply4, .hook = ip_vs_reply4,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_FORWARD, .hooknum = NF_INET_FORWARD,
.priority = 100, .priority = 100,
...@@ -1978,7 +1969,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { ...@@ -1978,7 +1969,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
/* After packet filtering, change source only for VS/NAT */ /* After packet filtering, change source only for VS/NAT */
{ {
.hook = ip_vs_reply6, .hook = ip_vs_reply6,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN, .hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP6_PRI_NAT_SRC - 2, .priority = NF_IP6_PRI_NAT_SRC - 2,
...@@ -1988,7 +1978,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { ...@@ -1988,7 +1978,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
* applied to IPVS. */ * applied to IPVS. */
{ {
.hook = ip_vs_remote_request6, .hook = ip_vs_remote_request6,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN, .hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP6_PRI_NAT_SRC - 1, .priority = NF_IP6_PRI_NAT_SRC - 1,
...@@ -1996,7 +1985,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { ...@@ -1996,7 +1985,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
/* Before ip_vs_in, change source only for VS/NAT */ /* Before ip_vs_in, change source only for VS/NAT */
{ {
.hook = ip_vs_local_reply6, .hook = ip_vs_local_reply6,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT, .hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_NAT_DST + 1, .priority = NF_IP6_PRI_NAT_DST + 1,
...@@ -2004,7 +1992,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { ...@@ -2004,7 +1992,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
/* After mangle, schedule and forward local requests */ /* After mangle, schedule and forward local requests */
{ {
.hook = ip_vs_local_request6, .hook = ip_vs_local_request6,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT, .hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_NAT_DST + 2, .priority = NF_IP6_PRI_NAT_DST + 2,
...@@ -2013,7 +2000,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { ...@@ -2013,7 +2000,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
* destined for 0.0.0.0/0, which is for incoming IPVS connections */ * destined for 0.0.0.0/0, which is for incoming IPVS connections */
{ {
.hook = ip_vs_forward_icmp_v6, .hook = ip_vs_forward_icmp_v6,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_FORWARD, .hooknum = NF_INET_FORWARD,
.priority = 99, .priority = 99,
...@@ -2021,7 +2007,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { ...@@ -2021,7 +2007,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
/* After packet filtering, change source only for VS/NAT */ /* After packet filtering, change source only for VS/NAT */
{ {
.hook = ip_vs_reply6, .hook = ip_vs_reply6,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_FORWARD, .hooknum = NF_INET_FORWARD,
.priority = 100, .priority = 100,
......
...@@ -940,10 +940,13 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, ...@@ -940,10 +940,13 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
} }
timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL; timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL;
if (timeout_ext) if (timeout_ext) {
timeouts = NF_CT_TIMEOUT_EXT_DATA(timeout_ext); timeouts = nf_ct_timeout_data(timeout_ext);
else if (unlikely(!timeouts))
timeouts = l4proto->get_timeouts(net);
} else {
timeouts = l4proto->get_timeouts(net); timeouts = l4proto->get_timeouts(net);
}
if (!l4proto->new(ct, skb, dataoff, timeouts)) { if (!l4proto->new(ct, skb, dataoff, timeouts)) {
nf_conntrack_free(ct); nf_conntrack_free(ct);
...@@ -952,7 +955,8 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, ...@@ -952,7 +955,8 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
} }
if (timeout_ext) if (timeout_ext)
nf_ct_timeout_ext_add(ct, timeout_ext->timeout, GFP_ATOMIC); nf_ct_timeout_ext_add(ct, rcu_dereference(timeout_ext->timeout),
GFP_ATOMIC);
nf_ct_acct_ext_add(ct, GFP_ATOMIC); nf_ct_acct_ext_add(ct, GFP_ATOMIC);
nf_ct_tstamp_ext_add(ct, GFP_ATOMIC); nf_ct_tstamp_ext_add(ct, GFP_ATOMIC);
......
...@@ -2133,9 +2133,9 @@ ctnetlink_alloc_expect(const struct nlattr *const cda[], struct nf_conn *ct, ...@@ -2133,9 +2133,9 @@ ctnetlink_alloc_expect(const struct nlattr *const cda[], struct nf_conn *ct,
struct nf_conntrack_tuple *tuple, struct nf_conntrack_tuple *tuple,
struct nf_conntrack_tuple *mask); struct nf_conntrack_tuple *mask);
#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT #ifdef CONFIG_NETFILTER_NETLINK_GLUE_CT
static size_t static size_t
ctnetlink_nfqueue_build_size(const struct nf_conn *ct) ctnetlink_glue_build_size(const struct nf_conn *ct)
{ {
return 3 * nla_total_size(0) /* CTA_TUPLE_ORIG|REPL|MASTER */ return 3 * nla_total_size(0) /* CTA_TUPLE_ORIG|REPL|MASTER */
+ 3 * nla_total_size(0) /* CTA_TUPLE_IP */ + 3 * nla_total_size(0) /* CTA_TUPLE_IP */
...@@ -2162,8 +2162,19 @@ ctnetlink_nfqueue_build_size(const struct nf_conn *ct) ...@@ -2162,8 +2162,19 @@ ctnetlink_nfqueue_build_size(const struct nf_conn *ct)
; ;
} }
static int static struct nf_conn *ctnetlink_glue_get_ct(const struct sk_buff *skb,
ctnetlink_nfqueue_build(struct sk_buff *skb, struct nf_conn *ct) enum ip_conntrack_info *ctinfo)
{
struct nf_conn *ct;
ct = nf_ct_get(skb, ctinfo);
if (ct && nf_ct_is_untracked(ct))
ct = NULL;
return ct;
}
static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
{ {
const struct nf_conntrack_zone *zone; const struct nf_conntrack_zone *zone;
struct nlattr *nest_parms; struct nlattr *nest_parms;
...@@ -2236,7 +2247,32 @@ ctnetlink_nfqueue_build(struct sk_buff *skb, struct nf_conn *ct) ...@@ -2236,7 +2247,32 @@ ctnetlink_nfqueue_build(struct sk_buff *skb, struct nf_conn *ct)
} }
static int static int
ctnetlink_nfqueue_parse_ct(const struct nlattr *cda[], struct nf_conn *ct) ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
u_int16_t ct_attr, u_int16_t ct_info_attr)
{
struct nlattr *nest_parms;
nest_parms = nla_nest_start(skb, ct_attr | NLA_F_NESTED);
if (!nest_parms)
goto nla_put_failure;
if (__ctnetlink_glue_build(skb, ct) < 0)
goto nla_put_failure;
nla_nest_end(skb, nest_parms);
if (nla_put_be32(skb, ct_info_attr, htonl(ctinfo)))
goto nla_put_failure;
return 0;
nla_put_failure:
return -ENOSPC;
}
static int
ctnetlink_glue_parse_ct(const struct nlattr *cda[], struct nf_conn *ct)
{ {
int err; int err;
...@@ -2276,7 +2312,7 @@ ctnetlink_nfqueue_parse_ct(const struct nlattr *cda[], struct nf_conn *ct) ...@@ -2276,7 +2312,7 @@ ctnetlink_nfqueue_parse_ct(const struct nlattr *cda[], struct nf_conn *ct)
} }
static int static int
ctnetlink_nfqueue_parse(const struct nlattr *attr, struct nf_conn *ct) ctnetlink_glue_parse(const struct nlattr *attr, struct nf_conn *ct)
{ {
struct nlattr *cda[CTA_MAX+1]; struct nlattr *cda[CTA_MAX+1];
int ret; int ret;
...@@ -2286,16 +2322,16 @@ ctnetlink_nfqueue_parse(const struct nlattr *attr, struct nf_conn *ct) ...@@ -2286,16 +2322,16 @@ ctnetlink_nfqueue_parse(const struct nlattr *attr, struct nf_conn *ct)
return ret; return ret;
spin_lock_bh(&nf_conntrack_expect_lock); spin_lock_bh(&nf_conntrack_expect_lock);
ret = ctnetlink_nfqueue_parse_ct((const struct nlattr **)cda, ct); ret = ctnetlink_glue_parse_ct((const struct nlattr **)cda, ct);
spin_unlock_bh(&nf_conntrack_expect_lock); spin_unlock_bh(&nf_conntrack_expect_lock);
return ret; return ret;
} }
static int ctnetlink_nfqueue_exp_parse(const struct nlattr * const *cda, static int ctnetlink_glue_exp_parse(const struct nlattr * const *cda,
const struct nf_conn *ct, const struct nf_conn *ct,
struct nf_conntrack_tuple *tuple, struct nf_conntrack_tuple *tuple,
struct nf_conntrack_tuple *mask) struct nf_conntrack_tuple *mask)
{ {
int err; int err;
...@@ -2309,8 +2345,8 @@ static int ctnetlink_nfqueue_exp_parse(const struct nlattr * const *cda, ...@@ -2309,8 +2345,8 @@ static int ctnetlink_nfqueue_exp_parse(const struct nlattr * const *cda,
} }
static int static int
ctnetlink_nfqueue_attach_expect(const struct nlattr *attr, struct nf_conn *ct, ctnetlink_glue_attach_expect(const struct nlattr *attr, struct nf_conn *ct,
u32 portid, u32 report) u32 portid, u32 report)
{ {
struct nlattr *cda[CTA_EXPECT_MAX+1]; struct nlattr *cda[CTA_EXPECT_MAX+1];
struct nf_conntrack_tuple tuple, mask; struct nf_conntrack_tuple tuple, mask;
...@@ -2322,8 +2358,8 @@ ctnetlink_nfqueue_attach_expect(const struct nlattr *attr, struct nf_conn *ct, ...@@ -2322,8 +2358,8 @@ ctnetlink_nfqueue_attach_expect(const struct nlattr *attr, struct nf_conn *ct,
if (err < 0) if (err < 0)
return err; return err;
err = ctnetlink_nfqueue_exp_parse((const struct nlattr * const *)cda, err = ctnetlink_glue_exp_parse((const struct nlattr * const *)cda,
ct, &tuple, &mask); ct, &tuple, &mask);
if (err < 0) if (err < 0)
return err; return err;
...@@ -2350,14 +2386,24 @@ ctnetlink_nfqueue_attach_expect(const struct nlattr *attr, struct nf_conn *ct, ...@@ -2350,14 +2386,24 @@ ctnetlink_nfqueue_attach_expect(const struct nlattr *attr, struct nf_conn *ct,
return 0; return 0;
} }
static struct nfq_ct_hook ctnetlink_nfqueue_hook = { static void ctnetlink_glue_seqadj(struct sk_buff *skb, struct nf_conn *ct,
.build_size = ctnetlink_nfqueue_build_size, enum ip_conntrack_info ctinfo, int diff)
.build = ctnetlink_nfqueue_build, {
.parse = ctnetlink_nfqueue_parse, if (!(ct->status & IPS_NAT_MASK))
.attach_expect = ctnetlink_nfqueue_attach_expect, return;
.seq_adjust = nf_ct_tcp_seqadj_set,
nf_ct_tcp_seqadj_set(skb, ct, ctinfo, diff);
}
static struct nfnl_ct_hook ctnetlink_glue_hook = {
.get_ct = ctnetlink_glue_get_ct,
.build_size = ctnetlink_glue_build_size,
.build = ctnetlink_glue_build,
.parse = ctnetlink_glue_parse,
.attach_expect = ctnetlink_glue_attach_expect,
.seq_adjust = ctnetlink_glue_seqadj,
}; };
#endif /* CONFIG_NETFILTER_NETLINK_QUEUE_CT */ #endif /* CONFIG_NETFILTER_NETLINK_GLUE_CT */
/*********************************************************************** /***********************************************************************
* EXPECT * EXPECT
...@@ -3341,9 +3387,9 @@ static int __init ctnetlink_init(void) ...@@ -3341,9 +3387,9 @@ static int __init ctnetlink_init(void)
pr_err("ctnetlink_init: cannot register pernet operations\n"); pr_err("ctnetlink_init: cannot register pernet operations\n");
goto err_unreg_exp_subsys; goto err_unreg_exp_subsys;
} }
#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT #ifdef CONFIG_NETFILTER_NETLINK_GLUE_CT
/* setup interaction between nf_queue and nf_conntrack_netlink. */ /* setup interaction between nf_queue and nf_conntrack_netlink. */
RCU_INIT_POINTER(nfq_ct_hook, &ctnetlink_nfqueue_hook); RCU_INIT_POINTER(nfnl_ct_hook, &ctnetlink_glue_hook);
#endif #endif
return 0; return 0;
...@@ -3362,8 +3408,8 @@ static void __exit ctnetlink_exit(void) ...@@ -3362,8 +3408,8 @@ static void __exit ctnetlink_exit(void)
unregister_pernet_subsys(&ctnetlink_net_ops); unregister_pernet_subsys(&ctnetlink_net_ops);
nfnetlink_subsys_unregister(&ctnl_exp_subsys); nfnetlink_subsys_unregister(&ctnl_exp_subsys);
nfnetlink_subsys_unregister(&ctnl_subsys); nfnetlink_subsys_unregister(&ctnl_subsys);
#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT #ifdef CONFIG_NETFILTER_NETLINK_GLUE_CT
RCU_INIT_POINTER(nfq_ct_hook, NULL); RCU_INIT_POINTER(nfnl_ct_hook, NULL);
#endif #endif
} }
......
...@@ -69,19 +69,14 @@ void nf_queue_entry_release_refs(struct nf_queue_entry *entry) ...@@ -69,19 +69,14 @@ void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
dev_put(physdev); dev_put(physdev);
} }
#endif #endif
/* Drop reference to owner of hook which queued us. */
module_put(entry->elem->owner);
} }
EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs); EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs);
/* Bump dev refs so they don't vanish while packet is out */ /* Bump dev refs so they don't vanish while packet is out */
bool nf_queue_entry_get_refs(struct nf_queue_entry *entry) void nf_queue_entry_get_refs(struct nf_queue_entry *entry)
{ {
struct nf_hook_state *state = &entry->state; struct nf_hook_state *state = &entry->state;
if (!try_module_get(entry->elem->owner))
return false;
if (state->in) if (state->in)
dev_hold(state->in); dev_hold(state->in);
if (state->out) if (state->out)
...@@ -100,8 +95,6 @@ bool nf_queue_entry_get_refs(struct nf_queue_entry *entry) ...@@ -100,8 +95,6 @@ bool nf_queue_entry_get_refs(struct nf_queue_entry *entry)
dev_hold(physdev); dev_hold(physdev);
} }
#endif #endif
return true;
} }
EXPORT_SYMBOL_GPL(nf_queue_entry_get_refs); EXPORT_SYMBOL_GPL(nf_queue_entry_get_refs);
...@@ -131,22 +124,20 @@ int nf_queue(struct sk_buff *skb, ...@@ -131,22 +124,20 @@ int nf_queue(struct sk_buff *skb,
const struct nf_queue_handler *qh; const struct nf_queue_handler *qh;
/* QUEUE == DROP if no one is waiting, to be safe. */ /* QUEUE == DROP if no one is waiting, to be safe. */
rcu_read_lock();
qh = rcu_dereference(queue_handler); qh = rcu_dereference(queue_handler);
if (!qh) { if (!qh) {
status = -ESRCH; status = -ESRCH;
goto err_unlock; goto err;
} }
afinfo = nf_get_afinfo(state->pf); afinfo = nf_get_afinfo(state->pf);
if (!afinfo) if (!afinfo)
goto err_unlock; goto err;
entry = kmalloc(sizeof(*entry) + afinfo->route_key_size, GFP_ATOMIC); entry = kmalloc(sizeof(*entry) + afinfo->route_key_size, GFP_ATOMIC);
if (!entry) { if (!entry) {
status = -ENOMEM; status = -ENOMEM;
goto err_unlock; goto err;
} }
*entry = (struct nf_queue_entry) { *entry = (struct nf_queue_entry) {
...@@ -156,16 +147,11 @@ int nf_queue(struct sk_buff *skb, ...@@ -156,16 +147,11 @@ int nf_queue(struct sk_buff *skb,
.size = sizeof(*entry) + afinfo->route_key_size, .size = sizeof(*entry) + afinfo->route_key_size,
}; };
if (!nf_queue_entry_get_refs(entry)) { nf_queue_entry_get_refs(entry);
status = -ECANCELED;
goto err_unlock;
}
skb_dst_force(skb); skb_dst_force(skb);
afinfo->saveroute(skb, entry); afinfo->saveroute(skb, entry);
status = qh->outfn(entry, queuenum); status = qh->outfn(entry, queuenum);
rcu_read_unlock();
if (status < 0) { if (status < 0) {
nf_queue_entry_release_refs(entry); nf_queue_entry_release_refs(entry);
goto err; goto err;
...@@ -173,8 +159,6 @@ int nf_queue(struct sk_buff *skb, ...@@ -173,8 +159,6 @@ int nf_queue(struct sk_buff *skb,
return 0; return 0;
err_unlock:
rcu_read_unlock();
err: err:
kfree(entry); kfree(entry);
return status; return status;
...@@ -187,15 +171,11 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) ...@@ -187,15 +171,11 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
const struct nf_afinfo *afinfo; const struct nf_afinfo *afinfo;
int err; int err;
rcu_read_lock();
nf_queue_entry_release_refs(entry); nf_queue_entry_release_refs(entry);
/* Continue traversal iff userspace said ok... */ /* Continue traversal iff userspace said ok... */
if (verdict == NF_REPEAT) { if (verdict == NF_REPEAT)
elem = list_entry(elem->list.prev, struct nf_hook_ops, list); verdict = elem->hook(elem->priv, skb, &entry->state);
verdict = NF_ACCEPT;
}
if (verdict == NF_ACCEPT) { if (verdict == NF_ACCEPT) {
afinfo = nf_get_afinfo(entry->state.pf); afinfo = nf_get_afinfo(entry->state.pf);
...@@ -222,8 +202,6 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) ...@@ -222,8 +202,6 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
err = nf_queue(skb, elem, &entry->state, err = nf_queue(skb, elem, &entry->state,
verdict >> NF_VERDICT_QBITS); verdict >> NF_VERDICT_QBITS);
if (err < 0) { if (err < 0) {
if (err == -ECANCELED)
goto next_hook;
if (err == -ESRCH && if (err == -ESRCH &&
(verdict & NF_VERDICT_FLAG_QUEUE_BYPASS)) (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
goto next_hook; goto next_hook;
...@@ -235,7 +213,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) ...@@ -235,7 +213,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
default: default:
kfree_skb(skb); kfree_skb(skb);
} }
rcu_read_unlock();
kfree(entry); kfree(entry);
} }
EXPORT_SYMBOL(nf_reinject); EXPORT_SYMBOL(nf_reinject);
...@@ -1433,7 +1433,6 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb, ...@@ -1433,7 +1433,6 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
for (i = 0; i < afi->nops; i++) { for (i = 0; i < afi->nops; i++) {
ops = &basechain->ops[i]; ops = &basechain->ops[i];
ops->pf = family; ops->pf = family;
ops->owner = afi->owner;
ops->hooknum = hooknum; ops->hooknum = hooknum;
ops->priority = priority; ops->priority = priority;
ops->priv = chain; ops->priv = chain;
......
...@@ -291,6 +291,34 @@ cttimeout_get_timeout(struct sock *ctnl, struct sk_buff *skb, ...@@ -291,6 +291,34 @@ cttimeout_get_timeout(struct sock *ctnl, struct sk_buff *skb,
return ret; return ret;
} }
static void untimeout(struct nf_conntrack_tuple_hash *i,
struct ctnl_timeout *timeout)
{
struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(i);
struct nf_conn_timeout *timeout_ext = nf_ct_timeout_find(ct);
if (timeout_ext && (!timeout || timeout_ext->timeout == timeout))
RCU_INIT_POINTER(timeout_ext->timeout, NULL);
}
static void ctnl_untimeout(struct ctnl_timeout *timeout)
{
struct nf_conntrack_tuple_hash *h;
const struct hlist_nulls_node *nn;
int i;
local_bh_disable();
for (i = 0; i < init_net.ct.htable_size; i++) {
spin_lock(&nf_conntrack_locks[i % CONNTRACK_LOCKS]);
if (i < init_net.ct.htable_size) {
hlist_nulls_for_each_entry(h, nn, &init_net.ct.hash[i], hnnode)
untimeout(h, timeout);
}
spin_unlock(&nf_conntrack_locks[i % CONNTRACK_LOCKS]);
}
local_bh_enable();
}
/* try to delete object, fail if it is still in use. */ /* try to delete object, fail if it is still in use. */
static int ctnl_timeout_try_del(struct ctnl_timeout *timeout) static int ctnl_timeout_try_del(struct ctnl_timeout *timeout)
{ {
...@@ -301,6 +329,7 @@ static int ctnl_timeout_try_del(struct ctnl_timeout *timeout) ...@@ -301,6 +329,7 @@ static int ctnl_timeout_try_del(struct ctnl_timeout *timeout)
/* We are protected by nfnl mutex. */ /* We are protected by nfnl mutex. */
list_del_rcu(&timeout->head); list_del_rcu(&timeout->head);
nf_ct_l4proto_put(timeout->l4proto); nf_ct_l4proto_put(timeout->l4proto);
ctnl_untimeout(timeout);
kfree_rcu(timeout, rcu_head); kfree_rcu(timeout, rcu_head);
} else { } else {
/* still in use, restore reference counter. */ /* still in use, restore reference counter. */
...@@ -567,6 +596,10 @@ static void __exit cttimeout_exit(void) ...@@ -567,6 +596,10 @@ static void __exit cttimeout_exit(void)
pr_info("cttimeout: unregistering from nfnetlink.\n"); pr_info("cttimeout: unregistering from nfnetlink.\n");
nfnetlink_subsys_unregister(&cttimeout_subsys); nfnetlink_subsys_unregister(&cttimeout_subsys);
/* Make sure no conntrack objects refer to custom timeouts anymore. */
ctnl_untimeout(NULL);
list_for_each_entry_safe(cur, tmp, &cttimeout_list, head) { list_for_each_entry_safe(cur, tmp, &cttimeout_list, head) {
list_del_rcu(&cur->head); list_del_rcu(&cur->head);
/* We are sure that our objects have no clients at this point, /* We are sure that our objects have no clients at this point,
...@@ -579,6 +612,7 @@ static void __exit cttimeout_exit(void) ...@@ -579,6 +612,7 @@ static void __exit cttimeout_exit(void)
RCU_INIT_POINTER(nf_ct_timeout_find_get_hook, NULL); RCU_INIT_POINTER(nf_ct_timeout_find_get_hook, NULL);
RCU_INIT_POINTER(nf_ct_timeout_put_hook, NULL); RCU_INIT_POINTER(nf_ct_timeout_put_hook, NULL);
#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */ #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
rcu_barrier();
} }
module_init(cttimeout_init); module_init(cttimeout_init);
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <net/netlink.h> #include <net/netlink.h>
#include <linux/netfilter/nfnetlink.h> #include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_log.h> #include <linux/netfilter/nfnetlink_log.h>
#include <linux/netfilter/nf_conntrack_common.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/sysctl.h> #include <linux/sysctl.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
...@@ -401,7 +402,9 @@ __build_packet_message(struct nfnl_log_net *log, ...@@ -401,7 +402,9 @@ __build_packet_message(struct nfnl_log_net *log,
unsigned int hooknum, unsigned int hooknum,
const struct net_device *indev, const struct net_device *indev,
const struct net_device *outdev, const struct net_device *outdev,
const char *prefix, unsigned int plen) const char *prefix, unsigned int plen,
const struct nfnl_ct_hook *nfnl_ct,
struct nf_conn *ct, enum ip_conntrack_info ctinfo)
{ {
struct nfulnl_msg_packet_hdr pmsg; struct nfulnl_msg_packet_hdr pmsg;
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
...@@ -575,6 +578,10 @@ __build_packet_message(struct nfnl_log_net *log, ...@@ -575,6 +578,10 @@ __build_packet_message(struct nfnl_log_net *log,
htonl(atomic_inc_return(&log->global_seq)))) htonl(atomic_inc_return(&log->global_seq))))
goto nla_put_failure; goto nla_put_failure;
if (ct && nfnl_ct->build(inst->skb, ct, ctinfo,
NFULA_CT, NFULA_CT_INFO) < 0)
goto nla_put_failure;
if (data_len) { if (data_len) {
struct nlattr *nla; struct nlattr *nla;
int size = nla_attr_size(data_len); int size = nla_attr_size(data_len);
...@@ -620,12 +627,16 @@ nfulnl_log_packet(struct net *net, ...@@ -620,12 +627,16 @@ nfulnl_log_packet(struct net *net,
const struct nf_loginfo *li_user, const struct nf_loginfo *li_user,
const char *prefix) const char *prefix)
{ {
unsigned int size, data_len; size_t size;
unsigned int data_len;
struct nfulnl_instance *inst; struct nfulnl_instance *inst;
const struct nf_loginfo *li; const struct nf_loginfo *li;
unsigned int qthreshold; unsigned int qthreshold;
unsigned int plen; unsigned int plen;
struct nfnl_log_net *log = nfnl_log_pernet(net); struct nfnl_log_net *log = nfnl_log_pernet(net);
const struct nfnl_ct_hook *nfnl_ct = NULL;
struct nf_conn *ct = NULL;
enum ip_conntrack_info uninitialized_var(ctinfo);
if (li_user && li_user->type == NF_LOG_TYPE_ULOG) if (li_user && li_user->type == NF_LOG_TYPE_ULOG)
li = li_user; li = li_user;
...@@ -671,6 +682,14 @@ nfulnl_log_packet(struct net *net, ...@@ -671,6 +682,14 @@ nfulnl_log_packet(struct net *net,
size += nla_total_size(sizeof(u_int32_t)); size += nla_total_size(sizeof(u_int32_t));
if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL)
size += nla_total_size(sizeof(u_int32_t)); size += nla_total_size(sizeof(u_int32_t));
if (inst->flags & NFULNL_CFG_F_CONNTRACK) {
nfnl_ct = rcu_dereference(nfnl_ct_hook);
if (nfnl_ct != NULL) {
ct = nfnl_ct->get_ct(skb, &ctinfo);
if (ct != NULL)
size += nfnl_ct->build_size(ct);
}
}
qthreshold = inst->qthreshold; qthreshold = inst->qthreshold;
/* per-rule qthreshold overrides per-instance */ /* per-rule qthreshold overrides per-instance */
...@@ -715,7 +734,8 @@ nfulnl_log_packet(struct net *net, ...@@ -715,7 +734,8 @@ nfulnl_log_packet(struct net *net,
inst->qlen++; inst->qlen++;
__build_packet_message(log, inst, skb, data_len, pf, __build_packet_message(log, inst, skb, data_len, pf,
hooknum, in, out, prefix, plen); hooknum, in, out, prefix, plen,
nfnl_ct, ct, ctinfo);
if (inst->qlen >= qthreshold) if (inst->qlen >= qthreshold)
__nfulnl_flush(inst); __nfulnl_flush(inst);
...@@ -805,6 +825,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, ...@@ -805,6 +825,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
struct net *net = sock_net(ctnl); struct net *net = sock_net(ctnl);
struct nfnl_log_net *log = nfnl_log_pernet(net); struct nfnl_log_net *log = nfnl_log_pernet(net);
int ret = 0; int ret = 0;
u16 flags;
if (nfula[NFULA_CFG_CMD]) { if (nfula[NFULA_CFG_CMD]) {
u_int8_t pf = nfmsg->nfgen_family; u_int8_t pf = nfmsg->nfgen_family;
...@@ -826,6 +847,28 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, ...@@ -826,6 +847,28 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
goto out_put; goto out_put;
} }
/* Check if we support these flags in first place, dependencies should
* be there too not to break atomicity.
*/
if (nfula[NFULA_CFG_FLAGS]) {
flags = ntohs(nla_get_be16(nfula[NFULA_CFG_FLAGS]));
if ((flags & NFULNL_CFG_F_CONNTRACK) &&
!rcu_access_pointer(nfnl_ct_hook)) {
#ifdef CONFIG_MODULES
nfnl_unlock(NFNL_SUBSYS_ULOG);
request_module("ip_conntrack_netlink");
nfnl_lock(NFNL_SUBSYS_ULOG);
if (rcu_access_pointer(nfnl_ct_hook)) {
ret = -EAGAIN;
goto out_put;
}
#endif
ret = -EOPNOTSUPP;
goto out_put;
}
}
if (cmd != NULL) { if (cmd != NULL) {
switch (cmd->command) { switch (cmd->command) {
case NFULNL_CFG_CMD_BIND: case NFULNL_CFG_CMD_BIND:
...@@ -854,16 +897,15 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, ...@@ -854,16 +897,15 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
ret = -ENOTSUPP; ret = -ENOTSUPP;
break; break;
} }
} else if (!inst) {
ret = -ENODEV;
goto out;
} }
if (nfula[NFULA_CFG_MODE]) { if (nfula[NFULA_CFG_MODE]) {
struct nfulnl_msg_config_mode *params; struct nfulnl_msg_config_mode *params =
params = nla_data(nfula[NFULA_CFG_MODE]); nla_data(nfula[NFULA_CFG_MODE]);
if (!inst) {
ret = -ENODEV;
goto out;
}
nfulnl_set_mode(inst, params->copy_mode, nfulnl_set_mode(inst, params->copy_mode,
ntohl(params->copy_range)); ntohl(params->copy_range));
} }
...@@ -871,42 +913,23 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, ...@@ -871,42 +913,23 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
if (nfula[NFULA_CFG_TIMEOUT]) { if (nfula[NFULA_CFG_TIMEOUT]) {
__be32 timeout = nla_get_be32(nfula[NFULA_CFG_TIMEOUT]); __be32 timeout = nla_get_be32(nfula[NFULA_CFG_TIMEOUT]);
if (!inst) {
ret = -ENODEV;
goto out;
}
nfulnl_set_timeout(inst, ntohl(timeout)); nfulnl_set_timeout(inst, ntohl(timeout));
} }
if (nfula[NFULA_CFG_NLBUFSIZ]) { if (nfula[NFULA_CFG_NLBUFSIZ]) {
__be32 nlbufsiz = nla_get_be32(nfula[NFULA_CFG_NLBUFSIZ]); __be32 nlbufsiz = nla_get_be32(nfula[NFULA_CFG_NLBUFSIZ]);
if (!inst) {
ret = -ENODEV;
goto out;
}
nfulnl_set_nlbufsiz(inst, ntohl(nlbufsiz)); nfulnl_set_nlbufsiz(inst, ntohl(nlbufsiz));
} }
if (nfula[NFULA_CFG_QTHRESH]) { if (nfula[NFULA_CFG_QTHRESH]) {
__be32 qthresh = nla_get_be32(nfula[NFULA_CFG_QTHRESH]); __be32 qthresh = nla_get_be32(nfula[NFULA_CFG_QTHRESH]);
if (!inst) {
ret = -ENODEV;
goto out;
}
nfulnl_set_qthresh(inst, ntohl(qthresh)); nfulnl_set_qthresh(inst, ntohl(qthresh));
} }
if (nfula[NFULA_CFG_FLAGS]) { if (nfula[NFULA_CFG_FLAGS])
__be16 flags = nla_get_be16(nfula[NFULA_CFG_FLAGS]); nfulnl_set_flags(inst, flags);
if (!inst) {
ret = -ENODEV;
goto out;
}
nfulnl_set_flags(inst, ntohs(flags));
}
out_put: out_put:
instance_put(inst); instance_put(inst);
......
...@@ -28,12 +28,12 @@ ...@@ -28,12 +28,12 @@
#include <linux/netfilter_bridge.h> #include <linux/netfilter_bridge.h>
#include <linux/netfilter/nfnetlink.h> #include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_queue.h> #include <linux/netfilter/nfnetlink_queue.h>
#include <linux/netfilter/nf_conntrack_common.h>
#include <linux/list.h> #include <linux/list.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/tcp_states.h> #include <net/tcp_states.h>
#include <net/netfilter/nf_queue.h> #include <net/netfilter/nf_queue.h>
#include <net/netns/generic.h> #include <net/netns/generic.h>
#include <net/netfilter/nfnetlink_queue.h>
#include <linux/atomic.h> #include <linux/atomic.h>
...@@ -313,6 +313,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, ...@@ -313,6 +313,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
struct net_device *outdev; struct net_device *outdev;
struct nf_conn *ct = NULL; struct nf_conn *ct = NULL;
enum ip_conntrack_info uninitialized_var(ctinfo); enum ip_conntrack_info uninitialized_var(ctinfo);
struct nfnl_ct_hook *nfnl_ct;
bool csum_verify; bool csum_verify;
char *secdata = NULL; char *secdata = NULL;
u32 seclen = 0; u32 seclen = 0;
...@@ -364,8 +365,14 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, ...@@ -364,8 +365,14 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
break; break;
} }
if (queue->flags & NFQA_CFG_F_CONNTRACK) if (queue->flags & NFQA_CFG_F_CONNTRACK) {
ct = nfqnl_ct_get(entskb, &size, &ctinfo); nfnl_ct = rcu_dereference(nfnl_ct_hook);
if (nfnl_ct != NULL) {
ct = nfnl_ct->get_ct(entskb, &ctinfo);
if (ct != NULL)
size += nfnl_ct->build_size(ct);
}
}
if (queue->flags & NFQA_CFG_F_UID_GID) { if (queue->flags & NFQA_CFG_F_UID_GID) {
size += (nla_total_size(sizeof(u_int32_t)) /* uid */ size += (nla_total_size(sizeof(u_int32_t)) /* uid */
...@@ -493,9 +500,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, ...@@ -493,9 +500,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
if (entskb->tstamp.tv64) { if (entskb->tstamp.tv64) {
struct nfqnl_msg_packet_timestamp ts; struct nfqnl_msg_packet_timestamp ts;
struct timeval tv = ktime_to_timeval(entskb->tstamp); struct timespec64 kts = ktime_to_timespec64(skb->tstamp);
ts.sec = cpu_to_be64(tv.tv_sec);
ts.usec = cpu_to_be64(tv.tv_usec); ts.sec = cpu_to_be64(kts.tv_sec);
ts.usec = cpu_to_be64(kts.tv_nsec / NSEC_PER_USEC);
if (nla_put(skb, NFQA_TIMESTAMP, sizeof(ts), &ts)) if (nla_put(skb, NFQA_TIMESTAMP, sizeof(ts), &ts))
goto nla_put_failure; goto nla_put_failure;
...@@ -508,7 +516,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, ...@@ -508,7 +516,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
if (seclen && nla_put(skb, NFQA_SECCTX, seclen, secdata)) if (seclen && nla_put(skb, NFQA_SECCTX, seclen, secdata))
goto nla_put_failure; goto nla_put_failure;
if (ct && nfqnl_ct_put(skb, ct, ctinfo) < 0) if (ct && nfnl_ct->build(skb, ct, ctinfo, NFQA_CT, NFQA_CT_INFO) < 0)
goto nla_put_failure; goto nla_put_failure;
if (cap_len > data_len && if (cap_len > data_len &&
...@@ -598,12 +606,9 @@ static struct nf_queue_entry * ...@@ -598,12 +606,9 @@ static struct nf_queue_entry *
nf_queue_entry_dup(struct nf_queue_entry *e) nf_queue_entry_dup(struct nf_queue_entry *e)
{ {
struct nf_queue_entry *entry = kmemdup(e, e->size, GFP_ATOMIC); struct nf_queue_entry *entry = kmemdup(e, e->size, GFP_ATOMIC);
if (entry) { if (entry)
if (nf_queue_entry_get_refs(entry)) nf_queue_entry_get_refs(entry);
return entry; return entry;
kfree(entry);
}
return NULL;
} }
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
...@@ -698,7 +703,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum) ...@@ -698,7 +703,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
nf_bridge_adjust_skb_data(skb); nf_bridge_adjust_skb_data(skb);
segs = skb_gso_segment(skb, 0); segs = skb_gso_segment(skb, 0);
/* Does not use PTR_ERR to limit the number of error codes that can be /* Does not use PTR_ERR to limit the number of error codes that can be
* returned by nf_queue. For instance, callers rely on -ECANCELED to * returned by nf_queue. For instance, callers rely on -ESRCH to
* mean 'ignore this hook'. * mean 'ignore this hook'.
*/ */
if (IS_ERR_OR_NULL(segs)) if (IS_ERR_OR_NULL(segs))
...@@ -1001,6 +1006,28 @@ nfqnl_recv_verdict_batch(struct sock *ctnl, struct sk_buff *skb, ...@@ -1001,6 +1006,28 @@ nfqnl_recv_verdict_batch(struct sock *ctnl, struct sk_buff *skb,
return 0; return 0;
} }
static struct nf_conn *nfqnl_ct_parse(struct nfnl_ct_hook *nfnl_ct,
const struct nlmsghdr *nlh,
const struct nlattr * const nfqa[],
struct nf_queue_entry *entry,
enum ip_conntrack_info *ctinfo)
{
struct nf_conn *ct;
ct = nfnl_ct->get_ct(entry->skb, ctinfo);
if (ct == NULL)
return NULL;
if (nfnl_ct->parse(nfqa[NFQA_CT], ct) < 0)
return NULL;
if (nfqa[NFQA_EXP])
nfnl_ct->attach_expect(nfqa[NFQA_EXP], ct,
NETLINK_CB(entry->skb).portid,
nlmsg_report(nlh));
return ct;
}
static int static int
nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
const struct nlmsghdr *nlh, const struct nlmsghdr *nlh,
...@@ -1014,6 +1041,7 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, ...@@ -1014,6 +1041,7 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
unsigned int verdict; unsigned int verdict;
struct nf_queue_entry *entry; struct nf_queue_entry *entry;
enum ip_conntrack_info uninitialized_var(ctinfo); enum ip_conntrack_info uninitialized_var(ctinfo);
struct nfnl_ct_hook *nfnl_ct;
struct nf_conn *ct = NULL; struct nf_conn *ct = NULL;
struct net *net = sock_net(ctnl); struct net *net = sock_net(ctnl);
...@@ -1037,12 +1065,10 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, ...@@ -1037,12 +1065,10 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
return -ENOENT; return -ENOENT;
if (nfqa[NFQA_CT]) { if (nfqa[NFQA_CT]) {
ct = nfqnl_ct_parse(entry->skb, nfqa[NFQA_CT], &ctinfo); /* rcu lock already held from nfnl->call_rcu. */
if (ct && nfqa[NFQA_EXP]) { nfnl_ct = rcu_dereference(nfnl_ct_hook);
nfqnl_attach_expect(ct, nfqa[NFQA_EXP], if (nfnl_ct != NULL)
NETLINK_CB(skb).portid, ct = nfqnl_ct_parse(nfnl_ct, nlh, nfqa, entry, &ctinfo);
nlmsg_report(nlh));
}
} }
if (nfqa[NFQA_PAYLOAD]) { if (nfqa[NFQA_PAYLOAD]) {
...@@ -1053,8 +1079,8 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, ...@@ -1053,8 +1079,8 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
payload_len, entry, diff) < 0) payload_len, entry, diff) < 0)
verdict = NF_DROP; verdict = NF_DROP;
if (ct) if (ct && diff)
nfqnl_ct_seq_adjust(entry->skb, ct, ctinfo, diff); nfnl_ct->seq_adjust(entry->skb, ct, ctinfo, diff);
} }
if (nfqa[NFQA_MARK]) if (nfqa[NFQA_MARK])
......
/*
* (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
*
* 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
* published by the Free Software Foundation.
*
*/
#include <linux/skbuff.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_queue.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nfnetlink_queue.h>
struct nf_conn *nfqnl_ct_get(struct sk_buff *entskb, size_t *size,
enum ip_conntrack_info *ctinfo)
{
struct nfq_ct_hook *nfq_ct;
struct nf_conn *ct;
/* rcu_read_lock()ed by __nf_queue already. */
nfq_ct = rcu_dereference(nfq_ct_hook);
if (nfq_ct == NULL)
return NULL;
ct = nf_ct_get(entskb, ctinfo);
if (ct) {
if (!nf_ct_is_untracked(ct))
*size += nfq_ct->build_size(ct);
else
ct = NULL;
}
return ct;
}
struct nf_conn *
nfqnl_ct_parse(const struct sk_buff *skb, const struct nlattr *attr,
enum ip_conntrack_info *ctinfo)
{
struct nfq_ct_hook *nfq_ct;
struct nf_conn *ct;
/* rcu_read_lock()ed by __nf_queue already. */
nfq_ct = rcu_dereference(nfq_ct_hook);
if (nfq_ct == NULL)
return NULL;
ct = nf_ct_get(skb, ctinfo);
if (ct && !nf_ct_is_untracked(ct))
nfq_ct->parse(attr, ct);
return ct;
}
int nfqnl_ct_put(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo)
{
struct nfq_ct_hook *nfq_ct;
struct nlattr *nest_parms;
u_int32_t tmp;
nfq_ct = rcu_dereference(nfq_ct_hook);
if (nfq_ct == NULL)
return 0;
nest_parms = nla_nest_start(skb, NFQA_CT | NLA_F_NESTED);
if (!nest_parms)
goto nla_put_failure;
if (nfq_ct->build(skb, ct) < 0)
goto nla_put_failure;
nla_nest_end(skb, nest_parms);
tmp = ctinfo;
if (nla_put_be32(skb, NFQA_CT_INFO, htonl(tmp)))
goto nla_put_failure;
return 0;
nla_put_failure:
return -1;
}
void nfqnl_ct_seq_adjust(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo, int diff)
{
struct nfq_ct_hook *nfq_ct;
nfq_ct = rcu_dereference(nfq_ct_hook);
if (nfq_ct == NULL)
return;
if ((ct->status & IPS_NAT_MASK) && diff)
nfq_ct->seq_adjust(skb, ct, ctinfo, diff);
}
int nfqnl_attach_expect(struct nf_conn *ct, const struct nlattr *attr,
u32 portid, u32 report)
{
struct nfq_ct_hook *nfq_ct;
if (nf_ct_is_untracked(ct))
return 0;
nfq_ct = rcu_dereference(nfq_ct_hook);
if (nfq_ct == NULL)
return -EOPNOTSUPP;
return nfq_ct->attach_expect(attr, ct, portid, report);
}
...@@ -1193,7 +1193,6 @@ struct nf_hook_ops *xt_hook_link(const struct xt_table *table, nf_hookfn *fn) ...@@ -1193,7 +1193,6 @@ struct nf_hook_ops *xt_hook_link(const struct xt_table *table, nf_hookfn *fn)
if (!(hook_mask & 1)) if (!(hook_mask & 1))
continue; continue;
ops[i].hook = fn; ops[i].hook = fn;
ops[i].owner = table->me;
ops[i].pf = table->af; ops[i].pf = table->af;
ops[i].hooknum = hooknum; ops[i].hooknum = hooknum;
ops[i].priority = table->priority; ops[i].priority = table->priority;
......
...@@ -171,6 +171,9 @@ xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par, ...@@ -171,6 +171,9 @@ xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par,
if (timeout_ext == NULL) if (timeout_ext == NULL)
ret = -ENOMEM; ret = -ENOMEM;
rcu_read_unlock();
return ret;
err_put_timeout: err_put_timeout:
__xt_ct_tg_timeout_put(timeout); __xt_ct_tg_timeout_put(timeout);
out: out:
...@@ -318,8 +321,10 @@ static void xt_ct_destroy_timeout(struct nf_conn *ct) ...@@ -318,8 +321,10 @@ static void xt_ct_destroy_timeout(struct nf_conn *ct)
if (timeout_put) { if (timeout_put) {
timeout_ext = nf_ct_timeout_find(ct); timeout_ext = nf_ct_timeout_find(ct);
if (timeout_ext) if (timeout_ext) {
timeout_put(timeout_ext->timeout); timeout_put(timeout_ext->timeout);
RCU_INIT_POINTER(timeout_ext->timeout, NULL);
}
} }
rcu_read_unlock(); rcu_read_unlock();
#endif #endif
......
...@@ -6131,21 +6131,18 @@ security_initcall(selinux_init); ...@@ -6131,21 +6131,18 @@ security_initcall(selinux_init);
static struct nf_hook_ops selinux_nf_ops[] = { static struct nf_hook_ops selinux_nf_ops[] = {
{ {
.hook = selinux_ipv4_postroute, .hook = selinux_ipv4_postroute,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_POST_ROUTING, .hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP_PRI_SELINUX_LAST, .priority = NF_IP_PRI_SELINUX_LAST,
}, },
{ {
.hook = selinux_ipv4_forward, .hook = selinux_ipv4_forward,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_FORWARD, .hooknum = NF_INET_FORWARD,
.priority = NF_IP_PRI_SELINUX_FIRST, .priority = NF_IP_PRI_SELINUX_FIRST,
}, },
{ {
.hook = selinux_ipv4_output, .hook = selinux_ipv4_output,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_OUT, .hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_SELINUX_FIRST, .priority = NF_IP_PRI_SELINUX_FIRST,
...@@ -6153,14 +6150,12 @@ static struct nf_hook_ops selinux_nf_ops[] = { ...@@ -6153,14 +6150,12 @@ static struct nf_hook_ops selinux_nf_ops[] = {
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
{ {
.hook = selinux_ipv6_postroute, .hook = selinux_ipv6_postroute,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_POST_ROUTING, .hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP6_PRI_SELINUX_LAST, .priority = NF_IP6_PRI_SELINUX_LAST,
}, },
{ {
.hook = selinux_ipv6_forward, .hook = selinux_ipv6_forward,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_FORWARD, .hooknum = NF_INET_FORWARD,
.priority = NF_IP6_PRI_SELINUX_FIRST, .priority = NF_IP6_PRI_SELINUX_FIRST,
......
...@@ -57,7 +57,6 @@ static unsigned int smack_ipv4_output(void *priv, ...@@ -57,7 +57,6 @@ static unsigned int smack_ipv4_output(void *priv,
static struct nf_hook_ops smack_nf_ops[] = { static struct nf_hook_ops smack_nf_ops[] = {
{ {
.hook = smack_ipv4_output, .hook = smack_ipv4_output,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4, .pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_OUT, .hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_SELINUX_FIRST, .priority = NF_IP_PRI_SELINUX_FIRST,
...@@ -65,7 +64,6 @@ static struct nf_hook_ops smack_nf_ops[] = { ...@@ -65,7 +64,6 @@ static struct nf_hook_ops smack_nf_ops[] = {
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
{ {
.hook = smack_ipv6_output, .hook = smack_ipv6_output,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV6, .pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT, .hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_SELINUX_FIRST, .priority = NF_IP6_PRI_SELINUX_FIRST,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册