Le mercredi 26 mai 2010 à 11:47 +0200, Jan Engelhardt a écrit : > On Wednesday 2010-05-26 10:11, Eric Dumazet wrote: > >Le mardi 25 mai 2010 à 21:31 -0300, Felipe W Damasio a écrit : > >> > >> So I'd like to know if I can cycle through all these rules based on > >> the number of connections. > >> > >> Is it possible? > >> > >> If it isn't currently, can this functionality be added? How can I help? > > > >So all connections are coming from the NAT device, with a single IP, and > >ports from say 30000 to 60000 (check your NAT device) > > > >iptables -t mangle -A PREROUTING -i eth0 -p tcp --dport 80 -m multiport > >--source-ports 30000:31000 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 3127 > > There may be a non-uniform distribution so it may not be advisable. > Instead perhaps, > > -A PREROUTING -m conntrack --ctstate NEW -j extrachain > for (I = 0; I < N; ++I) > -A extrachain -m statistic --mode nth --every I \ > -j CONNMARK --set-mark I > for (I = 0; I < N; ++I) > -A PREROUTING -m connmark --mark I -j TPROXY \ > --tproxy-mark I/0xff --on-port I+3127 ok, you probably meant "-A extrachain -m statistic --mode nth --every N ..." packet for target "N" will take N time the nth_lock spinlock, but yes, it should work. This nth_lock should be removed BTW... [PATCH] netfilter: xt_statistic: remove nth_lock spinlock Use atomic_cmpxchg() to avoid dirtying a shared location. xt_statistic_priv smp aligned to avoid sharing same cache line with other stuff. Signed-off-by: Eric Dumazet <eric.dumazet@xxxxxxxxx> --- diff --git a/net/netfilter/xt_statistic.c b/net/netfilter/xt_statistic.c index 96e62b8..0114d2b 100644 --- a/net/netfilter/xt_statistic.c +++ b/net/netfilter/xt_statistic.c @@ -18,8 +18,8 @@ #include <linux/netfilter/x_tables.h> struct xt_statistic_priv { - uint32_t count; -}; + atomic_t count; +} ____cacheline_aligned_in_smp; MODULE_LICENSE("GPL"); MODULE_AUTHOR("Patrick McHardy <kaber@xxxxxxxxx>"); @@ -27,13 +27,12 @@ MODULE_DESCRIPTION("Xtables: statistics-based matching (\"Nth\", random)"); MODULE_ALIAS("ipt_statistic"); MODULE_ALIAS("ip6t_statistic"); -static DEFINE_SPINLOCK(nth_lock); - static bool statistic_mt(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_statistic_info *info = par->matchinfo; bool ret = info->flags & XT_STATISTIC_INVERT; + int nval, oval; switch (info->mode) { case XT_STATISTIC_MODE_RANDOM: @@ -41,12 +40,14 @@ statistic_mt(const struct sk_buff *skb, struct xt_action_param *par) ret = !ret; break; case XT_STATISTIC_MODE_NTH: - spin_lock_bh(&nth_lock); - if (info->master->count++ == info->u.nth.every) { - info->master->count = 0; + do { + oval = atomic_read(&info->master->count); + nval = oval + 1; + if (nval == info->u.nth.every) + nval = 0; + } while (atomic_cmpxchg(&info->master->count, oval, nval) != oval); + if (nval == 0) ret = !ret; - } - spin_unlock_bh(&nth_lock); break; } @@ -64,7 +65,7 @@ static int statistic_mt_check(const struct xt_mtchk_param *par) info->master = kzalloc(sizeof(*info->master), GFP_KERNEL); if (info->master == NULL) return -ENOMEM; - info->master->count = info->u.nth.count; + atomic_set(&info->master->count, info->u.nth.count); return 0; } -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html