Skip to contentSkip to conversation

fix quota on SMP

PATCH Applied Pablo Neira 2 participants 2 messages Apr 12, 2005 – Apr 15, 2005

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 fix quota on SMP

This patch fixes quota on SMP boxes.

o 01-24.patch: For 2.4.x
o 01-26.patch: For 2.6.x
o 02kill-ip-discount.patch: quota doesn't count the size of the IP header on 2.6.x.
o quota-iptables.patch: iptables requires this patch to fix SMP for quota.
o x-help: remove `quota is broken on SMP' warning that isn't true anymore.

--
Pablo

include/linux/netfilter_ipv4/ipt_quota.h +1 -0
Index: linux/include/linux/netfilter_ipv4/ipt_quota.h
===================================================================
@@ -6,6 +6,7 @@
 
 struct ipt_quota_info {
         u_int64_t quota;
+	struct ipt_quota_info *master;
 };
 
 #endif /*_IPT_QUOTA_H*/
net/ipv4/netfilter/ipt_quota.c +9 -2
Index: linux/net/ipv4/netfilter/ipt_quota.c
===================================================================
@@ -2,6 +2,8 @@
  * netfilter module to enforce network quotas
  *
  * Sam Johnston <[email protected]>
+ *
+ * 30/01/05: Fixed on SMP --Pablo Neira <[email protected]>
  */
 #include <linux/module.h>
 #include <linux/skbuff.h>
@@ -22,9 +24,9 @@
       const void *matchinfo,
       int offset, const void *hdr, u_int16_t datalen, int *hotdrop)
 {
+	struct ipt_quota_info *q =
+		((struct ipt_quota_info *) matchinfo)->master;
 
-        struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo;
-
         spin_lock_bh(&quota_lock);
 
         if (q->quota >= datalen) {
@@ -55,8 +57,13 @@
            void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
 {
         /* TODO: spinlocks? sanity checks? */
+	struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo;
+
         if (matchsize != IPT_ALIGN(sizeof (struct ipt_quota_info)))
                 return 0;
+	
+	/* For SMP, we only want to use one set of counters. */
+	q->master = q;
 
         return 1;
 }
include/linux/netfilter_ipv4/ipt_quota.h +1 -0
Index: linux-2.6/include/linux/netfilter_ipv4/ipt_quota.h
===================================================================
@@ -6,6 +6,7 @@
 
 struct ipt_quota_info {
         u_int64_t quota;
+	struct ipt_quota_info *master;
 };
 
 #endif /*_IPT_QUOTA_H*/
net/ipv4/netfilter/ipt_quota.c +9 -1
Index: linux-2.6/net/ipv4/netfilter/ipt_quota.c
===================================================================
@@ -2,6 +2,8 @@
  * netfilter module to enforce network quotas
  *
  * Sam Johnston <[email protected]>
+ *
+ * 30/01/05: Fixed on SMP --Pablo Neira <[email protected]>
  */
 #include <linux/module.h>
 #include <linux/skbuff.h>
@@ -23,7 +25,8 @@
       const void *matchinfo,
       int offset, int *hotdrop)
 {
-        struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo;
+        struct ipt_quota_info *q = 
+		((struct ipt_quota_info *) matchinfo)->master;
 	unsigned int datalen;
 
 	if (skb->len < sizeof(struct iphdr))
@@ -61,8 +64,13 @@
            void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
 {
         /* TODO: spinlocks? sanity checks? */
+	struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo;
+
         if (matchsize != IPT_ALIGN(sizeof (struct ipt_quota_info)))
                 return 0;
+	
+	/* For SMP, we only want to use one set of counters. */
+	q->master = q;
 
         return 1;
 }
net/ipv4/netfilter/ipt_quota.c renamed from net/ipv4/netfilter/ipt_quota.c.orig +4 -7
@@ -27,22 +27,19 @@
 {
         struct ipt_quota_info *q = 
 		((struct ipt_quota_info *) matchinfo)->master;
-	unsigned int datalen;
 
 	if (skb->len < sizeof(struct iphdr))
 		return NF_ACCEPT;
 	
-	datalen = skb->len - skb->nh.iph->ihl*4;
-
         spin_lock_bh(&quota_lock);
 
-        if (q->quota >= datalen) {
+        if (q->quota >= skb->len) {
                 /* we can afford this one */
-                q->quota -= datalen;
+                q->quota -= skb->len;
                 spin_unlock_bh(&quota_lock);
 
 #ifdef DEBUG_IPT_QUOTA
-                printk("IPT Quota OK: %llu datlen %d \n", q->quota, datalen);
+                printk("IPT Quota OK: %llu datlen %d \n", q->quota, skb->len);
 #endif
                 return 1;
         }
@@ -51,7 +48,7 @@
         q->quota = 0;
 
 #ifdef DEBUG_IPT_QUOTA
-        printk("IPT Quota Failed: %llu datlen %d \n", q->quota, datalen);
+        printk("IPT Quota Failed: %llu datlen %d \n", q->quota, skb->len);
 #endif
 
         spin_unlock_bh(&quota_lock);
help +0 -3
Index: help
===================================================================
@@ -4,6 +4,3 @@
 Supported options are:
 --quota <bytes>
   The quota in bytes.
-
-KNOWN BUGS: this does not work on SMP systems.
-
Applied
#1 lore raw
Quoted 8 lines · Pablo Neira

This patch fixes quota on SMP boxes.

o 01-24.patch: For 2.4.x
o 01-26.patch: For 2.6.x
o 02kill-ip-discount.patch: quota doesn't count the size of the IP header on 2.6.x.
o quota-iptables.patch: iptables requires this patch to fix SMP for quota.
o x-help: remove `quota is broken on SMP' warning that isn't true anymore.

thanks, applied.

btw: I would appreciate if you would submit all hunks that belong to one issue (e.g. 01-24, 01-26 and x-help in this example) as one single patch.

Signature · 5 lines
- Harald Welte <[email protected]>                 http://netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie