You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Pablo Neira Ayuso says:
====================
Netfilter updates for net-next
The following patchset contains Netfilter updates for your net-next
tree. Most relevant updates are the removal of per-conntrack timers to
use a workqueue/garbage collection approach instead from Florian
Westphal, the hash and numgen expression for nf_tables from Laura
Garcia, updates on nf_tables hash set to honor the NLM_F_EXCL flag,
removal of ip_conntrack sysctl and many other incremental updates on our
Netfilter codebase.
More specifically, they are:
1) Retrieve only 4 bytes to fetch ports in case of non-linear skb
transport area in dccp, sctp, tcp, udp and udplite protocol
conntrackers, from Gao Feng.
2) Missing whitespace on error message in physdev match, from Hangbin Liu.
3) Skip redundant IPv4 checksum calculation in nf_dup_ipv4, from Liping Zhang.
4) Add nf_ct_expires() helper function and use it, from Florian Westphal.
5) Replace opencoded nf_ct_kill() call in IPVS conntrack support, also
from Florian.
6) Rename nf_tables set implementation to nft_set_{name}.c
7) Introduce the hash expression to allow arbitrary hashing of selector
concatenations, from Laura Garcia Liebana.
8) Remove ip_conntrack sysctl backward compatibility code, this code has
been around for long time already, and we have two interfaces to do
this already: nf_conntrack sysctl and ctnetlink.
9) Use nf_conntrack_get_ht() helper function whenever possible, instead
of opencoding fetch of hashtable pointer and size, patch from Liping Zhang.
10) Add quota expression for nf_tables.
11) Add number generator expression for nf_tables, this supports
incremental and random generators that can be combined with maps,
very useful for load balancing purpose, again from Laura Garcia Liebana.
12) Fix a typo in a debug message in FTP conntrack helper, from Colin Ian King.
13) Introduce a nft_chain_parse_hook() helper function to parse chain hook
configuration, this is used by a follow up patch to perform better chain
update validation.
14) Add rhashtable_lookup_get_insert_key() to rhashtable and use it from the
nft_set_hash implementation to honor the NLM_F_EXCL flag.
15) Missing nulls check in nf_conntrack from nf_conntrack_tuple_taken(),
patch from Florian Westphal.
16) Don't use the DYING bit to know if the conntrack event has been already
delivered, instead a state variable to track event re-delivery
states, also from Florian.
17) Remove the per-conntrack timer, use the workqueue approach that was
discussed during the NFWS, from Florian Westphal.
18) Use the netlink conntrack table dump path to kill stale entries,
again from Florian.
19) Add a garbage collector to get rid of stale conntracks, from
Florian.
20) Reschedule garbage collector if eviction rate is high.
21) Get rid of the __nf_ct_kill_acct() helper.
22) Use ARPHRD_ETHER instead of hardcoded 1 from ARP logger.
23) Make nf_log_set() interface assertive on unsupported families.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
+57
-13
@@ -343,7 +343,8 @@ int rhashtable_init(struct rhashtable *ht,
|
||||
struct bucket_table *rhashtable_insert_slow(struct rhashtable *ht,
|
||||
const void *key,
|
||||
struct rhash_head *obj,
|
||||
struct bucket_table *old_tbl);
|
||||
struct bucket_table *old_tbl,
|
||||
void **data);
|
||||
int rhashtable_insert_rehash(struct rhashtable *ht, struct bucket_table *tbl);
|
||||
|
||||
void rhashtable_walk_enter(struct rhashtable *ht,
|
||||
@@ -563,8 +564,11 @@ restart:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Internal function, please use rhashtable_insert_fast() instead */
|
||||
static inline int __rhashtable_insert_fast(
|
||||
/* Internal function, please use rhashtable_insert_fast() instead. This
|
||||
* function returns the existing element already in hashes in there is a clash,
|
||||
* otherwise it returns an error via ERR_PTR().
|
||||
*/
|
||||
static inline void *__rhashtable_insert_fast(
|
||||
struct rhashtable *ht, const void *key, struct rhash_head *obj,
|
||||
const struct rhashtable_params params)
|
||||
{
|
||||
@@ -577,6 +581,7 @@ static inline int __rhashtable_insert_fast(
|
||||
spinlock_t *lock;
|
||||
unsigned int elasticity;
|
||||
unsigned int hash;
|
||||
void *data = NULL;
|
||||
int err;
|
||||
|
||||
restart:
|
||||
@@ -601,11 +606,14 @@ restart:
|
||||
|
||||
new_tbl = rht_dereference_rcu(tbl->future_tbl, ht);
|
||||
if (unlikely(new_tbl)) {
|
||||
tbl = rhashtable_insert_slow(ht, key, obj, new_tbl);
|
||||
tbl = rhashtable_insert_slow(ht, key, obj, new_tbl, &data);
|
||||
if (!IS_ERR_OR_NULL(tbl))
|
||||
goto slow_path;
|
||||
|
||||
err = PTR_ERR(tbl);
|
||||
if (err == -EEXIST)
|
||||
err = 0;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -619,25 +627,25 @@ slow_path:
|
||||
err = rhashtable_insert_rehash(ht, tbl);
|
||||
rcu_read_unlock();
|
||||
if (err)
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
|
||||
goto restart;
|
||||
}
|
||||
|
||||
err = -EEXIST;
|
||||
err = 0;
|
||||
elasticity = ht->elasticity;
|
||||
rht_for_each(head, tbl, hash) {
|
||||
if (key &&
|
||||
unlikely(!(params.obj_cmpfn ?
|
||||
params.obj_cmpfn(&arg, rht_obj(ht, head)) :
|
||||
rhashtable_compare(&arg, rht_obj(ht, head)))))
|
||||
rhashtable_compare(&arg, rht_obj(ht, head))))) {
|
||||
data = rht_obj(ht, head);
|
||||
goto out;
|
||||
}
|
||||
if (!--elasticity)
|
||||
goto slow_path;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
|
||||
head = rht_dereference_bucket(tbl->buckets[hash], tbl, hash);
|
||||
|
||||
RCU_INIT_POINTER(obj->next, head);
|
||||
@@ -652,7 +660,7 @@ out:
|
||||
spin_unlock_bh(lock);
|
||||
rcu_read_unlock();
|
||||
|
||||
return err;
|
||||
return err ? ERR_PTR(err) : data;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -675,7 +683,13 @@ static inline int rhashtable_insert_fast(
|
||||
struct rhashtable *ht, struct rhash_head *obj,
|
||||
const struct rhashtable_params params)
|
||||
{
|
||||
return __rhashtable_insert_fast(ht, NULL, obj, params);
|
||||
void *ret;
|
||||
|
||||
ret = __rhashtable_insert_fast(ht, NULL, obj, params);
|
||||
if (IS_ERR(ret))
|
||||
return PTR_ERR(ret);
|
||||
|
||||
return ret == NULL ? 0 : -EEXIST;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -704,11 +718,15 @@ static inline int rhashtable_lookup_insert_fast(
|
||||
const struct rhashtable_params params)
|
||||
{
|
||||
const char *key = rht_obj(ht, obj);
|
||||
void *ret;
|
||||
|
||||
BUG_ON(ht->p.obj_hashfn);
|
||||
|
||||
return __rhashtable_insert_fast(ht, key + ht->p.key_offset, obj,
|
||||
params);
|
||||
ret = __rhashtable_insert_fast(ht, key + ht->p.key_offset, obj, params);
|
||||
if (IS_ERR(ret))
|
||||
return PTR_ERR(ret);
|
||||
|
||||
return ret == NULL ? 0 : -EEXIST;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -736,6 +754,32 @@ static inline int rhashtable_lookup_insert_fast(
|
||||
static inline int rhashtable_lookup_insert_key(
|
||||
struct rhashtable *ht, const void *key, struct rhash_head *obj,
|
||||
const struct rhashtable_params params)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
BUG_ON(!ht->p.obj_hashfn || !key);
|
||||
|
||||
ret = __rhashtable_insert_fast(ht, key, obj, params);
|
||||
if (IS_ERR(ret))
|
||||
return PTR_ERR(ret);
|
||||
|
||||
return ret == NULL ? 0 : -EEXIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* rhashtable_lookup_get_insert_key - lookup and insert object into hash table
|
||||
* @ht: hash table
|
||||
* @obj: pointer to hash head inside object
|
||||
* @params: hash table parameters
|
||||
* @data: pointer to element data already in hashes
|
||||
*
|
||||
* Just like rhashtable_lookup_insert_key(), but this function returns the
|
||||
* object if it exists, NULL if it does not and the insertion was successful,
|
||||
* and an ERR_PTR otherwise.
|
||||
*/
|
||||
static inline void *rhashtable_lookup_get_insert_key(
|
||||
struct rhashtable *ht, const void *key, struct rhash_head *obj,
|
||||
const struct rhashtable_params params)
|
||||
{
|
||||
BUG_ON(!ht->p.obj_hashfn || !key);
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ union nf_conntrack_expect_proto {
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/timer.h>
|
||||
|
||||
#ifdef CONFIG_NETFILTER_DEBUG
|
||||
#define NF_CT_ASSERT(x) WARN_ON(!(x))
|
||||
@@ -73,7 +72,7 @@ struct nf_conn_help {
|
||||
#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
|
||||
|
||||
struct nf_conn {
|
||||
/* Usage count in here is 1 for hash table/destruct timer, 1 per skb,
|
||||
/* Usage count in here is 1 for hash table, 1 per skb,
|
||||
* plus 1 for any connection(s) we are `master' for
|
||||
*
|
||||
* Hint, SKB address this struct and refcnt via skb->nfct and
|
||||
@@ -96,8 +95,8 @@ struct nf_conn {
|
||||
/* Have we seen traffic both ways yet? (bitset) */
|
||||
unsigned long status;
|
||||
|
||||
/* Timer function; drops refcnt when it goes off. */
|
||||
struct timer_list timeout;
|
||||
/* jiffies32 when this ct is considered dead */
|
||||
u32 timeout;
|
||||
|
||||
possible_net_t ct_net;
|
||||
|
||||
@@ -220,21 +219,14 @@ static inline void nf_ct_refresh(struct nf_conn *ct,
|
||||
__nf_ct_refresh_acct(ct, 0, skb, extra_jiffies, 0);
|
||||
}
|
||||
|
||||
bool __nf_ct_kill_acct(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
|
||||
const struct sk_buff *skb, int do_acct);
|
||||
|
||||
/* kill conntrack and do accounting */
|
||||
static inline bool nf_ct_kill_acct(struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
const struct sk_buff *skb)
|
||||
{
|
||||
return __nf_ct_kill_acct(ct, ctinfo, skb, 1);
|
||||
}
|
||||
bool nf_ct_kill_acct(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
|
||||
const struct sk_buff *skb);
|
||||
|
||||
/* kill conntrack without accounting */
|
||||
static inline bool nf_ct_kill(struct nf_conn *ct)
|
||||
{
|
||||
return __nf_ct_kill_acct(ct, 0, NULL, 0);
|
||||
return nf_ct_delete(ct, 0, 0);
|
||||
}
|
||||
|
||||
/* These are for NAT. Icky. */
|
||||
@@ -291,21 +283,55 @@ static inline bool nf_is_loopback_packet(const struct sk_buff *skb)
|
||||
return skb->dev && skb->skb_iif && skb->dev->flags & IFF_LOOPBACK;
|
||||
}
|
||||
|
||||
#define nfct_time_stamp ((u32)(jiffies))
|
||||
|
||||
/* jiffies until ct expires, 0 if already expired */
|
||||
static inline unsigned long nf_ct_expires(const struct nf_conn *ct)
|
||||
{
|
||||
long timeout = (long)ct->timeout.expires - (long)jiffies;
|
||||
s32 timeout = ct->timeout - nfct_time_stamp;
|
||||
|
||||
return timeout > 0 ? timeout : 0;
|
||||
}
|
||||
|
||||
static inline bool nf_ct_is_expired(const struct nf_conn *ct)
|
||||
{
|
||||
return (__s32)(ct->timeout - nfct_time_stamp) <= 0;
|
||||
}
|
||||
|
||||
/* use after obtaining a reference count */
|
||||
static inline bool nf_ct_should_gc(const struct nf_conn *ct)
|
||||
{
|
||||
return nf_ct_is_expired(ct) && nf_ct_is_confirmed(ct) &&
|
||||
!nf_ct_is_dying(ct);
|
||||
}
|
||||
|
||||
struct kernel_param;
|
||||
|
||||
int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp);
|
||||
int nf_conntrack_hash_resize(unsigned int hashsize);
|
||||
|
||||
extern struct hlist_nulls_head *nf_conntrack_hash;
|
||||
extern unsigned int nf_conntrack_htable_size;
|
||||
extern seqcount_t nf_conntrack_generation;
|
||||
extern unsigned int nf_conntrack_max;
|
||||
|
||||
/* must be called with rcu read lock held */
|
||||
static inline void
|
||||
nf_conntrack_get_ht(struct hlist_nulls_head **hash, unsigned int *hsize)
|
||||
{
|
||||
struct hlist_nulls_head *hptr;
|
||||
unsigned int sequence, hsz;
|
||||
|
||||
do {
|
||||
sequence = read_seqcount_begin(&nf_conntrack_generation);
|
||||
hsz = nf_conntrack_htable_size;
|
||||
hptr = nf_conntrack_hash;
|
||||
} while (read_seqcount_retry(&nf_conntrack_generation, sequence));
|
||||
|
||||
*hash = hptr;
|
||||
*hsize = hsz;
|
||||
}
|
||||
|
||||
struct nf_conn *nf_ct_tmpl_alloc(struct net *net,
|
||||
const struct nf_conntrack_zone *zone,
|
||||
gfp_t flags);
|
||||
|
||||
@@ -51,8 +51,6 @@ bool nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
|
||||
const struct nf_conntrack_l3proto *l3proto,
|
||||
const struct nf_conntrack_l4proto *l4proto);
|
||||
|
||||
void nf_conntrack_get_ht(struct hlist_nulls_head **hash, unsigned int *hsize);
|
||||
|
||||
/* Find a connection corresponding to a tuple. */
|
||||
struct nf_conntrack_tuple_hash *
|
||||
nf_conntrack_find_get(struct net *net,
|
||||
@@ -83,7 +81,6 @@ print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
|
||||
|
||||
#define CONNTRACK_LOCKS 1024
|
||||
|
||||
extern struct hlist_nulls_head *nf_conntrack_hash;
|
||||
extern spinlock_t nf_conntrack_locks[CONNTRACK_LOCKS];
|
||||
void nf_conntrack_lock(spinlock_t *lock);
|
||||
|
||||
|
||||
@@ -12,12 +12,19 @@
|
||||
#include <linux/netfilter/nf_conntrack_tuple_common.h>
|
||||
#include <net/netfilter/nf_conntrack_extend.h>
|
||||
|
||||
enum nf_ct_ecache_state {
|
||||
NFCT_ECACHE_UNKNOWN, /* destroy event not sent */
|
||||
NFCT_ECACHE_DESTROY_FAIL, /* tried but failed to send destroy event */
|
||||
NFCT_ECACHE_DESTROY_SENT, /* sent destroy event after failure */
|
||||
};
|
||||
|
||||
struct nf_conntrack_ecache {
|
||||
unsigned long cache; /* bitops want long */
|
||||
unsigned long missed; /* missed events */
|
||||
u16 ctmask; /* bitmask of ct events to be delivered */
|
||||
u16 expmask; /* bitmask of expect events to be delivered */
|
||||
u32 portid; /* netlink portid of destroyer */
|
||||
unsigned long cache; /* bitops want long */
|
||||
unsigned long missed; /* missed events */
|
||||
u16 ctmask; /* bitmask of ct events to be delivered */
|
||||
u16 expmask; /* bitmask of expect events to be delivered */
|
||||
u32 portid; /* netlink portid of destroyer */
|
||||
enum nf_ct_ecache_state state; /* ecache state */
|
||||
};
|
||||
|
||||
static inline struct nf_conntrack_ecache *
|
||||
|
||||
@@ -134,14 +134,6 @@ void nf_ct_l4proto_pernet_unregister(struct net *net,
|
||||
int nf_ct_l4proto_register(struct nf_conntrack_l4proto *proto);
|
||||
void nf_ct_l4proto_unregister(struct nf_conntrack_l4proto *proto);
|
||||
|
||||
static inline void nf_ct_kfree_compat_sysctl_table(struct nf_proto_net *pn)
|
||||
{
|
||||
#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
|
||||
kfree(pn->ctl_compat_table);
|
||||
pn->ctl_compat_table = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Generic netlink helpers */
|
||||
int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb,
|
||||
const struct nf_conntrack_tuple *tuple);
|
||||
|
||||
@@ -60,8 +60,7 @@ struct nf_logger {
|
||||
int nf_log_register(u_int8_t pf, struct nf_logger *logger);
|
||||
void nf_log_unregister(struct nf_logger *logger);
|
||||
|
||||
void nf_log_set(struct net *net, u_int8_t pf,
|
||||
const struct nf_logger *logger);
|
||||
int nf_log_set(struct net *net, u_int8_t pf, const struct nf_logger *logger);
|
||||
void nf_log_unset(struct net *net, const struct nf_logger *logger);
|
||||
|
||||
int nf_log_bind_pf(struct net *net, u_int8_t pf,
|
||||
|
||||
@@ -251,7 +251,8 @@ struct nft_set_ops {
|
||||
|
||||
int (*insert)(const struct net *net,
|
||||
const struct nft_set *set,
|
||||
const struct nft_set_elem *elem);
|
||||
const struct nft_set_elem *elem,
|
||||
struct nft_set_ext **ext);
|
||||
void (*activate)(const struct net *net,
|
||||
const struct nft_set *set,
|
||||
const struct nft_set_elem *elem);
|
||||
|
||||
@@ -15,10 +15,6 @@ struct nf_proto_net {
|
||||
#ifdef CONFIG_SYSCTL
|
||||
struct ctl_table_header *ctl_table_header;
|
||||
struct ctl_table *ctl_table;
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
struct ctl_table_header *ctl_compat_header;
|
||||
struct ctl_table *ctl_compat_table;
|
||||
#endif
|
||||
#endif
|
||||
unsigned int users;
|
||||
};
|
||||
@@ -58,10 +54,6 @@ struct nf_ip_net {
|
||||
struct nf_udp_net udp;
|
||||
struct nf_icmp_net icmp;
|
||||
struct nf_icmp_net icmpv6;
|
||||
#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
|
||||
struct ctl_table_header *ctl_table_header;
|
||||
struct ctl_table *ctl_table;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct ct_pcpu {
|
||||
|
||||
@@ -723,6 +723,26 @@ enum nft_meta_keys {
|
||||
NFT_META_PRANDOM,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum nft_hash_attributes - nf_tables hash expression netlink attributes
|
||||
*
|
||||
* @NFTA_HASH_SREG: source register (NLA_U32)
|
||||
* @NFTA_HASH_DREG: destination register (NLA_U32)
|
||||
* @NFTA_HASH_LEN: source data length (NLA_U32)
|
||||
* @NFTA_HASH_MODULUS: modulus value (NLA_U32)
|
||||
* @NFTA_HASH_SEED: seed value (NLA_U32)
|
||||
*/
|
||||
enum nft_hash_attributes {
|
||||
NFTA_HASH_UNSPEC,
|
||||
NFTA_HASH_SREG,
|
||||
NFTA_HASH_DREG,
|
||||
NFTA_HASH_LEN,
|
||||
NFTA_HASH_MODULUS,
|
||||
NFTA_HASH_SEED,
|
||||
__NFTA_HASH_MAX,
|
||||
};
|
||||
#define NFTA_HASH_MAX (__NFTA_HASH_MAX - 1)
|
||||
|
||||
/**
|
||||
* enum nft_meta_attributes - nf_tables meta expression netlink attributes
|
||||
*
|
||||
@@ -880,6 +900,25 @@ enum nft_queue_attributes {
|
||||
#define NFT_QUEUE_FLAG_CPU_FANOUT 0x02 /* use current CPU (no hashing) */
|
||||
#define NFT_QUEUE_FLAG_MASK 0x03
|
||||
|
||||
enum nft_quota_flags {
|
||||
NFT_QUOTA_F_INV = (1 << 0),
|
||||
};
|
||||
|
||||
/**
|
||||
* enum nft_quota_attributes - nf_tables quota expression netlink attributes
|
||||
*
|
||||
* @NFTA_QUOTA_BYTES: quota in bytes (NLA_U16)
|
||||
* @NFTA_QUOTA_FLAGS: flags (NLA_U32)
|
||||
*/
|
||||
enum nft_quota_attributes {
|
||||
NFTA_QUOTA_UNSPEC,
|
||||
NFTA_QUOTA_BYTES,
|
||||
NFTA_QUOTA_FLAGS,
|
||||
NFTA_QUOTA_PAD,
|
||||
__NFTA_QUOTA_MAX
|
||||
};
|
||||
#define NFTA_QUOTA_MAX (__NFTA_QUOTA_MAX - 1)
|
||||
|
||||
/**
|
||||
* enum nft_reject_types - nf_tables reject expression reject types
|
||||
*
|
||||
@@ -1051,7 +1090,7 @@ enum nft_gen_attributes {
|
||||
* @NFTA_TRACE_NFPROTO: nf protocol processed (NLA_U32)
|
||||
* @NFTA_TRACE_POLICY: policy that decided fate of packet (NLA_U32)
|
||||
*/
|
||||
enum nft_trace_attibutes {
|
||||
enum nft_trace_attributes {
|
||||
NFTA_TRACE_UNSPEC,
|
||||
NFTA_TRACE_TABLE,
|
||||
NFTA_TRACE_CHAIN,
|
||||
@@ -1082,4 +1121,28 @@ enum nft_trace_types {
|
||||
__NFT_TRACETYPE_MAX
|
||||
};
|
||||
#define NFT_TRACETYPE_MAX (__NFT_TRACETYPE_MAX - 1)
|
||||
|
||||
/**
|
||||
* enum nft_ng_attributes - nf_tables number generator expression netlink attributes
|
||||
*
|
||||
* @NFTA_NG_DREG: destination register (NLA_U32)
|
||||
* @NFTA_NG_UNTIL: source value to increment the counter until reset (NLA_U32)
|
||||
* @NFTA_NG_TYPE: operation type (NLA_U32)
|
||||
*/
|
||||
enum nft_ng_attributes {
|
||||
NFTA_NG_UNSPEC,
|
||||
NFTA_NG_DREG,
|
||||
NFTA_NG_UNTIL,
|
||||
NFTA_NG_TYPE,
|
||||
__NFTA_NG_MAX
|
||||
};
|
||||
#define NFTA_NG_MAX (__NFTA_NG_MAX - 1)
|
||||
|
||||
enum nft_ng_types {
|
||||
NFT_NG_INCREMENTAL,
|
||||
NFT_NG_RANDOM,
|
||||
__NFT_NG_MAX
|
||||
};
|
||||
#define NFT_NG_MAX (__NFT_NG_MAX - 1)
|
||||
|
||||
#endif /* _LINUX_NF_TABLES_H */
|
||||
|
||||
+7
-3
@@ -444,7 +444,8 @@ EXPORT_SYMBOL_GPL(rhashtable_insert_rehash);
|
||||
struct bucket_table *rhashtable_insert_slow(struct rhashtable *ht,
|
||||
const void *key,
|
||||
struct rhash_head *obj,
|
||||
struct bucket_table *tbl)
|
||||
struct bucket_table *tbl,
|
||||
void **data)
|
||||
{
|
||||
struct rhash_head *head;
|
||||
unsigned int hash;
|
||||
@@ -455,8 +456,11 @@ struct bucket_table *rhashtable_insert_slow(struct rhashtable *ht,
|
||||
spin_lock_nested(rht_bucket_lock(tbl, hash), SINGLE_DEPTH_NESTING);
|
||||
|
||||
err = -EEXIST;
|
||||
if (key && rhashtable_lookup_fast(ht, key, ht->p))
|
||||
goto exit;
|
||||
if (key) {
|
||||
*data = rhashtable_lookup_fast(ht, key, ht->p);
|
||||
if (*data)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
err = -E2BIG;
|
||||
if (unlikely(rht_grow_above_max(ht, tbl)))
|
||||
|
||||
@@ -50,8 +50,7 @@ static struct nf_logger nf_bridge_logger __read_mostly = {
|
||||
|
||||
static int __net_init nf_log_bridge_net_init(struct net *net)
|
||||
{
|
||||
nf_log_set(net, NFPROTO_BRIDGE, &nf_bridge_logger);
|
||||
return 0;
|
||||
return nf_log_set(net, NFPROTO_BRIDGE, &nf_bridge_logger);
|
||||
}
|
||||
|
||||
static void __net_exit nf_log_bridge_net_exit(struct net *net)
|
||||
|
||||
@@ -25,17 +25,6 @@ config NF_CONNTRACK_IPV4
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config NF_CONNTRACK_PROC_COMPAT
|
||||
bool "proc/sysctl compatibility with old connection tracking"
|
||||
depends on NF_CONNTRACK_PROCFS && NF_CONNTRACK_IPV4
|
||||
default y
|
||||
help
|
||||
This option enables /proc and sysctl compatibility with the old
|
||||
layer 3 dependent connection tracking. This is needed to keep
|
||||
old programs that have not been adapted to the new names working.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
if NF_TABLES
|
||||
|
||||
config NF_TABLES_IPV4
|
||||
|
||||
@@ -4,11 +4,6 @@
|
||||
|
||||
# objects for l3 independent conntrack
|
||||
nf_conntrack_ipv4-y := nf_conntrack_l3proto_ipv4.o nf_conntrack_proto_icmp.o
|
||||
ifeq ($(CONFIG_NF_CONNTRACK_PROC_COMPAT),y)
|
||||
ifeq ($(CONFIG_PROC_FS),y)
|
||||
nf_conntrack_ipv4-objs += nf_conntrack_l3proto_ipv4_compat.o
|
||||
endif
|
||||
endif
|
||||
|
||||
# connection tracking
|
||||
obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o
|
||||
|
||||
@@ -202,47 +202,6 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
|
||||
},
|
||||
};
|
||||
|
||||
#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
|
||||
static int log_invalid_proto_min = 0;
|
||||
static int log_invalid_proto_max = 255;
|
||||
|
||||
static struct ctl_table ip_ct_sysctl_table[] = {
|
||||
{
|
||||
.procname = "ip_conntrack_max",
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_count",
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0444,
|
||||
.proc_handler = proc_dointvec,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_buckets",
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0444,
|
||||
.proc_handler = proc_dointvec,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_checksum",
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec,
|
||||
},
|
||||
{
|
||||
.procname = "ip_conntrack_log_invalid",
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = &log_invalid_proto_min,
|
||||
.extra2 = &log_invalid_proto_max,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
#endif /* CONFIG_SYSCTL && CONFIG_NF_CONNTRACK_PROC_COMPAT */
|
||||
|
||||
/* Fast function for those who don't want to parse /proc (and I don't
|
||||
blame them). */
|
||||
/* Reversing the socket's dst/src point of view gives us the reply
|
||||
@@ -350,20 +309,6 @@ static struct nf_sockopt_ops so_getorigdst = {
|
||||
|
||||
static int ipv4_init_net(struct net *net)
|
||||
{
|
||||
#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
|
||||
struct nf_ip_net *in = &net->ct.nf_ct_proto;
|
||||
in->ctl_table = kmemdup(ip_ct_sysctl_table,
|
||||
sizeof(ip_ct_sysctl_table),
|
||||
GFP_KERNEL);
|
||||
if (!in->ctl_table)
|
||||
return -ENOMEM;
|
||||
|
||||
in->ctl_table[0].data = &nf_conntrack_max;
|
||||
in->ctl_table[1].data = &net->ct.count;
|
||||
in->ctl_table[2].data = &nf_conntrack_htable_size;
|
||||
in->ctl_table[3].data = &net->ct.sysctl_checksum;
|
||||
in->ctl_table[4].data = &net->ct.sysctl_log_invalid;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -379,9 +324,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = {
|
||||
.nlattr_tuple_size = ipv4_nlattr_tuple_size,
|
||||
.nlattr_to_tuple = ipv4_nlattr_to_tuple,
|
||||
.nla_policy = ipv4_nla_policy,
|
||||
#endif
|
||||
#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
|
||||
.ctl_table_path = "net/ipv4/netfilter",
|
||||
#endif
|
||||
.init_net = ipv4_init_net,
|
||||
.me = THIS_MODULE,
|
||||
@@ -492,16 +434,7 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
|
||||
goto cleanup_icmpv4;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
|
||||
ret = nf_conntrack_ipv4_compat_init();
|
||||
if (ret < 0)
|
||||
goto cleanup_proto;
|
||||
#endif
|
||||
return ret;
|
||||
#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
|
||||
cleanup_proto:
|
||||
nf_ct_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
|
||||
#endif
|
||||
cleanup_icmpv4:
|
||||
nf_ct_l4proto_unregister(&nf_conntrack_l4proto_icmp);
|
||||
cleanup_udp4:
|
||||
@@ -520,9 +453,6 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
|
||||
static void __exit nf_conntrack_l3proto_ipv4_fini(void)
|
||||
{
|
||||
synchronize_net();
|
||||
#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
|
||||
nf_conntrack_ipv4_compat_fini();
|
||||
#endif
|
||||
nf_ct_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
|
||||
nf_ct_l4proto_unregister(&nf_conntrack_l4proto_icmp);
|
||||
nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udp4);
|
||||
|
||||
@@ -1,492 +0,0 @@
|
||||
/* ip_conntrack proc compat - based on ip_conntrack_standalone.c
|
||||
*
|
||||
* (C) 1999-2001 Paul `Rusty' Russell
|
||||
* (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
|
||||
* (C) 2006-2010 Patrick McHardy <kaber@trash.net>
|
||||
*
|
||||
* 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/types.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/security.h>
|
||||
#include <net/net_namespace.h>
|
||||
|
||||
#include <linux/netfilter.h>
|
||||
#include <net/netfilter/nf_conntrack_core.h>
|
||||
#include <net/netfilter/nf_conntrack_l3proto.h>
|
||||
#include <net/netfilter/nf_conntrack_l4proto.h>
|
||||
#include <net/netfilter/nf_conntrack_expect.h>
|
||||
#include <net/netfilter/nf_conntrack_acct.h>
|
||||
#include <linux/rculist_nulls.h>
|
||||
#include <linux/export.h>
|
||||
|
||||
struct ct_iter_state {
|
||||
struct seq_net_private p;
|
||||
struct hlist_nulls_head *hash;
|
||||
unsigned int htable_size;
|
||||
unsigned int bucket;
|
||||
};
|
||||
|
||||
static struct hlist_nulls_node *ct_get_first(struct seq_file *seq)
|
||||
{
|
||||
struct ct_iter_state *st = seq->private;
|
||||
struct hlist_nulls_node *n;
|
||||
|
||||
for (st->bucket = 0;
|
||||
st->bucket < st->htable_size;
|
||||
st->bucket++) {
|
||||
n = rcu_dereference(
|
||||
hlist_nulls_first_rcu(&st->hash[st->bucket]));
|
||||
if (!is_a_nulls(n))
|
||||
return n;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct hlist_nulls_node *ct_get_next(struct seq_file *seq,
|
||||
struct hlist_nulls_node *head)
|
||||
{
|
||||
struct ct_iter_state *st = seq->private;
|
||||
|
||||
head = rcu_dereference(hlist_nulls_next_rcu(head));
|
||||
while (is_a_nulls(head)) {
|
||||
if (likely(get_nulls_value(head) == st->bucket)) {
|
||||
if (++st->bucket >= st->htable_size)
|
||||
return NULL;
|
||||
}
|
||||
head = rcu_dereference(
|
||||
hlist_nulls_first_rcu(&st->hash[st->bucket]));
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
static struct hlist_nulls_node *ct_get_idx(struct seq_file *seq, loff_t pos)
|
||||
{
|
||||
struct hlist_nulls_node *head = ct_get_first(seq);
|
||||
|
||||
if (head)
|
||||
while (pos && (head = ct_get_next(seq, head)))
|
||||
pos--;
|
||||
return pos ? NULL : head;
|
||||
}
|
||||
|
||||
static void *ct_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
__acquires(RCU)
|
||||
{
|
||||
struct ct_iter_state *st = seq->private;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
nf_conntrack_get_ht(&st->hash, &st->htable_size);
|
||||
return ct_get_idx(seq, *pos);
|
||||
}
|
||||
|
||||
static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos)
|
||||
{
|
||||
(*pos)++;
|
||||
return ct_get_next(s, v);
|
||||
}
|
||||
|
||||
static void ct_seq_stop(struct seq_file *s, void *v)
|
||||
__releases(RCU)
|
||||
{
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_SECMARK
|
||||
static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)
|
||||
{
|
||||
int ret;
|
||||
u32 len;
|
||||
char *secctx;
|
||||
|
||||
ret = security_secid_to_secctx(ct->secmark, &secctx, &len);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
seq_printf(s, "secctx=%s ", secctx);
|
||||
|
||||
security_release_secctx(secctx, len);
|
||||
}
|
||||
#else
|
||||
static inline void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool ct_seq_should_skip(const struct nf_conn *ct,
|
||||
const struct net *net,
|
||||
const struct nf_conntrack_tuple_hash *hash)
|
||||
{
|
||||
/* we only want to print DIR_ORIGINAL */
|
||||
if (NF_CT_DIRECTION(hash))
|
||||
return true;
|
||||
|
||||
if (nf_ct_l3num(ct) != AF_INET)
|
||||
return true;
|
||||
|
||||
if (!net_eq(nf_ct_net(ct), net))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int ct_seq_show(struct seq_file *s, void *v)
|
||||
{
|
||||
struct nf_conntrack_tuple_hash *hash = v;
|
||||
struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash);
|
||||
const struct nf_conntrack_l3proto *l3proto;
|
||||
const struct nf_conntrack_l4proto *l4proto;
|
||||
int ret = 0;
|
||||
|
||||
NF_CT_ASSERT(ct);
|
||||
if (ct_seq_should_skip(ct, seq_file_net(s), hash))
|
||||
return 0;
|
||||
|
||||
if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
|
||||
return 0;
|
||||
|
||||
/* check if we raced w. object reuse */
|
||||
if (!nf_ct_is_confirmed(ct) ||
|
||||
ct_seq_should_skip(ct, seq_file_net(s), hash))
|
||||
goto release;
|
||||
|
||||
l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct));
|
||||
NF_CT_ASSERT(l3proto);
|
||||
l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
|
||||
NF_CT_ASSERT(l4proto);
|
||||
|
||||
ret = -ENOSPC;
|
||||
seq_printf(s, "%-8s %u %ld ",
|
||||
l4proto->name, nf_ct_protonum(ct),
|
||||
timer_pending(&ct->timeout)
|
||||
? (long)(ct->timeout.expires - jiffies)/HZ : 0);
|
||||
|
||||
if (l4proto->print_conntrack)
|
||||
l4proto->print_conntrack(s, ct);
|
||||
|
||||
if (seq_has_overflowed(s))
|
||||
goto release;
|
||||
|
||||
print_tuple(s, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
|
||||
l3proto, l4proto);
|
||||
|
||||
if (seq_has_overflowed(s))
|
||||
goto release;
|
||||
|
||||
if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL))
|
||||
goto release;
|
||||
|
||||
if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status)))
|
||||
seq_printf(s, "[UNREPLIED] ");
|
||||
|
||||
print_tuple(s, &ct->tuplehash[IP_CT_DIR_REPLY].tuple,
|
||||
l3proto, l4proto);
|
||||
|
||||
if (seq_has_overflowed(s))
|
||||
goto release;
|
||||
|
||||
if (seq_print_acct(s, ct, IP_CT_DIR_REPLY))
|
||||
goto release;
|
||||
|
||||
if (test_bit(IPS_ASSURED_BIT, &ct->status))
|
||||
seq_printf(s, "[ASSURED] ");
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_MARK
|
||||
seq_printf(s, "mark=%u ", ct->mark);
|
||||
#endif
|
||||
|
||||
ct_show_secctx(s, ct);
|
||||
|
||||
seq_printf(s, "use=%u\n", atomic_read(&ct->ct_general.use));
|
||||
|
||||
if (seq_has_overflowed(s))
|
||||
goto release;
|
||||
|
||||
ret = 0;
|
||||
release:
|
||||
nf_ct_put(ct);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct seq_operations ct_seq_ops = {
|
||||
.start = ct_seq_start,
|
||||
.next = ct_seq_next,
|
||||
.stop = ct_seq_stop,
|
||||
.show = ct_seq_show
|
||||
};
|
||||
|
||||
static int ct_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open_net(inode, file, &ct_seq_ops,
|
||||
sizeof(struct ct_iter_state));
|
||||
}
|
||||
|
||||
static const struct file_operations ct_file_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = ct_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release_net,
|
||||
};
|
||||
|
||||
/* expects */
|
||||
struct ct_expect_iter_state {
|
||||
struct seq_net_private p;
|
||||
unsigned int bucket;
|
||||
};
|
||||
|
||||
static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
|
||||
{
|
||||
struct ct_expect_iter_state *st = seq->private;
|
||||
struct hlist_node *n;
|
||||
|
||||
for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
|
||||
n = rcu_dereference(
|
||||
hlist_first_rcu(&nf_ct_expect_hash[st->bucket]));
|
||||
if (n)
|
||||
return n;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
|
||||
struct hlist_node *head)
|
||||
{
|
||||
struct ct_expect_iter_state *st = seq->private;
|
||||
|
||||
head = rcu_dereference(hlist_next_rcu(head));
|
||||
while (head == NULL) {
|
||||
if (++st->bucket >= nf_ct_expect_hsize)
|
||||
return NULL;
|
||||
head = rcu_dereference(
|
||||
hlist_first_rcu(&nf_ct_expect_hash[st->bucket]));
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
static struct hlist_node *ct_expect_get_idx(struct seq_file *seq, loff_t pos)
|
||||
{
|
||||
struct hlist_node *head = ct_expect_get_first(seq);
|
||||
|
||||
if (head)
|
||||
while (pos && (head = ct_expect_get_next(seq, head)))
|
||||
pos--;
|
||||
return pos ? NULL : head;
|
||||
}
|
||||
|
||||
static void *exp_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
__acquires(RCU)
|
||||
{
|
||||
rcu_read_lock();
|
||||
return ct_expect_get_idx(seq, *pos);
|
||||
}
|
||||
|
||||
static void *exp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
(*pos)++;
|
||||
return ct_expect_get_next(seq, v);
|
||||
}
|
||||
|
||||
static void exp_seq_stop(struct seq_file *seq, void *v)
|
||||
__releases(RCU)
|
||||
{
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static int exp_seq_show(struct seq_file *s, void *v)
|
||||
{
|
||||
struct nf_conntrack_expect *exp;
|
||||
const struct hlist_node *n = v;
|
||||
|
||||
exp = hlist_entry(n, struct nf_conntrack_expect, hnode);
|
||||
|
||||
if (!net_eq(nf_ct_net(exp->master), seq_file_net(s)))
|
||||
return 0;
|
||||
|
||||
if (exp->tuple.src.l3num != AF_INET)
|
||||
return 0;
|
||||
|
||||
if (exp->timeout.function)
|
||||
seq_printf(s, "%ld ", timer_pending(&exp->timeout)
|
||||
? (long)(exp->timeout.expires - jiffies)/HZ : 0);
|
||||
else
|
||||
seq_printf(s, "- ");
|
||||
|
||||
seq_printf(s, "proto=%u ", exp->tuple.dst.protonum);
|
||||
|
||||
print_tuple(s, &exp->tuple,
|
||||
__nf_ct_l3proto_find(exp->tuple.src.l3num),
|
||||
__nf_ct_l4proto_find(exp->tuple.src.l3num,
|
||||
exp->tuple.dst.protonum));
|
||||
seq_putc(s, '\n');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct seq_operations exp_seq_ops = {
|
||||
.start = exp_seq_start,
|
||||
.next = exp_seq_next,
|
||||
.stop = exp_seq_stop,
|
||||
.show = exp_seq_show
|
||||
};
|
||||
|
||||
static int exp_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open_net(inode, file, &exp_seq_ops,
|
||||
sizeof(struct ct_expect_iter_state));
|
||||
}
|
||||
|
||||
static const struct file_operations ip_exp_file_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = exp_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release_net,
|
||||
};
|
||||
|
||||
static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
{
|
||||
struct net *net = seq_file_net(seq);
|
||||
int cpu;
|
||||
|
||||
if (*pos == 0)
|
||||
return SEQ_START_TOKEN;
|
||||
|
||||
for (cpu = *pos-1; cpu < nr_cpu_ids; ++cpu) {
|
||||
if (!cpu_possible(cpu))
|
||||
continue;
|
||||
*pos = cpu+1;
|
||||
return per_cpu_ptr(net->ct.stat, cpu);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
struct net *net = seq_file_net(seq);
|
||||
int cpu;
|
||||
|
||||
for (cpu = *pos; cpu < nr_cpu_ids; ++cpu) {
|
||||
if (!cpu_possible(cpu))
|
||||
continue;
|
||||
*pos = cpu+1;
|
||||
return per_cpu_ptr(net->ct.stat, cpu);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void ct_cpu_seq_stop(struct seq_file *seq, void *v)
|
||||
{
|
||||
}
|
||||
|
||||
static int ct_cpu_seq_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
struct net *net = seq_file_net(seq);
|
||||
unsigned int nr_conntracks = atomic_read(&net->ct.count);
|
||||
const struct ip_conntrack_stat *st = v;
|
||||
|
||||
if (v == SEQ_START_TOKEN) {
|
||||
seq_printf(seq, "entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete search_restart\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x "
|
||||
"%08x %08x %08x %08x %08x %08x %08x %08x %08x\n",
|
||||
nr_conntracks,
|
||||
st->searched,
|
||||
st->found,
|
||||
st->new,
|
||||
st->invalid,
|
||||
st->ignore,
|
||||
st->delete,
|
||||
st->delete_list,
|
||||
st->insert,
|
||||
st->insert_failed,
|
||||
st->drop,
|
||||
st->early_drop,
|
||||
st->error,
|
||||
|
||||
st->expect_new,
|
||||
st->expect_create,
|
||||
st->expect_delete,
|
||||
st->search_restart
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct seq_operations ct_cpu_seq_ops = {
|
||||
.start = ct_cpu_seq_start,
|
||||
.next = ct_cpu_seq_next,
|
||||
.stop = ct_cpu_seq_stop,
|
||||
.show = ct_cpu_seq_show,
|
||||
};
|
||||
|
||||
static int ct_cpu_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open_net(inode, file, &ct_cpu_seq_ops,
|
||||
sizeof(struct seq_net_private));
|
||||
}
|
||||
|
||||
static const struct file_operations ct_cpu_seq_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = ct_cpu_seq_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release_net,
|
||||
};
|
||||
|
||||
static int __net_init ip_conntrack_net_init(struct net *net)
|
||||
{
|
||||
struct proc_dir_entry *proc, *proc_exp, *proc_stat;
|
||||
|
||||
proc = proc_create("ip_conntrack", 0440, net->proc_net, &ct_file_ops);
|
||||
if (!proc)
|
||||
goto err1;
|
||||
|
||||
proc_exp = proc_create("ip_conntrack_expect", 0440, net->proc_net,
|
||||
&ip_exp_file_ops);
|
||||
if (!proc_exp)
|
||||
goto err2;
|
||||
|
||||
proc_stat = proc_create("ip_conntrack", S_IRUGO,
|
||||
net->proc_net_stat, &ct_cpu_seq_fops);
|
||||
if (!proc_stat)
|
||||
goto err3;
|
||||
return 0;
|
||||
|
||||
err3:
|
||||
remove_proc_entry("ip_conntrack_expect", net->proc_net);
|
||||
err2:
|
||||
remove_proc_entry("ip_conntrack", net->proc_net);
|
||||
err1:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void __net_exit ip_conntrack_net_exit(struct net *net)
|
||||
{
|
||||
remove_proc_entry("ip_conntrack", net->proc_net_stat);
|
||||
remove_proc_entry("ip_conntrack_expect", net->proc_net);
|
||||
remove_proc_entry("ip_conntrack", net->proc_net);
|
||||
}
|
||||
|
||||
static struct pernet_operations ip_conntrack_net_ops = {
|
||||
.init = ip_conntrack_net_init,
|
||||
.exit = ip_conntrack_net_exit,
|
||||
};
|
||||
|
||||
int __init nf_conntrack_ipv4_compat_init(void)
|
||||
{
|
||||
return register_pernet_subsys(&ip_conntrack_net_ops);
|
||||
}
|
||||
|
||||
void __exit nf_conntrack_ipv4_compat_fini(void)
|
||||
{
|
||||
unregister_pernet_subsys(&ip_conntrack_net_ops);
|
||||
}
|
||||
@@ -327,17 +327,6 @@ static struct ctl_table icmp_sysctl_table[] = {
|
||||
},
|
||||
{ }
|
||||
};
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
static struct ctl_table icmp_compat_sysctl_table[] = {
|
||||
{
|
||||
.procname = "ip_conntrack_icmp_timeout",
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
|
||||
#endif /* CONFIG_SYSCTL */
|
||||
|
||||
static int icmp_kmemdup_sysctl_table(struct nf_proto_net *pn,
|
||||
@@ -355,40 +344,14 @@ static int icmp_kmemdup_sysctl_table(struct nf_proto_net *pn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int icmp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn,
|
||||
struct nf_icmp_net *in)
|
||||
{
|
||||
#ifdef CONFIG_SYSCTL
|
||||
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
|
||||
pn->ctl_compat_table = kmemdup(icmp_compat_sysctl_table,
|
||||
sizeof(icmp_compat_sysctl_table),
|
||||
GFP_KERNEL);
|
||||
if (!pn->ctl_compat_table)
|
||||
return -ENOMEM;
|
||||
|
||||
pn->ctl_compat_table[0].data = &in->timeout;
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int icmp_init_net(struct net *net, u_int16_t proto)
|
||||
{
|
||||
int ret;
|
||||
struct nf_icmp_net *in = icmp_pernet(net);
|
||||
struct nf_proto_net *pn = &in->pn;
|
||||
|
||||
in->timeout = nf_ct_icmp_timeout;
|
||||
|
||||
ret = icmp_kmemdup_compat_sysctl_table(pn, in);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = icmp_kmemdup_sysctl_table(pn, in);
|
||||
if (ret < 0)
|
||||
nf_ct_kfree_compat_sysctl_table(pn);
|
||||
|
||||
return ret;
|
||||
return icmp_kmemdup_sysctl_table(pn, in);
|
||||
}
|
||||
|
||||
static struct nf_proto_net *icmp_get_net_proto(struct net *net)
|
||||
|
||||
@@ -74,21 +74,19 @@ void nf_dup_ipv4(struct net *net, struct sk_buff *skb, unsigned int hooknum,
|
||||
nf_conntrack_get(skb->nfct);
|
||||
#endif
|
||||
/*
|
||||
* If we are in PREROUTING/INPUT, the checksum must be recalculated
|
||||
* since the length could have changed as a result of defragmentation.
|
||||
*
|
||||
* We also decrease the TTL to mitigate potential loops between two
|
||||
* hosts.
|
||||
* If we are in PREROUTING/INPUT, decrease the TTL to mitigate potential
|
||||
* loops between two hosts.
|
||||
*
|
||||
* Set %IP_DF so that the original source is notified of a potentially
|
||||
* decreased MTU on the clone route. IPv6 does this too.
|
||||
*
|
||||
* IP header checksum will be recalculated at ip_local_out.
|
||||
*/
|
||||
iph = ip_hdr(skb);
|
||||
iph->frag_off |= htons(IP_DF);
|
||||
if (hooknum == NF_INET_PRE_ROUTING ||
|
||||
hooknum == NF_INET_LOCAL_IN)
|
||||
--iph->ttl;
|
||||
ip_send_check(iph);
|
||||
|
||||
if (nf_dup_ipv4_route(net, skb, gw, oif)) {
|
||||
__this_cpu_write(nf_skb_duplicated, true);
|
||||
|
||||
@@ -62,7 +62,7 @@ static void dump_arp_packet(struct nf_log_buf *m,
|
||||
/* If it's for Ethernet and the lengths are OK, then log the ARP
|
||||
* payload.
|
||||
*/
|
||||
if (ah->ar_hrd != htons(1) ||
|
||||
if (ah->ar_hrd != htons(ARPHRD_ETHER) ||
|
||||
ah->ar_hln != ETH_ALEN ||
|
||||
ah->ar_pln != sizeof(__be32))
|
||||
return;
|
||||
@@ -111,8 +111,7 @@ static struct nf_logger nf_arp_logger __read_mostly = {
|
||||
|
||||
static int __net_init nf_log_arp_net_init(struct net *net)
|
||||
{
|
||||
nf_log_set(net, NFPROTO_ARP, &nf_arp_logger);
|
||||
return 0;
|
||||
return nf_log_set(net, NFPROTO_ARP, &nf_arp_logger);
|
||||
}
|
||||
|
||||
static void __net_exit nf_log_arp_net_exit(struct net *net)
|
||||
|
||||
@@ -347,8 +347,7 @@ static struct nf_logger nf_ip_logger __read_mostly = {
|
||||
|
||||
static int __net_init nf_log_ipv4_net_init(struct net *net)
|
||||
{
|
||||
nf_log_set(net, NFPROTO_IPV4, &nf_ip_logger);
|
||||
return 0;
|
||||
return nf_log_set(net, NFPROTO_IPV4, &nf_ip_logger);
|
||||
}
|
||||
|
||||
static void __net_exit nf_log_ipv4_net_exit(struct net *net)
|
||||
|
||||
@@ -379,8 +379,7 @@ static struct nf_logger nf_ip6_logger __read_mostly = {
|
||||
|
||||
static int __net_init nf_log_ipv6_net_init(struct net *net)
|
||||
{
|
||||
nf_log_set(net, NFPROTO_IPV6, &nf_ip6_logger);
|
||||
return 0;
|
||||
return nf_log_set(net, NFPROTO_IPV6, &nf_ip6_logger);
|
||||
}
|
||||
|
||||
static void __net_exit nf_log_ipv6_net_exit(struct net *net)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user