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