ChangeSet 1.1982.115.18, 2005/03/03 23:12:29+01:00, [EMAIL PROTECTED]

        [NETFILTER]: fix ip6_queue inefficiencies
        
        Check if packet exceeds max queue length before netlink_unicast(),
        add drop statistics.
        
        Signed-off-by: Patrick McHardy <[EMAIL PROTECTED]>



 ipv4/netfilter/ip_queue.c  |   42 +++++++++++++++++++++++++++---------------
 ipv6/netfilter/ip6_queue.c |   40 ++++++++++++++++++++++++++--------------
 2 files changed, 53 insertions(+), 29 deletions(-)


diff -Nru a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
--- a/net/ipv4/netfilter/ip_queue.c     2005-03-12 20:47:32 -08:00
+++ b/net/ipv4/netfilter/ip_queue.c     2005-03-12 20:47:32 -08:00
@@ -14,6 +14,9 @@
  *             Zander).
  * 2000-08-01: Added Nick Williams' MAC support.
  * 2002-06-25: Code cleanup.
+ * 2005-01-10: Added /proc counter for dropped packets; fixed so
+ *             packets aren't delivered to user space if they're going 
+ *             to be dropped. 
  *
  */
 #include <linux/module.h>
@@ -59,6 +62,8 @@
 static int peer_pid;
 static unsigned int copy_range;
 static unsigned int queue_total;
+static unsigned int queue_dropped = 0;
+static unsigned int queue_user_dropped = 0;
 static struct sock *ipqnl;
 static LIST_HEAD(queue_list);
 static DECLARE_MUTEX(ipqnl_sem);
@@ -70,18 +75,11 @@
        kfree(entry);
 }
 
-static inline int
+static inline void
 __ipq_enqueue_entry(struct ipq_queue_entry *entry)
 {
-       if (queue_total >= queue_maxlen) {
-               if (net_ratelimit()) 
-                       printk(KERN_WARNING "ip_queue: full at %d entries, "
-                              "dropping packet(s).\n", queue_total);
-               return -ENOSPC;
-       }
        list_add(&entry->list, &queue_list);
        queue_total++;
-       return 0;
 }
 
 /*
@@ -308,14 +306,24 @@
        if (!peer_pid)
                goto err_out_free_nskb; 
 
+       if (queue_total >= queue_maxlen) {
+                queue_dropped++;
+               status = -ENOSPC;
+               if (net_ratelimit())
+                         printk (KERN_WARNING "ip_queue: full at %d entries, "
+                                 "dropping packets(s). Dropped: %d\n", 
queue_total,
+                                 queue_dropped);
+               goto err_out_free_nskb;
+       }
+
        /* netlink_unicast will either free the nskb or attach it to a socket 
*/ 
        status = netlink_unicast(ipqnl, nskb, peer_pid, MSG_DONTWAIT);
-       if (status < 0)
-               goto err_out_unlock;
-       
-       status = __ipq_enqueue_entry(entry);
-       if (status < 0)
+       if (status < 0) {
+               queue_user_dropped++;
                goto err_out_unlock;
+       }
+
+       __ipq_enqueue_entry(entry);
 
        write_unlock_bh(&queue_lock);
        return status;
@@ -637,12 +645,16 @@
                      "Copy mode         : %hu\n"
                      "Copy range        : %u\n"
                      "Queue length      : %u\n"
-                     "Queue max. length : %u\n",
+                     "Queue max. length : %u\n"
+                     "Queue dropped     : %u\n"
+                     "Netlink dropped   : %u\n",
                      peer_pid,
                      copy_mode,
                      copy_range,
                      queue_total,
-                     queue_maxlen);
+                     queue_maxlen,
+                     queue_dropped,
+                     queue_user_dropped);
 
        read_unlock_bh(&queue_lock);
        
diff -Nru a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
--- a/net/ipv6/netfilter/ip6_queue.c    2005-03-12 20:47:32 -08:00
+++ b/net/ipv6/netfilter/ip6_queue.c    2005-03-12 20:47:32 -08:00
@@ -20,6 +20,9 @@
  *             Few changes needed, mainly the hard_routing code and
  *             the netlink socket protocol (we're NETLINK_IP6_FW).
  * 2002-06-25: Code cleanup. [JM: ported cleanup over from ip_queue.c]
+ * 2005-02-04: Added /proc counter for dropped packets; fixed so
+ *             packets aren't delivered to user space if they're going
+ *             to be dropped.
  */
 #include <linux/module.h>
 #include <linux/skbuff.h>
@@ -64,6 +67,8 @@
 static int peer_pid;
 static unsigned int copy_range;
 static unsigned int queue_total;
+static unsigned int queue_dropped = 0;
+static unsigned int queue_user_dropped = 0;
 static struct sock *ipqnl;
 static LIST_HEAD(queue_list);
 static DECLARE_MUTEX(ipqnl_sem);
@@ -75,18 +80,11 @@
        kfree(entry);
 }
 
-static inline int
+static inline void
 __ipq_enqueue_entry(struct ipq_queue_entry *entry)
 {
-       if (queue_total >= queue_maxlen) {
-               if (net_ratelimit()) 
-                       printk(KERN_WARNING "ip6_queue: full at %d entries, "
-                              "dropping packet(s).\n", queue_total);
-               return -ENOSPC;
-       }
        list_add(&entry->list, &queue_list);
        queue_total++;
-       return 0;
 }
 
 /*
@@ -312,14 +310,24 @@
        if (!peer_pid)
                goto err_out_free_nskb; 
 
+       if (queue_total >= queue_maxlen) {
+                queue_dropped++;
+               status = -ENOSPC;
+               if (net_ratelimit())
+                       printk (KERN_WARNING "ip6_queue: fill at %d entries, "
+                               "dropping packet(s).  Dropped: %d\n", 
queue_total,
+                               queue_dropped);
+               goto err_out_free_nskb;
+       }
+
        /* netlink_unicast will either free the nskb or attach it to a socket 
*/ 
        status = netlink_unicast(ipqnl, nskb, peer_pid, MSG_DONTWAIT);
-       if (status < 0)
+       if (status < 0) {
+               queue_user_dropped++;
                goto err_out_unlock;
+       }
        
-       status = __ipq_enqueue_entry(entry);
-       if (status < 0)
-               goto err_out_unlock;
+       __ipq_enqueue_entry(entry);
 
        write_unlock_bh(&queue_lock);
        return status;
@@ -639,12 +647,16 @@
                      "Copy mode         : %hu\n"
                      "Copy range        : %u\n"
                      "Queue length      : %u\n"
-                     "Queue max. length : %u\n",
+                     "Queue max. length : %u\n"
+                     "Queue dropped     : %u\n"
+                     "Netfilter dropped : %u\n",
                      peer_pid,
                      copy_mode,
                      copy_range,
                      queue_total,
-                     queue_maxlen);
+                     queue_maxlen,
+                     queue_dropped,
+                     queue_user_dropped);
 
        read_unlock_bh(&queue_lock);
        
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to