]> git.hungrycats.org Git - linux/commitdiff
[NETFILTER]: Resync with 2.4.x
authorHarald Welte <laforge@gnumonks.org>
Fri, 20 Feb 2004 06:52:20 +0000 (22:52 -0800)
committerDavid Woodhouse <dwmw2@dwmw2.baythorne.internal>
Fri, 20 Feb 2004 06:52:20 +0000 (22:52 -0800)
- Update listhelp.h to benefit from prefetching
- More efficient selective_cleanup() impl. in conntrack
- Export number of conntrack buckets via r/o sysctl.

include/linux/netfilter_ipv4/listhelp.h
include/linux/sysctl.h
net/ipv4/netfilter/ip_conntrack_core.c
net/ipv4/netfilter/ip_conntrack_standalone.c

index f19f448889d168e610f38c3734a6fb50b66c0cdc..f2ae7c5e57bb72bccfc46d3202e53b99a55aff19 100644 (file)
    required to allow inlining of cmpfn. */
 #define LIST_FIND(head, cmpfn, type, args...)          \
 ({                                                     \
-       const struct list_head *__i = (head);           \
+       const struct list_head *__i, *__j = NULL;       \
                                                        \
        ASSERT_READ_LOCK(head);                         \
-       do {                                            \
-               __i = __i->next;                        \
-               if (__i == (head)) {                    \
-                       __i = NULL;                     \
+       list_for_each(__i, (head))                      \
+               if (cmpfn((const type)__i , ## args)) { \
+                       __j = __i;                      \
                        break;                          \
                }                                       \
-       } while (!cmpfn((const type)__i , ## args));    \
-       (type)__i;                                      \
+       (type)__j;                                      \
 })
 
-#define LIST_FIND_W(head, cmpfn, type, args...)        \
-({                                             \
-       const struct list_head *__i = (head);   \
-                                               \
-       ASSERT_WRITE_LOCK(head);                \
-       do {                                    \
-               __i = __i->next;                \
-               if (__i == (head)) {            \
-                       __i = NULL;             \
-                       break;                  \
-               }                               \
-       } while (!cmpfn((type)__i , ## args));  \
-       (type)__i;                              \
+#define LIST_FIND_W(head, cmpfn, type, args...)                \
+({                                                     \
+       const struct list_head *__i, *__j = NULL;       \
+                                                       \
+       ASSERT_WRITE_LOCK(head);                        \
+       list_for_each(__i, (head))                      \
+               if (cmpfn((type)__i , ## args)) {       \
+                       __j = __i;                      \
+                       break;                          \
+               }                                       \
+       (type)__j;                                      \
 })
 
 /* Just like LIST_FIND but we search backwards */
 #define LIST_FIND_B(head, cmpfn, type, args...)                \
 ({                                                     \
-       const struct list_head *__i = (head);           \
+       const struct list_head *__i, *__j = NULL;       \
                                                        \
        ASSERT_READ_LOCK(head);                         \
-       do {                                            \
-               __i = __i->prev;                        \
-               if (__i == (head)) {                    \
-                       __i = NULL;                     \
+       list_for_each_prev(__i, (head))                 \
+               if (cmpfn((const type)__i , ## args)) { \
+                       __j = __i;                      \
                        break;                          \
                }                                       \
-       } while (!cmpfn((const type)__i , ## args));    \
-       (type)__i;                                      \
+       (type)__j;                                      \
 })
 
 static inline int
@@ -100,9 +94,9 @@ list_prepend(struct list_head *head, void *new)
 do {                                                           \
        struct list_head *__i;                                  \
        ASSERT_WRITE_LOCK(head);                                \
-       for (__i = (head)->next;                                \
-            !cmpfn((new), (typeof (new))__i) && __i != (head); \
-            __i = __i->next);                                  \
+       list_for_each(__i, (head))                              \
+               if ((new), (typeof (new))__i)                   \
+                       break;                                  \
        list_add((struct list_head *)(new), __i->prev);         \
 } while(0)
 
index b192b7f018f5696d0ce9d05a359d5fb4bec103c3..f800e292d8a1b511b84cef4e54e2d70047d406af 100644 (file)
@@ -382,6 +382,7 @@ enum
        NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11,
        NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT=12,
        NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT=13,
+       NET_IPV4_NF_CONNTRACK_BUCKETS=14,
 };
  
 /* /proc/sys/net/ipv6 */
index f38a2dccdbe737c46dfbc9bc92ebb1e8b0e6ad93..1a62ec122d7e3be6a0fc97873e3b771677389210 100644 (file)
@@ -1240,14 +1240,13 @@ do_kill(const struct ip_conntrack_tuple_hash *i,
 /* Bring out ya dead! */
 static struct ip_conntrack_tuple_hash *
 get_next_corpse(int (*kill)(const struct ip_conntrack *i, void *data),
-               void *data)
+               void *data, unsigned int *bucket)
 {
        struct ip_conntrack_tuple_hash *h = NULL;
-       unsigned int i;
 
        READ_LOCK(&ip_conntrack_lock);
-       for (i = 0; !h && i < ip_conntrack_htable_size; i++) {
-               h = LIST_FIND(&ip_conntrack_hash[i], do_kill,
+       for (; !h && *bucket < ip_conntrack_htable_size; (*bucket)++) {
+               h = LIST_FIND(&ip_conntrack_hash[*bucket], do_kill,
                              struct ip_conntrack_tuple_hash *, kill, data);
        }
        if (h)
@@ -1262,9 +1261,9 @@ ip_ct_selective_cleanup(int (*kill)(const struct ip_conntrack *i, void *data),
                        void *data)
 {
        struct ip_conntrack_tuple_hash *h;
+       unsigned int bucket = 0;
 
-       /* This is order n^2, by the way. */
-       while ((h = get_next_corpse(kill, data)) != NULL) {
+       while ((h = get_next_corpse(kill, data, &bucket)) != NULL) {
                /* Time to push up daises... */
                if (del_timer(&h->ctrack->timeout))
                        death_by_timeout((unsigned long)h->ctrack);
index ca317bfe193534f0141c0b83a1467f33c8b8b8b0..f6ec2134531e5be6451bcbcba95eb3ed8ba728a0 100644 (file)
@@ -275,6 +275,7 @@ static struct nf_hook_ops ip_conntrack_local_in_ops = {
 
 /* From ip_conntrack_core.c */
 extern int ip_conntrack_max;
+extern unsigned int ip_conntrack_htable_size;
 
 /* From ip_conntrack_proto_tcp.c */
 extern unsigned long ip_ct_tcp_timeout_syn_sent;
@@ -307,6 +308,14 @@ static ctl_table ip_ct_sysctl_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec,
        },
+       {
+               .ctl_name       = NET_IPV4_NF_CONNTRACK_BUCKETS,
+               .procname       = "ip_conntrack_buckets",
+               .data           = &ip_conntrack_htable_size,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0444,
+               .proc_handler   = &proc_dointvec,
+       },
        {
                .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,
                .procname       = "ip_conntrack_tcp_timeout_syn_sent",