diff mbox series

[iproute2,1/2] tc: pedit: parse_cmd: add flags argument

Message ID 20210618160635.703845-1-asbjorn@asbjorn.st
State New
Headers show
Series [iproute2,1/2] tc: pedit: parse_cmd: add flags argument | expand

Commit Message

Asbjørn Sloth Tønnesen June 18, 2021, 4:06 p.m. UTC
This patch just prepares the flags argument, so it's
available to the next patch.

Signed-off-by: Asbjørn Sloth Tønnesen <asbjorn@asbjorn.st>
---
 tc/m_pedit.c |  4 ++--
 tc/m_pedit.h |  2 +-
 tc/p_eth.c   |  6 +++---
 tc/p_ip.c    | 32 ++++++++++++++++----------------
 tc/p_ip6.c   | 14 +++++++-------
 tc/p_tcp.c   |  6 +++---
 tc/p_udp.c   |  4 ++--
 7 files changed, 34 insertions(+), 34 deletions(-)

Comments

David Ahern June 22, 2021, 3:39 p.m. UTC | #1
[ looks fine to me; adding tc folks to make sure they see it ]

On 6/18/21 10:06 AM, Asbjørn Sloth Tønnesen wrote:
> Implement a decrement operation for ttl and hoplimit.

> 

> Since this is just syntactic sugar, it goes that:

> 

>   tc filter add ... action pedit ex munge ip ttl dec ...

>   tc filter add ... action pedit ex munge ip6 hoplimit dec ...

> 

> is just a more readable version of this:

> 

>   tc filter add ... action pedit ex munge ip ttl add 0xff ...

>   tc filter add ... action pedit ex munge ip6 hoplimit add 0xff ...

> 

> This feature was suggested by some pseudo tc examples in Mellanox's

> documentation[1], but wasn't present in neither their mlnx-iproute2

> nor iproute2.

> 

> Tested with skip_sw on Mellanox ConnectX-6 Dx.

> 

> [1] https://docs.mellanox.com/pages/viewpage.action?pageId=47033989

> 

> v3:

>    - Use dedicated flags argument in parse_cmd() (David Ahern)

>    - Minor rewording of the man page

> 

> v2:

>    - Fix whitespace issue (Stephen Hemminger)

>    - Add to usage info in explain()

> 

> Signed-off-by: Asbjørn Sloth Tønnesen <asbjorn@asbjorn.st>

> ---

>  man/man8/tc-pedit.8 |  8 +++++++-

>  tc/m_pedit.c        | 25 +++++++++++++++++++------

>  tc/m_pedit.h        |  4 ++++

>  tc/p_ip.c           |  2 +-

>  tc/p_ip6.c          |  2 +-

>  5 files changed, 32 insertions(+), 9 deletions(-)

> 

> diff --git a/man/man8/tc-pedit.8 b/man/man8/tc-pedit.8

> index 376ad4a8..15159ddd 100644

> --- a/man/man8/tc-pedit.8

> +++ b/man/man8/tc-pedit.8

> @@ -77,6 +77,7 @@ pedit - generic packet editor action

>  .IR VAL " | "

>  .BR add

>  .IR VAL " | "

> +.BR decrement " | "

>  .BR preserve " } [ " retain

>  .IR RVAL " ]"

>  

> @@ -96,7 +97,7 @@ chosen automatically based on the header field size.

>  .B ex

>  Use extended pedit.

>  .I EXTENDED_LAYERED_OP

> -and the add

> +and the add/decrement

>  .I CMD_SPEC

>  are allowed only in this mode.

>  .TP

> @@ -288,6 +289,11 @@ is defined by the size of the addressed header field in

>  .IR EXTENDED_LAYERED_OP .

>  This operation is supported only for extended layered op.

>  .TP

> +.BI decrement

> +Decrease the addressed data by one.

> +This operation is supported only for

> +.BR ip " " ttl " and " ip6 " " hoplimit "."

> +.TP

>  .B preserve

>  Keep the addressed data as is.

>  .TP

> diff --git a/tc/m_pedit.c b/tc/m_pedit.c

> index b745c379..54949e43 100644

> --- a/tc/m_pedit.c

