mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
This commit is contained in:
@@ -223,4 +223,7 @@ config LEDS_TRIGGER_DEFAULT_ON
|
||||
This allows LEDs to be initialised in the ON state.
|
||||
If unsure, say Y.
|
||||
|
||||
comment "iptables trigger is under Netfilter config (LED target)"
|
||||
depends on LEDS_TRIGGERS
|
||||
|
||||
endif # NEW_LEDS
|
||||
|
||||
@@ -7,16 +7,21 @@ header-y += xt_CLASSIFY.h
|
||||
header-y += xt_CONNMARK.h
|
||||
header-y += xt_CONNSECMARK.h
|
||||
header-y += xt_DSCP.h
|
||||
header-y += xt_LED.h
|
||||
header-y += xt_MARK.h
|
||||
header-y += xt_NFLOG.h
|
||||
header-y += xt_NFQUEUE.h
|
||||
header-y += xt_RATEEST.h
|
||||
header-y += xt_SECMARK.h
|
||||
header-y += xt_TCPMSS.h
|
||||
header-y += xt_TCPOPTSTRIP.h
|
||||
header-y += xt_TPROXY.h
|
||||
header-y += xt_comment.h
|
||||
header-y += xt_connbytes.h
|
||||
header-y += xt_connlimit.h
|
||||
header-y += xt_connmark.h
|
||||
header-y += xt_conntrack.h
|
||||
header-y += xt_cluster.h
|
||||
header-y += xt_dccp.h
|
||||
header-y += xt_dscp.h
|
||||
header-y += xt_esp.h
|
||||
@@ -30,6 +35,7 @@ header-y += xt_mark.h
|
||||
header-y += xt_multiport.h
|
||||
header-y += xt_owner.h
|
||||
header-y += xt_pkttype.h
|
||||
header-y += xt_quota.h
|
||||
header-y += xt_rateest.h
|
||||
header-y += xt_realm.h
|
||||
header-y += xt_recent.h
|
||||
@@ -39,6 +45,8 @@ header-y += xt_statistic.h
|
||||
header-y += xt_string.h
|
||||
header-y += xt_tcpmss.h
|
||||
header-y += xt_tcpudp.h
|
||||
header-y += xt_time.h
|
||||
header-y += xt_u32.h
|
||||
|
||||
unifdef-y += nf_conntrack_common.h
|
||||
unifdef-y += nf_conntrack_ftp.h
|
||||
|
||||
@@ -76,6 +76,7 @@ extern int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n);
|
||||
extern int nfnetlink_has_listeners(unsigned int group);
|
||||
extern int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group,
|
||||
int echo);
|
||||
extern void nfnetlink_set_err(u32 pid, u32 group, int error);
|
||||
extern int nfnetlink_unicast(struct sk_buff *skb, u_int32_t pid, int flags);
|
||||
|
||||
extern void nfnl_lock(void);
|
||||
|
||||
@@ -349,23 +349,22 @@ struct xt_table
|
||||
{
|
||||
struct list_head list;
|
||||
|
||||
/* A unique name... */
|
||||
const char name[XT_TABLE_MAXNAMELEN];
|
||||
|
||||
/* What hooks you will enter on */
|
||||
unsigned int valid_hooks;
|
||||
|
||||
/* Lock for the curtain */
|
||||
rwlock_t lock;
|
||||
struct mutex lock;
|
||||
|
||||
/* Man behind the curtain... */
|
||||
//struct ip6t_table_info *private;
|
||||
void *private;
|
||||
struct xt_table_info *private;
|
||||
|
||||
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
|
||||
struct module *me;
|
||||
|
||||
u_int8_t af; /* address/protocol family */
|
||||
|
||||
/* A unique name... */
|
||||
const char name[XT_TABLE_MAXNAMELEN];
|
||||
};
|
||||
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
@@ -386,7 +385,7 @@ struct xt_table_info
|
||||
|
||||
/* ipt_entry tables: one per CPU */
|
||||
/* Note : this field MUST be the last one, see XT_TABLE_INFO_SZ */
|
||||
char *entries[1];
|
||||
void *entries[1];
|
||||
};
|
||||
|
||||
#define XT_TABLE_INFO_SZ (offsetof(struct xt_table_info, entries) \
|
||||
@@ -433,6 +432,8 @@ extern void xt_proto_fini(struct net *net, u_int8_t af);
|
||||
|
||||
extern struct xt_table_info *xt_alloc_table_info(unsigned int size);
|
||||
extern void xt_free_table_info(struct xt_table_info *info);
|
||||
extern void xt_table_entry_swap_rcu(struct xt_table_info *old,
|
||||
struct xt_table_info *new);
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#include <net/compat.h>
|
||||
|
||||
13
include/linux/netfilter/xt_LED.h
Normal file
13
include/linux/netfilter/xt_LED.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef _XT_LED_H
|
||||
#define _XT_LED_H
|
||||
|
||||
struct xt_led_info {
|
||||
char id[27]; /* Unique ID for this trigger in the LED class */
|
||||
__u8 always_blink; /* Blink even if the LED is already on */
|
||||
__u32 delay; /* Delay until LED is switched off after trigger */
|
||||
|
||||
/* Kernel data used in the module */
|
||||
void *internal_data __attribute__((aligned(8)));
|
||||
};
|
||||
|
||||
#endif /* _XT_LED_H */
|
||||
15
include/linux/netfilter/xt_cluster.h
Normal file
15
include/linux/netfilter/xt_cluster.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef _XT_CLUSTER_MATCH_H
|
||||
#define _XT_CLUSTER_MATCH_H
|
||||
|
||||
enum xt_cluster_flags {
|
||||
XT_CLUSTER_F_INV = (1 << 0)
|
||||
};
|
||||
|
||||
struct xt_cluster_match_info {
|
||||
u_int32_t total_nodes;
|
||||
u_int32_t node_mask;
|
||||
u_int32_t hash_seed;
|
||||
u_int32_t flags;
|
||||
};
|
||||
|
||||
#endif /* _XT_CLUSTER_MATCH_H */
|
||||
@@ -4,6 +4,8 @@
|
||||
/* timings are in milliseconds. */
|
||||
#define XT_LIMIT_SCALE 10000
|
||||
|
||||
struct xt_limit_priv;
|
||||
|
||||
/* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490
|
||||
seconds, or one every 59 hours. */
|
||||
struct xt_rateinfo {
|
||||
@@ -11,11 +13,10 @@ struct xt_rateinfo {
|
||||
u_int32_t burst; /* Period multiplier for upper limit. */
|
||||
|
||||
/* Used internally by the kernel */
|
||||
unsigned long prev;
|
||||
u_int32_t credit;
|
||||
unsigned long prev; /* moved to xt_limit_priv */
|
||||
u_int32_t credit; /* moved to xt_limit_priv */
|
||||
u_int32_t credit_cap, cost;
|
||||
|
||||
/* Ugly, ugly fucker. */
|
||||
struct xt_rateinfo *master;
|
||||
struct xt_limit_priv *master;
|
||||
};
|
||||
#endif /*_XT_RATE_H*/
|
||||
|
||||
@@ -6,13 +6,15 @@ enum xt_quota_flags {
|
||||
};
|
||||
#define XT_QUOTA_MASK 0x1
|
||||
|
||||
struct xt_quota_priv;
|
||||
|
||||
struct xt_quota_info {
|
||||
u_int32_t flags;
|
||||
u_int32_t pad;
|
||||
|
||||
/* Used internally by the kernel */
|
||||
aligned_u64 quota;
|
||||
struct xt_quota_info *master;
|
||||
struct xt_quota_priv *master;
|
||||
};
|
||||
|
||||
#endif /* _XT_QUOTA_H */
|
||||
|
||||
@@ -13,6 +13,8 @@ enum xt_statistic_flags {
|
||||
};
|
||||
#define XT_STATISTIC_MASK 0x1
|
||||
|
||||
struct xt_statistic_priv;
|
||||
|
||||
struct xt_statistic_info {
|
||||
u_int16_t mode;
|
||||
u_int16_t flags;
|
||||
@@ -23,11 +25,10 @@ struct xt_statistic_info {
|
||||
struct {
|
||||
u_int32_t every;
|
||||
u_int32_t packet;
|
||||
/* Used internally by the kernel */
|
||||
u_int32_t count;
|
||||
u_int32_t count; /* unused */
|
||||
} nth;
|
||||
} u;
|
||||
struct xt_statistic_info *master __attribute__((aligned(8)));
|
||||
struct xt_statistic_priv *master __attribute__((aligned(8)));
|
||||
};
|
||||
|
||||
#endif /* _XT_STATISTIC_H */
|
||||
|
||||
@@ -11,6 +11,7 @@ header-y += ip6t_length.h
|
||||
header-y += ip6t_limit.h
|
||||
header-y += ip6t_mac.h
|
||||
header-y += ip6t_mark.h
|
||||
header-y += ip6t_mh.h
|
||||
header-y += ip6t_multiport.h
|
||||
header-y += ip6t_opts.h
|
||||
header-y += ip6t_owner.h
|
||||
|
||||
@@ -287,7 +287,7 @@ static inline int nf_ct_is_untracked(const struct sk_buff *skb)
|
||||
|
||||
extern int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp);
|
||||
extern unsigned int nf_conntrack_htable_size;
|
||||
extern int nf_conntrack_max;
|
||||
extern unsigned int nf_conntrack_max;
|
||||
|
||||
#define NF_CT_STAT_INC(net, count) \
|
||||
(per_cpu_ptr((net)->ct.stat, raw_smp_processor_id())->count++)
|
||||
|
||||
@@ -90,10 +90,7 @@ struct nf_conntrack_l4proto
|
||||
struct module *me;
|
||||
};
|
||||
|
||||
/* Existing built-in protocols */
|
||||
extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6;
|
||||
extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4;
|
||||
extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6;
|
||||
/* Existing built-in generic protocol */
|
||||
extern struct nf_conntrack_l4proto nf_conntrack_l4proto_generic;
|
||||
|
||||
#define MAX_NF_CT_PROTO 256
|
||||
@@ -101,11 +98,6 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_generic;
|
||||
extern struct nf_conntrack_l4proto *
|
||||
__nf_ct_l4proto_find(u_int16_t l3proto, u_int8_t l4proto);
|
||||
|
||||
extern struct nf_conntrack_l4proto *
|
||||
nf_ct_l4proto_find_get(u_int16_t l3proto, u_int8_t protocol);
|
||||
|
||||
extern void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p);
|
||||
|
||||
/* Protocol registration. */
|
||||
extern int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *proto);
|
||||
extern void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *proto);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef _NF_LOG_H
|
||||
#define _NF_LOG_H
|
||||
|
||||
#include <linux/netfilter.h>
|
||||
|
||||
/* those NF_LOG_* defines and struct nf_loginfo are legacy definitios that will
|
||||
* disappear once iptables is replaced with pkttables. Please DO NOT use them
|
||||
* for any new code! */
|
||||
@@ -40,12 +42,15 @@ struct nf_logger {
|
||||
struct module *me;
|
||||
nf_logfn *logfn;
|
||||
char *name;
|
||||
struct list_head list[NFPROTO_NUMPROTO];
|
||||
};
|
||||
|
||||
/* Function to register/unregister log function. */
|
||||
int nf_log_register(u_int8_t pf, const struct nf_logger *logger);
|
||||
void nf_log_unregister(const struct nf_logger *logger);
|
||||
void nf_log_unregister_pf(u_int8_t pf);
|
||||
int nf_log_register(u_int8_t pf, struct nf_logger *logger);
|
||||
void nf_log_unregister(struct nf_logger *logger);
|
||||
|
||||
int nf_log_bind_pf(u_int8_t pf, const struct nf_logger *logger);
|
||||
void nf_log_unbind_pf(u_int8_t pf);
|
||||
|
||||
/* Calls the registered backend logging function */
|
||||
void nf_log_packet(u_int8_t pf,
|
||||
|
||||
@@ -46,7 +46,6 @@ static struct ebt_table broute_table =
|
||||
.name = "broute",
|
||||
.table = &initial_table,
|
||||
.valid_hooks = 1 << NF_BR_BROUTING,
|
||||
.lock = __RW_LOCK_UNLOCKED(broute_table.lock),
|
||||
.check = check,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
@@ -55,7 +55,6 @@ static struct ebt_table frame_filter =
|
||||
.name = "filter",
|
||||
.table = &initial_table,
|
||||
.valid_hooks = FILTER_VALID_HOOKS,
|
||||
.lock = __RW_LOCK_UNLOCKED(frame_filter.lock),
|
||||
.check = check,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
@@ -55,7 +55,6 @@ static struct ebt_table frame_nat =
|
||||
.name = "nat",
|
||||
.table = &initial_table,
|
||||
.valid_hooks = NAT_VALID_HOOKS,
|
||||
.lock = __RW_LOCK_UNLOCKED(frame_nat.lock),
|
||||
.check = check,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
@@ -31,7 +31,7 @@ config NF_CONNTRACK_PROC_COMPAT
|
||||
default y
|
||||
help
|
||||
This option enables /proc and sysctl compatibility with the old
|
||||
layer 3 dependant connection tracking. This is needed to keep
|
||||
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.
|
||||
@@ -95,11 +95,11 @@ config IP_NF_MATCH_ECN
|
||||
config IP_NF_MATCH_TTL
|
||||
tristate '"ttl" match support'
|
||||
depends on NETFILTER_ADVANCED
|
||||
help
|
||||
This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user
|
||||
to match packets by their TTL value.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
select NETFILTER_XT_MATCH_HL
|
||||
---help---
|
||||
This is a backwards-compat option for the user's convenience
|
||||
(e.g. when running oldconfig). It selects
|
||||
CONFIG_NETFILTER_XT_MATCH_HL.
|
||||
|
||||
# `filter', generic and specific targets
|
||||
config IP_NF_FILTER
|
||||
@@ -323,19 +323,13 @@ config IP_NF_TARGET_ECN
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_TARGET_TTL
|
||||
tristate 'TTL target support'
|
||||
depends on IP_NF_MANGLE
|
||||
tristate '"TTL" target support'
|
||||
depends on NETFILTER_ADVANCED
|
||||
help
|
||||
This option adds a `TTL' target, which enables the user to modify
|
||||
the TTL value of the IP header.
|
||||
|
||||
While it is safe to decrement/lower the TTL, this target also enables
|
||||
functionality to increment and set the TTL value of the IP header to
|
||||
arbitrary values. This is EXTREMELY DANGEROUS since you can easily
|
||||
create immortal packets that loop forever on the network.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
select NETFILTER_XT_TARGET_HL
|
||||
---help---
|
||||
This is a backwards-compat option for the user's convenience
|
||||
(e.g. when running oldconfig). It selects
|
||||
CONFIG_NETFILTER_XT_TARGET_HL.
|
||||
|
||||
# raw + specific targets
|
||||
config IP_NF_RAW
|
||||
|
||||
@@ -51,7 +51,6 @@ obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
|
||||
|
||||
# targets
|
||||
obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
|
||||
@@ -61,7 +60,6 @@ obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
|
||||
|
||||
# generic ARP tables
|
||||
|
||||
@@ -73,6 +73,36 @@ static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap,
|
||||
return (ret != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unfortunatly, _b and _mask are not aligned to an int (or long int)
|
||||
* Some arches dont care, unrolling the loop is a win on them.
|
||||
*/
|
||||
static unsigned long ifname_compare(const char *_a, const char *_b, const char *_mask)
|
||||
{
|
||||
#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
|
||||
const unsigned long *a = (const unsigned long *)_a;
|
||||
const unsigned long *b = (const unsigned long *)_b;
|
||||
const unsigned long *mask = (const unsigned long *)_mask;
|
||||
unsigned long ret;
|
||||
|
||||
ret = (a[0] ^ b[0]) & mask[0];
|
||||
if (IFNAMSIZ > sizeof(unsigned long))
|
||||
ret |= (a[1] ^ b[1]) & mask[1];
|
||||
if (IFNAMSIZ > 2 * sizeof(unsigned long))
|
||||
ret |= (a[2] ^ b[2]) & mask[2];
|
||||
if (IFNAMSIZ > 3 * sizeof(unsigned long))
|
||||
ret |= (a[3] ^ b[3]) & mask[3];
|
||||
BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long));
|
||||
#else
|
||||
unsigned long ret = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < IFNAMSIZ; i++)
|
||||
ret |= (_a[i] ^ _b[i]) & _mask[i];
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Returns whether packet matches rule or not. */
|
||||
static inline int arp_packet_match(const struct arphdr *arphdr,
|
||||
struct net_device *dev,
|
||||
@@ -83,7 +113,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
|
||||
const char *arpptr = (char *)(arphdr + 1);
|
||||
const char *src_devaddr, *tgt_devaddr;
|
||||
__be32 src_ipaddr, tgt_ipaddr;
|
||||
int i, ret;
|
||||
long ret;
|
||||
|
||||
#define FWINV(bool, invflg) ((bool) ^ !!(arpinfo->invflags & (invflg)))
|
||||
|
||||
@@ -156,10 +186,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
|
||||
}
|
||||
|
||||
/* Look for ifname matches. */
|
||||
for (i = 0, ret = 0; i < IFNAMSIZ; i++) {
|
||||
ret |= (indev[i] ^ arpinfo->iniface[i])
|
||||
& arpinfo->iniface_mask[i];
|
||||
}
|
||||
ret = ifname_compare(indev, arpinfo->iniface, arpinfo->iniface_mask);
|
||||
|
||||
if (FWINV(ret != 0, ARPT_INV_VIA_IN)) {
|
||||
dprintf("VIA in mismatch (%s vs %s).%s\n",
|
||||
@@ -168,10 +195,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0, ret = 0; i < IFNAMSIZ; i++) {
|
||||
ret |= (outdev[i] ^ arpinfo->outiface[i])
|
||||
& arpinfo->outiface_mask[i];
|
||||
}
|
||||
ret = ifname_compare(outdev, arpinfo->outiface, arpinfo->outiface_mask);
|
||||
|
||||
if (FWINV(ret != 0, ARPT_INV_VIA_OUT)) {
|
||||
dprintf("VIA out mismatch (%s vs %s).%s\n",
|
||||
@@ -221,7 +245,7 @@ unsigned int arpt_do_table(struct sk_buff *skb,
|
||||
const struct net_device *out,
|
||||
struct xt_table *table)
|
||||
{
|
||||
static const char nulldevname[IFNAMSIZ];
|
||||
static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
|
||||
unsigned int verdict = NF_DROP;
|
||||
const struct arphdr *arp;
|
||||
bool hotdrop = false;
|
||||
@@ -237,9 +261,10 @@ unsigned int arpt_do_table(struct sk_buff *skb,
|
||||
indev = in ? in->name : nulldevname;
|
||||
outdev = out ? out->name : nulldevname;
|
||||
|
||||
read_lock_bh(&table->lock);
|
||||
private = table->private;
|
||||
table_base = (void *)private->entries[smp_processor_id()];
|
||||
rcu_read_lock();
|
||||
private = rcu_dereference(table->private);
|
||||
table_base = rcu_dereference(private->entries[smp_processor_id()]);
|
||||
|
||||
e = get_entry(table_base, private->hook_entry[hook]);
|
||||
back = get_entry(table_base, private->underflow[hook]);
|
||||
|
||||
@@ -311,7 +336,8 @@ unsigned int arpt_do_table(struct sk_buff *skb,
|
||||
e = (void *)e + e->next_offset;
|
||||
}
|
||||
} while (!hotdrop);
|
||||
read_unlock_bh(&table->lock);
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
if (hotdrop)
|
||||
return NF_DROP;
|
||||
@@ -714,11 +740,65 @@ static void get_counters(const struct xt_table_info *t,
|
||||
}
|
||||
}
|
||||
|
||||
static inline struct xt_counters *alloc_counters(struct xt_table *table)
|
||||
|
||||
/* We're lazy, and add to the first CPU; overflow works its fey magic
|
||||
* and everything is OK. */
|
||||
static int
|
||||
add_counter_to_entry(struct arpt_entry *e,
|
||||
const struct xt_counters addme[],
|
||||
unsigned int *i)
|
||||
{
|
||||
ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt);
|
||||
|
||||
(*i)++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Take values from counters and add them back onto the current cpu */
|
||||
static void put_counters(struct xt_table_info *t,
|
||||
const struct xt_counters counters[])
|
||||
{
|
||||
unsigned int i, cpu;
|
||||
|
||||
local_bh_disable();
|
||||
cpu = smp_processor_id();
|
||||
i = 0;
|
||||
ARPT_ENTRY_ITERATE(t->entries[cpu],
|
||||
t->size,
|
||||
add_counter_to_entry,
|
||||
counters,
|
||||
&i);
|
||||
local_bh_enable();
|
||||
}
|
||||
|
||||
static inline int
|
||||
zero_entry_counter(struct arpt_entry *e, void *arg)
|
||||
{
|
||||
e->counters.bcnt = 0;
|
||||
e->counters.pcnt = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
clone_counters(struct xt_table_info *newinfo, const struct xt_table_info *info)
|
||||
{
|
||||
unsigned int cpu;
|
||||
const void *loc_cpu_entry = info->entries[raw_smp_processor_id()];
|
||||
|
||||
memcpy(newinfo, info, offsetof(struct xt_table_info, entries));
|
||||
for_each_possible_cpu(cpu) {
|
||||
memcpy(newinfo->entries[cpu], loc_cpu_entry, info->size);
|
||||
ARPT_ENTRY_ITERATE(newinfo->entries[cpu], newinfo->size,
|
||||
zero_entry_counter, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static struct xt_counters *alloc_counters(struct xt_table *table)
|
||||
{
|
||||
unsigned int countersize;
|
||||
struct xt_counters *counters;
|
||||
const struct xt_table_info *private = table->private;
|
||||
struct xt_table_info *private = table->private;
|
||||
struct xt_table_info *info;
|
||||
|
||||
/* We need atomic snapshot of counters: rest doesn't change
|
||||
* (other than comefrom, which userspace doesn't care
|
||||
@@ -728,14 +808,30 @@ static inline struct xt_counters *alloc_counters(struct xt_table *table)
|
||||
counters = vmalloc_node(countersize, numa_node_id());
|
||||
|
||||
if (counters == NULL)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
goto nomem;
|
||||
|
||||
/* First, sum counters... */
|
||||
write_lock_bh(&table->lock);
|
||||
get_counters(private, counters);
|
||||
write_unlock_bh(&table->lock);
|
||||
info = xt_alloc_table_info(private->size);
|
||||
if (!info)
|
||||
goto free_counters;
|
||||
|
||||
clone_counters(info, private);
|
||||
|
||||
mutex_lock(&table->lock);
|
||||
xt_table_entry_swap_rcu(private, info);
|
||||
synchronize_net(); /* Wait until smoke has cleared */
|
||||
|
||||
get_counters(info, counters);
|
||||
put_counters(private, counters);
|
||||
mutex_unlock(&table->lock);
|
||||
|
||||
xt_free_table_info(info);
|
||||
|
||||
return counters;
|
||||
|
||||
free_counters:
|
||||
vfree(counters);
|
||||
nomem:
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
static int copy_entries_to_user(unsigned int total_size,
|
||||
@@ -1075,20 +1171,6 @@ static int do_replace(struct net *net, void __user *user, unsigned int len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* We're lazy, and add to the first CPU; overflow works its fey magic
|
||||
* and everything is OK.
|
||||
*/
|
||||
static inline int add_counter_to_entry(struct arpt_entry *e,
|
||||
const struct xt_counters addme[],
|
||||
unsigned int *i)
|
||||
{
|
||||
|
||||
ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt);
|
||||
|
||||
(*i)++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_add_counters(struct net *net, void __user *user, unsigned int len,
|
||||
int compat)
|
||||
{
|
||||
@@ -1148,13 +1230,14 @@ static int do_add_counters(struct net *net, void __user *user, unsigned int len,
|
||||
goto free;
|
||||
}
|
||||
|
||||
write_lock_bh(&t->lock);
|
||||
mutex_lock(&t->lock);
|
||||
private = t->private;
|
||||
if (private->number != num_counters) {
|
||||
ret = -EINVAL;
|
||||
goto unlock_up_free;
|
||||
}
|
||||
|
||||
preempt_disable();
|
||||
i = 0;
|
||||
/* Choose the copy that is on our node */
|
||||
loc_cpu_entry = private->entries[smp_processor_id()];
|
||||
@@ -1163,8 +1246,10 @@ static int do_add_counters(struct net *net, void __user *user, unsigned int len,
|
||||
add_counter_to_entry,
|
||||
paddc,
|
||||
&i);
|
||||
preempt_enable();
|
||||
unlock_up_free:
|
||||
write_unlock_bh(&t->lock);
|
||||
mutex_unlock(&t->lock);
|
||||
|
||||
xt_table_unlock(t);
|
||||
module_put(t->me);
|
||||
free:
|
||||
|
||||
@@ -48,8 +48,6 @@ static struct
|
||||
static struct xt_table packet_filter = {
|
||||
.name = "filter",
|
||||
.valid_hooks = FILTER_VALID_HOOKS,
|
||||
.lock = __RW_LOCK_UNLOCKED(packet_filter.lock),
|
||||
.private = NULL,
|
||||
.me = THIS_MODULE,
|
||||
.af = NFPROTO_ARP,
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user