netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH iproute2 net 0/8] tc/act_pedit: Support offset relative to conventional header
@ 2017-04-23 12:53 Amir Vadai
  2017-04-23 12:53 ` [PATCH iproute2 net 1/8] tc/pedit: Fix a typo in pedit usage message Amir Vadai
                   ` (8 more replies)
  0 siblings, 9 replies; 15+ messages in thread
From: Amir Vadai @ 2017-04-23 12:53 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Or Gerlitz, Jamal Hadi Salim, Amir Vadai

Hi Stephen,

This patchset extends pedit to support modifying a field in an offset relative
to the conventional network headers (kenrel support was added [1] in 4.11 rc1).
Without the extended pedit, user could specify fields in TCP and ICMP headers,
but the kernel code was using an offset relative to the begining of the IP
header. This will break if IP header length is greater than the minimal value
of 20, or if L3 is not IPv4.

It also introduces support in manipulating ETH, TCP, UDP and IP.ttl fields and
a new command to increase/decrease the value of a field (current use case is IP.ttl).

Since there might be deployments already using pedit, special consideration was
taken, not to break those scripts - only by specifying the special keyword
'ex', the extended capabilities are available, thus there should be no impact
on existing scripts.
Also, the new code can live together with rules added by the old code. It
supports both the old netlink and the new one.

This patchset is against the master and not net-next as the functionality was
added in 4.11

Thanks,
Amir

[1] - 71d0ed7079df ("net/act_pedit: Support using offset relative to the
                     conventional network headers")

Amir Vadai (7):
  tc/pedit: Fix a typo in pedit usage message
  tc/pedit: Extend pedit to specify offset relative to mac/transport
    headers
  tc/pedit: Introduce 'add' operation
  tc/pedit: p_ip: introduce editing ttl header
  tc/pedit: Support fields bigger than 32 bits
  tc/pedit: p_eth: ETH header editor
  tc/pedit: p_tcp: introduce pedit tcp support

Or Gerlitz (1):
  tc/pedit: p_udp: introduce pedit udp support

 man/man8/tc-pedit.8 | 126 +++++++++++++++++++++--
 tc/Makefile         |   1 +
 tc/m_pedit.c        | 290 ++++++++++++++++++++++++++++++++++++++++++++++------
 tc/m_pedit.h        |  44 ++++++--
 tc/p_eth.c          |  72 +++++++++++++
 tc/p_icmp.c         |   3 +-
 tc/p_ip.c           |  21 +++-
 tc/p_tcp.c          |  40 +++++++-
 tc/p_udp.c          |  30 +++++-
 9 files changed, 572 insertions(+), 55 deletions(-)
 create mode 100644 tc/p_eth.c

-- 
2.12.0

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

* [PATCH iproute2 net 1/8] tc/pedit: Fix a typo in pedit usage message
  2017-04-23 12:53 [PATCH iproute2 net 0/8] tc/act_pedit: Support offset relative to conventional header Amir Vadai
@ 2017-04-23 12:53 ` Amir Vadai
  2017-04-23 12:53 ` [PATCH iproute2 net 2/8] tc/pedit: Extend pedit to specify offset relative to mac/transport headers Amir Vadai
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Amir Vadai @ 2017-04-23 12:53 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Or Gerlitz, Jamal Hadi Salim, Amir Vadai

Signed-off-by: Amir Vadai <amir@vadai.me>
---
 tc/m_pedit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tc/m_pedit.c b/tc/m_pedit.c
index 8e9bf0720dfe..939a6a1455a5 100644
--- a/tc/m_pedit.c
+++ b/tc/m_pedit.c
@@ -40,7 +40,7 @@ static void explain(void)
 		"\t<RAW>:= <OFFSETC>[ATC]<CMD>\n \t\tOFFSETC:= offset <offval> <u8|u16|u32>\n"
 		"\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 is a shift value\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>| retain\n"
 		"\t<LAYERED>:= ip <ipdata> | ip6 <ip6data>\n"
 		" \t\t| udp <udpdata> | tcp <tcpdata> | icmp <icmpdata>\n"
-- 
2.12.0

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

* [PATCH iproute2 net 2/8] tc/pedit: Extend pedit to specify offset relative to mac/transport headers
  2017-04-23 12:53 [PATCH iproute2 net 0/8] tc/act_pedit: Support offset relative to conventional header Amir Vadai
  2017-04-23 12:53 ` [PATCH iproute2 net 1/8] tc/pedit: Fix a typo in pedit usage message Amir Vadai
@ 2017-04-23 12:53 ` Amir Vadai
  2017-05-01 16:21   ` Stephen Hemminger
  2017-04-23 12:53 ` [PATCH iproute2 net 3/8] tc/pedit: Introduce 'add' operation Amir Vadai
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 15+ messages in thread
From: Amir Vadai @ 2017-04-23 12:53 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Or Gerlitz, Jamal Hadi Salim, Amir Vadai

Utilize the extended pedit netlink to set an offset relative to a
specific header type. Old netlink only enabled the user to set
approximated  offset relative to the IPv4 header.

To use this extended functionality need to use the 'ex' keyword after
'pedit' and before any 'munge'.
e.g:
$ tc filter add dev ens9 protocol ip parent ffff: \
    flower \
      ip_proto udp \
      dst_port 80 \
    action pedit ex munge \
      ip dst set 1.1.1.1 \
      pipe \
    action mirred egress redirect dev veth0

Signed-off-by: Amir Vadai <amir@vadai.me>
---
 man/man8/tc-pedit.8 |  41 +++++++---
 tc/m_pedit.c        | 213 +++++++++++++++++++++++++++++++++++++++++++++-------
 tc/m_pedit.h        |  43 ++++++++---
 tc/p_icmp.c         |   3 +-
 tc/p_ip.c           |  15 +++-
 tc/p_tcp.c          |   3 +-
 tc/p_udp.c          |   3 +-
 7 files changed, 270 insertions(+), 51 deletions(-)

diff --git a/man/man8/tc-pedit.8 b/man/man8/tc-pedit.8
index c34520c046a6..761d5c8ee2d5 100644
--- a/man/man8/tc-pedit.8
+++ b/man/man8/tc-pedit.8
@@ -5,8 +5,8 @@ pedit - generic packet editor action
 .SH SYNOPSIS
 .in +8
 .ti -8
-.BR tc " ... " "action pedit munge " {
-.IR RAW_OP " | " LAYERED_OP " } [ " CONTROL " ]"
+.BR tc " ... " "action pedit [ex] munge " {
+.IR RAW_OP " | " LAYERED_OP " | " EXTENDED_LAYERED_OP " } [ " CONTROL " ]"
 
 .ti -8
 .IR RAW_OP " := "
@@ -22,20 +22,22 @@ pedit - generic packet editor action
 .IR LAYERED_OP " := { "
 .BI ip " IPHDR_FIELD"
 |
-.BI ip6 " IP6HDR_FIELD"
-|
-.BI udp " UDPHDR_FIELD"
-|
-.BI tcp " TCPHDR_FIELD"
-|
-.BI icmp " ICMPHDR_FIELD"
+.BI ip " BEYOND_IPHDR_FIELD"
+.RI } " CMD_SPEC"
+
+.ti -8
+.IR EXTENDED_LAYERED_OP " := { "
+.BI ip " IPHDR_FIELD"
 .RI } " CMD_SPEC"
 
 .ti -8
 .IR IPHDR_FIELD " := { "
 .BR src " | " dst " | " tos " | " dsfield " | " ihl " | " protocol " |"
-.BR precedence " | " nofrag " | " firstfrag " | " ce " | " df " |"
-.BR mf " | " dport " | " sport " | " icmp_type " | " icmp_code " }"
+.BR precedence " | " nofrag " | " firstfrag " | " ce " | " df " }"
+
+.ti -8
+.IR BEYOND_IPHDR_FIELD " := { "
+.BR dport " | " sport " | " icmp_type " | " icmp_code " }"
 
 .ti -8
 .IR CMD_SPEC " := {"
@@ -58,6 +60,11 @@ chosen automatically based on the header field size. Currently this is supported
 only for IPv4 headers.
 .SH OPTIONS
 .TP
+.B ex
+Use extended pedit.
+.I EXTENDED_LAYERED_OP
+is allowed only in this mode.
+.TP
 .BI offset " OFFSET " "\fR{ \fBu32 \fR| \fBu16 \fR| \fBu8 \fR}"
 Specify the offset at which to change data.
 .I OFFSET
@@ -123,6 +130,15 @@ Change IP header flags. Note that the value to pass to the
 .B set
 command is not just a bit value, but the full byte including the flags field.
 Though only the relevant bits of that value are respected, the rest ignored.
+.RE
+.TP
+.BI ip " BEYOND_IPHDR_FIELD"
+Supported only for non-extended layered op. It is passed to the kernel as
+offsets relative to the beginning of the IP header and assumes the IP header is
+of minimum size (20 bytes). The supported keywords for
+.I BEYOND_IPHDR_FIELD
+are:
+.RS
 .TP
 .B dport
 .TQ
@@ -222,6 +238,9 @@ tc filter add dev eth0 parent 1: u32 \\
 tc filter add dev eth0 parent ffff: u32 \\
 	match ip sport 22 0xffff \\
 	action pedit pedit munge ip sport set 23
+tc filter add dev eth0 parent ffff: u32 \\
+	match ip sport 22 0xffff \\
+	action pedit ex munge ip dst set 192.168.1.199
 .EE
 .RE
 .SH SEE ALSO
diff --git a/tc/m_pedit.c b/tc/m_pedit.c
index 939a6a1455a5..a26fd3e5bc5e 100644
--- a/tc/m_pedit.c
+++ b/tc/m_pedit.c
@@ -34,7 +34,7 @@ static int pedit_debug;
 
 static void explain(void)
 {
-	fprintf(stderr, "Usage: ... pedit munge <MUNGE> [CONTROL]\n");
+	fprintf(stderr, "Usage: ... pedit munge [ex] <MUNGE> [CONTROL]\n");
 	fprintf(stderr,
 		"Where: MUNGE := <RAW>|<LAYERED>\n"
 		"\t<RAW>:= <OFFSETC>[ATC]<CMD>\n \t\tOFFSETC:= offset <offval> <u8|u16|u32>\n"
@@ -45,6 +45,7 @@ static void explain(void)
 		"\t<LAYERED>:= ip <ipdata> | ip6 <ip6data>\n"
 		" \t\t| udp <udpdata> | tcp <tcpdata> | icmp <icmpdata>\n"
 		"\tCONTROL:= reclassify | pipe | drop | continue | pass\n"
+		"\tNOTE: if 'ex' is set, extended functionality will be supported (kernel >= 4.11)\n"
 		"For Example usage look at the examples directory\n");
 
 }
@@ -56,8 +57,8 @@ static void usage(void)
 }
 
 static int pedit_parse_nopopt(int *argc_p, char ***argv_p,
-			      struct tc_pedit_sel *sel,
-			      struct tc_pedit_key *tkey)
+			      struct m_pedit_sel *sel,
+			      struct m_pedit_key *tkey)
 {
 	int argc = *argc_p;
 	char **argv = *argv_p;
@@ -116,8 +117,10 @@ noexist:
 	return p;
 }
 