> +++ b/tc/m_pedit.c

> @@ -41,7 +41,7 @@ static void explain(void)

>  		"\t\tATC:= at <atval> offmask <maskval> shift <shiftval>\n"

>  		"\t\tNOTE: offval is byte offset, must be multiple of 4\n"

>  		"\t\tNOTE: maskval is a 32 bit hex number\n \t\tNOTE: shiftval is a shift value\n"

> -		"\t\tCMD:= clear | invert | set <setval>| add <addval> | retain\n"

> +		"\t\tCMD:= clear | invert | set <setval> | add <addval> | decrement | retain\n"

>  		"\t<LAYERED>:= ip <ipdata> | ip6 <ip6data>\n"

>  		" \t\t| udp <udpdata> | tcp <tcpdata> | icmp <icmpdata>\n"

>  		"\tCONTROL:= reclassify | pipe | drop | continue | pass |\n"

> @@ -360,15 +360,24 @@ int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type, __u32 retain,

>  		if (matches(*argv, "add") == 0)

>  			tkey->cmd = TCA_PEDIT_KEY_EX_CMD_ADD;

>  

> -		if (!sel->extended && tkey->cmd) {

> -			fprintf(stderr,

> -				"Non extended mode. only 'set' command is supported\n");

> -			return -1;

> -		}

> +		if (!sel->extended && tkey->cmd)

> +			goto non_ext_only_set_cmd;

>  

>  		NEXT_ARG();

>  		if (parse_val(&argc, &argv, val, type))

>  			return -1;

> +	} else if (matches(*argv, "decrement") == 0) {

> +		if ((flags & PEDIT_ALLOW_DEC) == 0) {

> +			fprintf(stderr,

> +				"decrement command is not supported for this field\n");

> +			return -1;

> +		}

> +

> +		if (!sel->extended)

> +			goto non_ext_only_set_cmd;

> +

> +		tkey->cmd = TCA_PEDIT_KEY_EX_CMD_ADD;

> +		*v = retain; /* decrement by overflow */

>  	} else if (matches(*argv, "preserve") == 0) {

>  		retain = 0;

>  	} else {

> @@ -431,6 +440,10 @@ done:

>  	*argv_p = argv;

>  	return res;

>  

> +non_ext_only_set_cmd:

> +	fprintf(stderr,

> +		"Non extended mode. only 'set' command is supported\n");

> +	return -1;

>  }

>  

