summaryrefslogtreecommitdiffstats
path: root/sbin/ipfw
diff options
context:
space:
mode:
authorLuiz Souza <luiz@netgate.com>2017-07-15 09:05:39 -0500
committerLuiz Souza <luiz@netgate.com>2017-07-15 11:24:41 -0500
commite1d7d4f6c8167b601dfec75902ed603d0b5ef347 (patch)
tree06a9d27860f45cf1973a77ae9ce2b80ab8f6cfcf /sbin/ipfw
parent2a5777d0acaec430d6893f33afc2a1f3b43e6455 (diff)
downloadFreeBSD-src-e1d7d4f6c8167b601dfec75902ed603d0b5ef347.zip
FreeBSD-src-e1d7d4f6c8167b601dfec75902ed603d0b5ef347.tar.gz
Add the timestamp of the last match, packet and byte counters to table
entries with a new ipfw table command to zero the counters. Each table type implementation needs to be modified to add the support to this feature and the FIB backend is the only one that was not modified (because the backend does not have any local storage). (cherry picked from commit 3b06c382c8a2e04b7a64291bfb6b0ca0e5dd8dca) (cherry picked from commit b969fab78206744b1d323f47828125389299e450)
Diffstat (limited to 'sbin/ipfw')
-rw-r--r--sbin/ipfw/ipfw2.h1
-rw-r--r--sbin/ipfw/tables.c72
2 files changed, 68 insertions, 5 deletions
diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h
index 0218a4a..6cd452c 100644
--- a/sbin/ipfw/ipfw2.h
+++ b/sbin/ipfw/ipfw2.h
@@ -254,6 +254,7 @@ enum tokens {
TOK_UNLOCK,
TOK_VLIST,
TOK_OLIST,
+ TOK_ZEROCNT,
/* NAT64 tokens */
TOK_NAT64STL,
diff --git a/sbin/ipfw/tables.c b/sbin/ipfw/tables.c
index 85350a0..21287da 100644
--- a/sbin/ipfw/tables.c
+++ b/sbin/ipfw/tables.c
@@ -54,6 +54,7 @@ static void table_lock(ipfw_obj_header *oh, int lock);
static int table_swap(ipfw_obj_header *oh, char *second);
static int table_get_info(ipfw_obj_header *oh, ipfw_xtable_info *i);
static int table_show_info(ipfw_xtable_info *i, void *arg);
+static void table_zerocnt(ipfw_obj_header *oh, int ac, char *av[]);
static int table_flush_one(ipfw_xtable_info *i, void *arg);
static int table_show_one(ipfw_xtable_info *i, void *arg);
@@ -114,6 +115,7 @@ static struct _s_x tablecmds[] = {
{ "atomic", TOK_ATOMIC },
{ "lock", TOK_LOCK },
{ "unlock", TOK_UNLOCK },
+ { "zerocnt", TOK_ZEROCNT },
{ NULL, 0 }
};
@@ -289,6 +291,10 @@ ipfw_table_handler(int ac, char *av[])
ac--; av++;
table_lookup(&oh, ac, av);
break;
+ case TOK_ZEROCNT:
+ ac--; av++;
+ table_zerocnt(&oh, ac, av);
+ break;
}
}
@@ -1108,6 +1114,60 @@ table_lookup(ipfw_obj_header *oh, int ac, char *av[])
table_show_entry(&xi, &xtent);
}
+static int
+table_do_zerocnt(ipfw_obj_header *oh, char *key, ipfw_xtable_info *xi)
+{
+ char xbuf[sizeof(ipfw_obj_header) + sizeof(ipfw_obj_tentry)];
+ ipfw_obj_tentry *tent;
+ uint8_t type;
+ uint32_t vmask;
+
+ memcpy(xbuf, oh, sizeof(*oh));
+ oh = (ipfw_obj_header *)xbuf;
+ tent = (ipfw_obj_tentry *)(oh + 1);
+
+ memset(tent, 0, sizeof(*tent));
+ tent->head.length = sizeof(*tent);
+ tent->idx = 1;
+
+ tentry_fill_key(oh, tent, key, 0, &type, &vmask, xi);
+ oh->ntlv.type = type;
+
+ if (do_set3(IP_FW_TABLE_XZEROCNT, &oh->opheader, sizeof(xbuf)) != 0)
+ return (errno);
+
+ return (0);
+}
+
+static void
+table_zerocnt(ipfw_obj_header *oh, int ac, char *av[])
+{
+ ipfw_xtable_info xi;
+ char key[64];
+ int error;
+
+ if (ac == 0)
+ errx(EX_USAGE, "address required");
+
+ strlcpy(key, *av, sizeof(key));
+
+ memset(&xi, 0, sizeof(xi));
+ error = table_do_zerocnt(oh, key, &xi);
+ switch (error) {
+ case 0:
+ break;
+ case ESRCH:
+ errx(EX_UNAVAILABLE, "Table %s not found", oh->ntlv.name);
+ case ENOENT:
+ errx(EX_UNAVAILABLE, "Entry %s not found", *av);
+ case ENOTSUP:
+ errx(EX_UNAVAILABLE, "Table %s algo does not support "
+ "\"zero_cnt\" method", oh->ntlv.name);
+ default:
+ err(EX_OSERR, "getsockopt(IP_FW_TABLE_XZEROCNT)");
+ }
+}
+
static void
tentry_fill_key_type(char *arg, ipfw_obj_tentry *tentry, uint8_t type,
uint8_t tflags)
@@ -1845,21 +1905,21 @@ table_show_entry(ipfw_xtable_info *i, ipfw_obj_tentry *tent)
case IPFW_TABLE_ADDR:
/* IPv4 or IPv6 prefixes */
inet_ntop(tent->subtype, &tent->k, tbuf, sizeof(tbuf));
- printf("%s/%u %s\n", tbuf, tent->masklen, pval);
+ printf("%s/%u %s", tbuf, tent->masklen, pval);
break;
case IPFW_TABLE_MAC2:
/* Ethernet MAC address */
print_mac(tent->k.mac.addr, tent->k.mac.mask);
print_mac(tent->k.mac.addr + 6, tent->k.mac.mask + 6);
- printf(" %s\n", pval);
+ printf(" %s", pval);
break;
case IPFW_TABLE_INTERFACE:
/* Interface names */
- printf("%s %s\n", tent->k.iface, pval);
+ printf("%s %s", tent->k.iface, pval);
break;
case IPFW_TABLE_NUMBER:
/* numbers */
- printf("%u %s\n", tent->k.key, pval);
+ printf("%u %s", tent->k.key, pval);
break;
case IPFW_TABLE_FLOW:
/* flows */
@@ -1902,8 +1962,10 @@ table_show_entry(ipfw_xtable_info *i, ipfw_obj_tentry *tent)
comma = ",";
}
- printf(" %s\n", pval);
+ printf(" %s", pval);
}
+ printf(" %ju %ju %ju\n", (uintmax_t)tent->pcnt,
+ (uintmax_t)tent->bcnt, (uintmax_t)tent->timestamp);
}
static int
OpenPOWER on IntegriCloud