mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 13:11:40 +00:00
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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
371f1c7e0d
@ -90,7 +90,6 @@ struct nf_hook_ops {
|
||||
/* User fills in from here down. */
|
||||
nf_hookfn *hook;
|
||||
struct net_device *dev;
|
||||
struct module *owner;
|
||||
void *priv;
|
||||
u_int8_t pf;
|
||||
unsigned int hooknum;
|
||||
@ -347,8 +346,23 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
|
||||
}
|
||||
|
||||
#else /* !CONFIG_NETFILTER */
|
||||
#define NF_HOOK(pf, hook, net, sk, skb, indev, outdev, okfn) (okfn)(net, sk, skb)
|
||||
#define NF_HOOK_COND(pf, hook, net, sk, skb, indev, outdev, okfn, cond) (okfn)(net, sk, skb)
|
||||
static inline int
|
||||
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,
|
||||
struct sock *sk, struct sk_buff *skb,
|
||||
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)
|
||||
extern void (*ip_ct_attach)(struct sk_buff *, const struct sk_buff *) __rcu;
|
||||
void nf_ct_attach(struct sk_buff *, const struct sk_buff *);
|
||||
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;
|
||||
enum ip_conntrack_info;
|
||||
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);
|
||||
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 (*attach_expect)(const struct nlattr *attr, struct nf_conn *ct,
|
||||
u32 portid, u32 report);
|
||||
void (*seq_adjust)(struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo, s32 off);
|
||||
};
|
||||
extern struct nfq_ct_hook __rcu *nfq_ct_hook;
|
||||
#else
|
||||
static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
|
||||
#endif
|
||||
extern struct nfnl_ct_hook __rcu *nfnl_ct_hook;
|
||||
|
||||
/**
|
||||
* nf_skb_duplicated - TEE target has sent a packet
|
||||
|
@ -183,10 +183,6 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls);
|
||||
|
||||
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);
|
||||
bool nf_ct_delete(struct nf_conn *ct, u32 pid, int report);
|
||||
|
||||
|
@ -20,10 +20,20 @@ struct ctnl_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
|
||||
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,
|
||||
if (timeout_ext == NULL)
|
||||
return NULL;
|
||||
|
||||
timeout_ext->timeout = timeout;
|
||||
rcu_assign_pointer(timeout_ext->timeout, timeout);
|
||||
|
||||
return timeout_ext;
|
||||
#else
|
||||
@ -64,10 +74,13 @@ nf_ct_timeout_lookup(struct net *net, struct nf_conn *ct,
|
||||
unsigned int *timeouts;
|
||||
|
||||
timeout_ext = nf_ct_timeout_find(ct);
|
||||
if (timeout_ext)
|
||||
timeouts = NF_CT_TIMEOUT_EXT_DATA(timeout_ext);
|
||||
else
|
||||
if (timeout_ext) {
|
||||
timeouts = nf_ct_timeout_data(timeout_ext);
|
||||
if (unlikely(!timeouts))
|
||||
timeouts = l4proto->get_timeouts(net);
|
||||
} else {
|
||||
timeouts = l4proto->get_timeouts(net);
|
||||
}
|
||||
|
||||
return timeouts;
|
||||
#else
|
||||
|
@ -32,7 +32,7 @@ void nf_register_queue_handler(const struct nf_queue_handler *qh);
|
||||
void nf_unregister_queue_handler(void);
|
||||
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);
|
||||
|
||||
static inline void init_hashrandom(u32 *jhash_initval)
|
||||
|
@ -1,51 +0,0 @@
|
||||
#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 {
|
||||
NFULA_HWTYPE, /* hardware type */
|
||||
NFULA_HWHEADER, /* hardware header */
|
||||
NFULA_HWLEN, /* hardware header length */
|
||||
NFULA_CT, /* nf_conntrack_netlink.h */
|
||||
NFULA_CT_INFO, /* enum ip_conntrack_info */
|
||||
|
||||
__NFULA_MAX
|
||||
};
|
||||
@ -93,5 +95,6 @@ enum nfulnl_attr_config {
|
||||
|
||||
#define NFULNL_CFG_F_SEQ 0x0001
|
||||
#define NFULNL_CFG_F_SEQ_GLOBAL 0x0002
|
||||
#define NFULNL_CFG_F_CONNTRACK 0x0004
|
||||
|
||||
#endif /* _NFNETLINK_LOG_H */
|
||||
|
@ -111,7 +111,6 @@ static inline __be16 pppoe_proto(const struct sk_buff *skb)
|
||||
/* largest possible L2 header, see br_nf_dev_queue_xmit() */
|
||||
#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 {
|
||||
char mac[NF_BRIDGE_MAX_MAC_HEADER_LENGTH];
|
||||
u8 encap_size;
|
||||
@ -121,7 +120,6 @@ struct brnf_frag_data {
|
||||
};
|
||||
|
||||
static DEFINE_PER_CPU(struct brnf_frag_data, brnf_frag_data_storage);
|
||||
#endif
|
||||
|
||||
static void nf_bridge_info_free(struct sk_buff *skb)
|
||||
{
|
||||
@ -666,7 +664,6 @@ static unsigned int br_nf_forward_arp(void *priv,
|
||||
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)
|
||||
{
|
||||
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
|
||||
nf_bridge_info_free(skb);
|
||||
return br_dev_queue_push_xmit(net, sk, skb);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
|
||||
static int
|
||||
br_nf_ip_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
|
||||
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,
|
||||
|
||||
return ip_do_fragment(net, sk, skb, output);
|
||||
}
|
||||
#endif
|
||||
|
||||
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
|
||||
|
||||
nf_bridge = nf_bridge_info_get(skb);
|
||||
|
||||
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
|
||||
/* This is wrong! We should preserve the original fragment
|
||||
* 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;
|
||||
|
||||
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
|
||||
|
||||
return br_nf_ip_fragment(net, sk, skb, br_nf_push_frag_xmit);
|
||||
}
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
|
||||
if (skb->protocol == htons(ETH_P_IPV6)) {
|
||||
if (IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) &&
|
||||
skb->protocol == htons(ETH_P_IPV6)) {
|
||||
const struct nf_ipv6_ops *v6ops = nf_get_ipv6_ops();
|
||||
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
|
||||
kfree_skb(skb);
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
#endif
|
||||
nf_bridge_info_free(skb);
|
||||
return br_dev_queue_push_xmit(net, sk, skb);
|
||||
drop:
|
||||
@ -904,49 +896,42 @@ EXPORT_SYMBOL_GPL(br_netfilter_enable);
|
||||
static struct nf_hook_ops br_nf_ops[] __read_mostly = {
|
||||
{
|
||||
.hook = br_nf_pre_routing,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_BRIDGE,
|
||||
.hooknum = NF_BR_PRE_ROUTING,
|
||||
.priority = NF_BR_PRI_BRNF,
|
||||
},
|
||||
{
|
||||
.hook = br_nf_local_in,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_BRIDGE,
|
||||
.hooknum = NF_BR_LOCAL_IN,
|
||||
.priority = NF_BR_PRI_BRNF,
|
||||
},
|
||||
{
|
||||
.hook = br_nf_forward_ip,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_BRIDGE,
|
||||
.hooknum = NF_BR_FORWARD,
|
||||
.priority = NF_BR_PRI_BRNF - 1,
|
||||
},
|
||||
{
|
||||
.hook = br_nf_forward_arp,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_BRIDGE,
|
||||
.hooknum = NF_BR_FORWARD,
|
||||
.priority = NF_BR_PRI_BRNF,
|
||||
},
|
||||
{
|
||||
.hook = br_nf_post_routing,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_BRIDGE,
|
||||
.hooknum = NF_BR_POST_ROUTING,
|
||||
.priority = NF_BR_PRI_LAST,
|
||||
},
|
||||
{
|
||||
.hook = ip_sabotage_in,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_PRE_ROUTING,
|
||||
.priority = NF_IP_PRI_FIRST,
|
||||
},
|
||||
{
|
||||
.hook = ip_sabotage_in,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_PRE_ROUTING,
|
||||
.priority = NF_IP6_PRI_FIRST,
|
||||
|
@ -73,21 +73,18 @@ ebt_out_hook(void *priv, struct sk_buff *skb,
|
||||
static struct nf_hook_ops ebt_ops_filter[] __read_mostly = {
|
||||
{
|
||||
.hook = ebt_in_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_BRIDGE,
|
||||
.hooknum = NF_BR_LOCAL_IN,
|
||||
.priority = NF_BR_PRI_FILTER_BRIDGED,
|
||||
},
|
||||
{
|
||||
.hook = ebt_in_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_BRIDGE,
|
||||
.hooknum = NF_BR_FORWARD,
|
||||
.priority = NF_BR_PRI_FILTER_BRIDGED,
|
||||
},
|
||||
{
|
||||
.hook = ebt_out_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_BRIDGE,
|
||||
.hooknum = NF_BR_LOCAL_OUT,
|
||||
.priority = NF_BR_PRI_FILTER_OTHER,
|
||||
|
@ -73,21 +73,18 @@ ebt_nat_out(void *priv, struct sk_buff *skb,
|
||||
static struct nf_hook_ops ebt_ops_nat[] __read_mostly = {
|
||||
{
|
||||
.hook = ebt_nat_out,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_BRIDGE,
|
||||
.hooknum = NF_BR_LOCAL_OUT,
|
||||
.priority = NF_BR_PRI_NAT_DST_OTHER,
|
||||
},
|
||||
{
|
||||
.hook = ebt_nat_out,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_BRIDGE,
|
||||
.hooknum = NF_BR_POST_ROUTING,
|
||||
.priority = NF_BR_PRI_NAT_SRC,
|
||||
},
|
||||
{
|
||||
.hook = ebt_nat_in,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_BRIDGE,
|
||||
.hooknum = NF_BR_PRE_ROUTING,
|
||||
.priority = NF_BR_PRI_NAT_DST_BRIDGED,
|
||||
|
@ -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_route *rt;
|
||||
int header_len;
|
||||
#ifdef CONFIG_NETFILTER
|
||||
struct net_device *dev = skb->dev;
|
||||
#endif
|
||||
|
||||
if (skb->pkt_type != PACKET_HOST)
|
||||
goto drop;
|
||||
|
@ -186,7 +186,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
|
||||
if (FWINV(ret != 0, ARPT_INV_VIA_IN)) {
|
||||
dprintf("VIA in mismatch (%s vs %s).%s\n",
|
||||
indev, arpinfo->iniface,
|
||||
arpinfo->invflags&ARPT_INV_VIA_IN ?" (INV)":"");
|
||||
arpinfo->invflags & ARPT_INV_VIA_IN ? " (INV)" : "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -195,7 +195,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
|
||||
if (FWINV(ret != 0, ARPT_INV_VIA_OUT)) {
|
||||
dprintf("VIA out mismatch (%s vs %s).%s\n",
|
||||
outdev, arpinfo->outiface,
|
||||
arpinfo->invflags&ARPT_INV_VIA_OUT ?" (INV)":"");
|
||||
arpinfo->invflags & ARPT_INV_VIA_OUT ? " (INV)" : "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -468,7 +468,7 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
|
||||
pos = newpos;
|
||||
}
|
||||
}
|
||||
next:
|
||||
next:
|
||||
duprintf("Finished chain %u\n", hook);
|
||||
}
|
||||
return 1;
|
||||
@ -632,7 +632,7 @@ static inline void cleanup_entry(struct arpt_entry *e)
|
||||
* newinfo).
|
||||
*/
|
||||
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;
|
||||
unsigned int i;
|
||||
@ -892,7 +892,7 @@ static int compat_table_info(const struct xt_table_info *info,
|
||||
#endif
|
||||
|
||||
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];
|
||||
struct xt_table *t;
|
||||
@ -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,
|
||||
unsigned int len)
|
||||
unsigned int len)
|
||||
{
|
||||
int ret;
|
||||
struct arpt_replace tmp;
|
||||
|
@ -102,7 +102,7 @@ ip_packet_match(const struct iphdr *ip,
|
||||
if (FWINV(ret != 0, IPT_INV_VIA_IN)) {
|
||||
dprintf("VIA in mismatch (%s vs %s).%s\n",
|
||||
indev, ipinfo->iniface,
|
||||
ipinfo->invflags&IPT_INV_VIA_IN ?" (INV)":"");
|
||||
ipinfo->invflags & IPT_INV_VIA_IN ? " (INV)" : "");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ ip_packet_match(const struct iphdr *ip,
|
||||
if (FWINV(ret != 0, IPT_INV_VIA_OUT)) {
|
||||
dprintf("VIA out mismatch (%s vs %s).%s\n",
|
||||
outdev, ipinfo->outiface,
|
||||
ipinfo->invflags&IPT_INV_VIA_OUT ?" (INV)":"");
|
||||
ipinfo->invflags & IPT_INV_VIA_OUT ? " (INV)" : "");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ ip_packet_match(const struct iphdr *ip,
|
||||
FWINV(ip->protocol != ipinfo->proto, IPT_INV_PROTO)) {
|
||||
dprintf("Packet protocol %hi does not match %hi.%s\n",
|
||||
ip->protocol, ipinfo->proto,
|
||||
ipinfo->invflags&IPT_INV_PROTO ? " (INV)":"");
|
||||
ipinfo->invflags & IPT_INV_PROTO ? " (INV)" : "");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -431,8 +431,8 @@ ipt_do_table(struct sk_buff *skb,
|
||||
} while (!acpar.hotdrop);
|
||||
pr_debug("Exiting %s; sp at %u\n", __func__, stackidx);
|
||||
|
||||
xt_write_recseq_end(addend);
|
||||
local_bh_enable();
|
||||
xt_write_recseq_end(addend);
|
||||
local_bh_enable();
|
||||
|
||||
#ifdef DEBUG_ALLOW_ALL
|
||||
return NF_ACCEPT;
|
||||
@ -484,7 +484,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
|
||||
unsigned int oldpos, size;
|
||||
|
||||
if ((strcmp(t->target.u.user.name,
|
||||
XT_STANDARD_TARGET) == 0) &&
|
||||
XT_STANDARD_TARGET) == 0) &&
|
||||
t->verdict < -NF_MAX_VERDICT - 1) {
|
||||
duprintf("mark_source_chains: bad "
|
||||
"negative verdict (%i)\n",
|
||||
@ -549,7 +549,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
|
||||
pos = newpos;
|
||||
}
|
||||
}
|
||||
next:
|
||||
next:
|
||||
duprintf("Finished chain %u\n", hook);
|
||||
}
|
||||
return 1;
|
||||
@ -804,7 +804,7 @@ cleanup_entry(struct ipt_entry *e, struct net *net)
|
||||
newinfo) */
|
||||
static int
|
||||
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;
|
||||
unsigned int i;
|
||||
@ -1078,7 +1078,7 @@ static int compat_table_info(const struct xt_table_info *info,
|
||||
#endif
|
||||
|
||||
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];
|
||||
struct xt_table *t;
|
||||
@ -1304,7 +1304,7 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
|
||||
|
||||
static int
|
||||
do_add_counters(struct net *net, const void __user *user,
|
||||
unsigned int len, int compat)
|
||||
unsigned int len, int compat)
|
||||
{
|
||||
unsigned int i;
|
||||
struct xt_counters_info tmp;
|
||||
|
@ -492,14 +492,14 @@ static void arp_print(struct arp_payload *payload)
|
||||
{
|
||||
#define HBUFFERLEN 30
|
||||
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_lo(payload->src_hw[j]);
|
||||
hbuffer[k++]=':';
|
||||
hbuffer[k++] = ':';
|
||||
}
|
||||
hbuffer[--k]='\0';
|
||||
hbuffer[--k] = '\0';
|
||||
|
||||
pr_debug("src %pI4@%s, dst %pI4\n",
|
||||
&payload->src_ip, hbuffer, &payload->dst_ip);
|
||||
|
@ -231,7 +231,7 @@ synproxy_send_client_ack(const struct synproxy_net *snet,
|
||||
synproxy_build_options(nth, opts);
|
||||
|
||||
synproxy_send_tcp(snet, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY,
|
||||
niph, nth, tcp_hdr_size);
|
||||
niph, nth, tcp_hdr_size);
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -437,14 +437,12 @@ static struct xt_target synproxy_tg4_reg __read_mostly = {
|
||||
static struct nf_hook_ops ipv4_synproxy_ops[] __read_mostly = {
|
||||
{
|
||||
.hook = ipv4_synproxy_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
|
||||
},
|
||||
{
|
||||
.hook = ipv4_synproxy_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.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)
|
||||
bool r;
|
||||
pr_debug("spi_match:%c 0x%x <= 0x%x <= 0x%x\n",
|
||||
invert ? '!' : ' ', min, spi, max);
|
||||
r=(spi >= min && spi <= max) ^ invert;
|
||||
r = (spi >= min && spi <= max) ^ invert;
|
||||
pr_debug(" result %s\n", r ? "PASS" : "FAILED");
|
||||
return r;
|
||||
}
|
||||
|
@ -68,7 +68,6 @@ static struct nf_hook_ops nf_nat_ipv4_ops[] __read_mostly = {
|
||||
/* Before packet filtering, change destination */
|
||||
{
|
||||
.hook = iptable_nat_ipv4_in,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_PRE_ROUTING,
|
||||
.priority = NF_IP_PRI_NAT_DST,
|
||||
@ -76,7 +75,6 @@ static struct nf_hook_ops nf_nat_ipv4_ops[] __read_mostly = {
|
||||
/* After packet filtering, change source */
|
||||
{
|
||||
.hook = iptable_nat_ipv4_out,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP_PRI_NAT_SRC,
|
||||
@ -84,7 +82,6 @@ static struct nf_hook_ops nf_nat_ipv4_ops[] __read_mostly = {
|
||||
/* Before packet filtering, change destination */
|
||||
{
|
||||
.hook = iptable_nat_ipv4_local_fn,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP_PRI_NAT_DST,
|
||||
@ -92,7 +89,6 @@ static struct nf_hook_ops nf_nat_ipv4_ops[] __read_mostly = {
|
||||
/* After packet filtering, change source */
|
||||
{
|
||||
.hook = iptable_nat_ipv4_fn,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP_PRI_NAT_SRC,
|
||||
|
@ -79,7 +79,7 @@ static int __init iptable_security_init(void)
|
||||
int ret;
|
||||
|
||||
ret = register_pernet_subsys(&iptable_security_net_ops);
|
||||
if (ret < 0)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
sectbl_ops = xt_hook_link(&security_table, iptable_security_hook);
|
||||
|
@ -166,42 +166,36 @@ static unsigned int ipv4_conntrack_local(void *priv,
|
||||
static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
|
||||
{
|
||||
.hook = ipv4_conntrack_in,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_PRE_ROUTING,
|
||||
.priority = NF_IP_PRI_CONNTRACK,
|
||||
},
|
||||
{
|
||||
.hook = ipv4_conntrack_local,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP_PRI_CONNTRACK,
|
||||
},
|
||||
{
|
||||
.hook = ipv4_helper,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP_PRI_CONNTRACK_HELPER,
|
||||
},
|
||||
{
|
||||
.hook = ipv4_confirm,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP_PRI_CONNTRACK_CONFIRM,
|
||||
},
|
||||
{
|
||||
.hook = ipv4_helper,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP_PRI_CONNTRACK_HELPER,
|
||||
},
|
||||
{
|
||||
.hook = ipv4_confirm,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP_PRI_CONNTRACK_CONFIRM,
|
||||
|
@ -95,14 +95,12 @@ static unsigned int ipv4_conntrack_defrag(void *priv,
|
||||
static struct nf_hook_ops ipv4_defrag_ops[] = {
|
||||
{
|
||||
.hook = ipv4_conntrack_defrag,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_PRE_ROUTING,
|
||||
.priority = NF_IP_PRI_CONNTRACK_DEFRAG,
|
||||
},
|
||||
{
|
||||
.hook = ipv4_conntrack_defrag,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP_PRI_CONNTRACK_DEFRAG,
|
||||
|
@ -1156,7 +1156,7 @@ static int snmp_parse_mangle(unsigned char *msg,
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -117,7 +117,7 @@ ip6_packet_match(const struct sk_buff *skb,
|
||||
if (FWINV(ret != 0, IP6T_INV_VIA_IN)) {
|
||||
dprintf("VIA in mismatch (%s vs %s).%s\n",
|
||||
indev, ip6info->iniface,
|
||||
ip6info->invflags&IP6T_INV_VIA_IN ?" (INV)":"");
|
||||
ip6info->invflags & IP6T_INV_VIA_IN ? " (INV)" : "");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -126,14 +126,14 @@ ip6_packet_match(const struct sk_buff *skb,
|
||||
if (FWINV(ret != 0, IP6T_INV_VIA_OUT)) {
|
||||
dprintf("VIA out mismatch (%s vs %s).%s\n",
|
||||
outdev, ip6info->outiface,
|
||||
ip6info->invflags&IP6T_INV_VIA_OUT ?" (INV)":"");
|
||||
ip6info->invflags & IP6T_INV_VIA_OUT ? " (INV)" : "");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ... might want to do something with class and flowlabel here ... */
|
||||
|
||||
/* look for the desired protocol header */
|
||||
if((ip6info->flags & IP6T_F_PROTO)) {
|
||||
if (ip6info->flags & IP6T_F_PROTO) {
|
||||
int protohdr;
|
||||
unsigned short _frag_off;
|
||||
|
||||
@ -151,9 +151,9 @@ ip6_packet_match(const struct sk_buff *skb,
|
||||
ip6info->proto);
|
||||
|
||||
if (ip6info->proto == protohdr) {
|
||||
if(ip6info->invflags & IP6T_INV_PROTO) {
|
||||
if (ip6info->invflags & IP6T_INV_PROTO)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -443,8 +443,8 @@ ip6t_do_table(struct sk_buff *skb,
|
||||
break;
|
||||
} while (!acpar.hotdrop);
|
||||
|
||||
xt_write_recseq_end(addend);
|
||||
local_bh_enable();
|
||||
xt_write_recseq_end(addend);
|
||||
local_bh_enable();
|
||||
|
||||
#ifdef DEBUG_ALLOW_ALL
|
||||
return NF_ACCEPT;
|
||||
@ -561,7 +561,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
|
||||
pos = newpos;
|
||||
}
|
||||
}
|
||||
next:
|
||||
next:
|
||||
duprintf("Finished chain %u\n", hook);
|
||||
}
|
||||
return 1;
|
||||
@ -816,7 +816,7 @@ static void cleanup_entry(struct ip6t_entry *e, struct net *net)
|
||||
newinfo) */
|
||||
static int
|
||||
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;
|
||||
unsigned int i;
|
||||
@ -1090,7 +1090,7 @@ static int compat_table_info(const struct xt_table_info *info,
|
||||
#endif
|
||||
|
||||
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];
|
||||
struct xt_table *t;
|
||||
@ -1152,7 +1152,7 @@ static int get_info(struct net *net, void __user *user,
|
||||
|
||||
static int
|
||||
get_entries(struct net *net, struct ip6t_get_entries __user *uptr,
|
||||
const int *len)
|
||||
const int *len)
|
||||
{
|
||||
int ret;
|
||||
struct ip6t_get_entries get;
|
||||
|
@ -244,7 +244,7 @@ synproxy_send_client_ack(const struct synproxy_net *snet,
|
||||
synproxy_build_options(nth, opts);
|
||||
|
||||
synproxy_send_tcp(snet, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY,
|
||||
niph, nth, tcp_hdr_size);
|
||||
niph, nth, tcp_hdr_size);
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -458,14 +458,12 @@ static struct xt_target synproxy_tg6_reg __read_mostly = {
|
||||
static struct nf_hook_ops ipv6_synproxy_ops[] __read_mostly = {
|
||||
{
|
||||
.hook = ipv6_synproxy_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
|
||||
},
|
||||
{
|
||||
.hook = ipv6_synproxy_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
|
||||
|
@ -70,7 +70,6 @@ static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = {
|
||||
/* Before packet filtering, change destination */
|
||||
{
|
||||
.hook = ip6table_nat_in,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_PRE_ROUTING,
|
||||
.priority = NF_IP6_PRI_NAT_DST,
|
||||
@ -78,7 +77,6 @@ static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = {
|
||||
/* After packet filtering, change source */
|
||||
{
|
||||
.hook = ip6table_nat_out,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP6_PRI_NAT_SRC,
|
||||
@ -86,7 +84,6 @@ static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = {
|
||||
/* Before packet filtering, change destination */
|
||||
{
|
||||
.hook = ip6table_nat_local_fn,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP6_PRI_NAT_DST,
|
||||
@ -94,7 +91,6 @@ static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = {
|
||||
/* After packet filtering, change source */
|
||||
{
|
||||
.hook = ip6table_nat_fn,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP6_PRI_NAT_SRC,
|
||||
|
@ -187,42 +187,36 @@ static unsigned int ipv6_conntrack_local(void *priv,
|
||||
static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
|
||||
{
|
||||
.hook = ipv6_conntrack_in,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_PRE_ROUTING,
|
||||
.priority = NF_IP6_PRI_CONNTRACK,
|
||||
},
|
||||
{
|
||||
.hook = ipv6_conntrack_local,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP6_PRI_CONNTRACK,
|
||||
},
|
||||
{
|
||||
.hook = ipv6_helper,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP6_PRI_CONNTRACK_HELPER,
|
||||
},
|
||||
{
|
||||
.hook = ipv6_confirm,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP6_PRI_LAST,
|
||||
},
|
||||
{
|
||||
.hook = ipv6_helper,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP6_PRI_CONNTRACK_HELPER,
|
||||
},
|
||||
{
|
||||
.hook = ipv6_confirm,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP6_PRI_LAST-1,
|
||||
|
@ -57,12 +57,12 @@ static const u_int8_t invmap[] = {
|
||||
[ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1,
|
||||
[ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 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[] = {
|
||||
[ICMPV6_MGM_QUERY - 130] = 1,
|
||||
[ICMPV6_MGM_REPORT -130] = 1,
|
||||
[ICMPV6_MGM_REPORT - 130] = 1,
|
||||
[ICMPV6_MGM_REDUCTION - 130] = 1,
|
||||
[NDISC_ROUTER_SOLICITATION - 130] = 1,
|
||||
[NDISC_ROUTER_ADVERTISEMENT - 130] = 1,
|
||||
|
@ -59,7 +59,7 @@ struct nf_ct_frag6_skb_cb
|
||||
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;
|
||||
|
||||
@ -445,7 +445,7 @@ nf_ct_frag6_reasm(struct frag_queue *fq, struct net_device *dev)
|
||||
skb_reset_transport_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->len += fp->len;
|
||||
if (head->ip_summed != fp->ip_summed)
|
||||
|
@ -85,14 +85,12 @@ static unsigned int ipv6_defrag(void *priv,
|
||||
static struct nf_hook_ops ipv6_defrag_ops[] = {
|
||||
{
|
||||
.hook = ipv6_defrag,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_PRE_ROUTING,
|
||||
.priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
|
||||
},
|
||||
{
|
||||
.hook = ipv6_defrag,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
|
||||
|
@ -26,7 +26,7 @@ const struct tcphdr *nf_reject_ip6_tcphdr_get(struct sk_buff *oldskb,
|
||||
int tcphoff;
|
||||
|
||||
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);
|
||||
|
||||
if ((tcphoff < 0) || (tcphoff > oldskb->len)) {
|
||||
@ -224,7 +224,7 @@ static bool reject6_csum_ok(struct sk_buff *skb, int hook)
|
||||
return true;
|
||||
|
||||
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)
|
||||
return false;
|
||||
|
@ -61,11 +61,11 @@ static const struct nf_chain_type nft_chain_route_ipv6 = {
|
||||
.name = "route",
|
||||
.type = NFT_CHAIN_T_ROUTE,
|
||||
.family = NFPROTO_IPV6,
|
||||
.owner = THIS_MODULE,
|
||||
.owner = THIS_MODULE,
|
||||
.hook_mask = (1 << NF_INET_LOCAL_OUT),
|
||||
.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)
|
||||
|
@ -354,7 +354,7 @@ config NF_CT_NETLINK_HELPER
|
||||
select NETFILTER_NETLINK
|
||||
depends on NF_CT_NETLINK
|
||||
depends on NETFILTER_NETLINK_QUEUE
|
||||
depends on NETFILTER_NETLINK_QUEUE_CT
|
||||
depends on NETFILTER_NETLINK_GLUE_CT
|
||||
depends on NETFILTER_ADVANCED
|
||||
help
|
||||
This option enables the user-space connection tracking helpers
|
||||
@ -362,13 +362,14 @@ config NF_CT_NETLINK_HELPER
|
||||
|
||||
If unsure, say `N'.
|
||||
|
||||
config NETFILTER_NETLINK_QUEUE_CT
|
||||
bool "NFQUEUE integration with Connection Tracking"
|
||||
default n
|
||||
depends on NETFILTER_NETLINK_QUEUE
|
||||
config NETFILTER_NETLINK_GLUE_CT
|
||||
bool "NFQUEUE and NFLOG integration with Connection Tracking"
|
||||
default n
|
||||
depends on (NETFILTER_NETLINK_QUEUE || NETFILTER_NETLINK_LOG) && NF_CT_NETLINK
|
||||
help
|
||||
If this option is enabled, NFQUEUE can include Connection Tracking
|
||||
information together with the packet is the enqueued via NFNETLINK.
|
||||
If this option is enabled, NFQUEUE and NFLOG can include
|
||||
Connection Tracking information together with the packet is
|
||||
the enqueued via NFNETLINK.
|
||||
|
||||
config NF_NAT
|
||||
tristate
|
||||
|
@ -10,8 +10,6 @@ obj-$(CONFIG_NETFILTER) = netfilter.o
|
||||
|
||||
obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.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_LOG) += nfnetlink_log.o
|
||||
|
||||
|
@ -313,8 +313,6 @@ next_hook:
|
||||
int err = nf_queue(skb, elem, state,
|
||||
verdict >> NF_VERDICT_QBITS);
|
||||
if (err < 0) {
|
||||
if (err == -ECANCELED)
|
||||
goto next_hook;
|
||||
if (err == -ESRCH &&
|
||||
(verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
|
||||
goto next_hook;
|
||||
@ -348,6 +346,12 @@ int skb_make_writable(struct sk_buff *skb, unsigned int writable_len)
|
||||
}
|
||||
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)
|
||||
/* 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
|
||||
@ -385,9 +389,6 @@ void nf_conntrack_destroy(struct nf_conntrack *nfct)
|
||||
}
|
||||
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. */
|
||||
const struct nf_conntrack_zone nf_ct_zone_dflt = {
|
||||
.id = NF_CT_DEFAULT_ZONE_ID,
|
||||
|
@ -1347,23 +1347,20 @@ flush_again:
|
||||
*/
|
||||
int __net_init ip_vs_conn_net_init(struct netns_ipvs *ipvs)
|
||||
{
|
||||
struct net *net = ipvs->net;
|
||||
|
||||
atomic_set(&ipvs->conn_count, 0);
|
||||
|
||||
proc_create("ip_vs_conn", 0, 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", 0, ipvs->net->proc_net, &ip_vs_conn_fops);
|
||||
proc_create("ip_vs_conn_sync", 0, ipvs->net->proc_net,
|
||||
&ip_vs_conn_sync_fops);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __net_exit ip_vs_conn_net_cleanup(struct netns_ipvs *ipvs)
|
||||
{
|
||||
struct net *net = ipvs->net;
|
||||
|
||||
/* flush all the connection entries first */
|
||||
ip_vs_conn_flush(ipvs);
|
||||
remove_proc_entry("ip_vs_conn", net->proc_net);
|
||||
remove_proc_entry("ip_vs_conn_sync", net->proc_net);
|
||||
remove_proc_entry("ip_vs_conn", ipvs->net->proc_net);
|
||||
remove_proc_entry("ip_vs_conn_sync", ipvs->net->proc_net);
|
||||
}
|
||||
|
||||
int __init ip_vs_conn_init(void)
|
||||
|
@ -547,7 +547,6 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
|
||||
return cp;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static inline int ip_vs_addr_is_unicast(struct net *net, int af,
|
||||
union nf_inet_addr *addr)
|
||||
{
|
||||
@ -557,7 +556,6 @@ static inline int ip_vs_addr_is_unicast(struct net *net, int af,
|
||||
#endif
|
||||
return (inet_addr_type(net, addr->ip) == RTN_UNICAST);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Pass or drop the packet.
|
||||
@ -1174,7 +1172,6 @@ drop:
|
||||
static unsigned int
|
||||
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_protocol *pp;
|
||||
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
|
||||
#ifdef CONFIG_IP_VS_IPV6
|
||||
if (af == AF_INET6) {
|
||||
if (!skb->dev)
|
||||
skb->dev = net->loopback_dev;
|
||||
skb->dev = ipvs->net->loopback_dev;
|
||||
icmpv6_send(skb,
|
||||
ICMPV6_DEST_UNREACH,
|
||||
ICMPV6_PORT_UNREACH,
|
||||
@ -1926,7 +1923,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
||||
/* After packet filtering, change source only for VS/NAT */
|
||||
{
|
||||
.hook = ip_vs_reply4,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP_PRI_NAT_SRC - 2,
|
||||
@ -1936,7 +1932,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
||||
* applied to IPVS. */
|
||||
{
|
||||
.hook = ip_vs_remote_request4,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP_PRI_NAT_SRC - 1,
|
||||
@ -1944,7 +1939,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
||||
/* Before ip_vs_in, change source only for VS/NAT */
|
||||
{
|
||||
.hook = ip_vs_local_reply4,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP_PRI_NAT_DST + 1,
|
||||
@ -1952,7 +1946,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
||||
/* After mangle, schedule and forward local requests */
|
||||
{
|
||||
.hook = ip_vs_local_request4,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP_PRI_NAT_DST + 2,
|
||||
@ -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 */
|
||||
{
|
||||
.hook = ip_vs_forward_icmp,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_FORWARD,
|
||||
.priority = 99,
|
||||
@ -1969,7 +1961,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
||||
/* After packet filtering, change source only for VS/NAT */
|
||||
{
|
||||
.hook = ip_vs_reply4,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_FORWARD,
|
||||
.priority = 100,
|
||||
@ -1978,7 +1969,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
||||
/* After packet filtering, change source only for VS/NAT */
|
||||
{
|
||||
.hook = ip_vs_reply6,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP6_PRI_NAT_SRC - 2,
|
||||
@ -1988,7 +1978,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
||||
* applied to IPVS. */
|
||||
{
|
||||
.hook = ip_vs_remote_request6,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP6_PRI_NAT_SRC - 1,
|
||||
@ -1996,7 +1985,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
||||
/* Before ip_vs_in, change source only for VS/NAT */
|
||||
{
|
||||
.hook = ip_vs_local_reply6,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP6_PRI_NAT_DST + 1,
|
||||
@ -2004,7 +1992,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
||||
/* After mangle, schedule and forward local requests */
|
||||
{
|
||||
.hook = ip_vs_local_request6,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP6_PRI_NAT_DST + 2,
|
||||
@ -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 */
|
||||
{
|
||||
.hook = ip_vs_forward_icmp_v6,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_FORWARD,
|
||||
.priority = 99,
|
||||
@ -2021,7 +2007,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
|
||||
/* After packet filtering, change source only for VS/NAT */
|
||||
{
|
||||
.hook = ip_vs_reply6,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_FORWARD,
|
||||
.priority = 100,
|
||||
|
@ -940,10 +940,13 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
|
||||
}
|
||||
|
||||
timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL;
|
||||
if (timeout_ext)
|
||||
timeouts = NF_CT_TIMEOUT_EXT_DATA(timeout_ext);
|
||||
else
|
||||
if (timeout_ext) {
|
||||
timeouts = nf_ct_timeout_data(timeout_ext);
|
||||
if (unlikely(!timeouts))
|
||||
timeouts = l4proto->get_timeouts(net);
|
||||
} else {
|
||||
timeouts = l4proto->get_timeouts(net);
|
||||
}
|
||||
|
||||
if (!l4proto->new(ct, skb, dataoff, timeouts)) {
|
||||
nf_conntrack_free(ct);
|
||||
@ -952,7 +955,8 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
|
||||
}
|
||||
|
||||
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_tstamp_ext_add(ct, GFP_ATOMIC);
|
||||
|
@ -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 *mask);
|
||||
|
||||
#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT
|
||||
#ifdef CONFIG_NETFILTER_NETLINK_GLUE_CT
|
||||
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 */
|
||||
+ 3 * nla_total_size(0) /* CTA_TUPLE_IP */
|
||||
@ -2162,8 +2162,19 @@ ctnetlink_nfqueue_build_size(const struct nf_conn *ct)
|
||||
;
|
||||
}
|
||||
|
||||
static int
|
||||
ctnetlink_nfqueue_build(struct sk_buff *skb, struct nf_conn *ct)
|
||||
static struct nf_conn *ctnetlink_glue_get_ct(const struct sk_buff *skb,
|
||||
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;
|
||||
struct nlattr *nest_parms;
|
||||
@ -2236,7 +2247,32 @@ nla_put_failure:
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@ -2276,7 +2312,7 @@ ctnetlink_nfqueue_parse_ct(const struct nlattr *cda[], struct nf_conn *ct)
|
||||
}
|
||||
|
||||
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];
|
||||
int ret;
|
||||
@ -2286,16 +2322,16 @@ ctnetlink_nfqueue_parse(const struct nlattr *attr, struct nf_conn *ct)
|
||||
return ret;
|
||||
|
||||
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);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ctnetlink_nfqueue_exp_parse(const struct nlattr * const *cda,
|
||||
const struct nf_conn *ct,
|
||||
struct nf_conntrack_tuple *tuple,
|
||||
struct nf_conntrack_tuple *mask)
|
||||
static int ctnetlink_glue_exp_parse(const struct nlattr * const *cda,
|
||||
const struct nf_conn *ct,
|
||||
struct nf_conntrack_tuple *tuple,
|
||||
struct nf_conntrack_tuple *mask)
|
||||
{
|
||||
int err;
|
||||
|
||||
@ -2309,8 +2345,8 @@ static int ctnetlink_nfqueue_exp_parse(const struct nlattr * const *cda,
|
||||
}
|
||||
|
||||
static int
|
||||
ctnetlink_nfqueue_attach_expect(const struct nlattr *attr, struct nf_conn *ct,
|
||||
u32 portid, u32 report)
|
||||
ctnetlink_glue_attach_expect(const struct nlattr *attr, struct nf_conn *ct,
|
||||
u32 portid, u32 report)
|
||||
{
|
||||
struct nlattr *cda[CTA_EXPECT_MAX+1];
|
||||
struct nf_conntrack_tuple tuple, mask;
|
||||
@ -2322,8 +2358,8 @@ ctnetlink_nfqueue_attach_expect(const struct nlattr *attr, struct nf_conn *ct,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = ctnetlink_nfqueue_exp_parse((const struct nlattr * const *)cda,
|
||||
ct, &tuple, &mask);
|
||||
err = ctnetlink_glue_exp_parse((const struct nlattr * const *)cda,
|
||||
ct, &tuple, &mask);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@ -2350,14 +2386,24 @@ ctnetlink_nfqueue_attach_expect(const struct nlattr *attr, struct nf_conn *ct,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct nfq_ct_hook ctnetlink_nfqueue_hook = {
|
||||
.build_size = ctnetlink_nfqueue_build_size,
|
||||
.build = ctnetlink_nfqueue_build,
|
||||
.parse = ctnetlink_nfqueue_parse,
|
||||
.attach_expect = ctnetlink_nfqueue_attach_expect,
|
||||
.seq_adjust = nf_ct_tcp_seqadj_set,
|
||||
static void ctnetlink_glue_seqadj(struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo, int diff)
|
||||
{
|
||||
if (!(ct->status & IPS_NAT_MASK))
|
||||
return;
|
||||
|
||||
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
|
||||
@ -3341,9 +3387,9 @@ static int __init ctnetlink_init(void)
|
||||
pr_err("ctnetlink_init: cannot register pernet operations\n");
|
||||
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. */
|
||||
RCU_INIT_POINTER(nfq_ct_hook, &ctnetlink_nfqueue_hook);
|
||||
RCU_INIT_POINTER(nfnl_ct_hook, &ctnetlink_glue_hook);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
@ -3362,8 +3408,8 @@ static void __exit ctnetlink_exit(void)
|
||||
unregister_pernet_subsys(&ctnetlink_net_ops);
|
||||
nfnetlink_subsys_unregister(&ctnl_exp_subsys);
|
||||
nfnetlink_subsys_unregister(&ctnl_subsys);
|
||||
#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT
|
||||
RCU_INIT_POINTER(nfq_ct_hook, NULL);
|
||||
#ifdef CONFIG_NETFILTER_NETLINK_GLUE_CT
|
||||
RCU_INIT_POINTER(nfnl_ct_hook, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -69,19 +69,14 @@ void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
|
||||
dev_put(physdev);
|
||||
}
|
||||
#endif
|
||||
/* Drop reference to owner of hook which queued us. */
|
||||
module_put(entry->elem->owner);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs);
|
||||
|
||||
/* 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;
|
||||
|
||||
if (!try_module_get(entry->elem->owner))
|
||||
return false;
|
||||
|
||||
if (state->in)
|
||||
dev_hold(state->in);
|
||||
if (state->out)
|
||||
@ -100,8 +95,6 @@ bool nf_queue_entry_get_refs(struct nf_queue_entry *entry)
|
||||
dev_hold(physdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_queue_entry_get_refs);
|
||||
|
||||
@ -131,22 +124,20 @@ int nf_queue(struct sk_buff *skb,
|
||||
const struct nf_queue_handler *qh;
|
||||
|
||||
/* QUEUE == DROP if no one is waiting, to be safe. */
|
||||
rcu_read_lock();
|
||||
|
||||
qh = rcu_dereference(queue_handler);
|
||||
if (!qh) {
|
||||
status = -ESRCH;
|
||||
goto err_unlock;
|
||||
goto err;
|
||||
}
|
||||
|
||||
afinfo = nf_get_afinfo(state->pf);
|
||||
if (!afinfo)
|
||||
goto err_unlock;
|
||||
goto err;
|
||||
|
||||
entry = kmalloc(sizeof(*entry) + afinfo->route_key_size, GFP_ATOMIC);
|
||||
if (!entry) {
|
||||
status = -ENOMEM;
|
||||
goto err_unlock;
|
||||
goto err;
|
||||
}
|
||||
|
||||
*entry = (struct nf_queue_entry) {
|
||||
@ -156,16 +147,11 @@ int nf_queue(struct sk_buff *skb,
|
||||
.size = sizeof(*entry) + afinfo->route_key_size,
|
||||
};
|
||||
|
||||
if (!nf_queue_entry_get_refs(entry)) {
|
||||
status = -ECANCELED;
|
||||
goto err_unlock;
|
||||
}
|
||||
nf_queue_entry_get_refs(entry);
|
||||
skb_dst_force(skb);
|
||||
afinfo->saveroute(skb, entry);
|
||||
status = qh->outfn(entry, queuenum);
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
if (status < 0) {
|
||||
nf_queue_entry_release_refs(entry);
|
||||
goto err;
|
||||
@ -173,8 +159,6 @@ int nf_queue(struct sk_buff *skb,
|
||||
|
||||
return 0;
|
||||
|
||||
err_unlock:
|
||||
rcu_read_unlock();
|
||||
err:
|
||||
kfree(entry);
|
||||
return status;
|
||||
@ -187,15 +171,11 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
|
||||
const struct nf_afinfo *afinfo;
|
||||
int err;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
nf_queue_entry_release_refs(entry);
|
||||
|
||||
/* Continue traversal iff userspace said ok... */
|
||||
if (verdict == NF_REPEAT) {
|
||||
elem = list_entry(elem->list.prev, struct nf_hook_ops, list);
|
||||
verdict = NF_ACCEPT;
|
||||
}
|
||||
if (verdict == NF_REPEAT)
|
||||
verdict = elem->hook(elem->priv, skb, &entry->state);
|
||||
|
||||
if (verdict == NF_ACCEPT) {
|
||||
afinfo = nf_get_afinfo(entry->state.pf);
|
||||
@ -222,8 +202,6 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
|
||||
err = nf_queue(skb, elem, &entry->state,
|
||||
verdict >> NF_VERDICT_QBITS);
|
||||
if (err < 0) {
|
||||
if (err == -ECANCELED)
|
||||
goto next_hook;
|
||||
if (err == -ESRCH &&
|
||||
(verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
|
||||
goto next_hook;
|
||||
@ -235,7 +213,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
|
||||
default:
|
||||
kfree_skb(skb);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
kfree(entry);
|
||||
}
|
||||
EXPORT_SYMBOL(nf_reinject);
|
||||
|
@ -1433,7 +1433,6 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
|
||||
for (i = 0; i < afi->nops; i++) {
|
||||
ops = &basechain->ops[i];
|
||||
ops->pf = family;
|
||||
ops->owner = afi->owner;
|
||||
ops->hooknum = hooknum;
|
||||
ops->priority = priority;
|
||||
ops->priv = chain;
|
||||
|
@ -291,6 +291,34 @@ cttimeout_get_timeout(struct sock *ctnl, struct sk_buff *skb,
|
||||
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. */
|
||||
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. */
|
||||
list_del_rcu(&timeout->head);
|
||||
nf_ct_l4proto_put(timeout->l4proto);
|
||||
ctnl_untimeout(timeout);
|
||||
kfree_rcu(timeout, rcu_head);
|
||||
} else {
|
||||
/* still in use, restore reference counter. */
|
||||
@ -567,6 +596,10 @@ static void __exit cttimeout_exit(void)
|
||||
pr_info("cttimeout: unregistering from nfnetlink.\n");
|
||||
|
||||
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_del_rcu(&cur->head);
|
||||
/* We are sure that our objects have no clients at this point,
|
||||
@ -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_put_hook, NULL);
|
||||
#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
|
||||
rcu_barrier();
|
||||
}
|
||||
|
||||
module_init(cttimeout_init);
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <net/netlink.h>
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netfilter/nfnetlink_log.h>
|
||||
#include <linux/netfilter/nf_conntrack_common.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/proc_fs.h>
|
||||
@ -401,7 +402,9 @@ __build_packet_message(struct nfnl_log_net *log,
|
||||
unsigned int hooknum,
|
||||
const struct net_device *indev,
|
||||
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 nlmsghdr *nlh;
|
||||
@ -575,6 +578,10 @@ __build_packet_message(struct nfnl_log_net *log,
|
||||
htonl(atomic_inc_return(&log->global_seq))))
|
||||
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) {
|
||||
struct nlattr *nla;
|
||||
int size = nla_attr_size(data_len);
|
||||
@ -620,12 +627,16 @@ nfulnl_log_packet(struct net *net,
|
||||
const struct nf_loginfo *li_user,
|
||||
const char *prefix)
|
||||
{
|
||||
unsigned int size, data_len;
|
||||
size_t size;
|
||||
unsigned int data_len;
|
||||
struct nfulnl_instance *inst;
|
||||
const struct nf_loginfo *li;
|
||||
unsigned int qthreshold;
|
||||
unsigned int plen;
|
||||
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)
|
||||
li = li_user;
|
||||
@ -671,6 +682,14 @@ nfulnl_log_packet(struct net *net,
|
||||
size += nla_total_size(sizeof(u_int32_t));
|
||||
if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL)
|
||||
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;
|
||||
/* per-rule qthreshold overrides per-instance */
|
||||
@ -715,7 +734,8 @@ nfulnl_log_packet(struct net *net,
|
||||
inst->qlen++;
|
||||
|
||||
__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)
|
||||
__nfulnl_flush(inst);
|
||||
@ -805,6 +825,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
||||
struct net *net = sock_net(ctnl);
|
||||
struct nfnl_log_net *log = nfnl_log_pernet(net);
|
||||
int ret = 0;
|
||||
u16 flags;
|
||||
|
||||
if (nfula[NFULA_CFG_CMD]) {
|
||||
u_int8_t pf = nfmsg->nfgen_family;
|
||||
@ -826,6 +847,28 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
||||
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) {
|
||||
switch (cmd->command) {
|
||||
case NFULNL_CFG_CMD_BIND:
|
||||
@ -854,16 +897,15 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
||||
ret = -ENOTSUPP;
|
||||
break;
|
||||
}
|
||||
} else if (!inst) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nfula[NFULA_CFG_MODE]) {
|
||||
struct nfulnl_msg_config_mode *params;
|
||||
params = nla_data(nfula[NFULA_CFG_MODE]);
|
||||
struct nfulnl_msg_config_mode *params =
|
||||
nla_data(nfula[NFULA_CFG_MODE]);
|
||||
|
||||
if (!inst) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
nfulnl_set_mode(inst, params->copy_mode,
|
||||
ntohl(params->copy_range));
|
||||
}
|
||||
@ -871,42 +913,23 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
||||
if (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));
|
||||
}
|
||||
|
||||
if (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));
|
||||
}
|
||||
|
||||
if (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));
|
||||
}
|
||||
|
||||
if (nfula[NFULA_CFG_FLAGS]) {
|
||||
__be16 flags = nla_get_be16(nfula[NFULA_CFG_FLAGS]);
|
||||
|
||||
if (!inst) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
nfulnl_set_flags(inst, ntohs(flags));
|
||||
}
|
||||
if (nfula[NFULA_CFG_FLAGS])
|
||||
nfulnl_set_flags(inst, flags);
|
||||
|
||||
out_put:
|
||||
instance_put(inst);
|
||||
|
@ -28,12 +28,12 @@
|
||||
#include <linux/netfilter_bridge.h>
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netfilter/nfnetlink_queue.h>
|
||||
#include <linux/netfilter/nf_conntrack_common.h>
|
||||
#include <linux/list.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/tcp_states.h>
|
||||
#include <net/netfilter/nf_queue.h>
|
||||
#include <net/netns/generic.h>
|
||||
#include <net/netfilter/nfnetlink_queue.h>
|
||||
|
||||
#include <linux/atomic.h>
|
||||
|
||||
@ -313,6 +313,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
|
||||
struct net_device *outdev;
|
||||
struct nf_conn *ct = NULL;
|
||||
enum ip_conntrack_info uninitialized_var(ctinfo);
|
||||
struct nfnl_ct_hook *nfnl_ct;
|
||||
bool csum_verify;
|
||||
char *secdata = NULL;
|
||||
u32 seclen = 0;
|
||||
@ -364,8 +365,14 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
|
||||
break;
|
||||
}
|
||||
|
||||
if (queue->flags & NFQA_CFG_F_CONNTRACK)
|
||||
ct = nfqnl_ct_get(entskb, &size, &ctinfo);
|
||||
if (queue->flags & NFQA_CFG_F_CONNTRACK) {
|
||||
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) {
|
||||
size += (nla_total_size(sizeof(u_int32_t)) /* uid */
|
||||
@ -493,9 +500,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
|
||||
|
||||
if (entskb->tstamp.tv64) {
|
||||
struct nfqnl_msg_packet_timestamp ts;
|
||||
struct timeval tv = ktime_to_timeval(entskb->tstamp);
|
||||
ts.sec = cpu_to_be64(tv.tv_sec);
|
||||
ts.usec = cpu_to_be64(tv.tv_usec);
|
||||
struct timespec64 kts = ktime_to_timespec64(skb->tstamp);
|
||||
|
||||
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))
|
||||
goto nla_put_failure;
|
||||
@ -508,7 +516,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
|
||||
if (seclen && nla_put(skb, NFQA_SECCTX, seclen, secdata))
|
||||
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;
|
||||
|
||||
if (cap_len > data_len &&
|
||||
@ -598,12 +606,9 @@ static struct nf_queue_entry *
|
||||
nf_queue_entry_dup(struct nf_queue_entry *e)
|
||||
{
|
||||
struct nf_queue_entry *entry = kmemdup(e, e->size, GFP_ATOMIC);
|
||||
if (entry) {
|
||||
if (nf_queue_entry_get_refs(entry))
|
||||
return entry;
|
||||
kfree(entry);
|
||||
}
|
||||
return NULL;
|
||||
if (entry)
|
||||
nf_queue_entry_get_refs(entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
|
||||
@ -698,7 +703,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
|
||||
nf_bridge_adjust_skb_data(skb);
|
||||
segs = skb_gso_segment(skb, 0);
|
||||
/* 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'.
|
||||
*/
|
||||
if (IS_ERR_OR_NULL(segs))
|
||||
@ -1001,6 +1006,28 @@ nfqnl_recv_verdict_batch(struct sock *ctnl, struct sk_buff *skb,
|
||||
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
|
||||
nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
|
||||
const struct nlmsghdr *nlh,
|
||||
@ -1014,6 +1041,7 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
|
||||
unsigned int verdict;
|
||||
struct nf_queue_entry *entry;
|
||||
enum ip_conntrack_info uninitialized_var(ctinfo);
|
||||
struct nfnl_ct_hook *nfnl_ct;
|
||||
struct nf_conn *ct = NULL;
|
||||
|
||||
struct net *net = sock_net(ctnl);
|
||||
@ -1037,12 +1065,10 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
|
||||
return -ENOENT;
|
||||
|
||||
if (nfqa[NFQA_CT]) {
|
||||
ct = nfqnl_ct_parse(entry->skb, nfqa[NFQA_CT], &ctinfo);
|
||||
if (ct && nfqa[NFQA_EXP]) {
|
||||
nfqnl_attach_expect(ct, nfqa[NFQA_EXP],
|
||||
NETLINK_CB(skb).portid,
|
||||
nlmsg_report(nlh));
|
||||
}
|
||||
/* rcu lock already held from nfnl->call_rcu. */
|
||||
nfnl_ct = rcu_dereference(nfnl_ct_hook);
|
||||
if (nfnl_ct != NULL)
|
||||
ct = nfqnl_ct_parse(nfnl_ct, nlh, nfqa, entry, &ctinfo);
|
||||
}
|
||||
|
||||
if (nfqa[NFQA_PAYLOAD]) {
|
||||
@ -1053,8 +1079,8 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
|
||||
payload_len, entry, diff) < 0)
|
||||
verdict = NF_DROP;
|
||||
|
||||
if (ct)
|
||||
nfqnl_ct_seq_adjust(entry->skb, ct, ctinfo, diff);
|
||||
if (ct && diff)
|
||||
nfnl_ct->seq_adjust(entry->skb, ct, ctinfo, diff);
|
||||
}
|
||||
|
||||
if (nfqa[NFQA_MARK])
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* (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)
|
||||
if (!(hook_mask & 1))
|
||||
continue;
|
||||
ops[i].hook = fn;
|
||||
ops[i].owner = table->me;
|
||||
ops[i].pf = table->af;
|
||||
ops[i].hooknum = hooknum;
|
||||
ops[i].priority = table->priority;
|
||||
|
@ -171,6 +171,9 @@ xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par,
|
||||
if (timeout_ext == NULL)
|
||||
ret = -ENOMEM;
|
||||
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
|
||||
err_put_timeout:
|
||||
__xt_ct_tg_timeout_put(timeout);
|
||||
out:
|
||||
@ -318,8 +321,10 @@ static void xt_ct_destroy_timeout(struct nf_conn *ct)
|
||||
|
||||
if (timeout_put) {
|
||||
timeout_ext = nf_ct_timeout_find(ct);
|
||||
if (timeout_ext)
|
||||
if (timeout_ext) {
|
||||
timeout_put(timeout_ext->timeout);
|
||||
RCU_INIT_POINTER(timeout_ext->timeout, NULL);
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
#endif
|
||||
|
@ -6131,21 +6131,18 @@ security_initcall(selinux_init);
|
||||
static struct nf_hook_ops selinux_nf_ops[] = {
|
||||
{
|
||||
.hook = selinux_ipv4_postroute,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP_PRI_SELINUX_LAST,
|
||||
},
|
||||
{
|
||||
.hook = selinux_ipv4_forward,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_FORWARD,
|
||||
.priority = NF_IP_PRI_SELINUX_FIRST,
|
||||
},
|
||||
{
|
||||
.hook = selinux_ipv4_output,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP_PRI_SELINUX_FIRST,
|
||||
@ -6153,14 +6150,12 @@ static struct nf_hook_ops selinux_nf_ops[] = {
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
{
|
||||
.hook = selinux_ipv6_postroute,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP6_PRI_SELINUX_LAST,
|
||||
},
|
||||
{
|
||||
.hook = selinux_ipv6_forward,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_FORWARD,
|
||||
.priority = NF_IP6_PRI_SELINUX_FIRST,
|
||||
|
@ -57,7 +57,6 @@ static unsigned int smack_ipv4_output(void *priv,
|
||||
static struct nf_hook_ops smack_nf_ops[] = {
|
||||
{
|
||||
.hook = smack_ipv4_output,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP_PRI_SELINUX_FIRST,
|
||||
@ -65,7 +64,6 @@ static struct nf_hook_ops smack_nf_ops[] = {
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
{
|
||||
.hook = smack_ipv6_output,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP6_PRI_SELINUX_FIRST,
|
||||
|
Loading…
Reference in New Issue
Block a user