aboutsummaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorAndrey V. Elsukov <ae@FreeBSD.org>2019-05-24 11:06:24 +0000
committerAndrey V. Elsukov <ae@FreeBSD.org>2019-05-24 11:06:24 +0000
commit05ab1ef64ebe48e68a7a3975c1f06e2ced5460a9 (patch)
treecb810f547199e190459fb65022fe7ed76ea59082 /sbin
parent2b32abd2b1804bea2bb6c7c57be997cecd931b72 (diff)
downloadsrc-05ab1ef64ebe48e68a7a3975c1f06e2ced5460a9.tar.gz
src-05ab1ef64ebe48e68a7a3975c1f06e2ced5460a9.zip
Add `missing` and `or-flush` options to "ipfw table <NAME> create"
command to simplify firewall reloading. The `missing` option suppresses EEXIST error code, but does check that existing table has the same parameters as new one. The `or-flush` option implies `missing` option and additionally does flush for table if it is already exist. Submitted by: lev MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D18339
Notes
Notes: svn path=/head/; revision=348235
Diffstat (limited to 'sbin')
-rw-r--r--sbin/ipfw/ipfw.811
-rw-r--r--sbin/ipfw/ipfw2.h3
-rw-r--r--sbin/ipfw/tables.c38
3 files changed, 45 insertions, 7 deletions
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index cf0c3affe029..fcba4a4b03f2 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -1,7 +1,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 21, 2019
+.Dd May 24, 2019
.Dt IPFW 8
.Os
.Sh NAME
@@ -2138,7 +2138,7 @@ The following creation options are supported:
.Bl -tag -width indent
.It Ar create-options : Ar create-option | create-options
.It Ar create-option : Cm type Ar table-type | Cm valtype Ar value-mask | Cm algo Ar algo-desc |
-.Cm limit Ar number | Cm locked
+.Cm limit Ar number | Cm locked | Cm missing | Cm or-flush
.It Cm type
Table key type.
.It Cm valtype
@@ -2149,6 +2149,13 @@ Table algorithm to use (see below).
Maximum number of items that may be inserted into table.
.It Cm locked
Restrict any table modifications.
+.It Cm missing
+Do not fail if table already exists and has exactly same options as new one.
+.It Cm or-flush
+Flush existing table with same name instead of returning error.
+Implies
+.Cm missing
+so existing table must be compatible with new one.
.El
.Pp
Some of these options may be modified later via
diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h
index 2b562734d15f..659285366c2c 100644
--- a/sbin/ipfw/ipfw2.h
+++ b/sbin/ipfw/ipfw2.h
@@ -264,6 +264,9 @@ enum tokens {
TOK_UNLOCK,
TOK_VLIST,
TOK_OLIST,
+ TOK_MISSING,
+ TOK_ORFLUSH,
+ TOK_OPTIONAL,
/* NAT64 tokens */
TOK_NAT64STL,
diff --git a/sbin/ipfw/tables.c b/sbin/ipfw/tables.c
index 3fa806348a27..4be24210d4f0 100644
--- a/sbin/ipfw/tables.c
+++ b/sbin/ipfw/tables.c
@@ -327,6 +327,8 @@ static struct _s_x tablenewcmds[] = {
{ "algo", TOK_ALGO },
{ "limit", TOK_LIMIT },
{ "locked", TOK_LOCK },
+ { "missing", TOK_MISSING },
+ { "or-flush", TOK_ORFLUSH },
{ NULL, 0 }
};
@@ -389,19 +391,19 @@ table_print_type(char *tbuf, size_t size, uint8_t type, uint8_t tflags)
* Creates new table
*
* ipfw table NAME create [ type { addr | iface | number | flow } ]
- * [ algo algoname ]
+ * [ algo algoname ] [missing] [or-flush]
*/
static void
table_create(ipfw_obj_header *oh, int ac, char *av[])
{
- ipfw_xtable_info xi;
- int error, tcmd, val;
+ ipfw_xtable_info xi, xie;
+ int error, missing, orflush, tcmd, val;
uint32_t fset, fclear;
char *e, *p;
char tbuf[128];
+ missing = orflush = 0;
memset(&xi, 0, sizeof(xi));
-
while (ac > 0) {
tcmd = get_token(tablenewcmds, *av, "option");
ac--; av++;
@@ -457,6 +459,12 @@ table_create(ipfw_obj_header *oh, int ac, char *av[])
case TOK_LOCK:
xi.flags |= IPFW_TGFLAGS_LOCKED;
break;
+ case TOK_ORFLUSH:
+ orflush = 1;
+ /* FALLTHROUGH */
+ case TOK_MISSING:
+ missing = 1;
+ break;
}
}
@@ -466,8 +474,28 @@ table_create(ipfw_obj_header *oh, int ac, char *av[])
if (xi.vmask == 0)
xi.vmask = IPFW_VTYPE_LEGACY;
- if ((error = table_do_create(oh, &xi)) != 0)
+ error = table_do_create(oh, &xi);
+
+ if (error == 0)
+ return;
+
+ if (errno != EEXIST || missing == 0)
err(EX_OSERR, "Table creation failed");
+
+ /* Check that existing table is the same we are trying to create */
+ if (table_get_info(oh, &xie) != 0)
+ err(EX_OSERR, "Existing table check failed");
+
+ if (xi.limit != xie.limit || xi.type != xie.type ||
+ xi.tflags != xie.tflags || xi.vmask != xie.vmask || (
+ xi.algoname[0] != '\0' && strcmp(xi.algoname,
+ xie.algoname) != 0) || xi.flags != xie.flags)
+ errx(EX_DATAERR, "The existing table is not compatible "
+ "with one you are creating.");
+
+ /* Flush existing table if instructed to do so */
+ if (orflush != 0 && table_flush(oh) != 0)
+ err(EX_OSERR, "Table flush on creation failed");
}
/*