libxtables: XTTYPE_MARKMASK32 support

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
diff --git a/include/xtables.h.in b/include/xtables.h.in
index c3c8da9..2fa5977 100644
--- a/include/xtables.h.in
+++ b/include/xtables.h.in
@@ -50,6 +50,7 @@
  * %XTTYPE_UINT*:	standard integer
  * %XTTYPE_UINT*RC:	colon-separated range of standard integers
  * %XTTYPE_STRING:	arbitrary string
+ * %XTTYPE_MARKMASK32:	32-bit mark with optional mask
  */
 enum xt_option_type {
 	XTTYPE_NONE,
@@ -57,6 +58,7 @@
 	XTTYPE_UINT32,
 	XTTYPE_UINT32RC,
 	XTTYPE_STRING,
+	XTTYPE_MARKMASK32,
 };
 
 /**
@@ -113,6 +115,9 @@
 	union {
 		uint8_t u8;
 		uint32_t u32, u32_range[2];
+		struct {
+			uint32_t mark, mask;
+		};
 	} val;
 };
 
diff --git a/xtoptions.c b/xtoptions.c
index 631e7a3..e9bcaa8 100644
--- a/xtoptions.c
+++ b/xtoptions.c
@@ -186,11 +186,40 @@
 	p[z] = '\0';
 }
 
+/**
+ * Validate the input for being conformant to "mark[/mask]".
+ */
+static void xtopt_parse_markmask(struct xt_option_call *cb)
+{
+	unsigned int mark = 0, mask = ~0U;
+	char *end;
+
+	if (!xtables_strtoui(cb->arg, &end, &mark, 0, UINT32_MAX))
+		xt_params->exit_err(PARAMETER_PROBLEM,
+			"%s: bad mark value for option \"--%s\", "
+			"or out of range.\n",
+			cb->ext_name, cb->entry->name);
+	if (*end == '/' &&
+	    !xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
+		xt_params->exit_err(PARAMETER_PROBLEM,
+			"%s: bad mask value for option \"--%s\", "
+			"or out of range.\n",
+			cb->ext_name, cb->entry->name);
+	if (*end != '\0')
+		xt_params->exit_err(PARAMETER_PROBLEM,
+			"%s: trailing garbage after value "
+			"for option \"--%s\".\n",
+			cb->ext_name, cb->entry->name);
+	cb->val.mark = mark;
+	cb->val.mask = mask;
+}
+
 static void (*const xtopt_subparse[])(struct xt_option_call *) = {
 	[XTTYPE_UINT8]       = xtopt_parse_int,
 	[XTTYPE_UINT32]      = xtopt_parse_int,
 	[XTTYPE_UINT32RC]    = xtopt_parse_mint,
 	[XTTYPE_STRING]      = xtopt_parse_string,
+	[XTTYPE_MARKMASK32]  = xtopt_parse_markmask,
 };
 
 static const size_t xtopt_psize[] = {