netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [iptables PATCH 0/6] Extend guided option parser for use by arptables
@ 2023-11-22 21:52 Phil Sutter
  2023-11-22 21:52 ` [iptables PATCH 1/6] libxtables: Combine the two extension option mergers Phil Sutter
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Phil Sutter @ 2023-11-22 21:52 UTC (permalink / raw)
  To: netfilter-devel

Patch 1 is unrelated to the remaining ones, but fits into a series about
libxtables option parser.

Patch 2 fixes for parsing of IP addresses with arptables, patches 3 and
4 enable users to parse integers in a fixed base.

Patches 5 and 6 then migrate more extensions over to using the guided
option parser.

Phil Sutter (6):
  libxtables: Combine the two extension option mergers
  libxtables: Fix guided option parser for use with arptables
  libxtables: Introduce xtables_strtoul_base()
  libxtables: Introduce struct xt_option_entry::base
  extensions: libarpt_mangle: Use guided option parser
  extensions: MARK: arptables: Use guided option parser

 extensions/libarpt_mangle.c | 128 +++++++++++++-----------------------
 extensions/libarpt_mangle.t |   4 ++
 extensions/libxt_MARK.c     |  82 +++++------------------
 include/xtables.h           |   5 +-
 libxtables/xtables.c        |  16 +++--
 libxtables/xtoptions.c      |  77 ++++++++--------------
 6 files changed, 106 insertions(+), 206 deletions(-)

-- 
2.41.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [iptables PATCH 1/6] libxtables: Combine the two extension option mergers
  2023-11-22 21:52 [iptables PATCH 0/6] Extend guided option parser for use by arptables Phil Sutter
@ 2023-11-22 21:52 ` Phil Sutter
  2023-11-22 21:52 ` [iptables PATCH 2/6] libxtables: Fix guided option parser for use with arptables Phil Sutter
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Phil Sutter @ 2023-11-22 21:52 UTC (permalink / raw)
  To: netfilter-devel

For extending the command parser's struct option array, there is
xtables_merge_options() and xtables_options_xfrm(). Since their bodies
were almost identical, make the latter a wrapper of the former by
transforming the passed struct xt_option_entry array into a temporary
struct option one before handing over.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 libxtables/xtoptions.c | 51 +++++++-----------------------------------
 1 file changed, 8 insertions(+), 43 deletions(-)

diff --git a/libxtables/xtoptions.c b/libxtables/xtoptions.c
index b16bbfbe32311..0667315ceccf8 100644
--- a/libxtables/xtoptions.c
+++ b/libxtables/xtoptions.c
@@ -73,56 +73,21 @@ struct option *
 xtables_options_xfrm(struct option *orig_opts, struct option *oldopts,
 		     const struct xt_option_entry *entry, unsigned int *offset)
 {
-	unsigned int num_orig, num_old = 0, num_new, i;
+	int num_new, i;
 	struct option *merge, *mp;
 
-	if (entry == NULL)
-		return oldopts;
-	for (num_orig = 0; orig_opts[num_orig].name != NULL; ++num_orig)
-		;
-	if (oldopts != NULL)
-		for (num_old = 0; oldopts[num_old].name != NULL; ++num_old)
-			;
 	for (num_new = 0; entry[num_new].name != NULL; ++num_new)
 		;
 
-	/*
-	 * Since @oldopts also has @orig_opts already (and does so at the
-	 * start), skip these entries.
-	 */
-	if (oldopts != NULL) {
-		oldopts += num_orig;
-		num_old -= num_orig;
-	}
-
-	merge = malloc(sizeof(*mp) * (num_orig + num_old + num_new + 1));
-	if (merge == NULL)
-		return NULL;
-
-	/* Let the base options -[ADI...] have precedence over everything */
-	memcpy(merge, orig_opts, sizeof(*mp) * num_orig);
-	mp = merge + num_orig;
-
-	/* Second, the new options */
-	xt_params->option_offset += XT_OPTION_OFFSET_SCALE;
-	*offset = xt_params->option_offset;
-
-	for (i = 0; i < num_new; ++i, ++mp, ++entry) {
-		mp->name         = entry->name;
-		mp->has_arg      = entry->type != XTTYPE_NONE;
-		mp->flag         = NULL;
-		mp->val          = entry->id + *offset;
-	}
-
-	/* Third, the old options */
-	if (oldopts != NULL) {
-		memcpy(mp, oldopts, sizeof(*mp) * num_old);
-		mp += num_old;
+	mp = xtables_calloc(num_new, sizeof(*mp));
+	for (i = 0; i < num_new; i++) {
+		mp[i].name	= entry[i].name;
+		mp[i].has_arg	= entry[i].type != XTTYPE_NONE;
+		mp[i].val	= entry[i].id;
 	}
-	xtables_free_opts(0);
+	merge = xtables_merge_options(orig_opts, oldopts, mp, offset);
 
-	/* Clear trailing entry */
-	memset(mp, 0, sizeof(*mp));
+	free(mp);
 	return merge;
 }
 
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [iptables PATCH 2/6] libxtables: Fix guided option parser for use with arptables
  2023-11-22 21:52 [iptables PATCH 0/6] Extend guided option parser for use by arptables Phil Sutter
  2023-11-22 21:52 ` [iptables PATCH 1/6] libxtables: Combine the two extension option mergers Phil Sutter
