SOURCES (LINUX_2_6): pom-ng-connrate-20060504.patch (NEW) - kernel...
cieciwa
cieciwa at pld-linux.org
Thu May 11 12:38:19 CEST 2006
Author: cieciwa Date: Thu May 11 10:38:19 2006 GMT
Module: SOURCES Tag: LINUX_2_6
---- Log message:
- kernel connrate module 20060504 snap.
---- Files affected:
SOURCES:
pom-ng-connrate-20060504.patch (NONE -> 1.1.2.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/pom-ng-connrate-20060504.patch
diff -u /dev/null SOURCES/pom-ng-connrate-20060504.patch:1.1.2.1
--- /dev/null Thu May 11 12:38:19 2006
+++ SOURCES/pom-ng-connrate-20060504.patch Thu May 11 12:38:14 2006
@@ -0,0 +1,318 @@
+ include/linux/netfilter_ipv4/ip_conntrack_rate.h | 32 +++++
+ include/linux/netfilter_ipv4/ipt_connrate.h | 12 ++
+ net/ipv4/netfilter/Kconfig | 29 +++++
+ net/ipv4/netfilter/Makefile | 2
+ net/ipv4/netfilter/ip_conntrack_rate.c | 133 +++++++++++++++++++++++
+ net/ipv4/netfilter/ipt_connrate.c | 73 ++++++++++++
+ 6 files changed, 281 insertions(+)
+
+diff -Nur --exclude '*.orig' linux.org/include/linux/netfilter_ipv4/ip_conntrack_rate.h linux/include/linux/netfilter_ipv4/ip_conntrack_rate.h
+--- linux.org/include/linux/netfilter_ipv4/ip_conntrack_rate.h 1970-01-01 01:00:00.000000000 +0100
++++ linux/include/linux/netfilter_ipv4/ip_conntrack_rate.h 2006-05-11 12:35:34.000000000 +0200
+@@ -0,0 +1,32 @@
++#ifndef _IP_CONNTRACK_RATE_H
++#define _IP_CONNTRACK_RATE_H
++
++/* estimation interval, in jiffies */
++#define IP_CONNTRACK_RATE_INTERVAL (3 * HZ)
++
++/* scale on how many tokens per byte to generate */
++#define IP_CONNTRACK_RATE_SCALE 100
++
++/* per conntrack: transfer rate in connection */
++struct ip_conntrack_rate {
++ /* jiffies of previous received packet */
++ unsigned long prev;
++ /* average rate of tokens per jiffy */
++ u_int32_t avgrate;
++};
++
++#ifdef __KERNEL__
++
++/* Count a packet of len into given rate structure. */
++extern void
++ip_conntrack_rate_count(struct ip_conntrack_rate *ctr, unsigned int len);
++
++/* Return current rate as bytes per second. Note that the returned
++ rate is the rate at last received packet, not counting time has
++ that passed after it. */
++extern u_int32_t
++ip_conntrack_rate_get(struct ip_conntrack_rate *ctr);
++
++#endif /* __KERNEL__ */
++
++#endif /* _IP_CONNTRACK_RATE_H */
+diff -Nur --exclude '*.orig' linux.org/include/linux/netfilter_ipv4/ipt_connrate.h linux/include/linux/netfilter_ipv4/ipt_connrate.h
+--- linux.org/include/linux/netfilter_ipv4/ipt_connrate.h 1970-01-01 01:00:00.000000000 +0100
++++ linux/include/linux/netfilter_ipv4/ipt_connrate.h 2006-05-11 12:35:34.000000000 +0200
+@@ -0,0 +1,12 @@
++#ifndef _IPT_CONNRATE_H
++#define _IPT_CONNRATE_H
++
++struct ipt_connrate_info
++{
++ /* Per connection transfer rate, in bytes per second. If
++ 'from' is smaller or equal to 'to', rate is matched to be
++ inside the inclusive range [from,to], otherwise rate is
++ matched to be outside the inclusive range [to,from]. */
++ u_int32_t from, to;
++};
++#endif
+diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/Kconfig linux/net/ipv4/netfilter/Kconfig
+--- linux.org/net/ipv4/netfilter/Kconfig 2006-05-02 23:38:44.000000000 +0200
++++ linux/net/ipv4/netfilter/Kconfig 2006-05-11 12:35:34.000000000 +0200
+@@ -606,5 +606,34 @@
+ Allows altering the ARP packet payload: source and destination
+ hardware and network addresses.
+
++config IP_NF_CONNTRACK_RATE
++ bool "Connection rate estimation"
++ depends on IP_NF_CONNTRACK
++ help
++
++ This enables per connection transfer rate estimation in connection
++ tracking code. This enlarges the amount of memory required by each
++ connection tracked a bit and adds the overhead of calculating the
++ transmission rate on every received packet.
++
++ This is required to be able to match on the per connection transfer
++ rate, and can be a nice statistic to see in the connection tracking
++ table, but is useless otherwise.
++
++ If unsure, say N.
++
++config IP_NF_MATCH_CONNRATE
++ tristate "Connection rate match support"
++ depends on IP_NF_CONNTRACK_RATE && IP_NF_CONNTRACK && IP_NF_IPTABLES
++ help
++ This allows matching on the transfer rate on a per connection basis.
++
++ Connection transfer rate estimation is performed separately by the
++ connection tracking code and is unaffected by the presence of matches
++ on it. Several connection rate matches may match a single packet and
++ every match will see the same rate.
++
++ To compile it as a module, choose M here. If unsure, say N.
++
+ endmenu
+
+diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/Makefile linux/net/ipv4/netfilter/Makefile
+--- linux.org/net/ipv4/netfilter/Makefile 2006-05-02 23:38:44.000000000 +0200
++++ linux/net/ipv4/netfilter/Makefile 2006-05-11 12:35:34.000000000 +0200
+@@ -0,0 +0,2 @@
++obj-$(CONFIG_IP_NF_CONNTRACK_RATE) += ip_conntrack_rate.o
++obj-$(CONFIG_IP_NF_MATCH_CONNRATE) += ipt_connrate.o
+diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/ip_conntrack_rate.c linux/net/ipv4/netfilter/ip_conntrack_rate.c
+--- linux.org/net/ipv4/netfilter/ip_conntrack_rate.c 1970-01-01 01:00:00.000000000 +0100
++++ linux/net/ipv4/netfilter/ip_conntrack_rate.c 2006-05-11 12:35:34.000000000 +0200
+@@ -0,0 +1,133 @@
++/* Connection transfer rate estimator for netfilter.
++ *
++ * Copyright (c) 2004 Nuutti Kotivuori <naked at iki.fi>
++ *
++ * 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/config.h>
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/skbuff.h>
++#include <linux/jiffies.h>
++#include <linux/netfilter_ipv4/ip_conntrack_rate.h>
++
++/*
++ I wanted to build a simpler and more robust rate estimator than the
++ one used in sched/estimator.c. After evaluating a few choices I
++ settled with the one given in an example in [RFC2859], which is the
++ rate estimator described in [TON98].
++
++ I will copy the example table from [RFC2859] here:
++
++========================================================================
++|Initially: |
++| |
++| AVG_INTERVAL = a constant; |
++| avg-rate = CTR; |
++| t-front = 0; |
++| |
++|Upon each packet's arrival, the rate estimator updates its variables: |
++| |
++| Bytes_in_win = avg-rate * AVG_INTERVAL; |
++| New_bytes = Bytes_in_win + pkt_size; |
++| avg-rate = New_bytes/( now - t-front + AVG_INTERVAL); |
++| t-front = now; |
++| |
++|Where: |
++| now = The time of the current packet arrival |
++| pkt_size = The packet size in bytes of the arriving packet |
++| avg-rate = Measured Arrival Rate of traffic stream |
++| AVG_INTERVAL = Time window over which history is kept |
++| |
++| |
++| Figure 2. Example Rate Estimator Algorithm |
++| |
++========================================================================
++
++ Additionally we have to be concerned about overflows, remainders
++ and resolution in the algorithm. These are documented in the code
++ below.
++
++ References:
++
++ [RFC2859] W. Fang, N. Seddigh and B. Nandy, "A Time Sliding Window
++ Three Colour Marker (TSWTCM)", RFC 2859, June 2000.
++
++ [TON98] D.D. Clark, W. Fang, "Explicit Allocation of Best Effort
++ Packet Delivery Service", IEEE/ACM Transactions on
++ Networking, August 1998, Vol 6. No. 4, pp. 362-373.
++*/
++
++/* There are three important limits which need to be explored: maximum
++ expressable rate, minimum expressable rate, minimum packet size to
++ be countable.
++
++ Maximum expressable rate depends on the size of the window and the
++ scale we have chosen. It is approximately 2^32 / window /
++ scale. For example with a window of 3 seconds and a scale of 100,
++ the maximum rate is 14 megabytes per second, eg. 115Mbit/s.
++
++ Minimum expressable rate depends on scale and the HZ on the
++ architecture. It is HZ / scale. For example on most platforms where
++ HZ is now 1000, this is 10 bytes per second, eg. 0.08kbit/s.
++
++ Minimum packet size to be countable depends on the window size,
++ scale and HZ. This is basically the smallest packet that when
++ arriving immediately after the previous packet can cause the
++ average rate to rise from zero to one. It is (HZ * window) /
++ scale. For example with a window of 3 seconds, a scale of 100 and a
++ HZ of 1000, this would be 30. That is, a continuous stream of
++ packets less than 30 bytes long would not be able to rise the rate
++ above zero.
++
++ These limitations are a simple consequence of the current
++ implementation using integer arithmetics. */
++
++/* Maximum number of tokens in total that we can have in a window is
++ limited by the range of the u_int32_t datatype. We prevent the
++ overflow of this by first calculating the maximum amount of tokens
++ a single packet can add and substracting that from the maximum
++ value the window can get. */
++#define MAX_PACKET_IN_TOKENS (0x0000ffff * IP_CONNTRACK_RATE_SCALE)
++#define MAX_TOKENS_IN_WINDOW (0xffffffff - MAX_PACKET_IN_TOKENS)
++
++/* Synchronizes all accesses to ip_conntrack_rate structures. */
++static DEFINE_RWLOCK(rate_lock);
++
++void
++ip_conntrack_rate_count(struct ip_conntrack_rate *ctr, unsigned int len)
++{
++ u_int32_t new_bytes;
++ unsigned long now = jiffies;
++
++ write_lock_bh(&rate_lock);
++ new_bytes = (ctr->avgrate * IP_CONNTRACK_RATE_INTERVAL +
++ len * IP_CONNTRACK_RATE_SCALE);
++ if(new_bytes > MAX_TOKENS_IN_WINDOW)
++ new_bytes = MAX_TOKENS_IN_WINDOW;
++ if(now >= ctr->prev) /* Ignore packets at possible jiffie wraps */
++ ctr->avgrate = new_bytes / (now - ctr->prev +
++ IP_CONNTRACK_RATE_INTERVAL);
++ ctr->prev = now;
++ write_unlock_bh(&rate_lock);
++}
++
++u_int32_t
++ip_conntrack_rate_get(struct ip_conntrack_rate *ctr)
++{
++ u_int32_t rate;
++
++ read_lock_bh(&rate_lock);
++ /* Rate can not overflow here if IP_CONNTRACK_RATE_INTERVAL is
++ atleast HZ. If it is not, we could change the order of
++ calculations at the possible cost of precision. */
++ rate = ctr->avgrate * HZ / IP_CONNTRACK_RATE_SCALE;
++ read_unlock_bh(&rate_lock);
++ return rate;
++}
++
++EXPORT_SYMBOL(ip_conntrack_rate_count);
++EXPORT_SYMBOL(ip_conntrack_rate_get);
+diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/ipt_connrate.c linux/net/ipv4/netfilter/ipt_connrate.c
+--- linux.org/net/ipv4/netfilter/ipt_connrate.c 1970-01-01 01:00:00.000000000 +0100
++++ linux/net/ipv4/netfilter/ipt_connrate.c 2006-05-11 12:35:34.000000000 +0200
+@@ -0,0 +1,73 @@
++/* Connection transfer rate match for netfilter.
++ *
++ * Copyright (c) 2004 Nuutti Kotivuori <naked at iki.fi>
++ *
++ * 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/module.h>
++#include <linux/skbuff.h>
++#include <linux/netfilter_ipv4/ip_conntrack.h>
++#include <linux/netfilter_ipv4/ip_tables.h>
++#include <linux/netfilter_ipv4/ipt_connrate.h>
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Nuutti Kotivuori <naked at iki.fi>");
++MODULE_DESCRIPTION("iptables connection transfer rate match module");
++
++static int
++match(const struct sk_buff *skb,
++ const struct net_device *in,
++ const struct net_device *out,
++ const void *matchinfo,
++ int offset,
++ int *hotdrop)
++{
++ const struct ipt_connrate_info *sinfo = matchinfo;
++ struct ip_conntrack *ct;
++ enum ip_conntrack_info ctinfo;
++ u_int32_t rate;
++
++ if (!(ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo)))
++ return 0; /* no match */
++
++ rate = ip_conntrack_rate_get(&ct->rate);
++ if (sinfo->from > sinfo->to) /* inverted range */
++ return (rate < sinfo->to || rate > sinfo->from);
++ else /* normal range */
++ return (rate >= sinfo->from && rate <= sinfo->to);
++}
++
++static int
++check(const char *tablename,
++ const struct ipt_ip *ip,
++ void *matchinfo,
++ unsigned int matchsize,
++ unsigned int hook_mask)
++{
++ if (matchsize != IPT_ALIGN(sizeof(struct ipt_connrate_info)))
++ return 0;
++
++ return 1;
++}
++
++static struct ipt_match connrate_match = {
++ .name = "connrate",
++ .match = &match,
++ .checkentry = &check,
++ .me = THIS_MODULE
++};
++
++static int __init init(void)
++{
++ return ipt_register_match(&connrate_match);
++}
++
++static void __exit fini(void)
++{
++ ipt_unregister_match(&connrate_match);
++}
++
++module_init(init);
++module_exit(fini);
================================================================
More information about the pld-cvs-commit
mailing list