>  static int parse_offset(int *argc_p, char ***argv_p, struct m_pedit_sel *sel,

> diff --git a/tc/m_pedit.h b/tc/m_pedit.h

> index 7398f66d..549bcf86 100644

> --- a/tc/m_pedit.h

> +++ b/tc/m_pedit.h

> @@ -39,6 +39,10 @@

>  

>  #define PEDITKINDSIZ 16

>  

> +enum m_pedit_flags {

> +	PEDIT_ALLOW_DEC = 1<<0,

> +};

> +

>  struct m_pedit_key {

>  	__u32           mask;  /* AND */

>  	__u32           val;   /*XOR */

> diff --git a/tc/p_ip.c b/tc/p_ip.c

> index 2d1643d0..8eed9e8d 100644

> --- a/tc/p_ip.c

> +++ b/tc/p_ip.c

> @@ -68,7 +68,7 @@ parse_ip(int *argc_p, char ***argv_p,

>  	if (strcmp(*argv, "ttl") == 0) {

>  		NEXT_ARG();

>  		tkey->off = 8;

> -		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey, 0);

> +		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey, PEDIT_ALLOW_DEC);

>  		goto done;

>  	}

>  	if (strcmp(*argv, "protocol") == 0) {

> diff --git a/tc/p_ip6.c b/tc/p_ip6.c

> index f9d5d3b0..f855c59e 100644

> --- a/tc/p_ip6.c

> +++ b/tc/p_ip6.c

> @@ -71,7 +71,7 @@ parse_ip6(int *argc_p, char ***argv_p,

>  	if (strcmp(*argv, "hoplimit") == 0) {

>  		NEXT_ARG();

>  		tkey->off = 7;

> -		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey, 0);

> +		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey, PEDIT_ALLOW_DEC);

>  		goto done;

>  	}

>  	if (strcmp(*argv, "traffic_class") == 0) {

>
Jamal Hadi Salim June 24, 2021, 8:24 p.m. UTC | #2
Hi Asbjørn,


On 2021-06-22 11:39 a.m., David Ahern wrote:
> [ looks fine to me; adding tc folks to make sure they see it ]

> 

> On 6/18/21 10:06 AM, Asbjørn Sloth Tønnesen wrote:

>> Implement a decrement operation for ttl and hoplimit.

>>

>> Since this is just syntactic sugar, it goes that:

>>

>>    tc filter add ... action pedit ex munge ip ttl dec ...

>>    tc filter add ... action pedit ex munge ip6 hoplimit dec ...

>>

>> is just a more readable version of this:

>>

>>    tc filter add ... action pedit ex munge ip ttl add 0xff ...

>>    tc filter add ... action pedit ex munge ip6 hoplimit add 0xff ...

>>


So you "add" essentially one's complement of the value you are trying to
decrement with?

>> This feature was suggested by some pseudo tc examples in Mellanox's

>> documentation[1], but wasn't present in neither their mlnx-iproute2

>> nor iproute2.

>>

>> Tested with skip_sw on Mellanox ConnectX-6 Dx.

>>

>> [1] https://docs.mellanox.com/pages/viewpage.action?pageId=47033989



I didnt see an example which showed using "dec" but what you described
above makes sense. And the changes below look sane. So:

Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>


cheers,
jamal
Asbjørn Sloth Tønnesen June 25, 2021, 7:21 p.m. UTC | #3
Hi Jamal,

Thank you for your review.

On 6/24/21 8:24 PM, Jamal Hadi Salim wrote:
> So you "add" essentially one's complement of the value you are trying to

> decrement with?


Almost (off by one), it's basically decrement by overflowing it, which
is safe since the operation is masked. One should however have another
rule, that matches on TTL == 1. so it can get a proper ICMP error.

Decrementing TTL by one was actually the prime example presented
when Amir Vadai introduced TCA_PEDIT_KEY_EX_CMD_ADD.

kernel   853a14ba net/act_pedit: Introduce 'add' operation     [1]
iproute2 8d193d96 tc/pedit: p_ip: introduce editing ttl header [2]

[1] https://git.kernel.org/torvalds/c/853a14ba
[2] https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/commit/?id=8d193d96


>>> This feature was suggested by some pseudo tc examples in Mellanox's

>>> documentation[1], but wasn't present in neither their mlnx-iproute2

>>> nor iproute2.

>>>

>>> Tested with skip_sw on Mellanox ConnectX-6 Dx.

>>>

>>> [1] https://docs.mellanox.com/pages/viewpage.action?pageId=47033989

> 

> 

> I didnt see an example which showed using "dec" but what you described

> above makes sense.


It is indeed a large document, so to be more specific:

https://docs.mellanox.com/pages/viewpage.action?pageId=47033989#highlighter_159101
 > Using TC rules:

 > IPv4:

 > tc filter add [..] munge ip ttl dec [..]

 > IPv6:

 > tc filter add [..] munge ipv6 hlimit dec [..]


"ipv6 hlimit" should obviously be "ip6 hoplimit".


-- 
Best regards
Asbjørn Sloth Tønnesen
David Ahern June 26, 2021, 4:45 a.m. UTC | #4
On 6/18/21 10:06 AM, Asbjørn Sloth Tønnesen wrote:
> Implement a decrement operation for ttl and hoplimit.

> 

> Since this is just syntactic sugar, it goes that:

> 

>   tc filter add ... action pedit ex munge ip ttl dec ...

>   tc filter add ... action pedit ex munge ip6 hoplimit dec ...

> 

> is just a more readable version of this:

> 

>   tc filter add ... action pedit ex munge ip ttl add 0xff ...

>   tc filter add ... action pedit ex munge ip6 hoplimit add 0xff ...

> 

> This feature was suggested by some pseudo tc examples in Mellanox's

> documentation[1], but wasn't present in neither their mlnx-iproute2

> nor iproute2.

> 

> Tested with skip_sw on Mellanox ConnectX-6 Dx.

> 

> [1] https://docs.mellanox.com/pages/viewpage.action?pageId=47033989

> 

> v3:

>    - Use dedicated flags argument in parse_cmd() (David Ahern)

>    - Minor rewording of the man page

> 

> v2:

>    - Fix whitespace issue (Stephen Hemminger)

>    - Add to usage info in explain()

> 

> Signed-off-by: Asbjørn Sloth Tønnesen <asbjorn@asbjorn.st>

> ---

>  man/man8/tc-pedit.8 |  8 +++++++-

>  tc/m_pedit.c        | 25 +++++++++++++++++++------

>  tc/m_pedit.h        |  4 ++++

>  tc/p_ip.c           |  2 +-

>  tc/p_ip6.c          |  2 +-

>  5 files changed, 32 insertions(+), 9 deletions(-)

> 


applied both to iproute2-next. Thanks,
diff mbox series

Patch

diff --git a/tc/m_pedit.c b/tc/m_pedit.c
index 74c91e8d..b745c379 100644
--- a/tc/m_pedit.c
+++ b/tc/m_pedit.c
@@ -330,7 +330,7 @@  static int parse_val(int *argc_p, char ***argv_p, __u32 *val, int type)
 }
 
 int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type, __u32 retain,
-	      struct m_pedit_sel *sel, struct m_pedit_key *tkey)
+	      struct m_pedit_sel *sel, struct m_pedit_key *tkey, int flags)
 {
 	__u32 mask[4] = { 0 };
 	__u32 val[4] = { 0 };
@@ -502,7 +502,7 @@  done:
 		NEXT_ARG();
 	}
 