@ 2023-11-22 21:52 ` Phil Sutter
  2023-11-22 21:52 ` [iptables PATCH 3/6] libxtables: Introduce xtables_strtoul_base() Phil Sutter
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Phil Sutter @ 2023-11-22 21:52 UTC (permalink / raw)
  To: netfilter-devel

With an unexpected value in afinfo->family, guided option parser was
rather useless when called from arptables extensions. Introduce
afinfo_family() wrapper to sanitize at least NFPROTO_ARP value.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 libxtables/xtoptions.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/libxtables/xtoptions.c b/libxtables/xtoptions.c
index 0667315ceccf8..25540f8b88c6d 100644
--- a/libxtables/xtoptions.c
+++ b/libxtables/xtoptions.c
@@ -65,6 +65,19 @@ static const size_t xtopt_psize[] = {
 	[XTTYPE_ETHERMAC]    = sizeof(uint8_t[6]),
 };
 
+/**
+ * Return a sanitized afinfo->family value, covering for NFPROTO_ARP
+ */
+static uint8_t afinfo_family(void)
+{
+	switch (afinfo->family) {
+	case NFPROTO_ARP:
+		return NFPROTO_IPV4;
+	default:
+		return afinfo->family;
+	}
+}
+
 /**
  * Creates getopt options from the x6-style option map, and assigns each a
  * getopt id.
@@ -461,7 +474,7 @@ static socklen_t xtables_sa_hostlen(unsigned int afproto)
  */
 static void xtopt_parse_host(struct xt_option_call *cb)
 {
-	struct addrinfo hints = {.ai_family = afinfo->family};
+	struct addrinfo hints = {.ai_family = afinfo_family()};
 	unsigned int adcount = 0;
 	struct addrinfo *res, *p;
 	int ret;
@@ -472,7 +485,7 @@ static void xtopt_parse_host(struct xt_option_call *cb)
 			"getaddrinfo: %s\n", gai_strerror(ret));
 
 	memset(&cb->val.hmask, 0xFF, sizeof(cb->val.hmask));
