summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavide Caratti <dcaratti@redhat.com>2023-03-31 18:49:03 +0200
committerDavid Ahern <dsahern@kernel.org>2023-04-07 09:37:32 -0600
commit8208365db4adf5e81ddf2e54590f3c732edac58c (patch)
treebe1a198402a41b3e7104d59900f4a3c5dcc0b64a
parent5dbb44707c8b66af9f614a556421fdeeb4a6d8c3 (diff)
downloadiproute2-8208365db4adf5e81ddf2e54590f3c732edac58c.tar.gz
tc: m_tunnel_key: support code for "nofrag" tunnels
add control plane for setting TCA_TUNNEL_KEY_NO_FRAG flag on act_tunnel_key actions. Signed-off-by: Davide Caratti <dcaratti@redhat.com> Reviewed-by: Simon Horman <simon.horman@corigine.com> Signed-off-by: David Ahern <dsahern@kernel.org>
-rw-r--r--man/man8/tc-tunnel_key.83
-rw-r--r--tc/m_tunnel_key.c48
2 files changed, 40 insertions, 11 deletions
diff --git a/man/man8/tc-tunnel_key.8 b/man/man8/tc-tunnel_key.8
index f639f433..b987cd0d 100644
--- a/man/man8/tc-tunnel_key.8
+++ b/man/man8/tc-tunnel_key.8
@@ -131,6 +131,9 @@ If using
.B nocsum
with IPv6, be sure you know what you are doing. Zero UDP checksums provide
weaker protection against corrupted packets. See RFC6935 for details.
+.TP
+.B nofrag
+disallow IP fragmentation.
.RE
.SH EXAMPLES
The following example encapsulates incoming ICMP packets on eth0 into a vxlan
diff --git a/tc/m_tunnel_key.c b/tc/m_tunnel_key.c
index 1b4c8bd6..ff699cc8 100644
--- a/tc/m_tunnel_key.c
+++ b/tc/m_tunnel_key.c
@@ -26,7 +26,8 @@ static void explain(void)
"dst_ip <IP> (mandatory)\n"
"dst_port <UDP_PORT>\n"
"geneve_opts | vxlan_opts | erspan_opts <OPTIONS>\n"
- "csum | nocsum (default is \"csum\")\n");
+ "csum | nocsum (default is \"csum\")\n"
+ "nofrag\n");
}
static void usage(void)
@@ -321,7 +322,7 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p,
int ret;
int has_src_ip = 0;
int has_dst_ip = 0;
- int csum = 1;
+ int csum = 1, nofrag = 0;
if (matches(*argv, "tunnel_key") != 0)
return -1;
@@ -425,6 +426,8 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p,
csum = 1;
} else if (matches(*argv, "nocsum") == 0) {
csum = 0;
+ } else if (strcmp(*argv, "nofrag") == 0) {
+ nofrag = 1;
} else if (matches(*argv, "help") == 0) {
usage();
} else {
@@ -435,6 +438,9 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p,
addattr8(n, MAX_MSG, TCA_TUNNEL_KEY_NO_CSUM, !csum);
+ if (nofrag)
+ addattr(n, MAX_MSG, TCA_TUNNEL_KEY_NO_FRAG);
+
parse_action_control_dflt(&argc, &argv, &parm.action,
false, TC_ACT_PIPE);
@@ -513,15 +519,36 @@ static void tunnel_key_print_dst_port(FILE *f, char *name,
rta_getattr_be16(attr));
}
-static void tunnel_key_print_flag(FILE *f, const char *name_on,
- const char *name_off,
- struct rtattr *attr)
+static const struct {
+ const char *name;
+ unsigned int nl_flag;
+} tunnel_key_flag_names[] = {
+ { "", TCA_TUNNEL_KEY_NO_CSUM }, /* special handling, not bool */
+ { "nofrag", TCA_TUNNEL_KEY_NO_FRAG },
+};
+
+static void tunnel_key_print_flags(struct rtattr *tb[])
{
- if (!attr)
- return;
+ unsigned int i, nl_flag;
+
print_nl();
- print_string(PRINT_ANY, "flag", "\t%s",
- rta_getattr_u8(attr) ? name_on : name_off);
+ for (i = 0; i < ARRAY_SIZE(tunnel_key_flag_names); i++) {
+ nl_flag = tunnel_key_flag_names[i].nl_flag;
+ if (nl_flag == TCA_TUNNEL_KEY_NO_CSUM) {
+ /* special handling to preserve csum/nocsum design */
+ if (!tb[nl_flag])
+ continue;
+ print_string(PRINT_ANY, "flag", "\t%s",
+ rta_getattr_u8(tb[nl_flag]) ?
+ "nocsum" : "csum" );
+ } else {
+ if (tb[nl_flag])
+ print_string(PRINT_FP, NULL, "\t%s",
+ tunnel_key_flag_names[i].name);
+ print_bool(PRINT_JSON, tunnel_key_flag_names[i].name,
+ NULL, !!tb[nl_flag]);
+ }
+ }
}
static void tunnel_key_print_geneve_options(struct rtattr *attr)
@@ -697,8 +724,7 @@ static int print_tunnel_key(struct action_util *au, FILE *f, struct rtattr *arg)
tunnel_key_print_dst_port(f, "dst_port",
tb[TCA_TUNNEL_KEY_ENC_DST_PORT]);
tunnel_key_print_key_opt(tb[TCA_TUNNEL_KEY_ENC_OPTS]);
- tunnel_key_print_flag(f, "nocsum", "csum",
- tb[TCA_TUNNEL_KEY_NO_CSUM]);
+ tunnel_key_print_flags(tb);
tunnel_key_print_tos_ttl(f, "tos",
tb[TCA_TUNNEL_KEY_ENC_TOS]);
tunnel_key_print_tos_ttl(f, "ttl",