-	res = parse_cmd(&argc, &argv, len, TU32, retain, sel, tkey);
+	res = parse_cmd(&argc, &argv, len, TU32, retain, sel, tkey, 0);
 
 	*argc_p = argc;
 	*argv_p = argv;
diff --git a/tc/m_pedit.h b/tc/m_pedit.h
index 5d3628a7..7398f66d 100644
--- a/tc/m_pedit.h
+++ b/tc/m_pedit.h
@@ -73,5 +73,5 @@  struct m_pedit_util {
 
 int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type,
 	      __u32 retain,
-	      struct m_pedit_sel *sel, struct m_pedit_key *tkey);
+	      struct m_pedit_sel *sel, struct m_pedit_key *tkey, int flags);
 #endif
diff --git a/tc/p_eth.c b/tc/p_eth.c
index 674f9c11..7b6b61f8 100644
--- a/tc/p_eth.c
+++ b/tc/p_eth.c
@@ -41,21 +41,21 @@  parse_eth(int *argc_p, char ***argv_p,
 	if (strcmp(*argv, "type") == 0) {
 		NEXT_ARG();
 		tkey->off = 12;
-		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey);
+		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey, 0);
 		goto done;
 	}
 
 	if (strcmp(*argv, "dst") == 0) {
 		NEXT_ARG();
 		tkey->off = 0;
-		res = parse_cmd(&argc, &argv, 6, TMAC, RU32, sel, tkey);
+		res = parse_cmd(&argc, &argv, 6, TMAC, RU32, sel, tkey, 0);
 		goto done;
 	}
 
 	if (strcmp(*argv, "src") == 0) {
 		NEXT_ARG();
 		tkey->off = 6;
-		res = parse_cmd(&argc, &argv, 6, TMAC, RU32, sel, tkey);
+		res = parse_cmd(&argc, &argv, 6, TMAC, RU32, sel, tkey, 0);
 		goto done;
 	}
 
