zero-ing IP accounting records [patch]

Matei Conovici ~SysAdm~ (cmatei@lbi.sfos.ro)
Mon, 19 Aug 1996 13:49:57 +0200 (GMT+0200)


OK, here is a patch for who might be interested. It allouds IP accounting
entries to be zero-ed individually, rather than all at once. This works for
both accounting and firewall rules.

Tested with 2.0.13.

Matei Conovici

---8<--- cut here
diff -u --recursive linux/include/linux/ip_fw.h linux-mine/include/linux/ip_fw.h
--- linux/include/linux/ip_fw.h Thu Aug 15 10:49:39 1996
+++ linux-mine/include/linux/ip_fw.h Mon Aug 19 12:21:08 1996
@@ -136,6 +138,7 @@
#define IP_FW_POLICY (IP_FW_BASE_CTL+5)
#define IP_FW_CHECK (IP_FW_BASE_CTL+6)
#define IP_FW_MASQ_TIMEOUTS (IP_FW_BASE_CTL+7)
+#define IP_FW_ZERO_R (IP_FW_BASE_CTL+8)

#define IP_FW_INSERT_FWD (IP_FW_INSERT | (IP_FW_FWD << IP_FW_SHIFT))
#define IP_FW_APPEND_FWD (IP_FW_APPEND | (IP_FW_FWD << IP_FW_SHIFT))
@@ -144,6 +147,7 @@
#define IP_FW_ZERO_FWD (IP_FW_ZERO | (IP_FW_FWD << IP_FW_SHIFT))
#define IP_FW_POLICY_FWD (IP_FW_POLICY | (IP_FW_FWD << IP_FW_SHIFT))
#define IP_FW_CHECK_FWD (IP_FW_CHECK | (IP_FW_FWD << IP_FW_SHIFT))
+#define IP_FW_ZERO_R_FWD (IP_FW_ZERO_R | (IP_FW_FWD << IP_FW_SHIFT))

#define IP_FW_INSERT_IN (IP_FW_INSERT | (IP_FW_IN << IP_FW_SHIFT))
#define IP_FW_APPEND_IN (IP_FW_APPEND | (IP_FW_IN << IP_FW_SHIFT))
@@ -152,6 +156,7 @@
#define IP_FW_ZERO_IN (IP_FW_ZERO | (IP_FW_IN << IP_FW_SHIFT))
#define IP_FW_POLICY_IN (IP_FW_POLICY | (IP_FW_IN << IP_FW_SHIFT))
#define IP_FW_CHECK_IN (IP_FW_CHECK | (IP_FW_IN << IP_FW_SHIFT))
+#define IP_FW_ZERO_R_IN (IP_FW_ZERO_R | (IP_FW_IN << IP_FW_SHIFT))

#define IP_FW_INSERT_OUT (IP_FW_INSERT | (IP_FW_OUT << IP_FW_SHIFT))
#define IP_FW_APPEND_OUT (IP_FW_APPEND | (IP_FW_OUT << IP_FW_SHIFT))
@@ -160,12 +165,14 @@
#define IP_FW_ZERO_OUT (IP_FW_ZERO | (IP_FW_OUT << IP_FW_SHIFT))
#define IP_FW_POLICY_OUT (IP_FW_POLICY | (IP_FW_OUT << IP_FW_SHIFT))
#define IP_FW_CHECK_OUT (IP_FW_CHECK | (IP_FW_OUT << IP_FW_SHIFT))
+#define IP_FW_ZERO_R_OUT (IP_FW_ZERO_R | (IP_FW_OUT << IP_FW_SHIFT))

#define IP_ACCT_INSERT (IP_FW_INSERT | (IP_FW_ACCT << IP_FW_SHIFT))
#define IP_ACCT_APPEND (IP_FW_APPEND | (IP_FW_ACCT << IP_FW_SHIFT))
#define IP_ACCT_DELETE (IP_FW_DELETE | (IP_FW_ACCT << IP_FW_SHIFT))
#define IP_ACCT_FLUSH (IP_FW_FLUSH | (IP_FW_ACCT << IP_FW_SHIFT))
#define IP_ACCT_ZERO (IP_FW_ZERO | (IP_FW_ACCT << IP_FW_SHIFT))
+#define IP_ACCT_ZERO_R (IP_FW_ZERO_R | (IP_FW_ACCT << IP_FW_SHIFT))

struct ip_fwpkt
{
diff -u --recursive linux/net/ipv4/ip_fw.c linux-mine/net/ipv4/ip_fw.c
--- linux/net/ipv4/ip_fw.c Sat Jun 29 11:00:48 1996
+++ linux-mine/net/ipv4/ip_fw.c Mon Aug 19 12:19:34 1996
@@ -571,6 +573,60 @@
return 0;
}