-int pack_key(struct tc_pedit_sel *sel, struct tc_pedit_key *tkey)
+int pack_key(struct m_pedit_sel *_sel, struct m_pedit_key *tkey)
 {
+	struct tc_pedit_sel *sel = &_sel->sel;
+	struct m_pedit_key_ex *keys_ex = _sel->keys_ex;
 	int hwm = sel->nkeys;
 
 	if (hwm >= MAX_OFFS)
@@ -134,12 +137,24 @@ int pack_key(struct tc_pedit_sel *sel, struct tc_pedit_key *tkey)
 	sel->keys[hwm].at = tkey->at;
 	sel->keys[hwm].offmask = tkey->offmask;
 	sel->keys[hwm].shift = tkey->shift;
+
+	if (_sel->extended) {
+		keys_ex[hwm].htype = tkey->htype;
+		keys_ex[hwm].cmd = tkey->cmd;
+	} else {
+		if (tkey->htype != TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK ||
+		    tkey->cmd != TCA_PEDIT_KEY_EX_CMD_SET) {
+			fprintf(stderr, "Munge parameters not supported. Use 'munge ex'.\n");
+			return -1;
+		}
+	}
+
 	sel->nkeys++;
 	return 0;
 }
 
-int pack_key32(__u32 retain, struct tc_pedit_sel *sel,
-	       struct tc_pedit_key *tkey)
+int pack_key32(__u32 retain, struct m_pedit_sel *sel,
+	       struct m_pedit_key *tkey)
 {
 	if (tkey->off > (tkey->off & ~3)) {
 		fprintf(stderr,
@@ -152,8 +167,8 @@ int pack_key32(__u32 retain, struct tc_pedit_sel *sel,
 	return pack_key(sel, tkey);
 }
 
-int pack_key16(__u32 retain, struct tc_pedit_sel *sel,
-	       struct tc_pedit_key *tkey)
+int pack_key16(__u32 retain, struct m_pedit_sel *sel,
+	       struct m_pedit_key *tkey)
 {
 	int ind, stride;
 	__u32 m[4] = { 0x0000FFFF, 0xFF0000FF, 0xFFFF0000 };
@@ -183,7 +198,7 @@ int pack_key16(__u32 retain, struct tc_pedit_sel *sel,
 
 }
 
-int pack_key8(__u32 retain, struct tc_pedit_sel *sel, struct tc_pedit_key *tkey)
+int pack_key8(__u32 retain, struct m_pedit_sel *sel, struct m_pedit_key *tkey)
 {
 	int ind, stride;
 	__u32 m[4] = { 0x00FFFFFF, 0xFF00FFFF, 0xFFFF00FF, 0xFFFFFF00 };
@@ -239,7 +254,7 @@ 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 tc_pedit_sel *sel, struct tc_pedit_key *tkey)
+	      struct m_pedit_sel *sel, struct m_pedit_key *tkey)
 {
 	__u32 mask = 0, val = 0;
 	__u32 o = 0xFF;
@@ -313,8 +328,8 @@ done:
 
 }
 
-int parse_offset(int *argc_p, char ***argv_p, struct tc_pedit_sel *sel,
-		 struct tc_pedit_key *tkey)
+int parse_offset(int *argc_p, char ***argv_p, struct m_pedit_sel *sel,
+		 struct m_pedit_key *tkey)
 {
 	int off;
 	__u32 len, retain;
@@ -389,9 +404,9 @@ done:
 	return res;
 }
 
-static int parse_munge(int *argc_p, char ***argv_p, struct tc_pedit_sel *sel)
+static int parse_munge(int *argc_p, char ***argv_p, struct m_pedit_sel *sel)
 {
-	struct tc_pedit_key tkey = {};
+	struct m_pedit_key tkey = {};
 	int argc = *argc_p;
 	char **argv = *argv_p;
 	int res = -1;
@@ -433,13 +448,69 @@ done:
 	return res;
 }
 
+static int pedit_keys_ex_getattr(struct rtattr *attr,
+				 struct m_pedit_key_ex *keys_ex, int n)
+{
+	struct rtattr *i;
+	int rem = RTA_PAYLOAD(attr);
+	struct rtattr *tb[TCA_PEDIT_KEY_EX_MAX + 1];
+	struct m_pedit_key_ex *k = keys_ex;
+
+	for (i = RTA_DATA(attr); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
+		if (!n)
+			return -1;
+
+		if (i->rta_type != TCA_PEDIT_KEY_EX)
+			return -1;
+
+		parse_rtattr_nested(tb, TCA_PEDIT_KEY_EX_MAX, i);
+
+		k->htype = rta_getattr_u16(tb[TCA_PEDIT_KEY_EX_HTYPE]);
+		k->cmd = rta_getattr_u16(tb[TCA_PEDIT_KEY_EX_CMD]);
+
+		k++;
+		n--;
+	}
+
+	return !!n;
+}
+
+static int pedit_keys_ex_addattr(struct m_pedit_sel *sel, struct nlmsghdr *n)
+{
+	struct m_pedit_key_ex *k = sel->keys_ex;
+	struct rtattr *keys_start;
+	int i;
+
+	if (!sel->extended)
+		return 0;
+
+	keys_start = addattr_nest(n, MAX_MSG, TCA_PEDIT_KEYS_EX | NLA_F_NESTED);
+
+	for (i = 0; i < sel->sel.nkeys; i++) {
+		struct rtattr *key_start;
+
+		key_start = addattr_nest(n, MAX_MSG,
+					 TCA_PEDIT_KEY_EX | NLA_F_NESTED);
+
+		if (addattr16(n, MAX_MSG, TCA_PEDIT_KEY_EX_HTYPE, k->htype) ||
+		    addattr16(n, MAX_MSG, TCA_PEDIT_KEY_EX_CMD, k->cmd)) {
+			return -1;
+		}
+
+		addattr_nest_end(n, key_start);
+
+		k++;
+	}
+
+	addattr_nest_end(n, keys_start);
+
+	return 0;
+}
+
 int parse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
 		struct nlmsghdr *n)
 {
-	struct {
-		struct tc_pedit_sel sel;
-		struct tc_pedit_key keys[MAX_OFFS];
-	} sel = {};
+	struct m_pedit_sel sel = {};
 
 	int argc = *argc_p;
 	char **argv = *argv_p;
@@ -452,6 +523,17 @@ int parse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
 		if (matches(*argv, "pedit") == 0) {
 			NEXT_ARG();
 			ok++;
+
+			if (matches(*argv, "ex") == 0) {
+				if (ok > 1) {
+					fprintf(stderr, "'ex' must be before first 'munge'\n");
+					explain();
+					return -1;
+				}
+				sel.extended = true;
+				NEXT_ARG();
+			}
+
 			continue;
 		} else if (matches(*argv, "help") == 0) {
 			usage();
@@ -463,7 +545,8 @@ int parse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
 				return -1;
 			}
 			NEXT_ARG();
-			if (parse_munge(&argc, &argv, &sel.sel)) {
+
+			if (parse_munge(&argc, &argv, &sel)) {
 				fprintf(stderr, "Bad pedit construct (%s)\n",
 					*argv);
 				explain();
@@ -499,9 +582,18 @@ int parse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
 
 	tail = NLMSG_TAIL(n);
 	addattr_l(n, MAX_MSG, tca_id, NULL, 0);
-	addattr_l(n, MAX_MSG, TCA_PEDIT_PARMS, &sel,
-		  sizeof(sel.sel) +
-		  sel.sel.nkeys * sizeof(struct tc_pedit_key));
+	if (!sel.extended) {
+		addattr_l(n, MAX_MSG, TCA_PEDIT_PARMS, &sel,
+			  sizeof(sel.sel) +
+			  sel.sel.nkeys * sizeof(struct tc_pedit_key));
+	} else {
+		addattr_l(n, MAX_MSG, TCA_PEDIT_PARMS_EX, &sel,
+			  sizeof(sel.sel) +
+			  sel.sel.nkeys * sizeof(struct tc_pedit_key));
+
+		pedit_keys_ex_addattr(&sel, n);
+	}
+
 	tail->rta_len = (void *)NLMSG_TAIL(n) - (void *)tail;
 
 	*argc_p = argc;
@@ -509,21 +601,74 @@ int parse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
 	return 0;
 }
 
+const char *pedit_htype_str[] = {
+	[TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK] = "",
+	[TCA_PEDIT_KEY_EX_HDR_TYPE_ETH] = "eth",
+	[TCA_PEDIT_KEY_EX_HDR_TYPE_IP4] = "ipv4",
+	[TCA_PEDIT_KEY_EX_HDR_TYPE_IP6] = "ipv6",
+	[TCA_PEDIT_KEY_EX_HDR_TYPE_TCP] = "tcp",
+	[TCA_PEDIT_KEY_EX_HDR_TYPE_UDP] = "udp",
+};
+
+static void print_pedit_location(FILE *f,
+				 enum pedit_header_type htype, __u32 off)
+{
+	if (htype == TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK) {
+		fprintf(f, "%d", (unsigned int)off);
+		return;
+	}
+
+	if (htype < ARRAY_SIZE(pedit_htype_str))
+		fprintf(f, "%s", pedit_htype_str[htype]);
+	else
+		fprintf(f, "unknown(%d)", htype);
+
+	fprintf(f, "%c%d", (int)off  >= 0 ? '+' : '-', abs((int)off));
+}
+
 int print_pedit(struct action_util *au, FILE *f, struct rtattr *arg)
 {
 	struct tc_pedit_sel *sel;
 	struct rtattr *tb[TCA_PEDIT_MAX + 1];
+	struct m_pedit_key_ex *keys_ex = NULL;
 
 	if (arg == NULL)
 		return -1;
 
 	parse_rtattr_nested(tb, TCA_PEDIT_MAX, arg);
 
-	if (tb[TCA_PEDIT_PARMS] == NULL) {
+	if (!tb[TCA_PEDIT_PARMS] && !tb[TCA_PEDIT_PARMS_EX]) {
 		fprintf(f, "[NULL pedit parameters]");
 		return -1;
 	}
-	sel = RTA_DATA(tb[TCA_PEDIT_PARMS]);
+
+	if (tb[TCA_PEDIT_PARMS]) {
+		sel = RTA_DATA(tb[TCA_PEDIT_PARMS]);
+	} else {
+		int err;
+
+		sel = RTA_DATA(tb[TCA_PEDIT_PARMS_EX]);
+
+		if (!tb[TCA_PEDIT_KEYS_EX]) {
+			fprintf(f, "Netlink error\n");
+			return -1;
+		}
+
+		keys_ex = calloc(sel->nkeys, sizeof(*keys_ex));
+		if (!keys_ex) {
+			fprintf(f, "Out of memory\n");
+			return -1;
+		}
+
+		err = pedit_keys_ex_getattr(tb[TCA_PEDIT_KEYS_EX], keys_ex,
+					    sel->nkeys);
+		if (err) {
+			fprintf(f, "Netlink error\n");
+
+			free(keys_ex);
+			return -1;
+		}
+	}
 
 	fprintf(f, " pedit action %s keys %d\n ",
 		action_n2a(sel->action), sel->nkeys);
@@ -540,11 +685,25 @@ int print_pedit(struct action_util *au, FILE *f, struct rtattr *arg)
 	if (sel->nkeys) {
 		int i;
 		struct tc_pedit_key *key = sel->keys;
+		struct m_pedit_key_ex *key_ex = keys_ex;
 
 		for (i = 0; i < sel->nkeys; i++, key++) {
+			enum pedit_header_type htype =
+				TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK;
+
+			if (keys_ex) {
+				htype = key_ex->htype;
+
+				key_ex++;
+			}
+
 			fprintf(f, "\n\t key #%d", i);
-			fprintf(f, "  at %d: val %08x mask %08x",
-				(unsigned int)key->off,
+
+			fprintf(f, "  at ");
+
+			print_pedit_location(f, htype, key->off);
+
+			fprintf(f, ": val %08x mask %08x",
 				(unsigned int)ntohl(key->val),
 				(unsigned int)ntohl(key->mask));
 		}
@@ -554,6 +713,8 @@ int print_pedit(struct action_util *au, FILE *f, struct rtattr *arg)
 	}
 
 	fprintf(f, "\n ");
+
+	free(keys_ex);
 	return 0;
 }
 
diff --git a/tc/m_pedit.h b/tc/m_pedit.h
index 1698c954e999..e2897b0c9808 100644
--- a/tc/m_pedit.h
+++ b/tc/m_pedit.h
@@ -39,22 +39,47 @@
 
 #define PEDITKINDSIZ 16
 
+struct m_pedit_key {
+	__u32           mask;  /* AND */
+	__u32           val;   /*XOR */
+	__u32           off;  /*offset */
+	__u32           at;
+	__u32           offmask;
+	__u32           shift;
+
+	enum pedit_header_type htype;
+	enum pedit_cmd cmd;
+};
+
+struct m_pedit_key_ex {
+	enum pedit_header_type htype;
+	enum pedit_cmd cmd;
+};
+
+struct m_pedit_sel {
+	struct tc_pedit_sel sel;
+	struct tc_pedit_key keys[MAX_OFFS];
+	struct m_pedit_key_ex keys_ex[MAX_OFFS];
+	bool extended;
+};
+
 struct m_pedit_util
 {
 	struct m_pedit_util *next;
 	char    id[PEDITKINDSIZ];
-	int     (*parse_peopt)(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey);
+	int     (*parse_peopt)(int *argc_p, char ***argv_p,
+			       struct m_pedit_sel *sel, struct m_pedit_key *tkey);
 };
 
-
-extern int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type,__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey);
-extern int pack_key(struct tc_pedit_sel *sel,struct tc_pedit_key *tkey);
-extern int pack_key32(__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey);
-extern int pack_key16(__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey);
-extern int pack_key8(__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey);
+extern int pack_key(struct m_pedit_sel *sel, struct m_pedit_key *tkey);
+extern int pack_key32(__u32 retain, struct m_pedit_sel *sel, struct m_pedit_key *tkey);
+extern int pack_key16(__u32 retain, struct m_pedit_sel *sel, struct m_pedit_key *tkey);
+extern int pack_key8(__u32 retain, struct m_pedit_sel *sel, struct m_pedit_key *tkey);
 extern int parse_val(int *argc_p, char ***argv_p, __u32 * val, int type);
-extern int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type,__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey);
-extern int parse_offset(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey);
+extern 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);
+extern int parse_offset(int *argc_p, char ***argv_p,
+			struct m_pedit_sel *sel, struct m_pedit_key *tkey);
 int parse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n);
 extern int print_pedit(struct action_util *au,FILE * f, struct rtattr *arg);
 extern int pedit_print_xstats(struct action_util *au, FILE *f, struct rtattr *xstats);
diff --git a/tc/p_icmp.c b/tc/p_icmp.c
index c2a6fcd69817..1c3a5d90006d 100644
--- a/tc/p_icmp.c
+++ b/tc/p_icmp.c
@@ -25,7 +25,8 @@
 
 
 static int
-parse_icmp(int *argc_p, char ***argv_p, struct tc_pedit_sel *sel, struct tc_pedit_key *tkey)
+parse_icmp(int *argc_p, char ***argv_p,
+	   struct m_pedit_sel *sel, struct m_pedit_key *tkey)
 {
 	int res = -1;
 #if 0
diff --git a/tc/p_ip.c b/tc/p_ip.c
index 535151e5d766..e56eb39317ba 100644
--- a/tc/p_ip.c
+++ b/tc/p_ip.c
@@ -25,7 +25,7 @@
 
 static int
 parse_ip(int *argc_p, char ***argv_p,
-	 struct tc_pedit_sel *sel, struct tc_pedit_key *tkey)
+	 struct m_pedit_sel *sel, struct m_pedit_key *tkey)
 {
 	int res = -1;
 	int argc = *argc_p;
@@ -34,6 +34,10 @@ parse_ip(int *argc_p, char ***argv_p,
 	if (argc < 2)
 		return -1;
 
+	tkey->htype = sel->extended ?
+		TCA_PEDIT_KEY_EX_HDR_TYPE_IP4 :
+		TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK;
+
 	if (strcmp(*argv, "src") == 0) {
 		NEXT_ARG();
 		tkey->off = 12;
@@ -107,6 +111,13 @@ parse_ip(int *argc_p, char ***argv_p,
 		res = parse_cmd(&argc, &argv, 1, TU32, 0x20, sel, tkey);
 		goto done;
 	}
+
+	if (sel->extended)
+		return -1; /* fields located outside IP header should be
+			    * addressed using the relevant header type in
+			    * extended pedit kABI
+			    */
+
 	if (strcmp(*argv, "dport") == 0) {
 		NEXT_ARG();
 		tkey->off = 22;
@@ -141,7 +152,7 @@ done:
 
 static int
 parse_ip6(int *argc_p, char ***argv_p,
-	  struct tc_pedit_sel *sel, struct tc_pedit_key *tkey)
+	  struct m_pedit_sel *sel, struct m_pedit_key *tkey)
 {
 	int res = -1;
 	return res;
diff --git a/tc/p_tcp.c b/tc/p_tcp.c
index 79f16c58cad6..53ee9842160b 100644
--- a/tc/p_tcp.c
+++ b/tc/p_tcp.c
@@ -24,7 +24,8 @@
 #include "m_pedit.h"
 
 static int
-parse_tcp(int *argc_p, char ***argv_p, struct tc_pedit_sel *sel, struct tc_pedit_key *tkey)
+parse_tcp(int *argc_p, char ***argv_p,
+	  struct m_pedit_sel *sel, struct m_pedit_key *tkey)
 {
 	int res = -1;
 	return res;
diff --git a/tc/p_udp.c b/tc/p_udp.c
index c056414e6eb3..3a86ba382391 100644
--- a/tc/p_udp.c
+++ b/tc/p_udp.c
@@ -24,7 +24,8 @@
 #include "m_pedit.h"
 
 static int
-parse_udp(int *argc_p, char ***argv_p, struct tc_pedit_sel *sel, struct tc_pedit_key *tkey)
+parse_udp(int *argc_p, char ***argv_p,
+	  struct m_pedit_sel *sel, struct m_pedit_key *tkey)
 {
 	int res = -1;
 	return res;
-- 
2.12.0

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

* [PATCH iproute2 net 3/8] tc/pedit: Introduce 'add' operation
  2017-04-23 12:53 [PATCH iproute2 net 0/8] tc/act_pedit: Support offset relative to conventional header Amir Vadai
  2017-04-23 12:53 ` [PATCH iproute2 net 1/8] tc/pedit: Fix a typo in pedit usage message Amir Vadai
  2017-04-23 12:53 ` [PATCH iproute2 net 2/8] tc/pedit: Extend pedit to specify offset relative to mac/transport headers Amir Vadai
@ 2017-04-23 12:53 ` Amir Vadai
  2017-04-23 17:44   ` Jamal Hadi Salim
  2017-04-23 12:53 ` [PATCH iproute2 net 4/8] tc/pedit: p_ip: introduce editing ttl header Amir Vadai
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 15+ messages in thread
From: Amir Vadai @ 2017-04-23 12:53 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Or Gerlitz, Jamal Hadi Salim, Amir Vadai

This command could be useful to increase/decrease fields value.

Signed-off-by: Amir Vadai <amir@vadai.me>
---
 man/man8/tc-pedit.8 | 13 ++++++++++++-
 tc/m_pedit.c        | 18 +++++++++++++++---
 2 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/man/man8/tc-pedit.8 b/man/man8/tc-pedit.8
index 761d5c8ee2d5..6bba741956f1 100644
--- a/man/man8/tc-pedit.8
+++ b/man/man8/tc-pedit.8
@@ -43,6 +43,8 @@ pedit - generic packet editor action
 .IR CMD_SPEC " := {"
 .BR clear " | " invert " | " set
 .IR VAL " | "
+.BR add
+.IR VAL " | "
 .BR preserve " } [ " retain
 .IR RVAL " ]"
 
@@ -63,7 +65,9 @@ only for IPv4 headers.
 .B ex
 Use extended pedit.
 .I EXTENDED_LAYERED_OP
-is allowed only in this mode.
+and the add
+.I CMD_SPEC
+are allowed only in this mode.
 .TP
 .BI offset " OFFSET " "\fR{ \fBu32 \fR| \fBu16 \fR| \fBu8 \fR}"
 Specify the offset at which to change data.
@@ -173,6 +177,13 @@ keywords in
 or the size of the addressed header field in
 .IR LAYERED_OP .
 .TP
+.BI add " VAL"
+Add the addressed data by a specific value. The size of
+.I VAL
+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
 .B preserve
 Keep the addressed data as is.
 .TP
diff --git a/tc/m_pedit.c b/tc/m_pedit.c
index a26fd3e5bc5e..7af074a5a97c 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>| retain\n"
+		"\t\tCMD:= clear | invert | set <setval>| add <addval> | 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"
@@ -276,7 +276,16 @@ int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type, __u32 retain,
 
 	if (matches(*argv, "invert") == 0) {
 		val = mask = o;
-	} else if (matches(*argv, "set") == 0) {
+	} else if (matches(*argv, "set") == 0 ||
+		   matches(*argv, "add") == 0) {
+		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;
+		}
+
 		NEXT_ARG();
 		if (parse_val(&argc, &argv, &val, type))
 			return -1;
@@ -690,9 +699,11 @@ int print_pedit(struct action_util *au, FILE *f, struct rtattr *arg)
 		for (i = 0; i < sel->nkeys; i++, key++) {
 			enum pedit_header_type htype =
 				TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK;
+			enum pedit_cmd cmd = TCA_PEDIT_KEY_EX_CMD_SET;
 
 			if (keys_ex) {
 				htype = key_ex->htype;
+				cmd = key_ex->cmd;
 
 				key_ex++;
 			}
@@ -703,7 +714,8 @@ int print_pedit(struct action_util *au, FILE *f, struct rtattr *arg)
 
 			print_pedit_location(f, htype, key->off);
 
-			fprintf(f, ": val %08x mask %08x",
+			fprintf(f, ": %s %08x mask %08x",
+				cmd ? "add" : "val",
 				(unsigned int)ntohl(key->val),
 				(unsigned int)ntohl(key->mask));
 		}
-- 
2.12.0

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

* [PATCH iproute2 net 4/8] tc/pedit: p_ip: introduce editing ttl header
  2017-04-23 12:53 [PATCH iproute2 net 0/8] tc/act_pedit: Support offset relative to conventional header Amir Vadai
                   ` (2 preceding siblings ...)
  2017-04-23 12:53 ` [PATCH iproute2 net 3/8] tc/pedit: Introduce 'add' operation Amir Vadai
@ 2017-04-23 12:53 ` Amir Vadai
  2017-04-23 12:53 ` [PATCH iproute2 net 5/8] tc/pedit: Support fields bigger than 32 bits Amir Vadai
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Amir Vadai @ 2017-04-23 12:53 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Or Gerlitz, Jamal Hadi Salim, Amir Vadai

Enable user to edit IP header ttl field.

For example, to forward any TCP packet and decrease its TTL by one:
$ tc filter add dev enp0s9 protocol ip parent ffff: \
    flower \
      ip_proto tcp \
    action pedit ex munge \
      ip ttl add 0xff pipe \
    action mirred egress \
      redirect dev veth0

Signed-off-by: Amir Vadai <amir@vadai.me>
---
 man/man8/tc-pedit.8 | 17 +++++++++++++++++
 tc/p_ip.c           |  6 ++++++
 2 files changed, 23 insertions(+)

diff --git a/man/man8/tc-pedit.8 b/man/man8/tc-pedit.8
index 6bba741956f1..c98d95cb0021 100644
--- a/man/man8/tc-pedit.8
+++ b/man/man8/tc-pedit.8
@@ -28,6 +28,8 @@ pedit - generic packet editor action
 .ti -8
 .IR EXTENDED_LAYERED_OP " := { "
 .BI ip " IPHDR_FIELD"
+|
+.BI ip " EX_IPHDR_FIELD"
 .RI } " CMD_SPEC"
 
 .ti -8
@@ -40,6 +42,10 @@ pedit - generic packet editor action
 .BR dport " | " sport " | " icmp_type " | " icmp_code " }"
 
 .ti -8
+.IR EX_IPHDR_FIELD " := { "
+.BR ttl " }"
+
+.ti -8
 .IR CMD_SPEC " := {"
 .BR clear " | " invert " | " set
 .IR VAL " | "
@@ -161,6 +167,17 @@ If it is not or the latter is bigger than the minimum of 20 bytes, this will do
 unexpected things. These fields are eight-bit values.
 .RE
 .TP
+.BI ip " EX_IPHDR_FIELD"
+Supported only when
+.I ex
+is used. The supported keywords for
+.I EX_IPHDR_FIELD
+are:
+.RS
+.TP
+.B ttl
+.RE
+.TP
 .B clear
 Clear the addressed data (i.e., set it to zero).
 .TP
diff --git a/tc/p_ip.c b/tc/p_ip.c
index e56eb39317ba..22fe6505e427 100644
--- a/tc/p_ip.c
+++ b/tc/p_ip.c
@@ -66,6 +66,12 @@ parse_ip(int *argc_p, char ***argv_p,
 		res = parse_cmd(&argc, &argv, 1, TU32, 0x0f, sel, tkey);
 		goto done;
 	}
+	if (strcmp(*argv, "ttl") == 0) {
+		NEXT_ARG();
+		tkey->off = 8;
+		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
+		goto done;
+	}
 	if (strcmp(*argv, "protocol") == 0) {
 		NEXT_ARG();
 		tkey->off = 9;
-- 
2.12.0

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

* [PATCH iproute2 net 5/8] tc/pedit: Support fields bigger than 32 bits
  2017-04-23 12:53 [PATCH iproute2 net 0/8] tc/act_pedit: Support offset relative to conventional header Amir Vadai
                   ` (3 preceding siblings ...)
  2017-04-23 12:53 ` [PATCH iproute2 net 4/8] tc/pedit: p_ip: introduce editing ttl header Amir Vadai
@ 2017-04-23 12:53 ` Amir Vadai
  2017-04-23 12:53 ` [PATCH iproute2 net 6/8] tc/pedit: p_eth: ETH header editor Amir Vadai
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Amir Vadai @ 2017-04-23 12:53 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Or Gerlitz, Jamal Hadi Salim, Amir Vadai

Make parse_val() accept fields up to 128 bits long, this should be
enough for current use cases and involves a minimal change to code.

Signed-off-by: Amir Vadai <amir@vadai.me>
---
 tc/m_pedit.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/tc/m_pedit.c b/tc/m_pedit.c
index 7af074a5a97c..d982c91a2585 100644
--- a/tc/m_pedit.c
+++ b/tc/m_pedit.c
@@ -256,7 +256,10 @@ 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)
 {
-	__u32 mask = 0, val = 0;
+	__u32 mask[4] = { 0 };
+	__u32 val[4] = { 0 };
+	__u32 *m = &mask[0];
+	__u32 *v = &val[0];
 	__u32 o = 0xFF;
 	int res = -1;
 	int argc = *argc_p;
@@ -275,7 +278,7 @@ int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type, __u32 retain,
 		o = 0xFFFFFFFF;
 
 	if (matches(*argv, "invert") == 0) {
-		val = mask = o;
+		*v = *m = o;
 	} else if (matches(*argv, "set") == 0 ||
 		   matches(*argv, "add") == 0) {
 		if (matches(*argv, "add") == 0)
@@ -287,7 +290,7 @@ int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type, __u32 retain,
 		}
 
 		NEXT_ARG();
-		if (parse_val(&argc, &argv, &val, type))
+		if (parse_val(&argc, &argv, val, type))
 			return -1;
 	} else if (matches(*argv, "preserve") == 0) {
 		retain = 0;
@@ -307,8 +310,8 @@ int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type, __u32 retain,
 		argv++;
 	}
 
-	tkey->val = val;
-	tkey->mask = mask;
+	tkey->val = *v;
+	tkey->mask = *m;
 
 	if (type == TIPV4)
 		tkey->val = ntohl(tkey->val);
-- 
2.12.0

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

* [PATCH iproute2 net 6/8] tc/pedit: p_eth: ETH header editor
  2017-04-23 12:53 [PATCH iproute2 net 0/8] tc/act_pedit: Support offset relative to conventional header Amir Vadai
                   ` (4 preceding siblings ...)
  2017-04-23 12:53 ` [PATCH iproute2 net 5/8] tc/pedit: Support fields bigger than 32 bits Amir Vadai
@ 2017-04-23 12:53 ` Amir Vadai
  2017-04-23 12:53 ` [PATCH iproute2 net 7/8] tc/pedit: p_tcp: introduce pedit tcp support Amir Vadai
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Amir Vadai @ 2017-04-23 12:53 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Or Gerlitz, Jamal Hadi Salim, Amir Vadai

For example, forward tcp traffic to veth0 and set
destination mac address to 11:22:33:44:55:66 :
$ tc filter add dev enp0s9 protocol ip parent ffff: \
    flower \
      ip_proto tcp \
    action pedit ex munge \
      eth dst set 11:22:33:44:55:66 \
    action mirred egress \
      redirect dev veth0

Signed-off-by: Amir Vadai <amir@vadai.me>
---
 man/man8/tc-pedit.8 | 24 ++++++++++++++++++
 tc/Makefile         |  1 +
 tc/m_pedit.c        | 46 ++++++++++++++++++++++++++++++++++
 tc/m_pedit.h        |  1 +
 tc/p_eth.c          | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 144 insertions(+)
 create mode 100644 tc/p_eth.c

diff --git a/man/man8/tc-pedit.8 b/man/man8/tc-pedit.8
index c98d95cb0021..8febdfe23f6e 100644
--- a/man/man8/tc-pedit.8
+++ b/man/man8/tc-pedit.8
@@ -27,12 +27,18 @@ pedit - generic packet editor action
 
 .ti -8
 .IR EXTENDED_LAYERED_OP " := { "
+.BI eth " ETHHDR_FIELD"
+|
 .BI ip " IPHDR_FIELD"
 |
 .BI ip " EX_IPHDR_FIELD"
 .RI } " CMD_SPEC"
 
 .ti -8
+.IR ETHHDR_FIELD " := { "
+.BR src " | " dst " | " type " }"
+
+.ti -8
 .IR IPHDR_FIELD " := { "
 .BR src " | " dst " | " tos " | " dsfield " | " ihl " | " protocol " |"
 .BR precedence " | " nofrag " | " firstfrag " | " ce " | " df " }"
@@ -103,6 +109,21 @@ and right-shifted by
 before adding it to
 .IR OFFSET .
 .TP
+.BI eth " ETHHDR_FIELD"
+Change an ETH header field. The supported keywords for
+.I ETHHDR_FIELD
+are:
+.RS
+.TP
+.B src
+.TQ
+.B dst
+Source or destination MAC address in the standard format: XX:XX:XX:XX:XX:XX
+.TP
+.B type
+Ether-type in numeric value
+.RE
+.TP
 .BI ip " IPHDR_FIELD"
 Change an IPv4 header field. The supported keywords for
 .I IPHDR_FIELD
@@ -269,6 +290,9 @@ tc filter add dev eth0 parent ffff: u32 \\
 tc filter add dev eth0 parent ffff: u32 \\
 	match ip sport 22 0xffff \\
 	action pedit ex munge ip dst set 192.168.1.199
+tc filter add dev eth0 parent ffff: u32 \\
+	match ip sport 22 0xffff \\
+	action pedit ex munge eth dst set 11:22:33:44:55:66
 .EE
 .RE
 .SH SEE ALSO
diff --git a/tc/Makefile b/tc/Makefile
index 3f7fc939e194..446a11391ad7 100644
--- a/tc/Makefile
+++ b/tc/Makefile
@@ -54,6 +54,7 @@ TCMODULES += m_tunnel_key.o
 TCMODULES += m_sample.o
 TCMODULES += p_ip.o
 TCMODULES += p_icmp.o
+TCMODULES += p_eth.o
 TCMODULES += p_tcp.o
 TCMODULES += p_udp.o
 TCMODULES += em_nbyte.o
diff --git a/tc/m_pedit.c b/tc/m_pedit.c
index d982c91a2585..0be42343ac88 100644
--- a/tc/m_pedit.c
+++ b/tc/m_pedit.c
@@ -28,6 +28,7 @@
 #include "utils.h"
 #include "tc_util.h"
 #include "m_pedit.h"
+#include "rt_names.h"
 
 static struct m_pedit_util *pedit_list;
 static int pedit_debug;
@@ -223,6 +224,38 @@ int pack_key8(__u32 retain, struct m_pedit_sel *sel, struct m_pedit_key *tkey)
 	return pack_key(sel, tkey);
 }
 
+static int pack_mac(struct m_pedit_sel *sel, struct m_pedit_key *tkey,
+		    __u8 *mac)
+{
+	int ret = 0;
+
+	if (!(tkey->off & 0x3)) {
+		tkey->mask = 0;
+		tkey->val = ntohl(*((__u32 *)mac));
+		ret |= pack_key32(~0, sel, tkey);
+
+		tkey->off += 4;
+		tkey->mask = 0;
+		tkey->val = ntohs(*((__u16 *)&mac[4]));
+		ret |= pack_key16(~0, sel, tkey);
+	} else if (!(tkey->off & 0x1)) {
+		tkey->mask = 0;
+		tkey->val = ntohs(*((__u16 *)mac));
+		ret |= pack_key16(~0, sel, tkey);
+
+		tkey->off += 4;
+		tkey->mask = 0;
+		tkey->val = ntohl(*((__u32 *)(mac + 2)));
+		ret |= pack_key32(~0, sel, tkey);
+	} else {
+		fprintf(stderr,
+			"pack_mac: mac offsets must begin in 32bit or 16bit boundaries\n");
+		return -1;
+	}
+
+	return ret;
+}
+
 int parse_val(int *argc_p, char ***argv_p, __u32 *val, int type)
 {
 	int argc = *argc_p;
@@ -250,6 +283,14 @@ int parse_val(int *argc_p, char ***argv_p, __u32 *val, int type)
 	if (type == TIPV6)
 		return -1; /* not implemented yet */
 
+	if (type == TMAC) {
+#define MAC_ALEN 6
+		int ret = ll_addr_a2n((char *)val, MAC_ALEN, *argv);
+
+		if (ret == MAC_ALEN)
+			return 0;
+	}
+
 	return -1;
 }
 
@@ -310,6 +351,11 @@ int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type, __u32 retain,
 		argv++;
 	}
 
+	if (type == TMAC) {
+		res = pack_mac(sel, tkey, (__u8 *)val);
+		goto done;
+	}
+
 	tkey->val = *v;
 	tkey->mask = *m;
 
diff --git a/tc/m_pedit.h b/tc/m_pedit.h
index e2897b0c9808..ecfb6add0df5 100644
--- a/tc/m_pedit.h
+++ b/tc/m_pedit.h
@@ -32,6 +32,7 @@
 #define TIPV6 2
 #define TINT 3
 #define TU32 4
+#define TMAC 5
 
 #define RU32 0xFFFFFFFF
 #define RU16 0xFFFF
diff --git a/tc/p_eth.c b/tc/p_eth.c
new file mode 100644
index 000000000000..ad3e28f80eb6
--- /dev/null
+++ b/tc/p_eth.c
@@ -0,0 +1,72 @@
+/*
+ * m_pedit_eth.c	packet editor: ETH header
+ *
+ *		This program is free software; you can distribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ *
+ * Authors:  Amir Vadai (amir@vadai.me)
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include "utils.h"
+#include "tc_util.h"
+#include "m_pedit.h"
+
+static int
+parse_eth(int *argc_p, char ***argv_p,
+	  struct m_pedit_sel *sel, struct m_pedit_key *tkey)
+{
+	int res = -1;
+	int argc = *argc_p;
+	char **argv = *argv_p;
+
+	if (argc < 2)
+		return -1;
+
+	tkey->htype = TCA_PEDIT_KEY_EX_HDR_TYPE_ETH;
+
+	if (strcmp(*argv, "type") == 0) {
+		NEXT_ARG();
+		tkey->off = 12;
+		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey);
+		goto done;
+	}
+
+	if (strcmp(*argv, "dst") == 0) {
+		NEXT_ARG();
+		tkey->off = 0;
+		res = parse_cmd(&argc, &argv, 6, TMAC, RU32, sel, tkey);
+		goto done;
+	}
+
+	if (strcmp(*argv, "src") == 0) {
+		NEXT_ARG();
+		tkey->off = 6;
+		res = parse_cmd(&argc, &argv, 6, TMAC, RU32, sel, tkey);
+		goto done;
+	}
+
+	return -1;
+
+done:
+	*argc_p = argc;
+	*argv_p = argv;
+	return res;
+}
+
+struct m_pedit_util p_pedit_eth = {
+	NULL,
+	"eth",
+	parse_eth,
+};
-- 
2.12.0

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

* [PATCH iproute2 net 7/8] tc/pedit: p_tcp: introduce pedit tcp support
  2017-04-23 12:53 [PATCH iproute2 net 0/8] tc/act_pedit: Support offset relative to conventional header Amir Vadai
                   ` (5 preceding siblings ...)
  2017-04-23 12:53 ` [PATCH iproute2 net 6/8] tc/pedit: p_eth: ETH header editor Amir Vadai
@ 2017-04-23 12:53 ` Amir Vadai
  2017-04-23 12:53 ` [PATCH iproute2 net 8/8] tc/pedit: p_udp: introduce pedit udp support Amir Vadai
  2017-05-01 16:26 ` [PATCH iproute2 net 0/8] tc/act_pedit: Support offset relative to conventional header Stephen Hemminger
  8 siblings, 0 replies; 15+ messages in thread
From: Amir Vadai @ 2017-04-23 12:53 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Or Gerlitz, Jamal Hadi Salim, Amir Vadai

For example, forward tcp traffic destined to port 80 to veth0 and set
tcp port to 8080:
$ tc filter add dev enp0s9 protocol ip parent ffff: \
    flower \
      ip_proto tcp \
      dst_port 80 \
    action pedit ex munge \
      tcp dport set 8080 \
    action mirred egress \
      redirect dev veth0

Signed-off-by: Amir Vadai <amir@vadai.me>
---
 man/man8/tc-pedit.8 | 23 +++++++++++++++++++++++
 tc/p_tcp.c          | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/man/man8/tc-pedit.8 b/man/man8/tc-pedit.8
index 8febdfe23f6e..ad1929592660 100644
--- a/man/man8/tc-pedit.8
+++ b/man/man8/tc-pedit.8
@@ -32,6 +32,8 @@ pedit - generic packet editor action
 .BI ip " IPHDR_FIELD"
 |
 .BI ip " EX_IPHDR_FIELD"
+|
+.BI tcp " TCPHDR_FIELD"
 .RI } " CMD_SPEC"
 
 .ti -8
@@ -52,6 +54,10 @@ pedit - generic packet editor action
 .BR ttl " }"
 
 .ti -8
+.IR TCPHDR_FIELD " := { "
+.BR sport " | " dport " | " flags " }"
+
+.ti -8
 .IR CMD_SPEC " := {"
 .BR clear " | " invert " | " set
 .IR VAL " | "
@@ -199,6 +205,20 @@ are:
 .B ttl
 .RE
 .TP
+.BI tcp " TCPHDR_FIELD"
+The supported keywords for
+.I TCPHDR_FIELD
+are:
+.RS
+.TP
+.B sport
+.TQ
+.B dport
+Source or destination TCP port number, a 16-bit value.
+.TP
+.B flags
+.RE
+.TP
 .B clear
 Clear the addressed data (i.e., set it to zero).
 .TP
@@ -293,6 +313,9 @@ tc filter add dev eth0 parent ffff: u32 \\
 tc filter add dev eth0 parent ffff: u32 \\
 	match ip sport 22 0xffff \\
 	action pedit ex munge eth dst set 11:22:33:44:55:66
+tc filter add dev eth0 parent ffff: u32 \\
+	match ip dport 23 0xffff \\
+	action pedit ex munge tcp dport set 22
 .EE
 .RE
 .SH SEE ALSO
diff --git a/tc/p_tcp.c b/tc/p_tcp.c
index 53ee9842160b..cf14574c9c3e 100644
--- a/tc/p_tcp.c
+++ b/tc/p_tcp.c
@@ -28,6 +28,43 @@ parse_tcp(int *argc_p, char ***argv_p,
 	  struct m_pedit_sel *sel, struct m_pedit_key *tkey)
 {
 	int res = -1;
+	int argc = *argc_p;
+	char **argv = *argv_p;
+
+	if (argc < 2)
+		return -1;
+
+	if (!sel->extended)
+		return -1;
+
+	tkey->htype = TCA_PEDIT_KEY_EX_HDR_TYPE_TCP;
+
+	if (strcmp(*argv, "sport") == 0) {
+		NEXT_ARG();
+		tkey->off = 0;
+		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey);
+		goto done;
+	}
+
+	if (strcmp(*argv, "dport") == 0) {
+		NEXT_ARG();
+		tkey->off = 2;
+		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey);
+		goto done;
+	}
+
+	if (strcmp(*argv, "flags") == 0) {
+		NEXT_ARG();
+		tkey->off = 13;
+		res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey);
+		goto done;
+	}
+
+	return -1;
+
+done:
+	*argc_p = argc;
+	*argv_p = argv;
 	return res;
 }
 struct m_pedit_util p_pedit_tcp = {
-- 
2.12.0

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

* [PATCH iproute2 net 8/8] tc/pedit: p_udp: introduce pedit udp support
  2017-04-23 12:53 [PATCH iproute2 net 0/8] tc/act_pedit: Support offset relative to conventional header Amir Vadai
                   ` (6 preceding siblings ...)
  2017-04-23 12:53 ` [PATCH iproute2 net 7/8] tc/pedit: p_tcp: introduce pedit tcp support Amir Vadai
@ 2017-04-23 12:53 ` Amir Vadai
  2017-05-01 16:26 ` [PATCH iproute2 net 0/8] tc/act_pedit: Support offset relative to conventional header Stephen Hemminger
  8 siblings, 0 replies; 15+ messages in thread
From: Amir Vadai @ 2017-04-23 12:53 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Or Gerlitz, Jamal Hadi Salim, Amir Vadai

From: Or Gerlitz <ogerlitz@mellanox.com>

For example, forward udp traffic destined to port 999 to veth0 and set
tcp port to 888:
$ tc filter add dev enp0s9 protocol ip parent ffff: \
    flower \
      ip_proto udp \
      dst_port 999 \
    action pedit ex munge \
      udp dport set 888 \
    action mirred egress \
      redirect dev veth0

Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Amir Vadai <amir@vadai.me>
---
 man/man8/tc-pedit.8 | 18 ++++++++++++++++++
 tc/p_udp.c          | 27 +++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/man/man8/tc-pedit.8 b/man/man8/tc-pedit.8
index ad1929592660..7f482eafc6c7 100644
--- a/man/man8/tc-pedit.8
+++ b/man/man8/tc-pedit.8
@@ -34,6 +34,8 @@ pedit - generic packet editor action
 .BI ip " EX_IPHDR_FIELD"
 |
 .BI tcp " TCPHDR_FIELD"
+|
+.BI udp " UDPHDR_FIELD"
 .RI } " CMD_SPEC"
 
 .ti -8
@@ -58,6 +60,10 @@ pedit - generic packet editor action
 .BR sport " | " dport " | " flags " }"
 
 .ti -8
+.IR UDPHDR_FIELD " := { "
+.BR sport " | " dport " }"
+
+.ti -8
 .IR CMD_SPEC " := {"
 .BR clear " | " invert " | " set
 .IR VAL " | "
@@ -219,6 +225,18 @@ Source or destination TCP port number, a 16-bit value.
 .B flags
 .RE
 .TP
+.BI udp " UDPHDR_FIELD"
+The supported keywords for
+.I UDPHDR_FIELD
+are:
+.RS
+.TP
+.B sport
+.TQ
+.B dport
+Source or destination TCP port number, a 16-bit value.
+.RE
+.TP
 .B clear
 Clear the addressed data (i.e., set it to zero).
 .TP
diff --git a/tc/p_udp.c b/tc/p_udp.c
index 3a86ba382391..a56a1b519254 100644
--- a/tc/p_udp.c
+++ b/tc/p_udp.c
@@ -28,6 +28,33 @@ parse_udp(int *argc_p, char ***argv_p,
 	  struct m_pedit_sel *sel, struct m_pedit_key *tkey)
 {
 	int res = -1;
+	int argc = *argc_p;
+	char **argv = *argv_p;
+
+	if (argc < 2)
+		return -1;
+
+	tkey->htype = TCA_PEDIT_KEY_EX_HDR_TYPE_UDP;
+
+	if (strcmp(*argv, "sport") == 0) {
+		NEXT_ARG();
+		tkey->off = 0;
+		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey);
+		goto done;
+	}
+
+	if (strcmp(*argv, "dport") == 0) {
+		NEXT_ARG();
+		tkey->off = 2;
+		res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey);
+		goto done;
+	}
+
+	return -1;
+
+done:
+	*argc_p = argc;
+	*argv_p = argv;
 	return res;
 }
 
-- 
2.12.0

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

* Re: [PATCH iproute2 net 3/8] tc/pedit: Introduce 'add' operation
  2017-04-23 12:53 ` [PATCH iproute2 net 3/8] tc/pedit: Introduce 'add' operation Amir Vadai
@ 2017-04-23 17:44   ` Jamal Hadi Salim
  2017-04-24  7:52     ` Amir Vadai
  0 siblings, 1 reply; 15+ messages in thread
From: Jamal Hadi Salim @ 2017-04-23 17:44 UTC (permalink / raw)
  To: Amir Vadai, Stephen Hemminger; +Cc: netdev, Or Gerlitz


Thanks for the excellent work.

On 17-04-23 08:53 AM, Amir Vadai wrote:
> This command could be useful to increase/decrease fields value.
>

Does this contradict the "retain" feature? Example rule to
retain the second nibble but set the first to 0xA
(essentially it X-ORs):
tc filter add dev lo parent ffff: protocol ip prio 10 \
u32 match ip dst 127.0.0.1/32 flowid 1:1 \
action pedit munge offset 0 u8 set 0x0A retain 0xF0

Mostly curious about hardware handling.

cheers,
jamal

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

* Re: [PATCH iproute2 net 3/8] tc/pedit: Introduce 'add' operation
  2017-04-23 17:44   ` Jamal Hadi Salim
@ 2017-04-24  7:52     ` Amir Vadai
  2017-04-24 11:04       ` Or Gerlitz
  0 siblings, 1 reply; 15+ messages in thread
From: Amir Vadai @ 2017-04-24  7:52 UTC (permalink / raw)
  To: Jamal Hadi Salim; +Cc: Stephen Hemminger, netdev, Or Gerlitz

On Sun, Apr 23, 2017 at 01:44:51PM -0400, Jamal Hadi Salim wrote:
> 
> Thanks for the excellent work.
> 
> On 17-04-23 08:53 AM, Amir Vadai wrote:
> > This command could be useful to increase/decrease fields value.
> > 
> 
> Does this contradict the "retain" feature? Example rule to
> retain the second nibble but set the first to 0xA
> (essentially it X-ORs):
> tc filter add dev lo parent ffff: protocol ip prio 10 \
> u32 match ip dst 127.0.0.1/32 flowid 1:1 \
> action pedit munge offset 0 u8 set 0x0A retain 0xF0

You mean, for example increasing a single nible in an ipv4 address?
If so, then it should work:
# tc filter add dev veth0 parent ffff:  u32 \
    match ip dport 23 0xffff \
		action pedit ex \
		  munge ip src add 1.0.0.0 retain 0xff000000

# tc -s filter show dev veth0 parent ffff:
filter protocol all pref 49151 u32
filter protocol all pref 49151 u32 fh 801: ht divisor 1
filter protocol all pref 49151 u32 fh 801::800 order 2048 key ht 801 bkt 0 terminal flowid ???  (rule hit 0 success 0)
  match 00000017/0000ffff at 20 (success 0 )
	action order 1:  pedit action pass keys 1
 	 index 48 ref 1 bind 1 installed 1 sec used 1 sec
	 key #0  at ipv4+12: add 01000000 mask 00ffffff
 	Action statistics:
	Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
	backlog 0b 0p requeues 0

> 
> Mostly curious about hardware handling.
As to hardware handling, Or did the implementation so he will answer
better. AFAIK, current implementation doesn't allow partial field
setting/adding, so such a rule can't be offloaded. I think it is only to
make things simple and because there was no use case for that.
To my knowledge, hardware should support such thing if needed.

Amir

> 
> cheers,
> jamal
> 

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

* Re: [PATCH iproute2 net 3/8] tc/pedit: Introduce 'add' operation
  2017-04-24  7:52     ` Amir Vadai
@ 2017-04-24 11:04       ` Or Gerlitz
  0 siblings, 0 replies; 15+ messages in thread
From: Or Gerlitz @ 2017-04-24 11:04 UTC (permalink / raw)
  To: Amir Vadai
  Cc: Jamal Hadi Salim, Stephen Hemminger, Linux Netdev List,
	Or Gerlitz

On Mon, Apr 24, 2017 at 10:52 AM, Amir Vadai <amir@vadai.me> wrote:
> On Sun, Apr 23, 2017 at 01:44:51PM -0400, Jamal Hadi Salim wrote:
>> Thanks for the excellent work.

sure, it's Amir, you know..

>> On 17-04-23 08:53 AM, Amir Vadai wrote:

>> Mostly curious about hardware handling.

> As to hardware handling, Or did the implementation so he will answer
> better. AFAIK, current implementation doesn't allow partial field
> setting/adding, so such a rule can't be offloaded. I think it is only to
> make things simple and because there was no use case for that.
> To my knowledge, hardware should support such thing if needed.

yeah (currently no partial setting) and yeah (in the future yes, will
support partial setting of offset into
field and partial length to set from there) and no for partial addition.

The reason we decided to disallow partial addition in the FW API was
what do you do with the carry, e.g you
add a value to the 2nd nibble of IP address and there are carry bits,
where do you take them? this becomes
even more ugly if you are dealing with mac addresses. I guess once
there's use case for partial add offload,
we will revisit that.

Or.

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

* Re: [PATCH iproute2 net 2/8] tc/pedit: Extend pedit to specify offset relative to mac/transport headers
  2017-04-23 12:53 ` [PATCH iproute2 net 2/8] tc/pedit: Extend pedit to specify offset relative to mac/transport headers Amir Vadai
@ 2017-05-01 16:21   ` Stephen Hemminger
  0 siblings, 0 replies; 15+ messages in thread
From: Stephen Hemminger @ 2017-05-01 16:21 UTC (permalink / raw)
  To: Amir Vadai; +Cc: netdev, Or Gerlitz, Jamal Hadi Salim

On Sun, 23 Apr 2017 15:53:50 +0300
Amir Vadai <amir@vadai.me> wrote:

> -extern int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type,__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey);
> -extern int pack_key(struct tc_pedit_sel *sel,struct tc_pedit_key *tkey);
> -extern int pack_key32(__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey);
> -extern int pack_key16(__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey);
> -extern int pack_key8(__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey);
> +extern int pack_key(struct m_pedit_sel *sel, struct m_pedit_key *tkey);
> +extern int pack_key32(__u32 retain, struct m_pedit_sel *sel, struct m_pedit_key *tkey);
> +extern int pack_key16(__u32 retain, struct m_pedit_sel *sel, struct m_pedit_key *tkey);
> +extern int pack_key8(__u32 retain, struct m_pedit_sel *sel, struct m_pedit_key *tkey);
>  extern int parse_val(int *argc_p, char ***argv_p, __u32 * val, int type);
> -extern int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type,__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey);
> -extern int parse_offset(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey);
> +extern 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);
> +extern int parse_offset(int *argc_p, char ***argv_p,
> +			struct m_pedit_sel *sel, struct m_pedit_key *tkey);
>  int parse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tc