diff --git a/tc/p_ip.c b/tc/p_ip.c
index c385ac6d..2d1643d0 100644
--- a/tc/p_ip.c
+++ b/tc/p_ip.c
@@ -40,13 +40,13 @@  parse_ip(int *argc_p, char ***argv_p,
 	if (strcmp(*argv, "src") == 0) {
 		NEXT_ARG();
 		tkey->off = 12;
-		res = parse_cmd(&argc, &argv, 4, TIPV4, RU32, sel, tkey);
+		res = parse_cmd(&argc, &argv, 4, TIPV4, RU32, sel, tkey, 0);
 		goto done;
 	}
 	if (strcmp(*argv, "dst") == 0) {
 		NEXT_ARG();
 		tkey->off = 16;
-		res = parse_cmd(&argc, &argv, 4, TIPV4, RU32, sel, tkey);
+		res = parse_cmd(&argc, &argv, 4, TIPV4, RU32, sel, tkey, 0);
 		goto done;
 	}
 	/* jamal - look at these and make them either old or new
@@ -56,64 +56,64 @@  parse_ip(int *argc_p, char ***argv_p,
 	if (strcmp(*argv, "tos") == 0 || matches(*argv, "dsfield") == 0) {
 		NEXT_ARG();
 		tkey->off = 1;
-		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
+		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey, 0);
 		goto done;
 	}
 	if (strcmp(*argv, "ihl") == 0) {
 		NEXT_ARG();
 		tkey->off = 0;
-		res = parse_cmd(&argc, &argv, 1, TU32, 0x0f, sel, tkey);
+		res = parse_cmd(&argc, &argv, 1, TU32, 0x0f, sel, tkey, 0);
 		goto done;
 	}
 	if (strcmp(*argv, "ttl") == 0) {
 		NEXT_ARG();
 		tkey->off = 8;
-		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
+		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey, 0);
 		goto done;
 	}
 	if (strcmp(*argv, "protocol") == 0) {
 		NEXT_ARG();
 		tkey->off = 9;
-		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
+		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey, 0);
 		goto done;
 	}
 	/* jamal - fix this */
 	if (matches(*argv, "precedence") == 0) {
 		NEXT_ARG();
 		tkey->off = 1;
-		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
+		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey, 0);
 		goto done;
 	}
 	/* jamal - validate this at some point */
 	if (strcmp(*argv, "nofrag") == 0) {
 		NEXT_ARG();
 		tkey->off = 6;
-		res = parse_cmd(&argc, &argv, 1, TU32, 0x3F, sel, tkey);
+		res = parse_cmd(&argc, &argv, 1, TU32, 0x3F, sel, tkey, 0);
 		goto done;
 	}
 	/* jamal - validate this at some point */
 	if (strcmp(*argv, "firstfrag") == 0) {
 		NEXT_ARG();
 		tkey->off = 6;
-		res = parse_cmd(&argc, &argv, 1, TU32, 0x1F, sel, tkey);
+		res = parse_cmd(&argc, &argv, 1, TU32, 0x1F, sel, tkey, 0);
 		goto done;
 	}
 	if (strcmp(*argv, "ce") == 0) {
 		NEXT_ARG();
 		tkey->off = 6;
-		res = parse_cmd(&argc, &argv, 1, TU32, 0x80, sel, tkey);
+		res = parse_cmd(&argc, &argv, 1, TU32, 0x80, sel, tkey, 0);
 		goto done;
 	}
 	if (strcmp(*argv, "df") == 0) {
 		NEXT_ARG();
 		tkey->off = 6;
-		res = parse_cmd(&argc, &argv, 1, TU32, 0x40, sel, tkey);
+		res = parse_cmd(&argc, &argv, 1, TU32, 0x40, sel, tkey, 0);
 		goto done;
 	}
 	if (strcmp(*argv, "mf") == 0) {
 		NEXT_ARG();
 		tkey->off = 6;
-		res = parse_cmd(&argc, &argv, 1, TU32, 0x20, sel, tkey);
+		res = parse_cmd(&argc, &argv, 1, TU32, 0x20, sel, tkey, 0);
 		goto done;
 	}
 
@@ -126,25 +126,25 @@  parse_ip(int *argc_p, char ***argv_p,
 	if (strcmp(*argv, "dport") == 0) {
 		NEXT_ARG();
 		tkey->off = 22;
-		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey);
+		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey, 0);
 		goto done;
 	}
 	if (strcmp(*argv, "sport") == 0) {
 		NEXT_ARG();
 		tkey->off = 20;
-		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey);
+		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey, 0);
 		goto done;
 	}
 	if (strcmp(*argv, "icmp_type") == 0) {
 		NEXT_ARG();
 		tkey->off = 20;
-		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
+		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey, 0);
 		goto done;
 	}
 	if (strcmp(*argv, "icmp_code") == 0) {
 		NEXT_ARG();
 		tkey->off = 20;
-		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
+		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey, 0);
 		goto done;
 	}
 	return -1;