+static int ip_fw_match(struct ip_fw *rule1, struct ip_fw *rule2)
+{
+ int matches;
+ unsigned short tport1,tport2,tmpnum;
+
+ matches=1;
+ if (rule1->fw_src.s_addr!=rule2->fw_src.s_addr
+ || rule1->fw_dst.s_addr!=rule2->fw_dst.s_addr
+ || rule1->fw_smsk.s_addr!=rule2->fw_smsk.s_addr
+ || rule1->fw_dmsk.s_addr!=rule2->fw_dmsk.s_addr
+ || rule1->fw_via.s_addr!=rule2->fw_via.s_addr
+ || rule1->fw_flg!=rule2->fw_flg)
+ matches=0;
+
+ tport1=rule1->fw_nsp+rule1->fw_ndp;
+ tport2=rule2->fw_nsp+rule2->fw_ndp;
+ if (tport1!=tport2)
+ matches=0;
+ else if (tport1!=0)
+ {
+ for (tmpnum=0;tmpnum < tport1 && tmpnum < IP_FW_MAX_PORTS;tmpnum++)
+ if (rule1->fw_pts[tmpnum]!=rule2->fw_pts[tmpnum])
+ matches=0;
+ }
+ if (strncmp(rule1->fw_vianame, rule2->fw_vianame, IFNAMSIZ))
+ matches=0;
+
+ return matches;
+}
+
+static int zero_fw(struct ip_fw *chain, struct ip_fw *rule)
+{
+ struct ip_fw *tmp=chain;
+ unsigned long flags;
+ int retval=EINVAL;
+
+ save_flags(flags);
+ cli();
+
+ while ( tmp )
+ {
+ if ( ip_fw_match(tmp, rule) )
+ {
+ tmp->fw_bcnt=0L;
+ tmp->fw_pcnt=0L;
+ retval = 0;
+ }
+ tmp=tmp->fw_next;
+ }
+
+ restore_flags(flags);
+
+ return retval;
+}

static void zero_fw_chain(struct ip_fw *chainptr)
{
@@ -690,10 +746,10 @@
return(0);
}

+
static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl)
{
struct ip_fw *ftmp,*ltmp;
- unsigned short tport1,tport2,tmpnum;
char matches,was_found;
unsigned long flags;

@@ -716,27 +772,7 @@

while( !was_found && ftmp != NULL )
{
- matches=1;
- if (ftmp->fw_src.s_addr!=frwl->fw_src.s_addr
- || ftmp->fw_dst.s_addr!=frwl->fw_dst.s_addr
- || ftmp->fw_smsk.s_addr!=frwl->fw_smsk.s_addr
- || ftmp->fw_dmsk.s_addr!=frwl->fw_dmsk.s_addr
- || ftmp->fw_via.s_addr!=frwl->fw_via.s_addr
- || ftmp->fw_flg!=frwl->fw_flg)
- matches=0;
-
- tport1=ftmp->fw_nsp+ftmp->fw_ndp;
- tport2=frwl->fw_nsp+frwl->fw_ndp;
- if (tport1!=tport2)
- matches=0;
- else if (tport1!=0)
- {
- for (tmpnum=0;tmpnum < tport1 && tmpnum < IP_FW_MAX_PORTS;tmpnum++)
- if (ftmp->fw_pts[tmpnum]!=frwl->fw_pts[tmpnum])
- matches=0;
- }
- if (strncmp(ftmp->fw_vianame, frwl->fw_vianame, IFNAMSIZ))
- matches=0;
+ matches = ip_fw_match(ftmp, frwl);
if(matches)
{
was_found=1;
@@ -853,6 +889,15 @@
zero_fw_chain(ip_acct_chain);
return(0);
}
+ if ( stage == IP_ACCT_ZERO_R )
+ {
+ struct ip_fw *frwl;
+
+ if (!(frwl=check_ipfw_struct(m,len)))
+ return (EINVAL);
+
+ return zero_fw(ip_acct_chain, frwl);
+ }
if ( stage == IP_ACCT_INSERT || stage == IP_ACCT_APPEND ||
stage == IP_ACCT_DELETE )
{
@@ -905,7 +950,17 @@
zero_fw_chain(*chains[fwtype]);
return(0);
}
+
+ if ( cmd == IP_FW_ZERO_R )
+ {
+ struct ip_fw *frwl;

+ if (!(frwl=check_ipfw_struct(m,len)))
+ return (EINVAL);
+
+ return zero_fw(*chains[fwtype], frwl);
+ }
+
if ( cmd == IP_FW_POLICY )
{
int *tmp_policy_ptr;
diff -u --recursive linux/net/ipv4/ip_sockglue.c linux-mine/net/ipv4/ip_sockglue.c
--- linux/net/ipv4/ip_sockglue.c Thu Jul 11 07:54:18 1996
+++ linux-mine/net/ipv4/ip_sockglue.c Mon Aug 19 12:14:34 1996
@@ -391,6 +391,9 @@
case IP_FW_ZERO_IN:
case IP_FW_ZERO_OUT:
case IP_FW_ZERO_FWD:
+ case IP_FW_ZERO_R_IN:
+ case IP_FW_ZERO_R_OUT:
+ case IP_FW_ZERO_R_FWD:
case IP_FW_POLICY_IN:
case IP_FW_POLICY_OUT:
case IP_FW_POLICY_FWD:
@@ -413,6 +416,7 @@
case IP_ACCT_DELETE:
case IP_ACCT_FLUSH:
case IP_ACCT_ZERO:
+ case IP_ACCT_ZERO_R:
if(!suser())
return -EPERM;
if(optlen>sizeof(tmp_fw) || optlen<1)