Please add newline to break the overly long lines here.
Try and keep with in the  80 column convention.

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

* Re: [PATCH iproute2 net 0/8] tc/act_pedit: Support offset relative to conventional header
  2017-04-23 12:53 [PATCH iproute2 net 0/8] tc/act_pedit: Support offset relative to conventional header Amir Vadai
                   ` (7 preceding siblings ...)
  2017-04-23 12:53 ` [PATCH iproute2 net 8/8] tc/pedit: p_udp: introduce pedit udp support Amir Vadai
@ 2017-05-01 16:26 ` Stephen Hemminger
  2017-05-03  6:27   ` Amir Vadai
  8 siblings, 1 reply; 15+ messages in thread
From: Stephen Hemminger @ 2017-05-01 16:26 UTC (permalink / raw)
  To: Amir Vadai; +Cc: netdev, Or Gerlitz, Jamal Hadi Salim

On Sun, 23 Apr 2017 15:53:48 +0300
Amir Vadai <amir@vadai.me> wrote:

> Hi Stephen,
> 
> This patchset extends pedit to support modifying a field in an offset relative
> to the conventional network headers (kenrel support was added [1] in 4.11 rc1).
> Without the extended pedit, user could specify fields in TCP and ICMP headers,
> but the kernel code was using an offset relative to the begining of the IP
> header. This will break if IP header length is greater than the minimal value
> of 20, or if L3 is not IPv4.
> 
> It also introduces support in manipulating ETH, TCP, UDP and IP.ttl fields and
> a new command to increase/decrease the value of a field (current use case is IP.ttl).
> 
> Since there might be deployments already using pedit, special consideration was
> taken, not to break those scripts - only by specifying the special keyword
> 'ex', the extended capabilities are available, thus there should be no impact
> on existing scripts.
> Also, the new code can live together with rules added by the old code. It
> supports both the old netlink and the new one.
> 
> This patchset is against the master and not net-next as the functionality was
> added in 4.11
> 
> Thanks,
> Amir
> 
> [1] - 71d0ed7079df ("net/act_pedit: Support using offset relative to the
>                      conventional network headers")
> 
> Amir Vadai (7):
>   tc/pedit: Fix a typo in pedit usage message
>   tc/pedit: Extend pedit to specify offset relative to mac/transport
>     headers
>   tc/pedit: Introduce 'add' operation
>   tc/pedit: p_ip: introduce editing ttl header
>   tc/pedit: Support fields bigger than 32 bits
>   tc/pedit: p_eth: ETH header editor
>   tc/pedit: p_tcp: introduce pedit tcp support
> 
> Or Gerlitz (1):
>   tc/pedit: p_udp: introduce pedit udp support
> 
>  man/man8/tc-pedit.8 | 126 +++++++++++++++++++++--
>  tc/Makefile         |   1 +
>  tc/m_pedit.c        | 290 ++++++++++++++++++++++++++++++++++++++++++++++------
>  tc/m_pedit.h        |  44 ++++++--
>  tc/p_eth.c          |  72 +++++++++++++
>  tc/p_icmp.c         |   3 +-
>  tc/p_ip.c           |  21 +++-
>  tc/p_tcp.c          |  40 +++++++-
>  tc/p_udp.c          |  30 +++++-
>  9 files changed, 572 insertions(+), 55 deletions(-)
>  create mode 100644 tc/p_eth.c
> 

Applied. Then I cleaned up long lines

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

* Re: [PATCH iproute2 net 0/8] tc/act_pedit: Support offset relative to conventional header
  2017-05-01 16:26 ` [PATCH iproute2 net 0/8] tc/act_pedit: Support offset relative to conventional header Stephen Hemminger
@ 2017-05-03  6:27   ` Amir Vadai
  0 siblings, 0 replies; 15+ messages in thread
From: Amir Vadai @ 2017-05-03  6:27 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Or Gerlitz, Jamal Hadi Salim

On Mon, May 01, 2017 at 09:26:25AM -0700, Stephen Hemminger wrote:
> On Sun, 23 Apr 2017 15:53:48 +0300
> Amir Vadai <amir@vadai.me> wrote:
> 
> > Hi Stephen,
> > 
> > This patchset extends pedit to support modifying a field in an offset relative
> > to the conventional network headers (kenrel support was added [1] in 4.11 rc1).
> > Without the extended pedit, user could specify fields in TCP and ICMP headers,
> > but the kernel code was using an offset relative to the begining of the IP
> > header. This will break if IP header length is greater than the minimal value
> > of 20, or if L3 is not IPv4.
> > 
> > It also introduces support in manipulating ETH, TCP, UDP and IP.ttl fields and
> > a new command to increase/decrease the value of a field (current use case is IP.ttl).
> > 
> > Since there might be deployments already using pedit, special consideration was
> > taken, not to break those scripts - only by specifying the special keyword
> > 'ex', the extended capabilities are available, thus there should be no impact
> > on existing scripts.
> > Also, the new code can live together with rules added by the old code. It
> > supports both the old netlink and the new one.
> > 
> > This patchset is against the master and not net-next as the functionality was
> > added in 4.11
> > 
> > Thanks,
> > Amir
> > 
> > [1] - 71d0ed7079df ("net/act_pedit: Support using offset relative to the
> >                      conventional network headers")

[...]

> 
> Applied. Then I cleaned up long lines

Thanks. Will make sure to clean up long lines in future patches.

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

end of thread, other threads:[~2017-05-03  6:27 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-04-23 12:53 [PATCH iproute2 net 0/8] tc/act_pedit: Support offset relative to conventional header Amir Vadai
2017-04-23 12:53 ` [PATCH iproute2 net 1/8] tc/pedit: Fix a typo in pedit usage message Amir Vadai
2017-04-23 12:53 ` [PATCH iproute2 net 2/8] tc/pedit: Extend pedit to specify offset relative to mac/transport headers Amir Vadai
2017-05-01 16:21   ` Stephen Hemminger
2017-04-23 12:53 ` [PATCH iproute2 net 3/8] tc/pedit: Introduce 'add' operation Amir Vadai
2017-04-23 17:44   ` Jamal Hadi Salim
2017-04-24  7:52     ` Amir Vadai
2017-04-24 11:04       ` Or Gerlitz
2017-04-23 12:53 ` [PATCH iproute2 net 4/8] tc/pedit: p_ip: introduce editing ttl header Amir Vadai
2017-04-23 12:53 ` [PATCH iproute2 net 5/8] tc/pedit: Support fields bigger than 32 bits Amir Vadai
2017-04-23 12:53 ` [PATCH iproute2 net 6/8] tc/pedit: p_eth: ETH header editor Amir Vadai
2017-04-23 12:53 ` [PATCH iproute2 net 7/8] tc/pedit: p_tcp: introduce pedit tcp support Amir Vadai
2017-04-23 12:53 ` [PATCH iproute2 net 8/8] tc/pedit: p_udp: introduce pedit udp support Amir Vadai
2017-05-01 16:26 ` [PATCH iproute2 net 0/8] tc/act_pedit: Support offset relative to conventional header Stephen Hemminger
2017-05-03  6:27   ` Amir Vadai

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).