-	cb->val.hlen = (afinfo->family == NFPROTO_IPV4) ? 32 : 128;
+	cb->val.hlen = (afinfo_family() == NFPROTO_IPV4) ? 32 : 128;
 
 	for (p = res; p != NULL; p = p->ai_next) {
 		if (adcount == 0) {
@@ -615,7 +628,7 @@ static void xtopt_parse_mport(struct xt_option_call *cb)
 
 static int xtopt_parse_mask(struct xt_option_call *cb)
 {
-	struct addrinfo hints = {.ai_family = afinfo->family,
+	struct addrinfo hints = {.ai_family = afinfo_family(),
 				 .ai_flags = AI_NUMERICHOST };
 	struct addrinfo *res;
 	int ret;
@@ -627,7 +640,7 @@ static int xtopt_parse_mask(struct xt_option_call *cb)
 	memcpy(&cb->val.hmask, xtables_sa_host(res->ai_addr, res->ai_family),
 	       xtables_sa_hostlen(res->ai_family));
 
-	switch(afinfo->family) {
+	switch(afinfo_family()) {
 	case AF_INET:
 		cb->val.hlen = xtables_ipmask_to_cidr(&cb->val.hmask.in);
 		break;
@@ -649,7 +662,7 @@ static void xtopt_parse_plen(struct xt_option_call *cb)
 	const struct xt_option_entry *entry = cb->entry;
 	unsigned int prefix_len = 128; /* happiness is a warm gcc */
 
-	cb->val.hlen = (afinfo->family == NFPROTO_IPV4) ? 32 : 128;
+	cb->val.hlen = (afinfo_family() == NFPROTO_IPV4) ? 32 : 128;
 	if (!xtables_strtoui(cb->arg, NULL, &prefix_len, 0, cb->val.hlen)) {
 		/* Is this mask expressed in full format? e.g. 255.255.255.0 */
 		if (xtopt_parse_mask(cb))
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [iptables PATCH 3/6] libxtables: Introduce xtables_strtoul_base()
  2023-11-22 21:52 [iptables PATCH 0/6] Extend guided option parser for use by arptables Phil Sutter
  2023-11-22 21:52 ` [iptables PATCH 1/6] libxtables: Combine the two extension option mergers Phil Sutter
  2023-11-22 21:52 ` [iptables PATCH 2/6] libxtables: Fix guided option parser for use with arptables Phil Sutter
@ 2023-11-22 21:52 ` Phil Sutter
  2023-11-22 21:52 ` [iptables PATCH 4/6] libxtables: Introduce struct xt_option_entry::base Phil Sutter
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Phil Sutter @ 2023-11-22 21:52 UTC (permalink / raw)
  To: netfilter-devel

Semantically identical to xtables_strtoul() but accepts the base as
parameter so callers may force it irrespective of number prefix. The old
xtables_strtoul() becomes a shallow wrapper.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 include/xtables.h    |  2 ++
 libxtables/xtables.c | 16 +++++++++++-----
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/include/xtables.h b/include/xtables.h
index 087a1d600f9ae..1a9e08bb131ab 100644
--- a/include/xtables.h
+++ b/include/xtables.h
@@ -486,6 +486,8 @@ extern void xtables_register_matches(struct xtables_match *, unsigned int);
 extern void xtables_register_target(struct xtables_target *me);
 extern void xtables_register_targets(struct xtables_target *, unsigned int);
 
+extern bool xtables_strtoul_base(const char *, char **, uintmax_t *,
+	uintmax_t, uintmax_t, unsigned int);
 extern bool xtables_strtoul(const char *, char **, uintmax_t *,
 	uintmax_t, uintmax_t);
 extern bool xtables_strtoui(const char *, char **, unsigned int *,
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
index ba9ceaeb3da41..b4339e8d31275 100644
--- a/libxtables/xtables.c
+++ b/libxtables/xtables.c
@@ -580,23 +580,23 @@ int xtables_load_ko(const char *modprobe, bool quiet)
 }
 
 /**
- * xtables_strtou{i,l} - string to number conversion
+ * xtables_strtoul_base - string to number conversion
  * @s:	input string
  * @end:	like strtoul's "end" pointer
  * @value:	pointer for result
  * @min:	minimum accepted value
  * @max:	maximum accepted value
+ * @base:	assumed base of value
  *
  * If @end is NULL, we assume the caller wants a "strict strtoul", and hence
  * "15a" is rejected.
  * In either case, the value obtained is compared for min-max compliance.
- * Base is always 0, i.e. autodetect depending on @s.
  *
  * Returns true/false whether number was accepted. On failure, *value has
  * undefined contents.
  */
-bool xtables_strtoul(const char *s, char **end, uintmax_t *value,
-                     uintmax_t min, uintmax_t max)
+bool xtables_strtoul_base(const char *s, char **end, uintmax_t *value,
+			  uintmax_t min, uintmax_t max, unsigned int base)
 {
 	uintmax_t v;
 	const char *p;
@@ -608,7 +608,7 @@ bool xtables_strtoul(const char *s, char **end, uintmax_t *value,
 		;
 	if (*p == '-')
 		return false;
-	v = strtoumax(s, &my_end, 0);
+	v = strtoumax(s, &my_end, base);
 	if (my_end == s)
 		return false;
 	if (end != NULL)
@@ -625,6 +625,12 @@ bool xtables_strtoul(const char *s, char **end, uintmax_t *value,
 	return false;
 }
 
+bool xtables_strtoul(const char *s, char **end, uintmax_t *value,
+		     uintmax_t min, uintmax_t max)
+{
+	return xtables_strtoul_base(s, end, value, min, max, 0);
+}
+
 bool xtables_strtoui(const char *s, char **end, unsigned int *value,
                      unsigned int min, unsigned int max)
 {
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [iptables PATCH 4/6] libxtables: Introduce struct xt_option_entry::base
  2023-11-22 21:52 [iptables PATCH 0/6] Extend guided option parser for use by arptables Phil Sutter
                   ` (2 preceding siblings ...)
  2023-11-22 21:52 ` [iptables PATCH 3/6] libxtables: Introduce xtables_strtoul_base() Phil Sutter
@ 2023-11-22 21:52 ` Phil Sutter
  2023-11-22 21:53 ` [iptables PATCH 5/6] extensions: libarpt_mangle: Use guided option parser Phil Sutter
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Phil Sutter @ 2023-11-22 21:52 UTC (permalink / raw)
  To: netfilter-devel

Enable guided option parser users to parse integer values with a fixed
base.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 include/xtables.h      | 3 ++-
 libxtables/xtoptions.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/xtables.h b/include/xtables.h
index 1a9e08bb131ab..b3c45c981b1c7 100644
--- a/include/xtables.h
+++ b/include/xtables.h
@@ -122,6 +122,7 @@ enum xt_option_flags {
  * @size:	size of the item pointed to by @ptroff; this is a safeguard
  * @min:	lowest allowed value (for singular integral types)
  * @max:	highest allowed value (for singular integral types)
+ * @base:	assumed base of parsed value for integer types (default 0)
  */
 struct xt_option_entry {
 	const char *name;
@@ -129,7 +130,7 @@ struct xt_option_entry {
 	unsigned int id, excl, also, flags;
 	unsigned int ptroff;
 	size_t size;
-	unsigned int min, max;
+	unsigned int min, max, base;
 };
 
 /**
diff --git a/libxtables/xtoptions.c b/libxtables/xtoptions.c
index 25540f8b88c6d..4fd0e70e6b555 100644
--- a/libxtables/xtoptions.c
+++ b/libxtables/xtoptions.c
@@ -161,7 +161,8 @@ static void xtopt_parse_int(struct xt_option_call *cb)
 	if (cb->entry->max != 0)
 		lmax = cb->entry->max;
 
-	if (!xtables_strtoul(cb->arg, NULL, &value, lmin, lmax))
+	if (!xtables_strtoul_base(cb->arg, NULL, &value,
+				  lmin, lmax, cb->entry->base))
 		xt_params->exit_err(PARAMETER_PROBLEM,
 			"%s: bad value for option \"--%s\", "
 			"or out of range (%ju-%ju).\n",
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [iptables PATCH 5/6] extensions: libarpt_mangle: Use guided option parser
  2023-11-22 21:52 [iptables PATCH 0/6] Extend guided option parser for use by arptables Phil Sutter
                   ` (3 preceding siblings ...)
  2023-11-22 21:52 ` [iptables PATCH 4/6] libxtables: Introduce struct xt_option_entry::base Phil Sutter
@ 2023-11-22 21:53 ` Phil Sutter
  2023-11-22 21:53 ` [iptables PATCH 6/6] extensions: MARK: arptables: " Phil Sutter
  2023-11-23 16:55 ` [iptables PATCH 0/6] Extend guided option parser for use by arptables Phil Sutter
  6 siblings, 0 replies; 8+ messages in thread
From: Phil Sutter @ 2023-11-22 21:53 UTC (permalink / raw)
  To: netfilter-devel

Sadly not the best conversion, struct arpt_mangle is not ideal for use
as storage backend: With MAC addresses, xtopt_parse_ethermac() refuses
to write into *_devaddr fields as they are larger than expected. With
XTTYPE_HOSTMASK OTOH, XTOPT_PUT is not supported in the first place.

As a side-effect, network names (from /etc/networks) are no longer
accepted. But earlier migrations to guided option parser had this
side-effect as well, so probably not a frequently used feature.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 extensions/libarpt_mangle.c | 128 +++++++++++++-----------------------
 extensions/libarpt_mangle.t |   4 ++
 2 files changed, 48 insertions(+), 84 deletions(-)

diff --git a/extensions/libarpt_mangle.c b/extensions/libarpt_mangle.c
index 364c9ce755b97..283bb1323806c 100644
--- a/extensions/libarpt_mangle.c
+++ b/extensions/libarpt_mangle.c
@@ -25,19 +25,16 @@ static void arpmangle_print_help(void)
 	"--mangle-target target (DROP, CONTINUE or ACCEPT -- default is ACCEPT)\n");
 }
 
-#define MANGLE_IPS    '1'
-#define MANGLE_IPT    '2'
-#define MANGLE_DEVS   '3'
-#define MANGLE_DEVT   '4'
-#define MANGLE_TARGET '5'
-
-static const struct option arpmangle_opts[] = {
-	{ .name = "mangle-ip-s",	.has_arg = true, .val = MANGLE_IPS },
-	{ .name = "mangle-ip-d",	.has_arg = true, .val = MANGLE_IPT },
-	{ .name = "mangle-mac-s",	.has_arg = true, .val = MANGLE_DEVS },
-	{ .name = "mangle-mac-d",	.has_arg = true, .val = MANGLE_DEVT },
-	{ .name = "mangle-target",	.has_arg = true, .val = MANGLE_TARGET },
-	XT_GETOPT_TABLEEND,
+/* internal use only, explicitly not covered by ARPT_MANGLE_MASK */
+#define ARPT_MANGLE_TARGET	0x10
+
+static const struct xt_option_entry arpmangle_opts[] = {
+{ .name = "mangle-ip-s", .id = ARPT_MANGLE_SIP, .type = XTTYPE_HOSTMASK },
+{ .name = "mangle-ip-d", .id = ARPT_MANGLE_TIP, .type = XTTYPE_HOSTMASK },
+{ .name = "mangle-mac-s", .id = ARPT_MANGLE_SDEV, .type = XTTYPE_ETHERMAC },
+{ .name = "mangle-mac-d", .id = ARPT_MANGLE_TDEV, .type = XTTYPE_ETHERMAC },
+{ .name = "mangle-target", .id = ARPT_MANGLE_TARGET, .type = XTTYPE_STRING },
+XTOPT_TABLEEND,
 };
 
 static void arpmangle_init(struct xt_entry_target *target)
@@ -47,86 +44,50 @@ static void arpmangle_init(struct xt_entry_target *target)
 	mangle->target = NF_ACCEPT;
 }
 
-static int
-arpmangle_parse(int c, char **argv, int invert, unsigned int *flags,
-		const void *entry, struct xt_entry_target **target)
+static void assert_hopts(const struct arpt_entry *e, const char *optname)
 {
-	struct arpt_mangle *mangle = (struct arpt_mangle *)(*target)->data;
-	struct in_addr *ipaddr, mask;
-	struct ether_addr *macaddr;
-	const struct arpt_entry *e = (const struct arpt_entry *)entry;
-	unsigned int nr;
-	int ret = 1;
-
-	memset(&mask, 0, sizeof(mask));
-
-	switch (c) {
-	case MANGLE_IPS:
-		xtables_ipparse_any(optarg, &ipaddr, &mask, &nr);
-		mangle->u_s.src_ip.s_addr = ipaddr->s_addr;
-		free(ipaddr);
-		mangle->flags |= ARPT_MANGLE_SIP;
-		break;
-	case MANGLE_IPT:
-		xtables_ipparse_any(optarg, &ipaddr, &mask, &nr);
-		mangle->u_t.tgt_ip.s_addr = ipaddr->s_addr;
-		free(ipaddr);
-		mangle->flags |= ARPT_MANGLE_TIP;
+	if (e->arp.arhln_mask == 0)
+		xtables_error(PARAMETER_PROBLEM, "no --h-length defined");
+	if (e->arp.invflags & IPT_INV_ARPHLN)
+		xtables_error(PARAMETER_PROBLEM,
+			      "! hln not allowed for --%s", optname);
+	if (e->arp.arhln != 6)
+		xtables_error(PARAMETER_PROBLEM, "only --h-length 6 supported");
+}
+
+static void arpmangle_parse(struct xt_option_call *cb)
+{
+	const struct arpt_entry *e = cb->xt_entry;
+	struct arpt_mangle *mangle = cb->data;
+
+	xtables_option_parse(cb);
+	mangle->flags |= (cb->entry->id & ARPT_MANGLE_MASK);
+	switch (cb->entry->id) {
+	case ARPT_MANGLE_SIP:
+		mangle->u_s.src_ip = cb->val.haddr.in;
 		break;
-	case MANGLE_DEVS:
-		if (e->arp.arhln_mask == 0)
-			xtables_error(PARAMETER_PROBLEM,
-				      "no --h-length defined");
-		if (e->arp.invflags & IPT_INV_ARPHLN)
-			xtables_error(PARAMETER_PROBLEM,
-				      "! --h-length not allowed for "
-				      "--mangle-mac-s");
-		if (e->arp.arhln != 6)
-			xtables_error(PARAMETER_PROBLEM,
-				      "only --h-length 6 supported");
-		macaddr = ether_aton(optarg);
-		if (macaddr == NULL)
-			xtables_error(PARAMETER_PROBLEM,
-				      "invalid source MAC");
-		memcpy(mangle->src_devaddr, macaddr, e->arp.arhln);
-		mangle->flags |= ARPT_MANGLE_SDEV;
+	case ARPT_MANGLE_TIP:
+		mangle->u_t.tgt_ip = cb->val.haddr.in;
 		break;
-	case MANGLE_DEVT:
-		if (e->arp.arhln_mask == 0)
-			xtables_error(PARAMETER_PROBLEM,
-				      "no --h-length defined");
-		if (e->arp.invflags & IPT_INV_ARPHLN)
-			xtables_error(PARAMETER_PROBLEM,
-				      "! hln not allowed for --mangle-mac-d");
-		if (e->arp.arhln != 6)
-			xtables_error(PARAMETER_PROBLEM,
-				      "only --h-length 6 supported");
-		macaddr = ether_aton(optarg);
-		if (macaddr == NULL)
-			xtables_error(PARAMETER_PROBLEM, "invalid target MAC");
-		memcpy(mangle->tgt_devaddr, macaddr, e->arp.arhln);
-		mangle->flags |= ARPT_MANGLE_TDEV;
+	case ARPT_MANGLE_SDEV:
+		assert_hopts(e, cb->entry->name);
+		memcpy(mangle->src_devaddr, cb->val.ethermac, ETH_ALEN);
+	case ARPT_MANGLE_TDEV:
+		assert_hopts(e, cb->entry->name);
+		memcpy(mangle->tgt_devaddr, cb->val.ethermac, ETH_ALEN);
 		break;
-	case MANGLE_TARGET:
-		if (!strcmp(optarg, "DROP"))
+	case ARPT_MANGLE_TARGET:
+		if (!strcmp(cb->arg, "DROP"))
 			mangle->target = NF_DROP;
-		else if (!strcmp(optarg, "ACCEPT"))
+		else if (!strcmp(cb->arg, "ACCEPT"))
 			mangle->target = NF_ACCEPT;
-		else if (!strcmp(optarg, "CONTINUE"))
+		else if (!strcmp(cb->arg, "CONTINUE"))
 			mangle->target = XT_CONTINUE;
 		else
 			xtables_error(PARAMETER_PROBLEM,
 				      "bad target for --mangle-target");
 		break;
-	default:
-		ret = 0;
 	}
-
-	return ret;
-}
-
-static void arpmangle_final_check(unsigned int flags)
-{
 }
 
 static const char *ipaddr_to(const struct in_addr *addrp, int numeric)
@@ -225,11 +186,10 @@ static struct xtables_target arpmangle_target = {
 	.userspacesize	= XT_ALIGN(sizeof(struct arpt_mangle)),
 	.help		= arpmangle_print_help,
 	.init		= arpmangle_init,
-	.parse		= arpmangle_parse,
-	.final_check	= arpmangle_final_check,
+	.x6_parse	= arpmangle_parse,
 	.print		= arpmangle_print,
 	.save		= arpmangle_save,
-	.extra_opts	= arpmangle_opts,
+	.x6_options	= arpmangle_opts,
 	.xlate		= arpmangle_xlate,
 };
 
diff --git a/extensions/libarpt_mangle.t b/extensions/libarpt_mangle.t
index da9669489d291..7a639ee10aa0f 100644
--- a/extensions/libarpt_mangle.t
+++ b/extensions/libarpt_mangle.t
@@ -3,3 +3,7 @@
 -j mangle -d 1.2.3.4 --mangle-ip-d 1.2.3.5;=;OK
 -j mangle -d 1.2.3.4 --mangle-mac-d 00:01:02:03:04:05;=;OK
 -d 1.2.3.4 --h-length 5 -j mangle --mangle-mac-s 00:01:02:03:04:05;=;FAIL
+-j mangle --mangle-ip-s 1.2.3.4 --mangle-target DROP;=;OK
+-j mangle --mangle-ip-s 1.2.3.4 --mangle-target ACCEPT;-j mangle --mangle-ip-s 1.2.3.4;OK
+-j mangle --mangle-ip-s 1.2.3.4 --mangle-target CONTINUE;=;OK
+-j mangle --mangle-ip-s 1.2.3.4 --mangle-target FOO;=;FAIL
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [iptables PATCH 6/6] extensions: MARK: arptables: Use guided option parser
  2023-11-22 21:52 [iptables PATCH 0/6] Extend guided option parser for use by arptables Phil Sutter
                   ` (4 preceding siblings ...)
  2023-11-22 21:53 ` [iptables PATCH 5/6] extensions: libarpt_mangle: Use guided option parser Phil Sutter
@ 2023-11-22 21:53 ` Phil Sutter
  2023-11-23 16:55 ` [iptables PATCH 0/6] Extend guided option parser for use by arptables Phil Sutter
  6 siblings, 0 replies; 8+ messages in thread
From: Phil Sutter @ 2023-11-22 21:53 UTC (permalink / raw)
  To: netfilter-devel

It expects mark values in hex which is possible by setting the base
field.

The only adjustment needed to use the revision 2 parser is to fill the
mask for --set-mark: With XTTYPE_MARKMASK32, an omitted mask sets all
mask bits, XTTYPE_UINT32 leaves it uninitialized, though.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 extensions/libxt_MARK.c | 82 ++++++++---------------------------------
 1 file changed, 15 insertions(+), 67 deletions(-)

diff --git a/extensions/libxt_MARK.c b/extensions/libxt_MARK.c
index d6eacfcb33f69..703d894f233d9 100644
--- a/extensions/libxt_MARK.c
+++ b/extensions/libxt_MARK.c
@@ -1,4 +1,3 @@
-#include <getopt.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <xtables.h>
@@ -69,6 +68,16 @@ static const struct xt_option_entry mark_tg_opts[] = {
 	XTOPT_TABLEEND,
 };
 
+static const struct xt_option_entry mark_tg_arp_opts[] = {
+	{.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_UINT32,
+	 .base = 16, .excl = F_ANY},
+	{.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32,
+	 .base = 16, .excl = F_ANY},
+	{.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32,
+	 .base = 16, .excl = F_ANY},
+	XTOPT_TABLEEND,
+};
+
 static void mark_tg_help(void)
 {
 	printf(
@@ -136,6 +145,8 @@ static void mark_tg_parse(struct xt_option_call *cb)
 	case O_SET_MARK:
 		info->mark = cb->val.mark;
 		info->mask = cb->val.mark | cb->val.mask;
+		if (cb->entry->type == XTTYPE_UINT32)
+			info->mask = UINT32_MAX;
 		break;
 	case O_AND_MARK:
 		info->mark = 0;
@@ -263,70 +274,6 @@ static void mark_tg_arp_print(const void *ip,
 	mark_tg_arp_save(ip, target);
 }
 
-#define MARK_OPT 1
-#define AND_MARK_OPT 2
-#define OR_MARK_OPT 3
-
-static struct option mark_tg_arp_opts[] = {
-	{ .name = "set-mark", .has_arg = required_argument, .flag = 0, .val = MARK_OPT },
-	{ .name = "and-mark", .has_arg = required_argument, .flag = 0, .val = AND_MARK_OPT },
-	{ .name = "or-mark", .has_arg = required_argument, .flag = 0, .val =  OR_MARK_OPT },
-	{ .name = NULL}
-};
-
-static int
-mark_tg_arp_parse(int c, char **argv, int invert, unsigned int *flags,
-		  const void *entry, struct xt_entry_target **target)
-{
-	struct xt_mark_tginfo2 *info =
-		(struct xt_mark_tginfo2 *)(*target)->data;
-	int i;
-
-	switch (c) {
-	case MARK_OPT:
-		if (sscanf(argv[optind-1], "%x", &i) != 1) {
-			xtables_error(PARAMETER_PROBLEM,
-				"Bad mark value `%s'", optarg);
-			return 0;
-		}
-		info->mark = i;
-		info->mask = 0xffffffffU;
-		if (*flags)
-			xtables_error(PARAMETER_PROBLEM,
-				"MARK: Can't specify --set-mark twice");
-		*flags = 1;
-		break;
-	case AND_MARK_OPT:
-		if (sscanf(argv[optind-1], "%x", &i) != 1) {
-			xtables_error(PARAMETER_PROBLEM,
-				"Bad mark value `%s'", optarg);
-			return 0;
-		}
-		info->mark = 0;
-		info->mask = ~i;
-		if (*flags)
-			xtables_error(PARAMETER_PROBLEM,
-				"MARK: Can't specify --and-mark twice");
-		*flags = 1;
-		break;
-	case OR_MARK_OPT:
-		if (sscanf(argv[optind-1], "%x", &i) != 1) {
-			xtables_error(PARAMETER_PROBLEM,
-				"Bad mark value `%s'", optarg);
-			return 0;
-		}
-		info->mark = info->mask = i;
-		if (*flags)
-			xtables_error(PARAMETER_PROBLEM,
-				"MARK: Can't specify --or-mark twice");
-		*flags = 1;
-		break;
-	default:
-		return 0;
-	}
-	return 1;
-}
-
 static int mark_tg_xlate(struct xt_xlate *xl,
 			 const struct xt_xlate_tg_params *params)
 {
@@ -429,8 +376,9 @@ static struct xtables_target mark_tg_reg[] = {
 		.help          = mark_tg_help,
 		.print         = mark_tg_arp_print,
 		.save          = mark_tg_arp_save,
-		.parse         = mark_tg_arp_parse,
-		.extra_opts    = mark_tg_arp_opts,
+		.x6_parse      = mark_tg_parse,
+		.x6_fcheck     = mark_tg_check,
+		.x6_options    = mark_tg_arp_opts,
 		.xlate	       = mark_tg_xlate,
 	},
 };
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [iptables PATCH 0/6] Extend guided option parser for use by arptables
  2023-11-22 21:52 [iptables PATCH 0/6] Extend guided option parser for use by arptables Phil Sutter
                   ` (5 preceding siblings ...)
  2023-11-22 21:53 ` [iptables PATCH 6/6] extensions: MARK: arptables: " Phil Sutter
@ 2023-11-23 16:55 ` Phil Sutter
  6 siblings, 0 replies; 8+ messages in thread
From: Phil Sutter @ 2023-11-23 16:55 UTC (permalink / raw)
  To: netfilter-devel

On Wed, Nov 22, 2023 at 10:52:55PM +0100, Phil Sutter wrote:
> Patch 1 is unrelated to the remaining ones, but fits into a series about
> libxtables option parser.
> 
> Patch 2 fixes for parsing of IP addresses with arptables, patches 3 and
> 4 enable users to parse integers in a fixed base.
> 
> Patches 5 and 6 then migrate more extensions over to using the guided
> option parser.
> 
> Phil Sutter (6):
>   libxtables: Combine the two extension option mergers
>   libxtables: Fix guided option parser for use with arptables
>   libxtables: Introduce xtables_strtoul_base()
>   libxtables: Introduce struct xt_option_entry::base
>   extensions: libarpt_mangle: Use guided option parser
>   extensions: MARK: arptables: Use guided option parser

Series applied.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-11-23 16:55 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-22 21:52 [iptables PATCH 0/6] Extend guided option parser for use by arptables Phil Sutter
2023-11-22 21:52 ` [iptables PATCH 1/6] libxtables: Combine the two extension option mergers Phil Sutter
2023-11-22 21:52 ` [iptables PATCH 2/6] libxtables: Fix guided option parser for use with arptables Phil Sutter
2023-11-22 21:52 ` [iptables PATCH 3/6] libxtables: Introduce xtables_strtoul_base() Phil Sutter
2023-11-22 21:52 ` [iptables PATCH 4/6] libxtables: Introduce struct xt_option_entry::base Phil Sutter
2023-11-22 21:53 ` [iptables PATCH 5/6] extensions: libarpt_mangle: Use guided option parser Phil Sutter
2023-11-22 21:53 ` [iptables PATCH 6/6] extensions: MARK: arptables: " Phil Sutter
2023-11-23 16:55 ` [iptables PATCH 0/6] Extend guided option parser for use by arptables Phil Sutter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).