diff --git a/tc/p_ip6.c b/tc/p_ip6.c
index 83a6ae81..f9d5d3b0 100644
--- a/tc/p_ip6.c
+++ b/tc/p_ip6.c
@@ -41,43 +41,43 @@  parse_ip6(int *argc_p, char ***argv_p,
 	if (strcmp(*argv, "src") == 0) {
 		NEXT_ARG();
 		tkey->off = 8;
-		res = parse_cmd(&argc, &argv, 16, TIPV6, RU32, sel, tkey);
+		res = parse_cmd(&argc, &argv, 16, TIPV6, RU32, sel, tkey, 0);
 		goto done;
 	}
 	if (strcmp(*argv, "dst") == 0) {
 		NEXT_ARG();
 		tkey->off = 24;
-		res = parse_cmd(&argc, &argv, 16, TIPV6, RU32, sel, tkey);
+		res = parse_cmd(&argc, &argv, 16, TIPV6, RU32, sel, tkey, 0);
 		goto done;
 	}
 	if (strcmp(*argv, "flow_lbl") == 0) {
 		NEXT_ARG();
 		tkey->off = 0;
-		res = parse_cmd(&argc, &argv, 4, TU32, 0x0007ffff, sel, tkey);
+		res = parse_cmd(&argc, &argv, 4, TU32, 0x0007ffff, sel, tkey, 0);
 		goto done;
 	}
 	if (strcmp(*argv, "payload_len") == 0) {
 		NEXT_ARG();
 		tkey->off = 4;
-		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey);
+		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey, 0);
 		goto done;
 	}
 	if (strcmp(*argv, "nexthdr") == 0) {
 		NEXT_ARG();
 		tkey->off = 6;
-		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
+		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey, 0);
 		goto done;
 	}
 	if (strcmp(*argv, "hoplimit") == 0) {
 		NEXT_ARG();
 		tkey->off = 7;
-		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
+		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey, 0);
 		goto done;
 	}
 	if (strcmp(*argv, "traffic_class") == 0) {
 		NEXT_ARG();
 		tkey->off = 1;
-		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
+		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey, 0);
 
 		/* Shift the field by 4 bits on success. */
 		if (!res) {
diff --git a/tc/p_tcp.c b/tc/p_tcp.c
index d2dbfd71..ec7b08a2 100644
--- a/tc/p_tcp.c
+++ b/tc/p_tcp.c
@@ -41,21 +41,21 @@  parse_tcp(int *argc_p, char ***argv_p,
 	if (strcmp(*argv, "sport") == 0) {
 		NEXT_ARG();
 		tkey->off = 0;
-		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey);
+		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey, 0);
 		goto done;
 	}
 
 	if (strcmp(*argv, "dport") == 0) {
 		NEXT_ARG();
 		tkey->off = 2;
-		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey);
+		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey, 0);
 		goto done;
 	}
 
 	if (strcmp(*argv, "flags") == 0) {
 		NEXT_ARG();
 		tkey->off = 13;
-		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
+		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey, 0);
 		goto done;
 	}
 
diff --git a/tc/p_udp.c b/tc/p_udp.c
index bab456de..742955e6 100644
--- a/tc/p_udp.c
+++ b/tc/p_udp.c
@@ -41,14 +41,14 @@  parse_udp(int *argc_p, char ***argv_p,
 	if (strcmp(*argv, "sport") == 0) {
 		NEXT_ARG();
 		tkey->off = 0;
-		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey);
+		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey, 0);
 		goto done;
 	}
 
 	if (strcmp(*argv, "dport") == 0) {
 		NEXT_ARG();
 		tkey->off = 2;
-		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey);
+		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey, 0);
 		goto done;
 	}