import iproute-5.3.0-1.el8

This commit is contained in:
CentOS Sources 2020-04-28 05:40:13 -04:00 committed by Andrew Lukoshko
parent 01f347d0ed
commit 7049c0d781
79 changed files with 9 additions and 11931 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/iproute2-4.18.0.tar.xz
SOURCES/iproute2-5.3.0.tar.xz

View File

@ -1 +1 @@
ff02c7352bae407a76d71b36558700bb489026fc SOURCES/iproute2-4.18.0.tar.xz
fb5e623678688304a42d29d27d22287dcca12135 SOURCES/iproute2-5.3.0.tar.xz

View File

@ -1,58 +0,0 @@
From 7a9b3fa0fe560cb209f01642e6591ff0b5d42d12 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 13 Sep 2018 20:36:09 +0200
Subject: [PATCH] man: bridge.8: Document -oneline option
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1612704
Upstream Status: iproute2.git commit 05758f5c7b357
commit 05758f5c7b357c53b53e16604bcdfb269fc68a13
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Aug 16 12:27:53 2018 +0200
man: bridge.8: Document -oneline option
Copied the description from ip.8.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
man/man8/bridge.8 | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index e7f7148..95851e0 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -24,7 +24,8 @@ bridge \- show / manipulate bridge addresses and devices
\fB\-b\fR[\fIatch\fR] filename |
\fB\-c\fR[\folor\fR] |
\fB\-p\fR[\fIretty\fR] |
-\fB\-j\fR[\fIson\fR] }
+\fB\-j\fR[\fIson\fR] |
+\fB\-o\fR[\fIneline\fr] }
.ti -8
.BR "bridge link set"
@@ -181,6 +182,18 @@ Output results in JavaScript Object Notation (JSON).
.BR "\-p", " \-pretty"
When combined with -j generate a pretty JSON output.
+.TP
+.BR "\-o", " \-oneline"
+output each record on a single line, replacing line feeds
+with the
+.B '\e'
+character. This is convenient when you want to count records
+with
+.BR wc (1)
+or to
+.BR grep (1)
+the output.
+
.SH BRIDGE - COMMAND SYNTAX
--
1.8.3.1

View File

@ -1,39 +0,0 @@
From 653ed98ba60d13b2c11338fe4d766eaf8eb5b364 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 13 Sep 2018 20:36:09 +0200
Subject: [PATCH] bridge: trivial: Make help text consistent
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1612704
Upstream Status: iproute2.git commit f9ff0cd69c451
commit f9ff0cd69c4514bc78657d33459655248c9e1357
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Aug 16 12:27:54 2018 +0200
bridge: trivial: Make help text consistent
Change curly braces into brackets for -json option in help text to be
consistent with the rest.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
bridge/bridge.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bridge/bridge.c b/bridge/bridge.c
index 7fcfe11..28e1381 100644
--- a/bridge/bridge.c
+++ b/bridge/bridge.c
@@ -42,7 +42,7 @@ static void usage(void)
"where OBJECT := { link | fdb | mdb | vlan | monitor }\n"
" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] |\n"
" -o[neline] | -t[imestamp] | -n[etns] name |\n"
-" -c[ompressvlans] -color -p[retty] -j{son} }\n");
+" -c[ompressvlans] -color -p[retty] -j[son] }\n");
exit(-1);
}
--
1.8.3.1

View File

@ -1,40 +0,0 @@
From fbcb1d0f1411bb21c9045a03188345e9c550624b Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 13 Sep 2018 20:36:09 +0200
Subject: [PATCH] devlink: trivial: Make help text consistent
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1612704
Upstream Status: iproute2.git commit bb75b9bf2f3fa
Conflicts: Context change due to missing 'region' support.
commit bb75b9bf2f3fa392807bf09ed41eef25b89e1e82
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Aug 16 12:27:55 2018 +0200
devlink: trivial: Make help text consistent
Typically the part of the flag in brackets completes the leading part
instead of repeating it.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
devlink/devlink.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/devlink/devlink.c b/devlink/devlink.c
index df2c66d..1142d16 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -4492,7 +4492,7 @@ static void help(void)
pr_err("Usage: devlink [ OPTIONS ] OBJECT { COMMAND | help }\n"
" devlink [ -f[orce] ] -b[atch] filename\n"
"where OBJECT := { dev | port | sb | monitor | dpipe | resource }\n"
- " OPTIONS := { -V[ersion] | -n[no-nice-names] | -j[json] | -p[pretty] | -v[verbose] }\n");
+ " OPTIONS := { -V[ersion] | -n[o-nice-names] | -j[json] | -p[pretty] | -v[verbose] }\n");
}
static int dl_cmd(struct dl *dl, int argc, char **argv)
--
1.8.3.1

View File

@ -1,40 +0,0 @@
From 6ab77b078026ed63e0234c1c1645b665723b0509 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 13 Sep 2018 20:38:04 +0200
Subject: [PATCH] man: devlink.8: Document -verbose option
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1612704
Upstream Status: iproute2.git commit 29b1430ba9aa9
commit 29b1430ba9aa9bceb42b07232f5138e511034a5a
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Aug 16 12:27:56 2018 +0200
man: devlink.8: Document -verbose option
This was the only bit missing in comparison to devlink help text.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
man/man8/devlink.8 | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/man/man8/devlink.8 b/man/man8/devlink.8
index efc6e62..92972b7 100644
--- a/man/man8/devlink.8
+++ b/man/man8/devlink.8
@@ -47,6 +47,10 @@ Generate JSON output.
.BR "\-p" , " --pretty"
When combined with -j generate a pretty JSON output.
+.TP
+.BR "\-v" , " --verbose"
+Turn on verbose output.
+
.SS
.I OBJECT
--
1.8.3.1

View File

@ -1,44 +0,0 @@
From 83af05569ffb9d607438f93d98c5ead84b1cc5ac Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 13 Sep 2018 20:38:04 +0200
Subject: [PATCH] genl: Fix help text
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1612704
Upstream Status: iproute2.git commit d94974bc91eb2
commit d94974bc91eb2aa2df4592140e1aa3ea0d3cddba
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Aug 16 12:27:57 2018 +0200
genl: Fix help text
The '| help' part was misleading: In fact, 'genl help' does not work but
'genl <OBJECT> help' does. Fix the help text to make that clear.
In addition to that, list -Version and -help flags as well.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
genl/genl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/genl/genl.c b/genl/genl.c
index 20ecb8b..1940a23 100644
--- a/genl/genl.c
+++ b/genl/genl.c
@@ -98,9 +98,9 @@ static void usage(void) __attribute__((noreturn));
static void usage(void)
{
- fprintf(stderr, "Usage: genl [ OPTIONS ] OBJECT | help }\n"
+ fprintf(stderr, "Usage: genl [ OPTIONS ] OBJECT [help] }\n"
"where OBJECT := { ctrl etc }\n"
- " OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] }\n");
+ " OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -V[ersion] | -h[elp] }\n");
exit(-1);
}
--
1.8.3.1

View File

@ -1,42 +0,0 @@
From a2e5a2d8f8c41fb4f87c66d827f3e22035a11dd7 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 13 Sep 2018 20:38:04 +0200
Subject: [PATCH] man: ifstat.8: Document --json and --pretty options
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1612704
Upstream Status: iproute2.git commit a486d25b9cbfc
commit a486d25b9cbfc3469e30297495333d95a5576bdc
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Aug 16 12:27:58 2018 +0200
man: ifstat.8: Document --json and --pretty options
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
man/man8/ifstat.8 | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/man/man8/ifstat.8 b/man/man8/ifstat.8
index 3ba0088..8cd164d 100644
--- a/man/man8/ifstat.8
+++ b/man/man8/ifstat.8
@@ -48,6 +48,14 @@ Report average over the last SECS seconds.
.B \-z, \-\-zeros
Show entries with zero activity.
.TP
+.B \-j, \-\-json
+Display results in JSON format
+.TP
+.B \-p, \-\-pretty
+If combined with
+.BR \-\-json ,
+pretty print the output.
+.TP
.B \-x, \-\-extended=TYPE
Show extended stats of TYPE. Supported types are:
--
1.8.3.1

View File

@ -1,69 +0,0 @@
From f586cb6ed5543621ec55ac07a6d2b72504c9c65b Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 13 Sep 2018 20:38:04 +0200
Subject: [PATCH] man: rtacct.8: Fix nstat options
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1612704
Upstream Status: iproute2.git commit 71170d854e96d
commit 71170d854e96d2e7dff338f482cb23dfadbbd702
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Aug 16 12:28:00 2018 +0200
man: rtacct.8: Fix nstat options
Add missing --pretty and --json options, correct --zero to --zeros and
correct the mess around --scan/--interval including broken man page
formatting.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
man/man8/rtacct.8 | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/man/man8/rtacct.8 b/man/man8/rtacct.8
index 01321e6..ccdbf6c 100644
--- a/man/man8/rtacct.8
+++ b/man/man8/rtacct.8
@@ -4,7 +4,7 @@
nstat, rtacct - network statistics tools.
.SH SYNOPSIS
-Usage: nstat [ -h?vVzrnasd:t: ] [ PATTERN [ PATTERN ] ]
+Usage: nstat [ -h?vVzrnasd:t:jp ] [ PATTERN [ PATTERN ] ]
.br
Usage: rtacct [ -h?vVzrnasd:t: ] [ ListOfRealms ]
@@ -21,7 +21,7 @@ Print help
.B \-V, \-\-version
Print version
.TP
-.B \-z, \-\-zero
+.B \-z, \-\-zeros
Dump zero counters too. By default they are not shown.
.TP
.B \-r, \-\-reset
@@ -39,12 +39,16 @@ Do not update history, so that the next time you will see counters including val
.B \-j, \-\-json
Display results in JSON format.
.TP
-.B \-d, \-\-interval <INTERVAL>
+.B \-p, \-\-pretty
+When combined with
+.BR \-\-json ,
+pretty print the output.
+.TP
+.B \-d, \-\-scan <INTERVAL>
Run in daemon mode collecting statistics. <INTERVAL> is interval between measurements in seconds.
.TP
-
+.B \-t, \-\-interval <INTERVAL>
Time interval to average rates. Default value is 60 seconds.
-.TP
.SH SEE ALSO
lnstat(8)
--
1.8.3.1

View File

@ -1,38 +0,0 @@
From b5ebd3fee37bc9d1832c545f605c639140b8d6f1 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 13 Sep 2018 20:38:04 +0200
Subject: [PATCH] rtmon: List options in help text
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1612704
Upstream Status: iproute2.git commit 6417c06b59b07
commit 6417c06b59b0731bcff4c0999661b256be6f52cb
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Aug 16 12:28:01 2018 +0200
rtmon: List options in help text
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/rtmon.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/ip/rtmon.c b/ip/rtmon.c
index acc11df..0e795f7 100644
--- a/ip/rtmon.c
+++ b/ip/rtmon.c
@@ -63,7 +63,9 @@ static int dump_msg2(const struct sockaddr_nl *who,
static void usage(void)
{
- fprintf(stderr, "Usage: rtmon file FILE [ all | LISTofOBJECTS]\n");
+ fprintf(stderr, "Usage: rtmon [ OPTIONS ] file FILE [ all | LISTofOBJECTS ]\n");
+ fprintf(stderr, "OPTIONS := { -f[amily] { inet | inet6 | link | help } |\n"
+ " -4 | -6 | -0 | -V[ersion] }\n");
fprintf(stderr, "LISTofOBJECTS := [ link ] [ address ] [ route ]\n");
exit(-1);
}
--
1.8.3.1

View File

@ -1,37 +0,0 @@
From 222a4bb5ed730ff84a984a49d4f7fea39e930f97 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 13 Sep 2018 20:38:04 +0200
Subject: [PATCH] man: ss.8: Describe --events option
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1612704
Upstream Status: iproute2.git commit d559db725cfe0
commit d559db725cfe033718d7bcfff01285c194a6e92d
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Aug 16 12:28:02 2018 +0200
man: ss.8: Describe --events option
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
man/man8/ss.8 | 3 +++
1 file changed, 3 insertions(+)
diff --git a/man/man8/ss.8 b/man/man8/ss.8
index 28033d8..7a6572b 100644
--- a/man/man8/ss.8
+++ b/man/man8/ss.8
@@ -242,6 +242,9 @@ Print summary statistics. This option does not parse socket lists obtaining
summary from various sources. It is useful when amount of sockets is so huge
that parsing /proc/net/tcp is painful.
.TP
+.B \-E, \-\-events
+Continually display sockets as they are destroyed
+.TP
.B \-Z, \-\-context
As the
.B \-p
--
1.8.3.1

View File

@ -1,36 +0,0 @@
From 093a6272457a68f18bd992f3667051bcd31e32bc Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 13 Sep 2018 20:38:04 +0200
Subject: [PATCH] ip: Add missing -M flag to help text
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1612704
Upstream Status: iproute2.git commit 644b9c238c2dd
commit 644b9c238c2dde8b0b931d153fc6719e00ebfc6b
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Aug 16 12:27:59 2018 +0200
ip: Add missing -M flag to help text
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/ip.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ip/ip.c b/ip/ip.c
index 71d5170..bb964f3 100644
--- a/ip/ip.c
+++ b/ip/ip.c
@@ -55,7 +55,7 @@ static void usage(void)
" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n"
" -h[uman-readable] | -iec | -j[son] | -p[retty] |\n"
" -f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |\n"
-" -4 | -6 | -I | -D | -B | -0 |\n"
+" -4 | -6 | -I | -D | -M | -B | -0 |\n"
" -l[oops] { maximum-addr-flush-attempts } | -br[ief] |\n"
" -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |\n"
" -rc[vbuf] [size] | -n[etns] name | -a[ll] | -c[olor]}\n");
--
1.8.3.1

View File

@ -1,47 +0,0 @@
From deef2321cf38ef0314bea307dbc27d376ad39624 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 13 Sep 2018 20:45:38 +0200
Subject: [PATCH] iprule: Fix destination prefix output
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1623503
Upstream Status: iproute2.git commit 1a75322c5a8de
commit 1a75322c5a8dee6e1ed0017d76c87ef85c505b98
Author: Stefan Bader <stefan.bader@canonical.com>
Date: Tue Aug 28 16:27:29 2018 +0200
iprule: Fix destination prefix output
When adding support for JSON output the new code for printing
the destination prefix adds a stray blank character before
the bitmask. This causes some user-space parsing to fail.
Current output:
...: from x.x.x.x/l to y.y.y.y /l
Previous output:
...: from x.x.x.x/l to y.y.y.y/l
Fixes: 0dd4ccc5 "iprule: add json support"
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Luca Boccassi <bluca@debian.org>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/iprule.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ip/iprule.c b/ip/iprule.c
index 8b94214..744d6d8 100644
--- a/ip/iprule.c
+++ b/ip/iprule.c
@@ -239,7 +239,7 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
print_string(PRINT_FP, NULL, "to ", NULL);
print_color_string(PRINT_ANY, ifa_family_color(frh->family),
- "dst", "%s ", dst);
+ "dst", "%s", dst);
if (frh->dst_len != host_len)
print_uint(PRINT_ANY, "dstlen", "/%u ", frh->dst_len);
else
--
1.8.3.1

View File

@ -1,147 +0,0 @@
From b24c686f3e5bb0acbebf40c3e7f5a16f0582fd64 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 13 Sep 2018 20:55:45 +0200
Subject: [PATCH] tc/act_tunnel_key: Enable setup of tos and ttl
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1615915
Upstream Status: iproute2.git commit 9f89b0cc0eda2
Conflicts: Context change due to missing Geneve support.
commit 9f89b0cc0eda2ef52d8850b0610f3e2e09fd7c1c
Author: Or Gerlitz <ogerlitz@mellanox.com>
Date: Thu Jul 19 14:02:14 2018 +0300
tc/act_tunnel_key: Enable setup of tos and ttl
Allow to set tos and ttl for the tunnel.
For example, here's encap rule that sets tos to the tunnel:
tc filter add dev eth0_0 protocol ip parent ffff: prio 10 flower \
src_mac e4:11:22:33:44:50 dst_mac e4:11:22:33:44:70 \
action tunnel_key set src_ip 192.168.10.1 dst_ip 192.168.10.2 id 100 dst_port 4789 tos 0x30 \
action mirred egress redirect dev vxlan_sys_4789
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Reviewed-by: Roi Dayan <roid@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
man/man8/tc-tunnel_key.8 | 8 ++++++++
tc/m_tunnel_key.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/man/man8/tc-tunnel_key.8 b/man/man8/tc-tunnel_key.8
index e979a74..71cee5b 100644
--- a/man/man8/tc-tunnel_key.8
+++ b/man/man8/tc-tunnel_key.8
@@ -16,6 +16,8 @@ tunnel_key - Tunnel metadata manipulation
.IR ADDRESS
.BI id " KEY_ID"
.BI dst_port " UDP_PORT"
+.BI tos " TOS"
+.BI ttl " TTL"
.RB "[ " csum " | " nocsum " ]"
.SH DESCRIPTION
@@ -79,6 +81,12 @@ Outer header destination IP address (IPv4 or IPv6)
.B dst_port
Outer header destination UDP port
.TP
+.B tos
+Outer header TOS
+.TP
+.B ttl
+Outer header TTL
+.TP
.RB [ no ] csum
Controlls outer UDP checksum. When set to
.B csum
diff --git a/tc/m_tunnel_key.c b/tc/m_tunnel_key.c
index 0fa4615..8d0a8d1 100644
--- a/tc/m_tunnel_key.c
+++ b/tc/m_tunnel_key.c
@@ -81,6 +81,22 @@ static int tunnel_key_parse_dst_port(char *str, int type, struct nlmsghdr *n)
return 0;
}
+static int tunnel_key_parse_tos_ttl(char *str, int type, struct nlmsghdr *n)
+{
+ int ret;
+ __u8 val;
+
+ ret = get_u8(&val, str, 10);
+ if (ret)
+ ret = get_u8(&val, str, 16);
+ if (ret)
+ return -1;
+
+ addattr8(n, MAX_MSG, type, val);
+
+ return 0;
+}
+
static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p,
int tca_id, struct nlmsghdr *n)
{
@@ -157,6 +173,22 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p,
fprintf(stderr, "Illegal \"dst port\"\n");
return -1;
}
+ } else if (matches(*argv, "tos") == 0) {
+ NEXT_ARG();
+ ret = tunnel_key_parse_tos_ttl(*argv,
+ TCA_TUNNEL_KEY_ENC_TOS, n);
+ if (ret < 0) {
+ fprintf(stderr, "Illegal \"tos\"\n");
+ return -1;
+ }
+ } else if (matches(*argv, "ttl") == 0) {
+ NEXT_ARG();
+ ret = tunnel_key_parse_tos_ttl(*argv,
+ TCA_TUNNEL_KEY_ENC_TTL, n);
+ if (ret < 0) {
+ fprintf(stderr, "Illegal \"ttl\"\n");
+ return -1;
+ }
} else if (matches(*argv, "csum") == 0) {
csum = 1;
} else if (matches(*argv, "nocsum") == 0) {
@@ -260,6 +292,23 @@ static void tunnel_key_print_flag(FILE *f, const char *name_on,
rta_getattr_u8(attr) ? name_on : name_off);
}
+static void tunnel_key_print_tos_ttl(FILE *f, char *name,
+ struct rtattr *attr)
+{
+ if (!attr)
+ return;
+
+ if (matches(name, "tos") == 0 && rta_getattr_u8(attr) != 0) {
+ print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_uint(PRINT_ANY, "tos", "\ttos 0x%x",
+ rta_getattr_u8(attr));
+ } else if (matches(name, "ttl") == 0 && rta_getattr_u8(attr) != 0) {
+ print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_uint(PRINT_ANY, "ttl", "\tttl %u",
+ rta_getattr_u8(attr));
+ }
+}
+
static int print_tunnel_key(struct action_util *au, FILE *f, struct rtattr *arg)
{
struct rtattr *tb[TCA_TUNNEL_KEY_MAX + 1];
@@ -299,6 +348,10 @@ static int print_tunnel_key(struct action_util *au, FILE *f, struct rtattr *arg)
tb[TCA_TUNNEL_KEY_ENC_DST_PORT]);
tunnel_key_print_flag(f, "nocsum", "csum",
tb[TCA_TUNNEL_KEY_NO_CSUM]);
+ tunnel_key_print_tos_ttl(f, "tos",
+ tb[TCA_TUNNEL_KEY_ENC_TOS]);
+ tunnel_key_print_tos_ttl(f, "ttl",
+ tb[TCA_TUNNEL_KEY_ENC_TTL]);
break;
}
print_action_control(f, " ", parm->action, "");
--
1.8.3.1

View File

@ -1,127 +0,0 @@
From 23c57e53c5dfdaf113ecf1ebde8e04e8c7a10c50 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 13 Sep 2018 20:56:18 +0200
Subject: [PATCH] tc/flower: Add match on encapsulating tos/ttl
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1615915
Upstream Status: iproute2.git commit 761ec9e29ff86
commit 761ec9e29ff867452057f59dc6ca430688b409ea
Author: Or Gerlitz <ogerlitz@mellanox.com>
Date: Thu Jul 19 14:02:15 2018 +0300
tc/flower: Add match on encapsulating tos/ttl
Add matching on tos/ttl of the IP tunnel headers.
For example, here's decap rule that matches on the tunnel tos:
tc filter add dev vxlan_sys_4789 protocol ip parent ffff: prio 10 flower \
enc_src_ip 192.168.10.2 enc_dst_ip 192.168.10.1 enc_key_id 100 enc_dst_port 4789 enc_tos 0x30 \
src_mac e4:11:22:33:44:70 dst_mac e4:11:22:33:44:50 \
action tunnel_key unset \
action mirred egress redirect dev eth0_0
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Reviewed-by: Roi Dayan <roid@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
man/man8/tc-flower.8 | 14 +++++++++++++-
tc/f_flower.c | 27 +++++++++++++++++++++++++++
2 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8
index 4f3714b..f917f24 100644
--- a/man/man8/tc-flower.8
+++ b/man/man8/tc-flower.8
@@ -70,6 +70,10 @@ flower \- flow based traffic control filter
.IR ipv4_address " | " ipv6_address " } | "
.B enc_dst_port
.IR port_number " | "
+.B enc_tos
+.IR TOS " | "
+.B enc_ttl
+.IR TTL " | "
.BR ip_flags
.IR IP_FLAGS
.SH DESCRIPTION
@@ -252,6 +256,10 @@ bits is assumed.
.BI enc_src_ip " PREFIX"
.TQ
.BI enc_dst_port " NUMBER"
+.TQ
+.BI enc_tos " NUMBER"
+.TQ
+.BI enc_ttl " NUMBER"
Match on IP tunnel metadata. Key id
.I NUMBER
is a 32 bit tunnel key id (e.g. VNI for VXLAN tunnel).
@@ -260,7 +268,11 @@ must be a valid IPv4 or IPv6 address optionally followed by a slash and the
prefix length. If the prefix is missing, \fBtc\fR assumes a full-length
host match. Dst port
.I NUMBER
-is a 16 bit UDP dst port.
+is a 16 bit UDP dst port. Tos
+.I NUMBER
+is an 8 bit tos (dscp+ecn) value, ttl
+.I NUMBER
+is an 8 bit time-to-live value.
.TP
.BI ip_flags " IP_FLAGS"
.I IP_FLAGS
diff --git a/tc/f_flower.c b/tc/f_flower.c
index 1dfd57d..cd102f2 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -74,6 +74,8 @@ static void explain(void)
" enc_dst_ip [ IPV4-ADDR | IPV6-ADDR ] |\n"
" enc_src_ip [ IPV4-ADDR | IPV6-ADDR ] |\n"
" enc_key_id [ KEY-ID ] |\n"
+ " enc_tos MASKED-IP_TOS |\n"
+ " enc_ttl MASKED-IP_TTL |\n"
" ip_flags IP-FLAGS | \n"
" enc_dst_port [ port_number ] }\n"
" FILTERID := X:Y:Z\n"
@@ -972,6 +974,26 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
fprintf(stderr, "Illegal \"enc_dst_port\"\n");
return -1;
}
+ } else if (matches(*argv, "enc_tos") == 0) {
+ NEXT_ARG();
+ ret = flower_parse_ip_tos_ttl(*argv,
+ TCA_FLOWER_KEY_ENC_IP_TOS,
+ TCA_FLOWER_KEY_ENC_IP_TOS_MASK,
+ n);
+ if (ret < 0) {
+ fprintf(stderr, "Illegal \"enc_tos\"\n");
+ return -1;
+ }
+ } else if (matches(*argv, "enc_ttl") == 0) {
+ NEXT_ARG();
+ ret = flower_parse_ip_tos_ttl(*argv,
+ TCA_FLOWER_KEY_ENC_IP_TTL,
+ TCA_FLOWER_KEY_ENC_IP_TTL_MASK,
+ n);
+ if (ret < 0) {
+ fprintf(stderr, "Illegal \"enc_ttl\"\n");
+ return -1;
+ }
} else if (matches(*argv, "action") == 0) {
NEXT_ARG();
ret = parse_action(&argc, &argv, TCA_FLOWER_ACT, n);
@@ -1463,6 +1485,11 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
flower_print_port("enc_dst_port", tb[TCA_FLOWER_KEY_ENC_UDP_DST_PORT]);
+ flower_print_ip_attr("enc_tos", tb[TCA_FLOWER_KEY_ENC_IP_TOS],
+ tb[TCA_FLOWER_KEY_ENC_IP_TOS_MASK]);
+ flower_print_ip_attr("enc_ttl", tb[TCA_FLOWER_KEY_ENC_IP_TTL],
+ tb[TCA_FLOWER_KEY_ENC_IP_TTL_MASK]);
+
flower_print_matching_flags("ip_flags", FLOWER_IP_FLAGS,
tb[TCA_FLOWER_KEY_FLAGS],
tb[TCA_FLOWER_KEY_FLAGS_MASK]);
--
1.8.3.1

View File

@ -1,668 +0,0 @@
From 7bd1daafe80ecd7e7419616fabadfe41c6e4fe7a Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 13 Sep 2018 21:29:59 +0200
Subject: [PATCH] Update kernel headers
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1615915
Upstream Status: RHEL-only
This updates include/uapi/linux to the state of upstream commit
761ec9e29ff867452057f59dc6ca430688b409ea.
---
include/uapi/linux/bpf.h | 9 +-
include/uapi/linux/btf.h | 113 +++++++++++++++++++++++++
include/uapi/linux/devlink.h | 42 ++++++++++
include/uapi/linux/if_link.h | 4 +
include/uapi/linux/ila.h | 1 +
include/uapi/linux/pkt_cls.h | 9 ++
include/uapi/linux/pkt_sched.h | 135 ++++++++++++++++++++++++++++++
include/uapi/linux/sctp.h | 5 ++
include/uapi/linux/tc_act/tc_pedit.h | 9 +-
include/uapi/linux/tc_act/tc_skbedit.h | 2 +
include/uapi/linux/tc_act/tc_tunnel_key.h | 28 +++++++
include/uapi/linux/tcp.h | 4 -
include/uapi/linux/tipc_netlink.h | 14 ++++
13 files changed, 365 insertions(+), 10 deletions(-)
create mode 100644 include/uapi/linux/btf.h
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 57e7390..b9a6367 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -1826,7 +1826,7 @@ union bpf_attr {
* A non-negative value equal to or less than *size* on success,
* or a negative error in case of failure.
*
- * int skb_load_bytes_relative(const struct sk_buff *skb, u32 offset, void *to, u32 len, u32 start_header)
+ * int bpf_skb_load_bytes_relative(const struct sk_buff *skb, u32 offset, void *to, u32 len, u32 start_header)
* Description
* This helper is similar to **bpf_skb_load_bytes**\ () in that
* it provides an easy way to load *len* bytes from *offset*
@@ -1877,7 +1877,7 @@ union bpf_attr {
* * < 0 if any input argument is invalid
* * 0 on success (packet is forwarded, nexthop neighbor exists)
* * > 0 one of **BPF_FIB_LKUP_RET_** codes explaining why the
- * * packet is not forwarded or needs assist from full stack
+ * packet is not forwarded or needs assist from full stack
*
* int bpf_sock_hash_update(struct bpf_sock_ops_kern *skops, struct bpf_map *map, void *key, u64 flags)
* Description
@@ -2033,7 +2033,6 @@ union bpf_attr {
* This helper is only available is the kernel was compiled with
* the **CONFIG_BPF_LIRC_MODE2** configuration option set to
* "**y**".
- *
* Return
* 0
*
@@ -2053,7 +2052,6 @@ union bpf_attr {
* This helper is only available is the kernel was compiled with
* the **CONFIG_BPF_LIRC_MODE2** configuration option set to
* "**y**".
- *
* Return
* 0
*
@@ -2557,6 +2555,9 @@ enum {
* Arg1: old_state
* Arg2: new_state
*/
+ BPF_SOCK_OPS_TCP_LISTEN_CB, /* Called on listen(2), right after
+ * socket transition to LISTEN state.
+ */
};
/* List of TCP states. There is a build check in net/ipv4/tcp.c to detect
diff --git a/include/uapi/linux/btf.h b/include/uapi/linux/btf.h
new file mode 100644
index 0000000..5dd580a
--- /dev/null
+++ b/include/uapi/linux/btf.h
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/* Copyright (c) 2018 Facebook */
+#ifndef __LINUX_BTF_H__
+#define __LINUX_BTF_H__
+
+#include <linux/types.h>
+
+#define BTF_MAGIC 0xeB9F
+#define BTF_VERSION 1
+
+struct btf_header {
+ __u16 magic;
+ __u8 version;
+ __u8 flags;
+ __u32 hdr_len;
+
+ /* All offsets are in bytes relative to the end of this header */
+ __u32 type_off; /* offset of type section */
+ __u32 type_len; /* length of type section */
+ __u32 str_off; /* offset of string section */
+ __u32 str_len; /* length of string section */
+};
+
+/* Max # of type identifier */
+#define BTF_MAX_TYPE 0x0000ffff
+/* Max offset into the string section */
+#define BTF_MAX_NAME_OFFSET 0x0000ffff
+/* Max # of struct/union/enum members or func args */
+#define BTF_MAX_VLEN 0xffff
+
+struct btf_type {
+ __u32 name_off;
+ /* "info" bits arrangement
+ * bits 0-15: vlen (e.g. # of struct's members)
+ * bits 16-23: unused
+ * bits 24-27: kind (e.g. int, ptr, array...etc)
+ * bits 28-31: unused
+ */
+ __u32 info;
+ /* "size" is used by INT, ENUM, STRUCT and UNION.
+ * "size" tells the size of the type it is describing.
+ *
+ * "type" is used by PTR, TYPEDEF, VOLATILE, CONST and RESTRICT.
+ * "type" is a type_id referring to another type.
+ */
+ union {
+ __u32 size;
+ __u32 type;
+ };
+};
+
+#define BTF_INFO_KIND(info) (((info) >> 24) & 0x0f)
+#define BTF_INFO_VLEN(info) ((info) & 0xffff)
+
+#define BTF_KIND_UNKN 0 /* Unknown */
+#define BTF_KIND_INT 1 /* Integer */
+#define BTF_KIND_PTR 2 /* Pointer */
+#define BTF_KIND_ARRAY 3 /* Array */
+#define BTF_KIND_STRUCT 4 /* Struct */
+#define BTF_KIND_UNION 5 /* Union */
+#define BTF_KIND_ENUM 6 /* Enumeration */
+#define BTF_KIND_FWD 7 /* Forward */
+#define BTF_KIND_TYPEDEF 8 /* Typedef */
+#define BTF_KIND_VOLATILE 9 /* Volatile */
+#define BTF_KIND_CONST 10 /* Const */
+#define BTF_KIND_RESTRICT 11 /* Restrict */
+#define BTF_KIND_MAX 11
+#define NR_BTF_KINDS 12
+
+/* For some specific BTF_KIND, "struct btf_type" is immediately
+ * followed by extra data.
+ */
+
+/* BTF_KIND_INT is followed by a u32 and the following
+ * is the 32 bits arrangement:
+ */
+#define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24)
+#define BTF_INT_OFFSET(VAL) (((VAL & 0x00ff0000)) >> 16)
+#define BTF_INT_BITS(VAL) ((VAL) & 0x0000ffff)
+
+/* Attributes stored in the BTF_INT_ENCODING */
+#define BTF_INT_SIGNED (1 << 0)
+#define BTF_INT_CHAR (1 << 1)
+#define BTF_INT_BOOL (1 << 2)
+
+/* BTF_KIND_ENUM is followed by multiple "struct btf_enum".
+ * The exact number of btf_enum is stored in the vlen (of the
+ * info in "struct btf_type").
+ */
+struct btf_enum {
+ __u32 name_off;
+ __s32 val;
+};
+
+/* BTF_KIND_ARRAY is followed by one "struct btf_array" */
+struct btf_array {
+ __u32 type;
+ __u32 index_type;
+ __u32 nelems;
+};
+
+/* BTF_KIND_STRUCT and BTF_KIND_UNION are followed
+ * by multiple "struct btf_member". The exact number
+ * of btf_member is stored in the vlen (of the info in
+ * "struct btf_type").
+ */
+struct btf_member {
+ __u32 name_off;
+ __u32 type;
+ __u32 offset; /* offset in bits */
+};
+
+#endif /* __LINUX_BTF_H__ */
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index 493f71f..5ee0e73 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -78,6 +78,17 @@ enum devlink_command {
*/
DEVLINK_CMD_RELOAD,
+ DEVLINK_CMD_PARAM_GET, /* can dump */
+ DEVLINK_CMD_PARAM_SET,
+ DEVLINK_CMD_PARAM_NEW,
+ DEVLINK_CMD_PARAM_DEL,
+
+ DEVLINK_CMD_REGION_GET,
+ DEVLINK_CMD_REGION_SET,
+ DEVLINK_CMD_REGION_NEW,
+ DEVLINK_CMD_REGION_DEL,
+ DEVLINK_CMD_REGION_READ,
+
/* add new commands above here */
__DEVLINK_CMD_MAX,
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
@@ -142,6 +153,16 @@ enum devlink_port_flavour {
*/
};
+enum devlink_param_cmode {
+ DEVLINK_PARAM_CMODE_RUNTIME,
+ DEVLINK_PARAM_CMODE_DRIVERINIT,
+ DEVLINK_PARAM_CMODE_PERMANENT,
+
+ /* Add new configuration modes above */
+ __DEVLINK_PARAM_CMODE_MAX,
+ DEVLINK_PARAM_CMODE_MAX = __DEVLINK_PARAM_CMODE_MAX - 1
+};
+
enum devlink_attr {
/* don't change the order or add anything between, this is ABI! */
DEVLINK_ATTR_UNSPEC,
@@ -238,6 +259,27 @@ enum devlink_attr {
DEVLINK_ATTR_PORT_NUMBER, /* u32 */
DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER, /* u32 */
+ DEVLINK_ATTR_PARAM, /* nested */
+ DEVLINK_ATTR_PARAM_NAME, /* string */
+ DEVLINK_ATTR_PARAM_GENERIC, /* flag */
+ DEVLINK_ATTR_PARAM_TYPE, /* u8 */
+ DEVLINK_ATTR_PARAM_VALUES_LIST, /* nested */
+ DEVLINK_ATTR_PARAM_VALUE, /* nested */
+ DEVLINK_ATTR_PARAM_VALUE_DATA, /* dynamic */
+ DEVLINK_ATTR_PARAM_VALUE_CMODE, /* u8 */
+
+ DEVLINK_ATTR_REGION_NAME, /* string */
+ DEVLINK_ATTR_REGION_SIZE, /* u64 */
+ DEVLINK_ATTR_REGION_SNAPSHOTS, /* nested */
+ DEVLINK_ATTR_REGION_SNAPSHOT, /* nested */
+ DEVLINK_ATTR_REGION_SNAPSHOT_ID, /* u32 */
+
+ DEVLINK_ATTR_REGION_CHUNKS, /* nested */
+ DEVLINK_ATTR_REGION_CHUNK, /* nested */
+ DEVLINK_ATTR_REGION_CHUNK_DATA, /* binary */
+ DEVLINK_ATTR_REGION_CHUNK_ADDR, /* u64 */
+ DEVLINK_ATTR_REGION_CHUNK_LEN, /* u64 */
+
/* add new attributes above here, update the policy in devlink.c */
__DEVLINK_ATTR_MAX,
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 4eccc7f..1c64ed4 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -918,6 +918,7 @@ enum {
XDP_ATTACHED_DRV,
XDP_ATTACHED_SKB,
XDP_ATTACHED_HW,
+ XDP_ATTACHED_MULTI,
};
enum {
@@ -926,6 +927,9 @@ enum {
IFLA_XDP_ATTACHED,
IFLA_XDP_FLAGS,
IFLA_XDP_PROG_ID,
+ IFLA_XDP_DRV_PROG_ID,
+ IFLA_XDP_SKB_PROG_ID,
+ IFLA_XDP_HW_PROG_ID,
__IFLA_XDP_MAX,
};
diff --git a/include/uapi/linux/ila.h b/include/uapi/linux/ila.h
index 666292c..6a6c97c 100644
--- a/include/uapi/linux/ila.h
+++ b/include/uapi/linux/ila.h
@@ -30,6 +30,7 @@ enum {
ILA_CMD_ADD,
ILA_CMD_DEL,
ILA_CMD_GET,
+ ILA_CMD_FLUSH,
__ILA_CMD_MAX,
};
diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index 84e4c1d..b451225 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -469,6 +469,15 @@ enum {
TCA_FLOWER_KEY_IP_TTL, /* u8 */
TCA_FLOWER_KEY_IP_TTL_MASK, /* u8 */
+ TCA_FLOWER_KEY_CVLAN_ID, /* be16 */
+ TCA_FLOWER_KEY_CVLAN_PRIO, /* u8 */
+ TCA_FLOWER_KEY_CVLAN_ETH_TYPE, /* be16 */
+
+ TCA_FLOWER_KEY_ENC_IP_TOS, /* u8 */
+ TCA_FLOWER_KEY_ENC_IP_TOS_MASK, /* u8 */
+ TCA_FLOWER_KEY_ENC_IP_TTL, /* u8 */
+ TCA_FLOWER_KEY_ENC_IP_TTL_MASK, /* u8 */
+
__TCA_FLOWER_MAX,
};
diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h
index 37b5096..d9cc9dc 100644
--- a/include/uapi/linux/pkt_sched.h
+++ b/include/uapi/linux/pkt_sched.h
@@ -539,6 +539,7 @@ enum {
TCA_NETEM_LATENCY64,
TCA_NETEM_JITTER64,
TCA_NETEM_SLOT,
+ TCA_NETEM_SLOT_DIST,
__TCA_NETEM_MAX,
};
@@ -581,6 +582,8 @@ struct tc_netem_slot {
__s64 max_delay;
__s32 max_packets;
__s32 max_bytes;
+ __s64 dist_delay; /* nsec */
+ __s64 dist_jitter; /* nsec */
};
enum {
@@ -934,4 +937,136 @@ enum {
#define TCA_CBS_MAX (__TCA_CBS_MAX - 1)
+
+/* ETF */
+struct tc_etf_qopt {
+ __s32 delta;
+ __s32 clockid;
+ __u32 flags;
+#define TC_ETF_DEADLINE_MODE_ON BIT(0)
+#define TC_ETF_OFFLOAD_ON BIT(1)
+};
+
+enum {
+ TCA_ETF_UNSPEC,
+ TCA_ETF_PARMS,
+ __TCA_ETF_MAX,
+};
+
+#define TCA_ETF_MAX (__TCA_ETF_MAX - 1)
+
+
+/* CAKE */
+enum {
+ TCA_CAKE_UNSPEC,
+ TCA_CAKE_PAD,
+ TCA_CAKE_BASE_RATE64,
+ TCA_CAKE_DIFFSERV_MODE,
+ TCA_CAKE_ATM,
+ TCA_CAKE_FLOW_MODE,
+ TCA_CAKE_OVERHEAD,
+ TCA_CAKE_RTT,
+ TCA_CAKE_TARGET,
+ TCA_CAKE_AUTORATE,
+ TCA_CAKE_MEMORY,
+ TCA_CAKE_NAT,
+ TCA_CAKE_RAW,
+ TCA_CAKE_WASH,
+ TCA_CAKE_MPU,
+ TCA_CAKE_INGRESS,
+ TCA_CAKE_ACK_FILTER,
+ TCA_CAKE_SPLIT_GSO,
+ __TCA_CAKE_MAX
+};
+#define TCA_CAKE_MAX (__TCA_CAKE_MAX - 1)
+
+enum {
+ __TCA_CAKE_STATS_INVALID,
+ TCA_CAKE_STATS_PAD,
+ TCA_CAKE_STATS_CAPACITY_ESTIMATE64,
+ TCA_CAKE_STATS_MEMORY_LIMIT,
+ TCA_CAKE_STATS_MEMORY_USED,
+ TCA_CAKE_STATS_AVG_NETOFF,
+ TCA_CAKE_STATS_MIN_NETLEN,
+ TCA_CAKE_STATS_MAX_NETLEN,
+ TCA_CAKE_STATS_MIN_ADJLEN,
+ TCA_CAKE_STATS_MAX_ADJLEN,
+ TCA_CAKE_STATS_TIN_STATS,
+ TCA_CAKE_STATS_DEFICIT,
+ TCA_CAKE_STATS_COBALT_COUNT,
+ TCA_CAKE_STATS_DROPPING,
+ TCA_CAKE_STATS_DROP_NEXT_US,
+ TCA_CAKE_STATS_P_DROP,
+ TCA_CAKE_STATS_BLUE_TIMER_US,
+ __TCA_CAKE_STATS_MAX
+};
+#define TCA_CAKE_STATS_MAX (__TCA_CAKE_STATS_MAX - 1)
+
+enum {
+ __TCA_CAKE_TIN_STATS_INVALID,
+ TCA_CAKE_TIN_STATS_PAD,
+ TCA_CAKE_TIN_STATS_SENT_PACKETS,
+ TCA_CAKE_TIN_STATS_SENT_BYTES64,
+ TCA_CAKE_TIN_STATS_DROPPED_PACKETS,
+ TCA_CAKE_TIN_STATS_DROPPED_BYTES64,
+ TCA_CAKE_TIN_STATS_ACKS_DROPPED_PACKETS,
+ TCA_CAKE_TIN_STATS_ACKS_DROPPED_BYTES64,
+ TCA_CAKE_TIN_STATS_ECN_MARKED_PACKETS,
+ TCA_CAKE_TIN_STATS_ECN_MARKED_BYTES64,
+ TCA_CAKE_TIN_STATS_BACKLOG_PACKETS,
+ TCA_CAKE_TIN_STATS_BACKLOG_BYTES,
+ TCA_CAKE_TIN_STATS_THRESHOLD_RATE64,
+ TCA_CAKE_TIN_STATS_TARGET_US,
+ TCA_CAKE_TIN_STATS_INTERVAL_US,
+ TCA_CAKE_TIN_STATS_WAY_INDIRECT_HITS,
+ TCA_CAKE_TIN_STATS_WAY_MISSES,
+ TCA_CAKE_TIN_STATS_WAY_COLLISIONS,
+ TCA_CAKE_TIN_STATS_PEAK_DELAY_US,
+ TCA_CAKE_TIN_STATS_AVG_DELAY_US,
+ TCA_CAKE_TIN_STATS_BASE_DELAY_US,
+ TCA_CAKE_TIN_STATS_SPARSE_FLOWS,
+ TCA_CAKE_TIN_STATS_BULK_FLOWS,
+ TCA_CAKE_TIN_STATS_UNRESPONSIVE_FLOWS,
+ TCA_CAKE_TIN_STATS_MAX_SKBLEN,
+ TCA_CAKE_TIN_STATS_FLOW_QUANTUM,
+ __TCA_CAKE_TIN_STATS_MAX
+};
+#define TCA_CAKE_TIN_STATS_MAX (__TCA_CAKE_TIN_STATS_MAX - 1)
+#define TC_CAKE_MAX_TINS (8)
+
+enum {
+ CAKE_FLOW_NONE = 0,
+ CAKE_FLOW_SRC_IP,
+ CAKE_FLOW_DST_IP,
+ CAKE_FLOW_HOSTS, /* = CAKE_FLOW_SRC_IP | CAKE_FLOW_DST_IP */
+ CAKE_FLOW_FLOWS,
+ CAKE_FLOW_DUAL_SRC, /* = CAKE_FLOW_SRC_IP | CAKE_FLOW_FLOWS */
+ CAKE_FLOW_DUAL_DST, /* = CAKE_FLOW_DST_IP | CAKE_FLOW_FLOWS */
+ CAKE_FLOW_TRIPLE, /* = CAKE_FLOW_HOSTS | CAKE_FLOW_FLOWS */
+ CAKE_FLOW_MAX,
+};
+
+enum {
+ CAKE_DIFFSERV_DIFFSERV3 = 0,
+ CAKE_DIFFSERV_DIFFSERV4,
+ CAKE_DIFFSERV_DIFFSERV8,
+ CAKE_DIFFSERV_BESTEFFORT,
+ CAKE_DIFFSERV_PRECEDENCE,
+ CAKE_DIFFSERV_MAX
+};
+
+enum {
+ CAKE_ACK_NONE = 0,
+ CAKE_ACK_FILTER,
+ CAKE_ACK_AGGRESSIVE,
+ CAKE_ACK_MAX
+};
+
+enum {
+ CAKE_ATM_NONE = 0,
+ CAKE_ATM_ATM,
+ CAKE_ATM_PTM,
+ CAKE_ATM_MAX
+};
+
#endif
diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
index 2d95ddc..dd164d7 100644
--- a/include/uapi/linux/sctp.h
+++ b/include/uapi/linux/sctp.h
@@ -100,6 +100,7 @@ typedef __s32 sctp_assoc_t;
#define SCTP_RECVNXTINFO 33
#define SCTP_DEFAULT_SNDINFO 34
#define SCTP_AUTH_DEACTIVATE_KEY 35
+#define SCTP_REUSE_PORT 36
/* Internal Socket Options. Some of the sctp library functions are
* implemented using these socket options.
@@ -762,6 +763,8 @@ enum sctp_spp_flags {
SPP_SACKDELAY_DISABLE = 1<<6, /*Disable SACK*/
SPP_SACKDELAY = SPP_SACKDELAY_ENABLE | SPP_SACKDELAY_DISABLE,
SPP_HB_TIME_IS_ZERO = 1<<7, /* Set HB delay to 0 */
+ SPP_IPV6_FLOWLABEL = 1<<8,
+ SPP_DSCP = 1<<9,
};
struct sctp_paddrparams {
@@ -772,6 +775,8 @@ struct sctp_paddrparams {
__u32 spp_pathmtu;
__u32 spp_sackdelay;
__u32 spp_flags;
+ __u32 spp_ipv6_flowlabel;
+ __u8 spp_dscp;
} __attribute__((packed, aligned(4)));
/*
diff --git a/include/uapi/linux/tc_act/tc_pedit.h b/include/uapi/linux/tc_act/tc_pedit.h
index 162d109..24ec792 100644
--- a/include/uapi/linux/tc_act/tc_pedit.h
+++ b/include/uapi/linux/tc_act/tc_pedit.h
@@ -17,13 +17,15 @@ enum {
TCA_PEDIT_KEY_EX,
__TCA_PEDIT_MAX
};
+
#define TCA_PEDIT_MAX (__TCA_PEDIT_MAX - 1)
-
+
enum {
TCA_PEDIT_KEY_EX_HTYPE = 1,
TCA_PEDIT_KEY_EX_CMD = 2,
__TCA_PEDIT_KEY_EX_MAX
};
+
#define TCA_PEDIT_KEY_EX_MAX (__TCA_PEDIT_KEY_EX_MAX - 1)
/* TCA_PEDIT_KEY_EX_HDR_TYPE_NETWROK is a special case for legacy users. It
@@ -38,6 +40,7 @@ enum pedit_header_type {
TCA_PEDIT_KEY_EX_HDR_TYPE_UDP = 5,
__PEDIT_HDR_TYPE_MAX,
};
+
#define TCA_PEDIT_HDR_TYPE_MAX (__PEDIT_HDR_TYPE_MAX - 1)
enum pedit_cmd {
@@ -45,6 +48,7 @@ enum pedit_cmd {
TCA_PEDIT_KEY_EX_CMD_ADD = 1,
__PEDIT_CMD_MAX,
};
+
#define TCA_PEDIT_CMD_MAX (__PEDIT_CMD_MAX - 1)
struct tc_pedit_key {
@@ -55,13 +59,14 @@ struct tc_pedit_key {
__u32 offmask;
__u32 shift;
};
-
+
struct tc_pedit_sel {
tc_gen;
unsigned char nkeys;
unsigned char flags;
struct tc_pedit_key keys[0];
};
+
#define tc_pedit tc_pedit_sel
#endif
diff --git a/include/uapi/linux/tc_act/tc_skbedit.h b/include/uapi/linux/tc_act/tc_skbedit.h
index fbcfe27..6de6071 100644
--- a/include/uapi/linux/tc_act/tc_skbedit.h
+++ b/include/uapi/linux/tc_act/tc_skbedit.h
@@ -30,6 +30,7 @@
#define SKBEDIT_F_MARK 0x4
#define SKBEDIT_F_PTYPE 0x8
#define SKBEDIT_F_MASK 0x10
+#define SKBEDIT_F_INHERITDSFIELD 0x20
struct tc_skbedit {
tc_gen;
@@ -45,6 +46,7 @@ enum {
TCA_SKBEDIT_PAD,
TCA_SKBEDIT_PTYPE,
TCA_SKBEDIT_MASK,
+ TCA_SKBEDIT_FLAGS,
__TCA_SKBEDIT_MAX
};
#define TCA_SKBEDIT_MAX (__TCA_SKBEDIT_MAX - 1)
diff --git a/include/uapi/linux/tc_act/tc_tunnel_key.h b/include/uapi/linux/tc_act/tc_tunnel_key.h
index 72bbefe..be384d6 100644
--- a/include/uapi/linux/tc_act/tc_tunnel_key.h
+++ b/include/uapi/linux/tc_act/tc_tunnel_key.h
@@ -36,9 +36,37 @@ enum {
TCA_TUNNEL_KEY_PAD,
TCA_TUNNEL_KEY_ENC_DST_PORT, /* be16 */
TCA_TUNNEL_KEY_NO_CSUM, /* u8 */
+ TCA_TUNNEL_KEY_ENC_OPTS, /* Nested TCA_TUNNEL_KEY_ENC_OPTS_
+ * attributes
+ */
+ TCA_TUNNEL_KEY_ENC_TOS, /* u8 */
+ TCA_TUNNEL_KEY_ENC_TTL, /* u8 */
__TCA_TUNNEL_KEY_MAX,
};
#define TCA_TUNNEL_KEY_MAX (__TCA_TUNNEL_KEY_MAX - 1)
+enum {
+ TCA_TUNNEL_KEY_ENC_OPTS_UNSPEC,
+ TCA_TUNNEL_KEY_ENC_OPTS_GENEVE, /* Nested
+ * TCA_TUNNEL_KEY_ENC_OPTS_
+ * attributes
+ */
+ __TCA_TUNNEL_KEY_ENC_OPTS_MAX,
+};
+
+#define TCA_TUNNEL_KEY_ENC_OPTS_MAX (__TCA_TUNNEL_KEY_ENC_OPTS_MAX - 1)
+
+enum {
+ TCA_TUNNEL_KEY_ENC_OPT_GENEVE_UNSPEC,
+ TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS, /* be16 */
+ TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE, /* u8 */
+ TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA, /* 4 to 128 bytes */
+
+ __TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX,
+};
+
+#define TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX \
+ (__TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX - 1)
+
#endif
diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h
index 99e329b..2e766cf 100644
--- a/include/uapi/linux/tcp.h
+++ b/include/uapi/linux/tcp.h
@@ -127,10 +127,6 @@ enum {
#define TCP_CM_INQ TCP_INQ
-#define TCP_REPAIR_ON 1
-#define TCP_REPAIR_OFF 0
-#define TCP_REPAIR_OFF_NO_WP -1 /* Turn off without window probes */
-
struct tcp_repair_opt {
__u32 opt_code;
__u32 opt_val;
diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h
index 85c1198..0ebe02e 100644
--- a/include/uapi/linux/tipc_netlink.h
+++ b/include/uapi/linux/tipc_netlink.h
@@ -121,6 +121,7 @@ enum {
TIPC_NLA_SOCK_TIPC_STATE, /* u32 */
TIPC_NLA_SOCK_COOKIE, /* u64 */
TIPC_NLA_SOCK_PAD, /* flag */
+ TIPC_NLA_SOCK_GROUP, /* nest */
__TIPC_NLA_SOCK_MAX,
TIPC_NLA_SOCK_MAX = __TIPC_NLA_SOCK_MAX - 1
@@ -233,6 +234,19 @@ enum {
TIPC_NLA_MON_PEER_MAX = __TIPC_NLA_MON_PEER_MAX - 1
};
+/* Nest, socket group info */
+enum {
+ TIPC_NLA_SOCK_GROUP_ID, /* u32 */
+ TIPC_NLA_SOCK_GROUP_OPEN, /* flag */
+ TIPC_NLA_SOCK_GROUP_NODE_SCOPE, /* flag */
+ TIPC_NLA_SOCK_GROUP_CLUSTER_SCOPE, /* flag */
+ TIPC_NLA_SOCK_GROUP_INSTANCE, /* u32 */
+ TIPC_NLA_SOCK_GROUP_BC_SEND_NEXT, /* u32 */
+
+ __TIPC_NLA_SOCK_GROUP_MAX,
+ TIPC_NLA_SOCK_GROUP_MAX = __TIPC_NLA_SOCK_GROUP_MAX - 1
+};
+
/* Nest, connection info */
enum {
TIPC_NLA_CON_UNSPEC,
--
1.8.3.1

View File

@ -1,529 +0,0 @@
From 4620f13fc0f0e344421c0b9a0b8747734d3caf00 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Wed, 19 Sep 2018 19:59:54 +0200
Subject: [PATCH] ip-route: Fix segfault with many nexthops
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1625358
Upstream Status: iproute2.git commit bd59e5b1517b0
commit bd59e5b1517b09b6f26d59f38fe6077d953c2396
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Sep 6 15:31:51 2018 +0200
ip-route: Fix segfault with many nexthops
It was possible to crash ip-route by adding an IPv6 route with 37
nexthop statements. A simple reproducer is:
| for i in `seq 37`; do
| nhs="nexthop via 1111::$i "$nhs
| done
| ip -6 route add 3333::/64 $nhs
The related code was broken in multiple ways:
* parse_one_nh() assumed that rta points to 4kB of storage but caller
provided just 1kB. Fixed by passing 'len' parameter with the correct
value.
* Error checking of rta_addattr*() calls in parse_one_nh() and called
functions was completely absent, so with above fix in place output
flood would occur due to parser looping forever.
While being at it, increase message buffer sizes to 4k. This allows for
at most 144 nexthops.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/iproute.c | 43 ++++++++++++--------
ip/iproute_lwtunnel.c | 108 ++++++++++++++++++++++++++++++--------------------
2 files changed, 91 insertions(+), 60 deletions(-)
diff --git a/ip/iproute.c b/ip/iproute.c
index 3083341..398322f 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -941,7 +941,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
}
static int parse_one_nh(struct nlmsghdr *n, struct rtmsg *r,
- struct rtattr *rta, struct rtnexthop *rtnh,
+ struct rtattr *rta, size_t len, struct rtnexthop *rtnh,
int *argcp, char ***argvp)
{
int argc = *argcp;
@@ -962,11 +962,16 @@ static int parse_one_nh(struct nlmsghdr *n, struct rtmsg *r,
if (r->rtm_family == AF_UNSPEC)
r->rtm_family = addr.family;
if (addr.family == r->rtm_family) {
- rta_addattr_l(rta, 4096, RTA_GATEWAY, &addr.data, addr.bytelen);
- rtnh->rtnh_len += sizeof(struct rtattr) + addr.bytelen;
+ if (rta_addattr_l(rta, len, RTA_GATEWAY,
+ &addr.data, addr.bytelen))
+ return -1;
+ rtnh->rtnh_len += sizeof(struct rtattr)
+ + addr.bytelen;
} else {
- rta_addattr_l(rta, 4096, RTA_VIA, &addr.family, addr.bytelen+2);
- rtnh->rtnh_len += RTA_SPACE(addr.bytelen+2);
+ if (rta_addattr_l(rta, len, RTA_VIA,
+ &addr.family, addr.bytelen + 2))
+ return -1;
+ rtnh->rtnh_len += RTA_SPACE(addr.bytelen + 2);
}
} else if (strcmp(*argv, "dev") == 0) {
NEXT_ARG();
@@ -988,13 +993,15 @@ static int parse_one_nh(struct nlmsghdr *n, struct rtmsg *r,
NEXT_ARG();
if (get_rt_realms_or_raw(&realm, *argv))
invarg("\"realm\" value is invalid\n", *argv);
- rta_addattr32(rta, 4096, RTA_FLOW, realm);
+ if (rta_addattr32(rta, len, RTA_FLOW, realm))
+ return -1;
rtnh->rtnh_len += sizeof(struct rtattr) + 4;
} else if (strcmp(*argv, "encap") == 0) {
- int len = rta->rta_len;
+ int old_len = rta->rta_len;
- lwt_parse_encap(rta, 4096, &argc, &argv);
- rtnh->rtnh_len += rta->rta_len - len;
+ if (lwt_parse_encap(rta, len, &argc, &argv))
+ return -1;
+ rtnh->rtnh_len += rta->rta_len - old_len;
} else if (strcmp(*argv, "as") == 0) {
inet_prefix addr;
@@ -1002,8 +1009,9 @@ static int parse_one_nh(struct nlmsghdr *n, struct rtmsg *r,
if (strcmp(*argv, "to") == 0)
NEXT_ARG();
get_addr(&addr, *argv, r->rtm_family);
- rta_addattr_l(rta, 4096, RTA_NEWDST, &addr.data,
- addr.bytelen);
+ if (rta_addattr_l(rta, len, RTA_NEWDST,
+ &addr.data, addr.bytelen))
+ return -1;
rtnh->rtnh_len += sizeof(struct rtattr) + addr.bytelen;
} else
break;
@@ -1016,7 +1024,7 @@ static int parse_one_nh(struct nlmsghdr *n, struct rtmsg *r,
static int parse_nexthops(struct nlmsghdr *n, struct rtmsg *r,
int argc, char **argv)
{
- char buf[1024];
+ char buf[4096];
struct rtattr *rta = (void *)buf;
struct rtnexthop *rtnh;
@@ -1036,7 +1044,7 @@ static int parse_nexthops(struct nlmsghdr *n, struct rtmsg *r,
memset(rtnh, 0, sizeof(*rtnh));
rtnh->rtnh_len = sizeof(*rtnh);
rta->rta_len += rtnh->rtnh_len;
- if (parse_one_nh(n, r, rta, rtnh, &argc, &argv)) {
+ if (parse_one_nh(n, r, rta, 4096, rtnh, &argc, &argv)) {
fprintf(stderr, "Error: cannot parse nexthop\n");
exit(-1);
}
@@ -1044,7 +1052,8 @@ static int parse_nexthops(struct nlmsghdr *n, struct rtmsg *r,
}
if (rta->rta_len > RTA_LENGTH(0))
- addattr_l(n, 1024, RTA_MULTIPATH, RTA_DATA(rta), RTA_PAYLOAD(rta));
+ return addattr_l(n, 4096, RTA_MULTIPATH,
+ RTA_DATA(rta), RTA_PAYLOAD(rta));
return 0;
}
@@ -1053,7 +1062,7 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv)
struct {
struct nlmsghdr n;
struct rtmsg r;
- char buf[1024];
+ char buf[4096];
} req = {
.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)),
.n.nlmsg_flags = NLM_F_REQUEST | flags,
@@ -1484,8 +1493,8 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv)
addattr_l(&req.n, sizeof(req), RTA_METRICS, RTA_DATA(mxrta), RTA_PAYLOAD(mxrta));
}
- if (nhs_ok)
- parse_nexthops(&req.n, &req.r, argc, argv);
+ if (nhs_ok && parse_nexthops(&req.n, &req.r, argc, argv))
+ return -1;
if (req.r.rtm_family == AF_UNSPEC)
req.r.rtm_family = AF_INET;
diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
index e604481..969a476 100644
--- a/ip/iproute_lwtunnel.c
+++ b/ip/iproute_lwtunnel.c
@@ -538,8 +538,9 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
memcpy(tuninfo->srh, srh, srhlen);
- rta_addattr_l(rta, len, SEG6_IPTUNNEL_SRH, tuninfo,
- sizeof(*tuninfo) + srhlen);
+ if (rta_addattr_l(rta, len, SEG6_IPTUNNEL_SRH, tuninfo,
+ sizeof(*tuninfo) + srhlen))
+ return -1;
free(tuninfo);
free(srh);
@@ -611,6 +612,7 @@ static int parse_encap_seg6local(struct rtattr *rta, size_t len, int *argcp,
char segbuf[1024];
inet_prefix addr;
__u32 hmac = 0;
+ int ret = 0;
while (argc > 0) {
if (strcmp(*argv, "action") == 0) {
@@ -620,27 +622,28 @@ static int parse_encap_seg6local(struct rtattr *rta, size_t len, int *argcp,
action = read_action_type(*argv);
if (!action)
invarg("\"action\" value is invalid\n", *argv);
- rta_addattr32(rta, len, SEG6_LOCAL_ACTION, action);
+ ret = rta_addattr32(rta, len, SEG6_LOCAL_ACTION,
+ action);
} else if (strcmp(*argv, "table") == 0) {
NEXT_ARG();
if (table_ok++)
duparg2("table", *argv);
get_u32(&table, *argv, 0);
- rta_addattr32(rta, len, SEG6_LOCAL_TABLE, table);
+ ret = rta_addattr32(rta, len, SEG6_LOCAL_TABLE, table);
} else if (strcmp(*argv, "nh4") == 0) {
NEXT_ARG();
if (nh4_ok++)
duparg2("nh4", *argv);
get_addr(&addr, *argv, AF_INET);
- rta_addattr_l(rta, len, SEG6_LOCAL_NH4, &addr.data,
- addr.bytelen);
+ ret = rta_addattr_l(rta, len, SEG6_LOCAL_NH4,
+ &addr.data, addr.bytelen);
} else if (strcmp(*argv, "nh6") == 0) {
NEXT_ARG();
if (nh6_ok++)
duparg2("nh6", *argv);
get_addr(&addr, *argv, AF_INET6);
- rta_addattr_l(rta, len, SEG6_LOCAL_NH6, &addr.data,
- addr.bytelen);
+ ret = rta_addattr_l(rta, len, SEG6_LOCAL_NH6,
+ &addr.data, addr.bytelen);
} else if (strcmp(*argv, "iif") == 0) {
NEXT_ARG();
if (iif_ok++)
@@ -648,7 +651,7 @@ static int parse_encap_seg6local(struct rtattr *rta, size_t len, int *argcp,
iif = ll_name_to_index(*argv);
if (!iif)
exit(nodev(*argv));
- rta_addattr32(rta, len, SEG6_LOCAL_IIF, iif);
+ ret = rta_addattr32(rta, len, SEG6_LOCAL_IIF, iif);
} else if (strcmp(*argv, "oif") == 0) {
NEXT_ARG();
if (oif_ok++)
@@ -656,7 +659,7 @@ static int parse_encap_seg6local(struct rtattr *rta, size_t len, int *argcp,
oif = ll_name_to_index(*argv);
if (!oif)
exit(nodev(*argv));
- rta_addattr32(rta, len, SEG6_LOCAL_OIF, oif);
+ ret = rta_addattr32(rta, len, SEG6_LOCAL_OIF, oif);
} else if (strcmp(*argv, "srh") == 0) {
NEXT_ARG();
if (srh_ok++)
@@ -691,6 +694,8 @@ static int parse_encap_seg6local(struct rtattr *rta, size_t len, int *argcp,
} else {
break;
}
+ if (ret)
+ return ret;
argc--; argv++;
}
@@ -705,14 +710,14 @@ static int parse_encap_seg6local(struct rtattr *rta, size_t len, int *argcp,
srh = parse_srh(segbuf, hmac,
action == SEG6_LOCAL_ACTION_END_B6_ENCAP);
srhlen = (srh->hdrlen + 1) << 3;
- rta_addattr_l(rta, len, SEG6_LOCAL_SRH, srh, srhlen);
+ ret = rta_addattr_l(rta, len, SEG6_LOCAL_SRH, srh, srhlen);
free(srh);
}
*argcp = argc + 1;
*argvp = argv - 1;
- return 0;
+ return ret;
}
static int parse_encap_mpls(struct rtattr *rta, size_t len,
@@ -730,8 +735,9 @@ static int parse_encap_mpls(struct rtattr *rta, size_t len,
exit(1);
}
- rta_addattr_l(rta, len, MPLS_IPTUNNEL_DST, &addr.data,
- addr.bytelen);
+ if (rta_addattr_l(rta, len, MPLS_IPTUNNEL_DST,
+ &addr.data, addr.bytelen))
+ return -1;
argc--;
argv++;
@@ -745,7 +751,8 @@ static int parse_encap_mpls(struct rtattr *rta, size_t len,
duparg2("ttl", *argv);
if (get_u8(&ttl, *argv, 0))
invarg("\"ttl\" value is invalid\n", *argv);
- rta_addattr8(rta, len, MPLS_IPTUNNEL_TTL, ttl);
+ if (rta_addattr8(rta, len, MPLS_IPTUNNEL_TTL, ttl))
+ return -1;
} else {
break;
}
@@ -768,6 +775,7 @@ static int parse_encap_ip(struct rtattr *rta, size_t len,
int id_ok = 0, dst_ok = 0, tos_ok = 0, ttl_ok = 0;
char **argv = *argvp;
int argc = *argcp;
+ int ret = 0;
while (argc > 0) {
if (strcmp(*argv, "id") == 0) {
@@ -778,7 +786,7 @@ static int parse_encap_ip(struct rtattr *rta, size_t len,
duparg2("id", *argv);
if (get_be64(&id, *argv, 0))
invarg("\"id\" value is invalid\n", *argv);
- rta_addattr64(rta, len, LWTUNNEL_IP_ID, id);
+ ret = rta_addattr64(rta, len, LWTUNNEL_IP_ID, id);
} else if (strcmp(*argv, "dst") == 0) {
inet_prefix addr;
@@ -786,8 +794,8 @@ static int parse_encap_ip(struct rtattr *rta, size_t len,
if (dst_ok++)
duparg2("dst", *argv);
get_addr(&addr, *argv, AF_INET);
- rta_addattr_l(rta, len, LWTUNNEL_IP_DST,
- &addr.data, addr.bytelen);
+ ret = rta_addattr_l(rta, len, LWTUNNEL_IP_DST,
+ &addr.data, addr.bytelen);
} else if (strcmp(*argv, "tos") == 0) {
__u32 tos;
@@ -796,7 +804,7 @@ static int parse_encap_ip(struct rtattr *rta, size_t len,
duparg2("tos", *argv);
if (rtnl_dsfield_a2n(&tos, *argv))
invarg("\"tos\" value is invalid\n", *argv);
- rta_addattr8(rta, len, LWTUNNEL_IP_TOS, tos);
+ ret = rta_addattr8(rta, len, LWTUNNEL_IP_TOS, tos);
} else if (strcmp(*argv, "ttl") == 0) {
__u8 ttl;
@@ -805,10 +813,12 @@ static int parse_encap_ip(struct rtattr *rta, size_t len,
duparg2("ttl", *argv);
if (get_u8(&ttl, *argv, 0))
invarg("\"ttl\" value is invalid\n", *argv);
- rta_addattr8(rta, len, LWTUNNEL_IP_TTL, ttl);
+ ret = rta_addattr8(rta, len, LWTUNNEL_IP_TTL, ttl);
} else {
break;
}
+ if (ret)
+ break;
argc--; argv++;
}
@@ -819,7 +829,7 @@ static int parse_encap_ip(struct rtattr *rta, size_t len,
*argcp = argc + 1;
*argvp = argv - 1;
- return 0;
+ return ret;
}
static int parse_encap_ila(struct rtattr *rta, size_t len,
@@ -828,6 +838,7 @@ static int parse_encap_ila(struct rtattr *rta, size_t len,
__u64 locator;
int argc = *argcp;
char **argv = *argvp;
+ int ret = 0;
if (get_addr64(&locator, *argv) < 0) {
fprintf(stderr, "Bad locator: %s\n", *argv);
@@ -836,7 +847,8 @@ static int parse_encap_ila(struct rtattr *rta, size_t len,
argc--; argv++;
- rta_addattr64(rta, 1024, ILA_ATTR_LOCATOR, locator);
+ if (rta_addattr64(rta, 1024, ILA_ATTR_LOCATOR, locator))
+ return -1;
while (argc > 0) {
if (strcmp(*argv, "csum-mode") == 0) {
@@ -849,8 +861,8 @@ static int parse_encap_ila(struct rtattr *rta, size_t len,
invarg("\"csum-mode\" value is invalid\n",
*argv);
- rta_addattr8(rta, 1024, ILA_ATTR_CSUM_MODE,
- (__u8)csum_mode);
+ ret = rta_addattr8(rta, 1024, ILA_ATTR_CSUM_MODE,
+ (__u8)csum_mode);
argc--; argv++;
} else if (strcmp(*argv, "ident-type") == 0) {
@@ -863,8 +875,8 @@ static int parse_encap_ila(struct rtattr *rta, size_t len,
invarg("\"ident-type\" value is invalid\n",
*argv);
- rta_addattr8(rta, 1024, ILA_ATTR_IDENT_TYPE,
- (__u8)ident_type);
+ ret = rta_addattr8(rta, 1024, ILA_ATTR_IDENT_TYPE,
+ (__u8)ident_type);
argc--; argv++;
} else if (strcmp(*argv, "hook-type") == 0) {
@@ -877,13 +889,15 @@ static int parse_encap_ila(struct rtattr *rta, size_t len,
invarg("\"hook-type\" value is invalid\n",
*argv);
- rta_addattr8(rta, 1024, ILA_ATTR_HOOK_TYPE,
- (__u8)hook_type);
+ ret = rta_addattr8(rta, 1024, ILA_ATTR_HOOK_TYPE,
+ (__u8)hook_type);
argc--; argv++;
} else {
break;
}
+ if (ret)
+ break;
}
/* argv is currently the first unparsed argument,
@@ -893,7 +907,7 @@ static int parse_encap_ila(struct rtattr *rta, size_t len,
*argcp = argc + 1;
*argvp = argv - 1;
- return 0;
+ return ret;
}
static int parse_encap_ip6(struct rtattr *rta, size_t len,
@@ -902,6 +916,7 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len,
int id_ok = 0, dst_ok = 0, tos_ok = 0, ttl_ok = 0;
char **argv = *argvp;
int argc = *argcp;
+ int ret = 0;
while (argc > 0) {
if (strcmp(*argv, "id") == 0) {
@@ -912,7 +927,7 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len,
duparg2("id", *argv);
if (get_be64(&id, *argv, 0))
invarg("\"id\" value is invalid\n", *argv);
- rta_addattr64(rta, len, LWTUNNEL_IP6_ID, id);
+ ret = rta_addattr64(rta, len, LWTUNNEL_IP6_ID, id);
} else if (strcmp(*argv, "dst") == 0) {
inet_prefix addr;
@@ -920,8 +935,8 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len,
if (dst_ok++)
duparg2("dst", *argv);
get_addr(&addr, *argv, AF_INET6);
- rta_addattr_l(rta, len, LWTUNNEL_IP6_DST,
- &addr.data, addr.bytelen);
+ ret = rta_addattr_l(rta, len, LWTUNNEL_IP6_DST,
+ &addr.data, addr.bytelen);
} else if (strcmp(*argv, "tc") == 0) {
__u32 tc;
@@ -930,7 +945,7 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len,
duparg2("tc", *argv);
if (rtnl_dsfield_a2n(&tc, *argv))
invarg("\"tc\" value is invalid\n", *argv);
- rta_addattr8(rta, len, LWTUNNEL_IP6_TC, tc);
+ ret = rta_addattr8(rta, len, LWTUNNEL_IP6_TC, tc);
} else if (strcmp(*argv, "hoplimit") == 0) {
__u8 hoplimit;
@@ -940,10 +955,13 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len,
if (get_u8(&hoplimit, *argv, 0))
invarg("\"hoplimit\" value is invalid\n",
*argv);
- rta_addattr8(rta, len, LWTUNNEL_IP6_HOPLIMIT, hoplimit);
+ ret = rta_addattr8(rta, len, LWTUNNEL_IP6_HOPLIMIT,
+ hoplimit);
} else {
break;
}
+ if (ret)
+ break;
argc--; argv++;
}
@@ -954,7 +972,7 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len,
*argcp = argc + 1;
*argvp = argv - 1;
- return 0;
+ return ret;
}
static void lwt_bpf_usage(void)
@@ -1021,6 +1039,7 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp)
int argc = *argcp;
char **argv = *argvp;
__u16 type;
+ int ret = 0;
NEXT_ARG();
type = read_encap_type(*argv);
@@ -1037,37 +1056,40 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp)
nest = rta_nest(rta, 1024, RTA_ENCAP);
switch (type) {
case LWTUNNEL_ENCAP_MPLS:
- parse_encap_mpls(rta, len, &argc, &argv);
+ ret = parse_encap_mpls(rta, len, &argc, &argv);
break;
case LWTUNNEL_ENCAP_IP:
- parse_encap_ip(rta, len, &argc, &argv);
+ ret = parse_encap_ip(rta, len, &argc, &argv);
break;
case LWTUNNEL_ENCAP_ILA:
- parse_encap_ila(rta, len, &argc, &argv);
+ ret = parse_encap_ila(rta, len, &argc, &argv);
break;
case LWTUNNEL_ENCAP_IP6:
- parse_encap_ip6(rta, len, &argc, &argv);
+ ret = parse_encap_ip6(rta, len, &argc, &argv);
break;
case LWTUNNEL_ENCAP_BPF:
if (parse_encap_bpf(rta, len, &argc, &argv) < 0)
exit(-1);
break;
case LWTUNNEL_ENCAP_SEG6:
- parse_encap_seg6(rta, len, &argc, &argv);
+ ret = parse_encap_seg6(rta, len, &argc, &argv);
break;
case LWTUNNEL_ENCAP_SEG6_LOCAL:
- parse_encap_seg6local(rta, len, &argc, &argv);
+ ret = parse_encap_seg6local(rta, len, &argc, &argv);
break;
default:
fprintf(stderr, "Error: unsupported encap type\n");
break;
}
+ if (ret)
+ return ret;
+
rta_nest_end(rta, nest);
- rta_addattr16(rta, 1024, RTA_ENCAP_TYPE, type);
+ ret = rta_addattr16(rta, 1024, RTA_ENCAP_TYPE, type);
*argcp = argc;
*argvp = argv;
- return 0;
+ return ret;
}
--
1.8.3.1

View File

@ -1,62 +0,0 @@
From e77e552d5814bf34ec65b8342875990c7f085edc Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Wed, 19 Sep 2018 20:00:42 +0200
Subject: [PATCH] bridge/mdb: fix missing new line when show bridge mdb
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1625500
Upstream Status: iproute2.git commit 92bba4ed4016a
commit 92bba4ed4016af3ce7f7071d3c37f2cb34f240f5
Author: Hangbin Liu <liuhangbin@gmail.com>
Date: Wed Sep 12 09:39:44 2018 +0800
bridge/mdb: fix missing new line when show bridge mdb
The bridge mdb show is broken on current iproute2. e.g.
]# bridge mdb show
34: br0 veth0_br 224.1.1.2 temp 34: br0 veth0_br 224.1.1.1 temp
After fix:
]# bridge mdb show
34: br0 veth0_br 224.1.1.2 temp
34: br0 veth0_br 224.1.1.1 temp
v2: Use json print lib as Stephen suggested.
v3: No need to use is_json_context() as print_string() could handle both cases.
v4: use new function print_nl() to print new line in non-json mode.
Reported-by: Ying Xu <yinxu@redhat.com>
Fixes: c7c1a1ef51aea ("bridge: colorize output and use JSON print library")
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
bridge/mdb.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/bridge/mdb.c b/bridge/mdb.c
index f38dc67..a7b7979 100644
--- a/bridge/mdb.c
+++ b/bridge/mdb.c
@@ -107,6 +107,10 @@ static void br_print_router_ports(FILE *f, struct rtattr *attr,
fprintf(f, "%s ", port_ifname);
}
}
+
+ if (!show_stats)
+ print_nl();
+
close_json_array(PRINT_JSON, NULL);
}
@@ -164,6 +168,8 @@ static void print_mdb_entry(FILE *f, int ifindex, const struct br_mdb_entry *e,
print_string(PRINT_ANY, "timer", " %s",
format_timer(timer));
}
+
+ print_nl();
close_json_object();
}
--
1.8.3.1

View File

@ -1,357 +0,0 @@
From 1934af7ac7bbd967f56d0cf5fa12ec0423bd5683 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Wed, 19 Sep 2018 20:23:03 +0200
Subject: [PATCH] lib: introduce print_nl
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1625500
Upstream Status: iproute2.git commit b85076cd74e77
commit b85076cd74e77538918d35992b1a9cd17ff86af8
Author: Stephen Hemminger <stephen@networkplumber.org>
Date: Tue Sep 11 08:29:33 2018 -0700
lib: introduce print_nl
Common pattern in iproute commands is to print a line seperator
in non-json mode. Make that a simple function.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
bridge/bridge.c | 1 -
include/json_print.h | 2 ++
ip/ip.c | 1 -
ip/ipaddress.c | 12 ++++++------
ip/ipila.c | 2 +-
ip/ipl2tp.c | 14 +++++++-------
ip/ipmacsec.c | 2 +-
ip/ipmaddr.c | 2 +-
ip/ipmroute.c | 2 +-
ip/ipntable.c | 16 ++++++++--------
lib/json_print.c | 7 +++++++
lib/utils.c | 1 +
tc/tc.c | 1 -
13 files changed, 35 insertions(+), 28 deletions(-)
diff --git a/bridge/bridge.c b/bridge/bridge.c
index 28e1381..7221c0b 100644
--- a/bridge/bridge.c
+++ b/bridge/bridge.c
@@ -30,7 +30,6 @@ int json;
int timestamp;
char *batch_file;
int force;
-const char *_SL_;
static void usage(void) __attribute__((noreturn));
diff --git a/include/json_print.h b/include/json_print.h
index 218fedc..78a6c83 100644
--- a/include/json_print.h
+++ b/include/json_print.h
@@ -41,6 +41,8 @@ void close_json_object(void);
void open_json_array(enum output_type type, const char *delim);
void close_json_array(enum output_type type, const char *delim);
+void print_nl(void);
+
#define _PRINT_FUNC(type_name, type) \
void print_color_##type_name(enum output_type t, \
enum color_attr color, \
diff --git a/ip/ip.c b/ip/ip.c
index bb964f3..2ca55e3 100644
--- a/ip/ip.c
+++ b/ip/ip.c
@@ -33,7 +33,6 @@ int oneline;
int brief;
int json;
int timestamp;
-const char *_SL_;
int force;
int max_flush_loops = 10;
int batch_mode;
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index b7b78f6..f315a81 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -240,7 +240,7 @@ static void print_linktype(FILE *fp, struct rtattr *tb)
const char *kind
= rta_getattr_str(linkinfo[IFLA_INFO_KIND]);
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
print_string(PRINT_ANY, "info_kind", " %s ", kind);
lu = get_link_kind(kind);
@@ -269,7 +269,7 @@ static void print_linktype(FILE *fp, struct rtattr *tb)
const char *slave_kind
= rta_getattr_str(linkinfo[IFLA_INFO_SLAVE_KIND]);
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
print_string(PRINT_ANY,
"info_slave_kind",
" %s_slave ",
@@ -749,7 +749,7 @@ static void print_link_stats(FILE *fp, struct nlmsghdr *n)
parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi),
n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)));
__print_link_stats(fp, tb);
- fprintf(fp, "%s", _SL_);
+ print_nl();
}
static int print_linkinfo_brief(FILE *fp, const char *name,
@@ -913,7 +913,7 @@ int print_linkinfo(const struct sockaddr_nl *who,
print_link_event(fp, rta_getattr_u32(tb[IFLA_EVENT]));
if (!filter.family || filter.family == AF_PACKET || show_details) {
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
print_string(PRINT_ANY,
"link_type",
" link/%s ",
@@ -1064,7 +1064,7 @@ int print_linkinfo(const struct sockaddr_nl *who,
xdp_dump(fp, tb[IFLA_XDP], true, true);
if (do_link && show_stats) {
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
__print_link_stats(fp, tb);
}
@@ -1392,7 +1392,7 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
if (rta_tb[IFA_CACHEINFO]) {
struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]);
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
print_string(PRINT_FP, NULL, " valid_lft ", NULL);
if (ci->ifa_valid == INFINITY_LIFE_TIME) {
diff --git a/ip/ipila.c b/ip/ipila.c
index 370385c..895fe0c 100644
--- a/ip/ipila.c
+++ b/ip/ipila.c
@@ -128,7 +128,7 @@ static int print_ila_mapping(const struct sockaddr_nl *who,
else
print_string(PRINT_FP, NULL, "%s", "-");
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
close_json_object();
return 0;
diff --git a/ip/ipl2tp.c b/ip/ipl2tp.c
index 05e9638..414a9eb 100644
--- a/ip/ipl2tp.c
+++ b/ip/ipl2tp.c
@@ -228,7 +228,7 @@ static void print_tunnel(const struct l2tp_data *data)
print_string(PRINT_ANY, "encap", " encap %s",
p->encap == L2TP_ENCAPTYPE_UDP ? "UDP" :
p->encap == L2TP_ENCAPTYPE_IP ? "IP" : "??");
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
print_string(PRINT_ANY, "local", " From %s ",
inet_ntop(p->local_ip.family, p->local_ip.data,
@@ -236,11 +236,11 @@ static void print_tunnel(const struct l2tp_data *data)
print_string(PRINT_ANY, "peer", "to %s",
inet_ntop(p->peer_ip.family, p->peer_ip.data,
buf, sizeof(buf)));
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
print_uint(PRINT_ANY, "peer_tunnel", " Peer tunnel %u",
p->peer_tunnel_id);
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
if (p->encap == L2TP_ENCAPTYPE_UDP) {
print_string(PRINT_FP, NULL,
@@ -250,7 +250,7 @@ static void print_tunnel(const struct l2tp_data *data)
p->local_udp_port);
print_uint(PRINT_ANY, "peer_port", "/%hu",
p->peer_udp_port);
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
switch (p->local_ip.family) {
case AF_INET:
@@ -292,18 +292,18 @@ static void print_session(struct l2tp_data *data)
print_uint(PRINT_ANY, "session_id", "Session %u", p->session_id);
print_uint(PRINT_ANY, "tunnel_id", " in tunnel %u", p->tunnel_id);
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
print_uint(PRINT_ANY, "peer_session_id",
" Peer session %u,", p->peer_session_id);
print_uint(PRINT_ANY, "peer_tunnel_id",
" tunnel %u", p->peer_tunnel_id);
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
if (p->ifname != NULL) {
print_color_string(PRINT_ANY, COLOR_IFNAME,
"interface", " interface name: %s" , p->ifname);
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
}
/* Show offsets only for plain console output (for legacy scripts) */
diff --git a/ip/ipmacsec.c b/ip/ipmacsec.c
index 4e4e158..fa56e0e 100644
--- a/ip/ipmacsec.c
+++ b/ip/ipmacsec.c
@@ -627,7 +627,7 @@ static void print_attrs(struct rtattr *attrs[])
if (attrs[MACSEC_SECY_ATTR_CIPHER_SUITE]) {
__u64 cid = rta_getattr_u64(attrs[MACSEC_SECY_ATTR_CIPHER_SUITE]);
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
print_string(PRINT_ANY, "cipher_suite",
" cipher suite: %s,", cs_id_to_name(cid));
}
diff --git a/ip/ipmaddr.c b/ip/ipmaddr.c
index a484990..992b212 100644
--- a/ip/ipmaddr.c
+++ b/ip/ipmaddr.c
@@ -240,7 +240,7 @@ static void print_mlist(FILE *fp, struct ma_info *list)
print_uint(PRINT_ANY, "ifindex", "%d:", list->index);
print_color_string(PRINT_ANY, COLOR_IFNAME,
"ifname", "\t%s", list->name);
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
cur_index = list->index;
open_json_array(PRINT_JSON, "maddr");
diff --git a/ip/ipmroute.c b/ip/ipmroute.c
index cdb4d89..bc23cfe 100644
--- a/ip/ipmroute.c
+++ b/ip/ipmroute.c
@@ -181,7 +181,7 @@ int print_mroute(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
if (show_stats && tb[RTA_MFC_STATS]) {
struct rta_mfc_stats *mfcs = RTA_DATA(tb[RTA_MFC_STATS]);
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
print_u64(PRINT_ANY, "packets", " %"PRIu64" packets,",
mfcs->mfcs_packets);
print_u64(PRINT_ANY, "bytes", " %"PRIu64" bytes", mfcs->mfcs_bytes);
diff --git a/ip/ipntable.c b/ip/ipntable.c
index 4fae181..dd4f7c2 100644
--- a/ip/ipntable.c
+++ b/ip/ipntable.c
@@ -346,7 +346,7 @@ static void print_ndtconfig(const struct ndt_config *ndtc)
"entry_size %u ", ndtc->ndtc_entry_size);
print_uint(PRINT_ANY, "entries", "entries %u ", ndtc->ndtc_entries);
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
print_string(PRINT_ANY, "last_flush",
" last_flush %s ",
@@ -355,7 +355,7 @@ static void print_ndtconfig(const struct ndt_config *ndtc)
"last_rand %s ",
ntable_strtime_delta(ndtc->ndtc_last_rand));
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
print_uint(PRINT_ANY, "hash_rnd",
" hash_rnd %u ", ndtc->ndtc_hash_rnd);
@@ -367,7 +367,7 @@ static void print_ndtconfig(const struct ndt_config *ndtc)
print_uint(PRINT_ANY, "proxy_qlen",
"proxy_qlen %u ", ndtc->ndtc_proxy_qlen);
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
}
static void print_ndtparams(struct rtattr *tpb[])
@@ -379,7 +379,7 @@ static void print_ndtparams(struct rtattr *tpb[])
print_string(PRINT_FP, NULL, " dev ", NULL);
print_color_string(PRINT_ANY, COLOR_IFNAME,
"dev", "%s ", ll_index_to_name(ifindex));
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
}
print_string(PRINT_FP, NULL, " ", NULL);
@@ -482,7 +482,7 @@ static void print_ndtparams(struct rtattr *tpb[])
print_u64(PRINT_ANY, "locktime", "locktime %llu ", locktime);
}
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
}
static void print_ndtstats(const struct ndt_stats *ndts)
@@ -517,7 +517,7 @@ static void print_ndtstats(const struct ndt_stats *ndts)
print_u64(PRINT_ANY, "forced_gc_runs", "forced_gc_runs %llu ",
ndts->ndts_forced_gc_runs);
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
}
static int print_ntable(const struct sockaddr_nl *who,
@@ -579,7 +579,7 @@ static int print_ntable(const struct sockaddr_nl *who,
print_string(PRINT_ANY, "name", "%s ", name);
}
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
ret = (tb[NDTA_THRESH1] || tb[NDTA_THRESH2] || tb[NDTA_THRESH3] ||
tb[NDTA_GC_INTERVAL]);
@@ -611,7 +611,7 @@ static int print_ntable(const struct sockaddr_nl *who,
}
if (ret)
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
if (tb[NDTA_CONFIG] && show_stats)
print_ndtconfig(RTA_DATA(tb[NDTA_CONFIG]));
diff --git a/lib/json_print.c b/lib/json_print.c
index 5dc41bf..09e51d0 100644
--- a/lib/json_print.c
+++ b/lib/json_print.c
@@ -221,3 +221,10 @@ void print_color_null(enum output_type type,
color_fprintf(stdout, color, fmt, value);
}
}
+
+/* Print line seperator (if not in JSON mode) */
+void print_nl(void)
+{
+ if (!_jw)
+ printf("%s", _SL_);
+}
diff --git a/lib/utils.c b/lib/utils.c
index 02ce677..e87ecf3 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -42,6 +42,7 @@
int resolve_hosts;
int timestamp_short;
int pretty;
+const char *_SL_ = "\n";
int read_prop(const char *dev, char *prop, long *value)
{
diff --git a/tc/tc.c b/tc/tc.c
index 3bb5910..2e97f2b 100644
--- a/tc/tc.c
+++ b/tc/tc.c
@@ -43,7 +43,6 @@ bool use_names;
int json;
int color;
int oneline;
-const char *_SL_;
static char *conf_file;
--
1.8.3.1

View File

@ -1,58 +0,0 @@
From 32c326673c4c2a5513d52898ebab453ccbb178a2 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 18 Oct 2018 10:52:09 +0200
Subject: [PATCH] bridge: fdb: Fix for missing keywords in non-JSON output
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1636532
Upstream Status: iproute2.git commit 4abb8c723a648
commit 4abb8c723a648ac9edc33741d2064e2507a6bae3
Author: Phil Sutter <phil@nwl.cc>
Date: Tue Oct 9 14:44:08 2018 +0200
bridge: fdb: Fix for missing keywords in non-JSON output
While migrating to JSON print library, some keywords were dropped from
standard output by accident. Add them back to unbreak output parsers.
Fixes: c7c1a1ef51aea ("bridge: colorize output and use JSON print library")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
bridge/fdb.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/bridge/fdb.c b/bridge/fdb.c
index 4dbc894..6487fac 100644
--- a/bridge/fdb.c
+++ b/bridge/fdb.c
@@ -182,7 +182,7 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
if (!is_json_context())
fprintf(fp, "dev ");
print_color_string(PRINT_ANY, COLOR_IFNAME,
- "ifname", "%s ",
+ "ifname", "dev %s ",
ll_index_to_name(r->ndm_ifindex));
}
@@ -199,7 +199,7 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
print_color_string(PRINT_ANY,
ifa_family_color(family),
- "dst", "%s ", dst);
+ "dst", "dst %s ", dst);
}
if (vid)
@@ -246,7 +246,7 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
if (tb[NDA_MASTER])
- print_string(PRINT_ANY, "master", "%s ",
+ print_string(PRINT_ANY, "master", "master %s ",
ll_index_to_name(rta_getattr_u32(tb[NDA_MASTER])));
print_string(PRINT_ANY, "state", "%s\n",
--
1.8.3.1

View File

@ -1,40 +0,0 @@
From fd07e443d264ddf25d4152af3a44144e1a9b3fd9 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 18 Oct 2018 10:52:51 +0200
Subject: [PATCH] ip-addrlabel: Fix printing of label value
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1639412
Upstream Status: iproute2.git commit 0b9b0d08c29f9
commit 0b9b0d08c29f9aa6cc1b83c853964d9cc18dc6f2
Author: Phil Sutter <phil@nwl.cc>
Date: Mon Oct 15 22:20:58 2018 +0200
ip-addrlabel: Fix printing of label value
Passing the return value of RTA_DATA() to rta_getattr_u32() is wrong
since that function will call RTA_DATA() by itself already.
Fixes: a7ad1c8a6845d ("ipaddrlabel: add json support")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/ipaddrlabel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ip/ipaddrlabel.c b/ip/ipaddrlabel.c
index 2f79c56..8abe572 100644
--- a/ip/ipaddrlabel.c
+++ b/ip/ipaddrlabel.c
@@ -95,7 +95,7 @@ int print_addrlabel(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg
}
if (tb[IFAL_LABEL] && RTA_PAYLOAD(tb[IFAL_LABEL]) == sizeof(uint32_t)) {
- uint32_t label = rta_getattr_u32(RTA_DATA(tb[IFAL_LABEL]));
+ uint32_t label = rta_getattr_u32(tb[IFAL_LABEL]);
print_uint(PRINT_ANY,
"label", "label %u ", label);
--
1.8.3.1

View File

@ -1,76 +0,0 @@
From f08a8608335d46bea1b2cb122823a4c538ce6e46 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 18 Oct 2018 10:53:57 +0200
Subject: [PATCH] iplink_vxlan: take into account preferred_family creating
vxlan device
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1626321
Upstream Status: iproute2.git commit c1360e3b483e5
commit c1360e3b483e54a61a36bd2fdb3bfb91a4d2b32a
Author: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Date: Fri Sep 21 15:34:25 2018 +0200
iplink_vxlan: take into account preferred_family creating vxlan device
Take into account the configured preferred_family if neither saddr or
daddr are provided since otherwise vxlan kernel module will use IPv4 as
default remote inet family neglecting the one provided by userspace.
This behaviour was originally in commit 97d564b90ccb ("vxlan: use
preferred address family when neither group or remote is specified").
The issue can be triggered with the following reproducer:
$ip -6 link add vxlan1 type vxlan id 42 dev enp0s2 \
proxy nolearning l2miss l3miss
$bridge fdb add 46:47:1f:a7:1c:25 dev vxlan1 dst 2000::2
RTNETLINK answers: Address family not supported by protocol
Fixes: 1e9b8072de2c ("iplink_vxlan: Get rid of inet_get_addr()")
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/iplink_vxlan.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/ip/iplink_vxlan.c b/ip/iplink_vxlan.c
index 2bc253f..831f39a 100644
--- a/ip/iplink_vxlan.c
+++ b/ip/iplink_vxlan.c
@@ -82,6 +82,7 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
__u64 attrs = 0;
bool set_op = (n->nlmsg_type == RTM_NEWLINK &&
!(n->nlmsg_flags & NLM_F_CREATE));
+ bool selected_family = false;
saddr.family = daddr.family = AF_UNSPEC;
@@ -356,12 +357,26 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
int type = (saddr.family == AF_INET) ? IFLA_VXLAN_LOCAL
: IFLA_VXLAN_LOCAL6;
addattr_l(n, 1024, type, saddr.data, saddr.bytelen);
+ selected_family = true;
}
if (is_addrtype_inet(&daddr)) {
int type = (daddr.family == AF_INET) ? IFLA_VXLAN_GROUP
: IFLA_VXLAN_GROUP6;
addattr_l(n, 1024, type, daddr.data, daddr.bytelen);
+ selected_family = true;
+ }
+
+ if (!selected_family) {
+ if (preferred_family == AF_INET) {
+ get_addr(&daddr, "default", AF_INET);
+ addattr_l(n, 1024, IFLA_VXLAN_GROUP,
+ daddr.data, daddr.bytelen);
+ } else if (preferred_family == AF_INET6) {
+ get_addr(&daddr, "default", AF_INET6);
+ addattr_l(n, 1024, IFLA_VXLAN_GROUP6,
+ daddr.data, daddr.bytelen);
+ }
}
if (!set_op || VXLAN_ATTRSET(attrs, IFLA_VXLAN_LEARNING))
--
1.8.3.1

View File

@ -1,73 +0,0 @@
From 9822fef7a13eaec70be8e86c23bdb71569835bd0 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 18 Oct 2018 12:49:51 +0200
Subject: [PATCH] json: make 0xhex handle u64
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1628428
Upstream Status: iproute2.git commit 45ec4771d40cb
commit 45ec4771d40cb367377e4148a2af22f25c20f3bf
Author: Sabrina Dubroca <sd@queasysnail.net>
Date: Fri Oct 12 17:34:32 2018 +0200
json: make 0xhex handle u64
Stephen converted macsec's sci to use 0xhex, but 0xhex handles
unsigned int's, not 64 bits ints. Thus, the output of the "ip macsec
show" command is mangled, with half of the SCI replaced with 0s:
# ip macsec show
11: macsec0: [...]
cipher suite: GCM-AES-128, using ICV length 16
TXSC: 0000000001560001 on SA 0
# ip -d link show macsec0
11: macsec0@ens3: [...]
link/ether 52:54:00:12:01:56 brd ff:ff:ff:ff:ff:ff promiscuity 0
macsec sci 5254001201560001 [...]
where TXSC and sci should match.
Fixes: c0b904de6211 ("macsec: support JSON")
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
include/json_print.h | 2 +-
lib/json_print.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/json_print.h b/include/json_print.h
index 78a6c83..218da31 100644
--- a/include/json_print.h
+++ b/include/json_print.h
@@ -66,7 +66,7 @@ _PRINT_FUNC(uint, unsigned int);
_PRINT_FUNC(u64, uint64_t);
_PRINT_FUNC(hu, unsigned short);
_PRINT_FUNC(hex, unsigned int);
-_PRINT_FUNC(0xhex, unsigned int);
+_PRINT_FUNC(0xhex, unsigned long long int);
_PRINT_FUNC(luint, unsigned long int);
_PRINT_FUNC(lluint, unsigned long long int);
_PRINT_FUNC(float, double);
diff --git a/lib/json_print.c b/lib/json_print.c
index 09e51d0..cf13e9b 100644
--- a/lib/json_print.c
+++ b/lib/json_print.c
@@ -171,12 +171,12 @@ void print_color_0xhex(enum output_type type,
enum color_attr color,
const char *key,
const char *fmt,
- unsigned int hex)
+ unsigned long long hex)
{
if (_IS_JSON_CONTEXT(type)) {
SPRINT_BUF(b1);
- snprintf(b1, sizeof(b1), "%#x", hex);
+ snprintf(b1, sizeof(b1), "%#llx", hex);
print_string(PRINT_JSON, key, NULL, b1);
} else if (_IS_FP_CONTEXT(type)) {
color_fprintf(stdout, color, fmt, hex);
--
1.8.3.1

View File

@ -1,114 +0,0 @@
From 03525ec63a5821a30461047da1dc8d907b3e3751 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 18 Oct 2018 12:49:51 +0200
Subject: [PATCH] macsec: fix off-by-one when parsing attributes
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1628428
Upstream Status: iproute2.git commit 9b45f8ec13b0d
commit 9b45f8ec13b0d338c70ef0758f751c249be6c7f0
Author: Sabrina Dubroca <sd@queasysnail.net>
Date: Fri Oct 12 17:34:12 2018 +0200
macsec: fix off-by-one when parsing attributes
I seem to have had a massive brainfart with uses of
parse_rtattr_nested(). The rtattr* array must have MAX+1 elements, and
the call to parse_rtattr_nested must have MAX as its bound. Let's fix
those.
Fixes: b26fc590ce62 ("ip: add MACsec support")
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/ipmacsec.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/ip/ipmacsec.c b/ip/ipmacsec.c
index fa56e0e..007ce54 100644
--- a/ip/ipmacsec.c
+++ b/ip/ipmacsec.c
@@ -727,7 +727,7 @@ static void print_txsc_stats(const char *prefix, struct rtattr *attr)
if (!attr || show_stats == 0)
return;
- parse_rtattr_nested(stats, MACSEC_TXSC_STATS_ATTR_MAX + 1, attr);
+ parse_rtattr_nested(stats, MACSEC_TXSC_STATS_ATTR_MAX, attr);
print_stats(prefix, txsc_stats_names, NUM_MACSEC_TXSC_STATS_ATTR,
stats);
@@ -751,7 +751,7 @@ static void print_secy_stats(const char *prefix, struct rtattr *attr)
if (!attr || show_stats == 0)
return;
- parse_rtattr_nested(stats, MACSEC_SECY_STATS_ATTR_MAX + 1, attr);
+ parse_rtattr_nested(stats, MACSEC_SECY_STATS_ATTR_MAX, attr);
print_stats(prefix, secy_stats_names,
NUM_MACSEC_SECY_STATS_ATTR, stats);
@@ -772,7 +772,7 @@ static void print_rxsa_stats(const char *prefix, struct rtattr *attr)
if (!attr || show_stats == 0)
return;
- parse_rtattr_nested(stats, MACSEC_SA_STATS_ATTR_MAX + 1, attr);
+ parse_rtattr_nested(stats, MACSEC_SA_STATS_ATTR_MAX, attr);
print_stats(prefix, rxsa_stats_names, NUM_MACSEC_SA_STATS_ATTR, stats);
}
@@ -789,7 +789,7 @@ static void print_txsa_stats(const char *prefix, struct rtattr *attr)
if (!attr || show_stats == 0)
return;
- parse_rtattr_nested(stats, MACSEC_SA_STATS_ATTR_MAX + 1, attr);
+ parse_rtattr_nested(stats, MACSEC_SA_STATS_ATTR_MAX, attr);
print_stats(prefix, txsa_stats_names, NUM_MACSEC_SA_STATS_ATTR, stats);
}
@@ -817,7 +817,7 @@ static void print_tx_sc(const char *prefix, __u64 sci, __u8 encoding_sa,
bool state;
open_json_object(NULL);
- parse_rtattr_nested(sa_attr, MACSEC_SA_ATTR_MAX + 1, a);
+ parse_rtattr_nested(sa_attr, MACSEC_SA_ATTR_MAX, a);
state = rta_getattr_u8(sa_attr[MACSEC_SA_ATTR_ACTIVE]);
print_string(PRINT_FP, NULL, "%s", prefix);
@@ -858,7 +858,7 @@ static void print_rxsc_stats(const char *prefix, struct rtattr *attr)
if (!attr || show_stats == 0)
return;
- parse_rtattr_nested(stats, MACSEC_RXSC_STATS_ATTR_MAX + 1, attr);
+ parse_rtattr_nested(stats, MACSEC_RXSC_STATS_ATTR_MAX, attr);
print_stats(prefix, rxsc_stats_names,
NUM_MACSEC_RXSC_STATS_ATTR, stats);
@@ -885,7 +885,7 @@ static void print_rx_sc(const char *prefix, __be64 sci, __u8 active,
bool state;
open_json_object(NULL);
- parse_rtattr_nested(sa_attr, MACSEC_SA_ATTR_MAX + 1, a);
+ parse_rtattr_nested(sa_attr, MACSEC_SA_ATTR_MAX, a);
state = rta_getattr_u8(sa_attr[MACSEC_SA_ATTR_ACTIVE]);
print_string(PRINT_FP, NULL, "%s", prefix);
@@ -918,7 +918,7 @@ static void print_rxsc_list(struct rtattr *sc)
open_json_object(NULL);
- parse_rtattr_nested(sc_attr, MACSEC_RXSC_ATTR_MAX + 1, c);
+ parse_rtattr_nested(sc_attr, MACSEC_RXSC_ATTR_MAX, c);
print_rx_sc(" ",
rta_getattr_u64(sc_attr[MACSEC_RXSC_ATTR_SCI]),
rta_getattr_u32(sc_attr[MACSEC_RXSC_ATTR_ACTIVE]),
@@ -958,7 +958,7 @@ static int process(const struct sockaddr_nl *who, struct nlmsghdr *n,
}
ifindex = rta_getattr_u32(attrs[MACSEC_ATTR_IFINDEX]);
- parse_rtattr_nested(attrs_secy, MACSEC_SECY_ATTR_MAX + 1,
+ parse_rtattr_nested(attrs_secy, MACSEC_SECY_ATTR_MAX,
attrs[MACSEC_ATTR_SECY]);
if (!validate_secy_dump(attrs_secy)) {
--
1.8.3.1

View File

@ -1,357 +0,0 @@
From 23bf1358295afa575227a41b5cd427cd1f3fdc0c Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 18 Oct 2018 12:51:12 +0200
Subject: [PATCH] uapi: add snmp header file
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1626306
Upstream Status: iproute2.git commit 9e030e77f20ab
commit 9e030e77f20ab177e8717f054c9d53050b9a5d53
Author: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Date: Wed Oct 10 17:00:57 2018 +0200
uapi: add snmp header file
Introduce snmp header file. It will be used in subsequent patch in
order to parse device statistics reported in
IFLA_INET6_STATS/IFLA_INET6_ICMP6STATS netlink attributes
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
include/uapi/linux/snmp.h | 323 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 323 insertions(+)
create mode 100644 include/uapi/linux/snmp.h
diff --git a/include/uapi/linux/snmp.h b/include/uapi/linux/snmp.h
new file mode 100644
index 0000000..f80135e
--- /dev/null
+++ b/include/uapi/linux/snmp.h
@@ -0,0 +1,323 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * Definitions for MIBs
+ *
+ * Author: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
+ */
+
+#ifndef _LINUX_SNMP_H
+#define _LINUX_SNMP_H
+
+/* ipstats mib definitions */
+/*
+ * RFC 1213: MIB-II
+ * RFC 2011 (updates 1213): SNMPv2-MIB-IP
+ * RFC 2863: Interfaces Group MIB
+ * RFC 2465: IPv6 MIB: General Group
+ * draft-ietf-ipv6-rfc2011-update-10.txt: MIB for IP: IP Statistics Tables
+ */
+enum
+{
+ IPSTATS_MIB_NUM = 0,
+/* frequently written fields in fast path, kept in same cache line */
+ IPSTATS_MIB_INPKTS, /* InReceives */
+ IPSTATS_MIB_INOCTETS, /* InOctets */
+ IPSTATS_MIB_INDELIVERS, /* InDelivers */
+ IPSTATS_MIB_OUTFORWDATAGRAMS, /* OutForwDatagrams */
+ IPSTATS_MIB_OUTPKTS, /* OutRequests */
+ IPSTATS_MIB_OUTOCTETS, /* OutOctets */
+/* other fields */
+ IPSTATS_MIB_INHDRERRORS, /* InHdrErrors */
+ IPSTATS_MIB_INTOOBIGERRORS, /* InTooBigErrors */
+ IPSTATS_MIB_INNOROUTES, /* InNoRoutes */
+ IPSTATS_MIB_INADDRERRORS, /* InAddrErrors */
+ IPSTATS_MIB_INUNKNOWNPROTOS, /* InUnknownProtos */
+ IPSTATS_MIB_INTRUNCATEDPKTS, /* InTruncatedPkts */
+ IPSTATS_MIB_INDISCARDS, /* InDiscards */
+ IPSTATS_MIB_OUTDISCARDS, /* OutDiscards */
+ IPSTATS_MIB_OUTNOROUTES, /* OutNoRoutes */
+ IPSTATS_MIB_REASMTIMEOUT, /* ReasmTimeout */
+ IPSTATS_MIB_REASMREQDS, /* ReasmReqds */
+ IPSTATS_MIB_REASMOKS, /* ReasmOKs */
+ IPSTATS_MIB_REASMFAILS, /* ReasmFails */
+ IPSTATS_MIB_FRAGOKS, /* FragOKs */
+ IPSTATS_MIB_FRAGFAILS, /* FragFails */
+ IPSTATS_MIB_FRAGCREATES, /* FragCreates */
+ IPSTATS_MIB_INMCASTPKTS, /* InMcastPkts */
+ IPSTATS_MIB_OUTMCASTPKTS, /* OutMcastPkts */
+ IPSTATS_MIB_INBCASTPKTS, /* InBcastPkts */
+ IPSTATS_MIB_OUTBCASTPKTS, /* OutBcastPkts */
+ IPSTATS_MIB_INMCASTOCTETS, /* InMcastOctets */
+ IPSTATS_MIB_OUTMCASTOCTETS, /* OutMcastOctets */
+ IPSTATS_MIB_INBCASTOCTETS, /* InBcastOctets */
+ IPSTATS_MIB_OUTBCASTOCTETS, /* OutBcastOctets */
+ IPSTATS_MIB_CSUMERRORS, /* InCsumErrors */
+ IPSTATS_MIB_NOECTPKTS, /* InNoECTPkts */
+ IPSTATS_MIB_ECT1PKTS, /* InECT1Pkts */
+ IPSTATS_MIB_ECT0PKTS, /* InECT0Pkts */
+ IPSTATS_MIB_CEPKTS, /* InCEPkts */
+ IPSTATS_MIB_REASM_OVERLAPS, /* ReasmOverlaps */
+ __IPSTATS_MIB_MAX
+};
+
+/* icmp mib definitions */
+/*
+ * RFC 1213: MIB-II ICMP Group
+ * RFC 2011 (updates 1213): SNMPv2 MIB for IP: ICMP group
+ */
+enum
+{
+ ICMP_MIB_NUM = 0,
+ ICMP_MIB_INMSGS, /* InMsgs */
+ ICMP_MIB_INERRORS, /* InErrors */
+ ICMP_MIB_INDESTUNREACHS, /* InDestUnreachs */
+ ICMP_MIB_INTIMEEXCDS, /* InTimeExcds */
+ ICMP_MIB_INPARMPROBS, /* InParmProbs */
+ ICMP_MIB_INSRCQUENCHS, /* InSrcQuenchs */
+ ICMP_MIB_INREDIRECTS, /* InRedirects */
+ ICMP_MIB_INECHOS, /* InEchos */
+ ICMP_MIB_INECHOREPS, /* InEchoReps */
+ ICMP_MIB_INTIMESTAMPS, /* InTimestamps */
+ ICMP_MIB_INTIMESTAMPREPS, /* InTimestampReps */
+ ICMP_MIB_INADDRMASKS, /* InAddrMasks */
+ ICMP_MIB_INADDRMASKREPS, /* InAddrMaskReps */
+ ICMP_MIB_OUTMSGS, /* OutMsgs */
+ ICMP_MIB_OUTERRORS, /* OutErrors */
+ ICMP_MIB_OUTDESTUNREACHS, /* OutDestUnreachs */
+ ICMP_MIB_OUTTIMEEXCDS, /* OutTimeExcds */
+ ICMP_MIB_OUTPARMPROBS, /* OutParmProbs */
+ ICMP_MIB_OUTSRCQUENCHS, /* OutSrcQuenchs */
+ ICMP_MIB_OUTREDIRECTS, /* OutRedirects */
+ ICMP_MIB_OUTECHOS, /* OutEchos */
+ ICMP_MIB_OUTECHOREPS, /* OutEchoReps */
+ ICMP_MIB_OUTTIMESTAMPS, /* OutTimestamps */
+ ICMP_MIB_OUTTIMESTAMPREPS, /* OutTimestampReps */
+ ICMP_MIB_OUTADDRMASKS, /* OutAddrMasks */
+ ICMP_MIB_OUTADDRMASKREPS, /* OutAddrMaskReps */
+ ICMP_MIB_CSUMERRORS, /* InCsumErrors */
+ __ICMP_MIB_MAX
+};
+
+#define __ICMPMSG_MIB_MAX 512 /* Out+In for all 8-bit ICMP types */
+
+/* icmp6 mib definitions */
+/*
+ * RFC 2466: ICMPv6-MIB
+ */
+enum
+{
+ ICMP6_MIB_NUM = 0,
+ ICMP6_MIB_INMSGS, /* InMsgs */
+ ICMP6_MIB_INERRORS, /* InErrors */
+ ICMP6_MIB_OUTMSGS, /* OutMsgs */
+ ICMP6_MIB_OUTERRORS, /* OutErrors */
+ ICMP6_MIB_CSUMERRORS, /* InCsumErrors */
+ __ICMP6_MIB_MAX
+};
+
+#define __ICMP6MSG_MIB_MAX 512 /* Out+In for all 8-bit ICMPv6 types */
+
+/* tcp mib definitions */
+/*
+ * RFC 1213: MIB-II TCP group
+ * RFC 2012 (updates 1213): SNMPv2-MIB-TCP
+ */
+enum
+{
+ TCP_MIB_NUM = 0,
+ TCP_MIB_RTOALGORITHM, /* RtoAlgorithm */
+ TCP_MIB_RTOMIN, /* RtoMin */
+ TCP_MIB_RTOMAX, /* RtoMax */
+ TCP_MIB_MAXCONN, /* MaxConn */
+ TCP_MIB_ACTIVEOPENS, /* ActiveOpens */
+ TCP_MIB_PASSIVEOPENS, /* PassiveOpens */
+ TCP_MIB_ATTEMPTFAILS, /* AttemptFails */
+ TCP_MIB_ESTABRESETS, /* EstabResets */
+ TCP_MIB_CURRESTAB, /* CurrEstab */
+ TCP_MIB_INSEGS, /* InSegs */
+ TCP_MIB_OUTSEGS, /* OutSegs */
+ TCP_MIB_RETRANSSEGS, /* RetransSegs */
+ TCP_MIB_INERRS, /* InErrs */
+ TCP_MIB_OUTRSTS, /* OutRsts */
+ TCP_MIB_CSUMERRORS, /* InCsumErrors */
+ __TCP_MIB_MAX
+};
+
+/* udp mib definitions */
+/*
+ * RFC 1213: MIB-II UDP group
+ * RFC 2013 (updates 1213): SNMPv2-MIB-UDP
+ */
+enum
+{
+ UDP_MIB_NUM = 0,
+ UDP_MIB_INDATAGRAMS, /* InDatagrams */
+ UDP_MIB_NOPORTS, /* NoPorts */
+ UDP_MIB_INERRORS, /* InErrors */
+ UDP_MIB_OUTDATAGRAMS, /* OutDatagrams */
+ UDP_MIB_RCVBUFERRORS, /* RcvbufErrors */
+ UDP_MIB_SNDBUFERRORS, /* SndbufErrors */
+ UDP_MIB_CSUMERRORS, /* InCsumErrors */
+ UDP_MIB_IGNOREDMULTI, /* IgnoredMulti */
+ __UDP_MIB_MAX
+};
+
+/* linux mib definitions */
+enum
+{
+ LINUX_MIB_NUM = 0,
+ LINUX_MIB_SYNCOOKIESSENT, /* SyncookiesSent */
+ LINUX_MIB_SYNCOOKIESRECV, /* SyncookiesRecv */
+ LINUX_MIB_SYNCOOKIESFAILED, /* SyncookiesFailed */
+ LINUX_MIB_EMBRYONICRSTS, /* EmbryonicRsts */
+ LINUX_MIB_PRUNECALLED, /* PruneCalled */
+ LINUX_MIB_RCVPRUNED, /* RcvPruned */
+ LINUX_MIB_OFOPRUNED, /* OfoPruned */
+ LINUX_MIB_OUTOFWINDOWICMPS, /* OutOfWindowIcmps */
+ LINUX_MIB_LOCKDROPPEDICMPS, /* LockDroppedIcmps */
+ LINUX_MIB_ARPFILTER, /* ArpFilter */
+ LINUX_MIB_TIMEWAITED, /* TimeWaited */
+ LINUX_MIB_TIMEWAITRECYCLED, /* TimeWaitRecycled */
+ LINUX_MIB_TIMEWAITKILLED, /* TimeWaitKilled */
+ LINUX_MIB_PAWSACTIVEREJECTED, /* PAWSActiveRejected */
+ LINUX_MIB_PAWSESTABREJECTED, /* PAWSEstabRejected */
+ LINUX_MIB_DELAYEDACKS, /* DelayedACKs */
+ LINUX_MIB_DELAYEDACKLOCKED, /* DelayedACKLocked */
+ LINUX_MIB_DELAYEDACKLOST, /* DelayedACKLost */
+ LINUX_MIB_LISTENOVERFLOWS, /* ListenOverflows */
+ LINUX_MIB_LISTENDROPS, /* ListenDrops */
+ LINUX_MIB_TCPHPHITS, /* TCPHPHits */
+ LINUX_MIB_TCPPUREACKS, /* TCPPureAcks */
+ LINUX_MIB_TCPHPACKS, /* TCPHPAcks */
+ LINUX_MIB_TCPRENORECOVERY, /* TCPRenoRecovery */
+ LINUX_MIB_TCPSACKRECOVERY, /* TCPSackRecovery */
+ LINUX_MIB_TCPSACKRENEGING, /* TCPSACKReneging */
+ LINUX_MIB_TCPSACKREORDER, /* TCPSACKReorder */
+ LINUX_MIB_TCPRENOREORDER, /* TCPRenoReorder */
+ LINUX_MIB_TCPTSREORDER, /* TCPTSReorder */
+ LINUX_MIB_TCPFULLUNDO, /* TCPFullUndo */
+ LINUX_MIB_TCPPARTIALUNDO, /* TCPPartialUndo */
+ LINUX_MIB_TCPDSACKUNDO, /* TCPDSACKUndo */
+ LINUX_MIB_TCPLOSSUNDO, /* TCPLossUndo */
+ LINUX_MIB_TCPLOSTRETRANSMIT, /* TCPLostRetransmit */
+ LINUX_MIB_TCPRENOFAILURES, /* TCPRenoFailures */
+ LINUX_MIB_TCPSACKFAILURES, /* TCPSackFailures */
+ LINUX_MIB_TCPLOSSFAILURES, /* TCPLossFailures */
+ LINUX_MIB_TCPFASTRETRANS, /* TCPFastRetrans */
+ LINUX_MIB_TCPSLOWSTARTRETRANS, /* TCPSlowStartRetrans */
+ LINUX_MIB_TCPTIMEOUTS, /* TCPTimeouts */
+ LINUX_MIB_TCPLOSSPROBES, /* TCPLossProbes */
+ LINUX_MIB_TCPLOSSPROBERECOVERY, /* TCPLossProbeRecovery */
+ LINUX_MIB_TCPRENORECOVERYFAIL, /* TCPRenoRecoveryFail */
+ LINUX_MIB_TCPSACKRECOVERYFAIL, /* TCPSackRecoveryFail */
+ LINUX_MIB_TCPRCVCOLLAPSED, /* TCPRcvCollapsed */
+ LINUX_MIB_TCPDSACKOLDSENT, /* TCPDSACKOldSent */
+ LINUX_MIB_TCPDSACKOFOSENT, /* TCPDSACKOfoSent */
+ LINUX_MIB_TCPDSACKRECV, /* TCPDSACKRecv */
+ LINUX_MIB_TCPDSACKOFORECV, /* TCPDSACKOfoRecv */
+ LINUX_MIB_TCPABORTONDATA, /* TCPAbortOnData */
+ LINUX_MIB_TCPABORTONCLOSE, /* TCPAbortOnClose */
+ LINUX_MIB_TCPABORTONMEMORY, /* TCPAbortOnMemory */
+ LINUX_MIB_TCPABORTONTIMEOUT, /* TCPAbortOnTimeout */
+ LINUX_MIB_TCPABORTONLINGER, /* TCPAbortOnLinger */
+ LINUX_MIB_TCPABORTFAILED, /* TCPAbortFailed */
+ LINUX_MIB_TCPMEMORYPRESSURES, /* TCPMemoryPressures */
+ LINUX_MIB_TCPMEMORYPRESSURESCHRONO, /* TCPMemoryPressuresChrono */
+ LINUX_MIB_TCPSACKDISCARD, /* TCPSACKDiscard */
+ LINUX_MIB_TCPDSACKIGNOREDOLD, /* TCPSACKIgnoredOld */
+ LINUX_MIB_TCPDSACKIGNOREDNOUNDO, /* TCPSACKIgnoredNoUndo */
+ LINUX_MIB_TCPSPURIOUSRTOS, /* TCPSpuriousRTOs */
+ LINUX_MIB_TCPMD5NOTFOUND, /* TCPMD5NotFound */
+ LINUX_MIB_TCPMD5UNEXPECTED, /* TCPMD5Unexpected */
+ LINUX_MIB_TCPMD5FAILURE, /* TCPMD5Failure */
+ LINUX_MIB_SACKSHIFTED,
+ LINUX_MIB_SACKMERGED,
+ LINUX_MIB_SACKSHIFTFALLBACK,
+ LINUX_MIB_TCPBACKLOGDROP,
+ LINUX_MIB_PFMEMALLOCDROP,
+ LINUX_MIB_TCPMINTTLDROP, /* RFC 5082 */
+ LINUX_MIB_TCPDEFERACCEPTDROP,
+ LINUX_MIB_IPRPFILTER, /* IP Reverse Path Filter (rp_filter) */
+ LINUX_MIB_TCPTIMEWAITOVERFLOW, /* TCPTimeWaitOverflow */
+ LINUX_MIB_TCPREQQFULLDOCOOKIES, /* TCPReqQFullDoCookies */
+ LINUX_MIB_TCPREQQFULLDROP, /* TCPReqQFullDrop */
+ LINUX_MIB_TCPRETRANSFAIL, /* TCPRetransFail */
+ LINUX_MIB_TCPRCVCOALESCE, /* TCPRcvCoalesce */
+ LINUX_MIB_TCPOFOQUEUE, /* TCPOFOQueue */
+ LINUX_MIB_TCPOFODROP, /* TCPOFODrop */
+ LINUX_MIB_TCPOFOMERGE, /* TCPOFOMerge */
+ LINUX_MIB_TCPCHALLENGEACK, /* TCPChallengeACK */
+ LINUX_MIB_TCPSYNCHALLENGE, /* TCPSYNChallenge */
+ LINUX_MIB_TCPFASTOPENACTIVE, /* TCPFastOpenActive */
+ LINUX_MIB_TCPFASTOPENACTIVEFAIL, /* TCPFastOpenActiveFail */
+ LINUX_MIB_TCPFASTOPENPASSIVE, /* TCPFastOpenPassive*/
+ LINUX_MIB_TCPFASTOPENPASSIVEFAIL, /* TCPFastOpenPassiveFail */
+ LINUX_MIB_TCPFASTOPENLISTENOVERFLOW, /* TCPFastOpenListenOverflow */
+ LINUX_MIB_TCPFASTOPENCOOKIEREQD, /* TCPFastOpenCookieReqd */
+ LINUX_MIB_TCPFASTOPENBLACKHOLE, /* TCPFastOpenBlackholeDetect */
+ LINUX_MIB_TCPSPURIOUS_RTX_HOSTQUEUES, /* TCPSpuriousRtxHostQueues */
+ LINUX_MIB_BUSYPOLLRXPACKETS, /* BusyPollRxPackets */
+ LINUX_MIB_TCPAUTOCORKING, /* TCPAutoCorking */
+ LINUX_MIB_TCPFROMZEROWINDOWADV, /* TCPFromZeroWindowAdv */
+ LINUX_MIB_TCPTOZEROWINDOWADV, /* TCPToZeroWindowAdv */
+ LINUX_MIB_TCPWANTZEROWINDOWADV, /* TCPWantZeroWindowAdv */
+ LINUX_MIB_TCPSYNRETRANS, /* TCPSynRetrans */
+ LINUX_MIB_TCPORIGDATASENT, /* TCPOrigDataSent */
+ LINUX_MIB_TCPHYSTARTTRAINDETECT, /* TCPHystartTrainDetect */
+ LINUX_MIB_TCPHYSTARTTRAINCWND, /* TCPHystartTrainCwnd */
+ LINUX_MIB_TCPHYSTARTDELAYDETECT, /* TCPHystartDelayDetect */
+ LINUX_MIB_TCPHYSTARTDELAYCWND, /* TCPHystartDelayCwnd */
+ LINUX_MIB_TCPACKSKIPPEDSYNRECV, /* TCPACKSkippedSynRecv */
+ LINUX_MIB_TCPACKSKIPPEDPAWS, /* TCPACKSkippedPAWS */
+ LINUX_MIB_TCPACKSKIPPEDSEQ, /* TCPACKSkippedSeq */
+ LINUX_MIB_TCPACKSKIPPEDFINWAIT2, /* TCPACKSkippedFinWait2 */
+ LINUX_MIB_TCPACKSKIPPEDTIMEWAIT, /* TCPACKSkippedTimeWait */
+ LINUX_MIB_TCPACKSKIPPEDCHALLENGE, /* TCPACKSkippedChallenge */
+ LINUX_MIB_TCPWINPROBE, /* TCPWinProbe */
+ LINUX_MIB_TCPKEEPALIVE, /* TCPKeepAlive */
+ LINUX_MIB_TCPMTUPFAIL, /* TCPMTUPFail */
+ LINUX_MIB_TCPMTUPSUCCESS, /* TCPMTUPSuccess */
+ LINUX_MIB_TCPDELIVERED, /* TCPDelivered */
+ LINUX_MIB_TCPDELIVEREDCE, /* TCPDeliveredCE */
+ LINUX_MIB_TCPACKCOMPRESSED, /* TCPAckCompressed */
+ LINUX_MIB_TCPZEROWINDOWDROP, /* TCPZeroWindowDrop */
+ LINUX_MIB_TCPRCVQDROP, /* TCPRcvQDrop */
+ __LINUX_MIB_MAX
+};
+
+/* linux Xfrm mib definitions */
+enum
+{
+ LINUX_MIB_XFRMNUM = 0,
+ LINUX_MIB_XFRMINERROR, /* XfrmInError */
+ LINUX_MIB_XFRMINBUFFERERROR, /* XfrmInBufferError */
+ LINUX_MIB_XFRMINHDRERROR, /* XfrmInHdrError */
+ LINUX_MIB_XFRMINNOSTATES, /* XfrmInNoStates */
+ LINUX_MIB_XFRMINSTATEPROTOERROR, /* XfrmInStateProtoError */
+ LINUX_MIB_XFRMINSTATEMODEERROR, /* XfrmInStateModeError */
+ LINUX_MIB_XFRMINSTATESEQERROR, /* XfrmInStateSeqError */
+ LINUX_MIB_XFRMINSTATEEXPIRED, /* XfrmInStateExpired */
+ LINUX_MIB_XFRMINSTATEMISMATCH, /* XfrmInStateMismatch */
+ LINUX_MIB_XFRMINSTATEINVALID, /* XfrmInStateInvalid */
+ LINUX_MIB_XFRMINTMPLMISMATCH, /* XfrmInTmplMismatch */
+ LINUX_MIB_XFRMINNOPOLS, /* XfrmInNoPols */
+ LINUX_MIB_XFRMINPOLBLOCK, /* XfrmInPolBlock */
+ LINUX_MIB_XFRMINPOLERROR, /* XfrmInPolError */
+ LINUX_MIB_XFRMOUTERROR, /* XfrmOutError */
+ LINUX_MIB_XFRMOUTBUNDLEGENERROR, /* XfrmOutBundleGenError */
+ LINUX_MIB_XFRMOUTBUNDLECHECKERROR, /* XfrmOutBundleCheckError */
+ LINUX_MIB_XFRMOUTNOSTATES, /* XfrmOutNoStates */
+ LINUX_MIB_XFRMOUTSTATEPROTOERROR, /* XfrmOutStateProtoError */
+ LINUX_MIB_XFRMOUTSTATEMODEERROR, /* XfrmOutStateModeError */
+ LINUX_MIB_XFRMOUTSTATESEQERROR, /* XfrmOutStateSeqError */
+ LINUX_MIB_XFRMOUTSTATEEXPIRED, /* XfrmOutStateExpired */
+ LINUX_MIB_XFRMOUTPOLBLOCK, /* XfrmOutPolBlock */
+ LINUX_MIB_XFRMOUTPOLDEAD, /* XfrmOutPolDead */
+ LINUX_MIB_XFRMOUTPOLERROR, /* XfrmOutPolError */
+ LINUX_MIB_XFRMFWDHDRERROR, /* XfrmFwdHdrError*/
+ LINUX_MIB_XFRMOUTSTATEINVALID, /* XfrmOutStateInvalid */
+ LINUX_MIB_XFRMACQUIREERROR, /* XfrmAcquireError */
+ __LINUX_MIB_XFRMMAX
+};
+
+#endif /* _LINUX_SNMP_H */
--
1.8.3.1

View File

@ -1,93 +0,0 @@
From 2e4e707b662df2cf505147ca19da94ef97b6ea25 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 18 Oct 2018 12:51:12 +0200
Subject: [PATCH] utils: fix get_rtnl_link_stats_rta stats parsing
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1626306
Upstream Status: iproute2.git commit c7a3b22961f52
commit c7a3b22961f528760766aa85095eb1ab04a39797
Author: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Date: Wed Oct 10 17:00:58 2018 +0200
utils: fix get_rtnl_link_stats_rta stats parsing
iproute2 walks through the list of available tunnels using netlink
protocol in order to get device info instead of reading
them from proc filesystem. However the kernel reports device statistics
using IFLA_INET6_STATS/IFLA_INET6_ICMP6STATS attributes nested in
IFLA_PROTINFO one but iproutes expects these info in
IFLA_STATS64/IFLA_STATS attributes.
The issue can be triggered with the following reproducer:
$ip link add ip6d0 type ip6tnl mode ip6ip6 local 1111::1 remote 2222::1
$ip -6 -d -s tunnel show ip6d0
ip6d0: ipv6/ipv6 remote 2222::1 local 1111::1 encaplimit 4 hoplimit 64
tclass 0x00 flowlabel 0x00000 (flowinfo 0x00000000)
Dump terminated
Fix the issue introducing IFLA_INET6_STATS attribute parsing
Fixes: 3e953938717f ("iptunnel/ip6tunnel: Use netlink to walk through
tunnels list")
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
lib/utils.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/lib/utils.c b/lib/utils.c
index e87ecf3..7be2d6b 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -27,6 +27,7 @@
#include <linux/param.h>
#include <linux/if_arp.h>
#include <linux/mpls.h>
+#include <linux/snmp.h>
#include <time.h>
#include <sys/time.h>
#include <errno.h>
@@ -1549,6 +1550,24 @@ static void copy_rtnl_link_stats64(struct rtnl_link_stats64 *stats64,
*a++ = *b++;
}
+#define IPSTATS_MIB_MAX_LEN (__IPSTATS_MIB_MAX * sizeof(__u64))
+static void get_snmp_counters(struct rtnl_link_stats64 *stats64,
+ struct rtattr *s)
+{
+ __u64 *mib = (__u64 *)RTA_DATA(s);
+
+ memset(stats64, 0, sizeof(*stats64));
+
+ stats64->rx_packets = mib[IPSTATS_MIB_INPKTS];
+ stats64->rx_bytes = mib[IPSTATS_MIB_INOCTETS];
+ stats64->tx_packets = mib[IPSTATS_MIB_OUTPKTS];
+ stats64->tx_bytes = mib[IPSTATS_MIB_OUTOCTETS];
+ stats64->rx_errors = mib[IPSTATS_MIB_INDISCARDS];
+ stats64->tx_errors = mib[IPSTATS_MIB_OUTDISCARDS];
+ stats64->multicast = mib[IPSTATS_MIB_INMCASTPKTS];
+ stats64->rx_frame_errors = mib[IPSTATS_MIB_CSUMERRORS];
+}
+
int get_rtnl_link_stats_rta(struct rtnl_link_stats64 *stats64,
struct rtattr *tb[])
{
@@ -1565,6 +1584,14 @@ int get_rtnl_link_stats_rta(struct rtnl_link_stats64 *stats64,
rta = tb[IFLA_STATS];
size = sizeof(struct rtnl_link_stats);
s = &stats;
+ } else if (tb[IFLA_PROTINFO]) {
+ struct rtattr *ptb[IPSTATS_MIB_MAX_LEN + 1];
+
+ parse_rtattr_nested(ptb, IPSTATS_MIB_MAX_LEN,
+ tb[IFLA_PROTINFO]);
+ if (ptb[IFLA_INET6_STATS])
+ get_snmp_counters(stats64, ptb[IFLA_INET6_STATS]);
+ return sizeof(*stats64);
} else {
return -1;
}
--
1.8.3.1

View File

@ -1,43 +0,0 @@
From 3e679f946a6313983ca544a28ce0ccf0072962e5 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 25 Oct 2018 12:22:23 +0200
Subject: [PATCH] tc: htb: Print default value in hex
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1641053
Upstream Status: iproute2.git commit 737b8258b35f4
commit 737b8258b35f4cc643a8153fdf955bfa0adec30f
Author: Phil Sutter <phil@nwl.cc>
Date: Tue Oct 23 12:36:24 2018 +0200
tc: htb: Print default value in hex
Value of 'default' is assumed to be hexadecimal when parsing, so
consequently it should be printed in hex as well. This is a regression
introduced when adding JSON output.
As requested, also change JSON output to print the value as hex string.
Fixes: f354fa6aa5ff0 ("tc: jsonify htb qdisc")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
tc/q_htb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tc/q_htb.c b/tc/q_htb.c
index b93d31d..cce9ebc 100644
--- a/tc/q_htb.c
+++ b/tc/q_htb.c
@@ -341,7 +341,7 @@ static int htb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (RTA_PAYLOAD(tb[TCA_HTB_INIT]) < sizeof(*gopt)) return -1;
print_int(PRINT_ANY, "r2q", "r2q %d", gopt->rate2quantum);
- print_uint(PRINT_ANY, "default", " default %u", gopt->defcls);
+ print_0xhex(PRINT_ANY, "default", " default %x", gopt->defcls);
print_uint(PRINT_ANY, "direct_packets_stat",
" direct_packets_stat %u", gopt->direct_pkts);
if (show_details) {
--
1.8.3.1

View File

@ -1,81 +0,0 @@
From 3ec32595e21849de3165d52e1af48ca3bdf51fab Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 25 Oct 2018 12:24:30 +0200
Subject: [PATCH] libnetlink: fix leak and using unused memory on error
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1602555
Upstream Status: iproute2.git commit c60389e4f9ea8
commit c60389e4f9ea88d7246dbb148d28791d577fe5b4
Author: Stephen Hemminger <stephen@networkplumber.org>
Date: Thu Sep 13 12:33:38 2018 -0700
libnetlink: fix leak and using unused memory on error
If an error happens in multi-segment message (tc only)
then report the error and stop processing further responses.
This also fixes refering to the buffer after free.
The sequence check is not necessary here because the
response message has already been validated to be in
the window of the sequence number of the iov.
Reported-by: Mahesh Bandewar <mahesh@bandewar.net>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Mahesh Bandewar <maheshb@google.com>
---
lib/libnetlink.c | 23 +++++++++--------------
1 file changed, 9 insertions(+), 14 deletions(-)
diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index 928de1d..5868092 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -617,7 +617,6 @@ static int __rtnl_talk_iov(struct rtnl_handle *rtnl, struct iovec *iov,
msg.msg_iovlen = 1;
i = 0;
while (1) {
-next:
status = rtnl_recvmsg(rtnl->fd, &msg, &buf);
++i;
@@ -660,27 +659,23 @@ next:
if (l < sizeof(struct nlmsgerr)) {
fprintf(stderr, "ERROR truncated\n");
- } else if (!err->error) {
+ free(buf);
+ return -1;
+ }
+
+ if (!err->error)
/* check messages from kernel */
nl_dump_ext_ack(h, errfn);
- if (answer)
- *answer = (struct nlmsghdr *)buf;
- else
- free(buf);
- if (h->nlmsg_seq == seq)
- return 0;
- else if (i < iovlen)
- goto next;
- return 0;
- }
-
if (rtnl->proto != NETLINK_SOCK_DIAG &&
show_rtnl_err)
rtnl_talk_error(h, err, errfn);
errno = -err->error;
- free(buf);
+ if (answer)
+ *answer = (struct nlmsghdr *)buf;
+ else
+ free(buf);
return -i;
}
--
1.8.3.1

View File

@ -1,56 +0,0 @@
From 0a9e18d65228376c332d7ec0f87a19b8042e8a43 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 25 Oct 2018 12:24:30 +0200
Subject: [PATCH] libnetlink: don't return error on success
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1602555
Upstream Status: iproute2.git commit b45e300024bb0
commit b45e300024bb0936a41821ad75117dc08b65669f
Author: Stephen Hemminger <stephen@networkplumber.org>
Date: Tue Sep 25 10:08:48 2018 +0200
libnetlink: don't return error on success
Change to error handling broke normal code.
Fixes: c60389e4f9ea ("libnetlink: fix leak and using unused memory on error")
Reported-by: David Ahern <dsahern@gmail.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/libnetlink.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index 5868092..f18dcea 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -666,17 +666,20 @@ static int __rtnl_talk_iov(struct rtnl_handle *rtnl, struct iovec *iov,
if (!err->error)
/* check messages from kernel */
nl_dump_ext_ack(h, errfn);
+ else {
+ errno = -err->error;
- if (rtnl->proto != NETLINK_SOCK_DIAG &&
- show_rtnl_err)
- rtnl_talk_error(h, err, errfn);
+ if (rtnl->proto != NETLINK_SOCK_DIAG &&
+ show_rtnl_err)
+ rtnl_talk_error(h, err, errfn);
+ }
- errno = -err->error;
if (answer)
*answer = (struct nlmsghdr *)buf;
else
free(buf);
- return -i;
+
+ return err->error ? -i : 0;
}
if (answer) {
--
1.8.3.1

View File

@ -1,53 +0,0 @@
From e7c11266309ffa65143455ceefc17fe92d93511c Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 25 Oct 2018 12:24:30 +0200
Subject: [PATCH] libnetlink: fix use-after-free of message buf
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1602555
Upstream Status: iproute2.git commit 8c50b728b226f
commit 8c50b728b226f6254251282697ce38a72639a6fc
Author: Vlad Buslov <vladbu@mellanox.com>
Date: Mon Oct 8 23:52:26 2018 +0300
libnetlink: fix use-after-free of message buf
In __rtnl_talk_iov() main loop, err is a pointer to memory in dynamically
allocated 'buf' that is used to store netlink messages. If netlink message
is an error message, buf is deallocated before returning with error code.
However, on return err->error code is checked one more time to generate
return value, after memory which err points to has already been
freed. Save error code in temporary variable and use the variable to
generate return value.
Fixes: c60389e4f9ea ("libnetlink: fix leak and using unused memory on error")
Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/libnetlink.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index f18dcea..a9932d4 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -656,6 +656,7 @@ static int __rtnl_talk_iov(struct rtnl_handle *rtnl, struct iovec *iov,
if (h->nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(h);
+ int error = err->error;
if (l < sizeof(struct nlmsgerr)) {
fprintf(stderr, "ERROR truncated\n");
@@ -679,7 +680,7 @@ static int __rtnl_talk_iov(struct rtnl_handle *rtnl, struct iovec *iov,
else
free(buf);
- return err->error ? -i : 0;
+ return error ? -i : 0;
}
if (answer) {
--
1.8.3.1

View File

@ -1,41 +0,0 @@
From 8193c9eaecd5a9a5237424081c109df0d27770fd Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 25 Oct 2018 12:24:30 +0200
Subject: [PATCH] devlink: Fix error reporting in cmd_resource_set()
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1602555
Upstream Status: iproute2.git commit b1ffc1f465928
commit b1ffc1f465928706e22d585932cead8d74f021de
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Oct 18 13:28:23 2018 +0200
devlink: Fix error reporting in cmd_resource_set()
resource_path_parse() returns either zero or a negative error code,
hence the negated value must be passed to strerror().
Fixes: 8cd644095842a ("devlink: Add support for devlink resource abstraction")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
devlink/devlink.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/devlink/devlink.c b/devlink/devlink.c
index 1142d16..7a5aef8 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -4457,7 +4457,7 @@ static int cmd_resource_set(struct dl *dl)
&dl->opts.resource_id,
&dl->opts.resource_id_valid);
if (err) {
- pr_err("error parsing resource path %s\n", strerror(err));
+ pr_err("error parsing resource path %s\n", strerror(-err));
goto out;
}
--
1.8.3.1

View File

@ -1,42 +0,0 @@
From ad7f7e4a1fd4e0362a6d256c0d093d43b44e2c1d Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 25 Oct 2018 12:24:30 +0200
Subject: [PATCH] rdma: Fix for ineffective check in add_filter()
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1602555
Upstream Status: iproute2.git commit 3b0070f6b1a31
commit 3b0070f6b1a319b7d6a431a39270a4804cb5927e
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Oct 18 13:41:54 2018 +0200
rdma: Fix for ineffective check in add_filter()
With 'name' field defined as array in struct filters, it will always
contain a value irrespective of whether a name was assigned or not.
Fix this by turning the field into a const char pointer.
Fixes: 1174be72d1b4c ("rdma: Add filtering infrastructure")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
rdma/rdma.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rdma/rdma.h b/rdma/rdma.h
index d4b7ba1..c3b7530 100644
--- a/rdma/rdma.h
+++ b/rdma/rdma.h
@@ -34,7 +34,7 @@
#define MAX_NUMBER_OF_FILTERS 64
struct filters {
- char name[32];
+ const char *name;
bool is_number;
};
--
1.8.3.1

View File

@ -1,65 +0,0 @@
From 0c762f107e6a5f6c56c42c0aba48f6aa9c6f1eef Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 25 Oct 2018 12:24:30 +0200
Subject: [PATCH] ip-route: Fix for memleak in error path
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1602555
Upstream Status: iproute2.git commit e5da392ff8e39
commit e5da392ff8e3979b86cad04b238ffbbc8076e005
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Oct 18 14:30:31 2018 +0200
ip-route: Fix for memleak in error path
If call to rta_addattr_l() failed, parse_encap_seg6() would leak memory.
Fix this by making sure calls to free() are not skipped.
Fixes: bd59e5b1517b0 ("ip-route: Fix segfault with many nexthops")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/iproute_lwtunnel.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
index 969a476..85045d4 100644
--- a/ip/iproute_lwtunnel.c
+++ b/ip/iproute_lwtunnel.c
@@ -498,6 +498,7 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
int argc = *argcp;
int encap = -1;
__u32 hmac = 0;
+ int ret = 0;
int srhlen;
while (argc > 0) {
@@ -539,16 +540,19 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
memcpy(tuninfo->srh, srh, srhlen);
if (rta_addattr_l(rta, len, SEG6_IPTUNNEL_SRH, tuninfo,
- sizeof(*tuninfo) + srhlen))
- return -1;
-
- free(tuninfo);
- free(srh);
+ sizeof(*tuninfo) + srhlen)) {
+ ret = -1;
+ goto out;
+ }
*argcp = argc + 1;
*argvp = argv - 1;
- return 0;
+out:
+ free(tuninfo);
+ free(srh);
+
+ return ret;
}
struct lwt_x {
--
1.8.3.1

View File

@ -1,59 +0,0 @@
From 97d754cf27798bc19ccdf8ce6d6b5b878e4d2c25 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 25 Oct 2018 12:24:30 +0200
Subject: [PATCH] rdma: Don't pass garbage to rd_check_is_filtered()
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1602555
Upstream Status: iproute2.git commit cdefe1d8e472f
commit cdefe1d8e472f3a69d5f54d90092b9b50961bf91
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Oct 18 14:35:50 2018 +0200
rdma: Don't pass garbage to rd_check_is_filtered()
Variables 'src_port' and 'dst_port' are initialized only if attributes
RDMA_NLDEV_ATTR_RES_SRC_ADDR or RDMA_NLDEV_ATTR_RES_DST_ADDR are
present. Make sure to pass them over to rd_check_is_filtered() only if
that is the case.
Fixes: 9a362cc71a455 ("rdma: Add CM_ID resource tracking information")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
rdma/res.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/rdma/res.c b/rdma/res.c
index 074b992..0d8c1c3 100644
--- a/rdma/res.c
+++ b/rdma/res.c
@@ -621,6 +621,8 @@ static int res_cm_id_parse_cb(const struct nlmsghdr *nlh, void *data)
if (rd_check_is_string_filtered(rd, "src-addr",
src_addr_str))
continue;
+ if (rd_check_is_filtered(rd, "src-port", src_port))
+ continue;
}
if (nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR]) {
@@ -630,14 +632,10 @@ static int res_cm_id_parse_cb(const struct nlmsghdr *nlh, void *data)
if (rd_check_is_string_filtered(rd, "dst-addr",
dst_addr_str))
continue;
+ if (rd_check_is_filtered(rd, "dst-port", dst_port))
+ continue;
}
- if (rd_check_is_filtered(rd, "src-port", src_port))
- continue;
-
- if (rd_check_is_filtered(rd, "dst-port", dst_port))
- continue;
-
if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
pid = mnl_attr_get_u32(
nla_line[RDMA_NLDEV_ATTR_RES_PID]);
--
1.8.3.1

View File

@ -1,41 +0,0 @@
From ffe33dd788af80a6645ab62b1df8e8f215b8902a Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 25 Oct 2018 12:24:30 +0200
Subject: [PATCH] ip-route: Fix parse_encap_seg6() srh parsing
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1602555
Upstream Status: iproute2.git commit 3b5c5ef0a75a9
commit 3b5c5ef0a75a9f685e78cd25da78706b5077bd83
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Oct 18 15:44:14 2018 +0200
ip-route: Fix parse_encap_seg6() srh parsing
In case caller did not specify 'segs' parameter, parse_srh() would read
garbage while iterating over 'segbuf'. Avoid this by initializing
'segbuf' to an empty string.
Fixes: e8493916a8ede ("iproute: add support for SR-IPv6 lwtunnel encapsulation")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/iproute_lwtunnel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
index 85045d4..4ebfaa7 100644
--- a/ip/iproute_lwtunnel.c
+++ b/ip/iproute_lwtunnel.c
@@ -494,7 +494,7 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
struct seg6_iptunnel_encap *tuninfo;
struct ipv6_sr_hdr *srh;
char **argv = *argvp;
- char segbuf[1024];
+ char segbuf[1024] = "";
int argc = *argcp;
int encap = -1;
__u32 hmac = 0;
--
1.8.3.1

View File

@ -1,76 +0,0 @@
From 03b579ec713d0a1062b16d0eab64d3189f6e325a Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 25 Oct 2018 12:24:30 +0200
Subject: [PATCH] tipc: Drop unused variable 'genl'
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1602555
Upstream Status: iproute2.git commit 8d05f33a381a2
commit 8d05f33a381a22572341204c667aafca02aabcca
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Oct 18 15:48:09 2018 +0200
tipc: Drop unused variable 'genl'
Although initialized by call to libmnl, the variable is used only in a
call to sizeof(). Drop it and call sizeof with its type instead.
Fixes: f043759dd4928 ("tipc: add new TIPC configuration tool")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
tipc/node.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/tipc/node.c b/tipc/node.c
index 0fa1064..2fec675 100644
--- a/tipc/node.c
+++ b/tipc/node.c
@@ -26,13 +26,12 @@
static int node_list_cb(const struct nlmsghdr *nlh, void *data)
{
- struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
struct nlattr *info[TIPC_NLA_MAX + 1] = {};
struct nlattr *attrs[TIPC_NLA_NODE_MAX + 1] = {};
char str[33] = {};
uint32_t addr;
- mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
+ mnl_attr_parse(nlh, sizeof(struct genlmsghdr), parse_attrs, info);
if (!info[TIPC_NLA_NODE])
return MNL_CB_ERROR;
@@ -160,7 +159,6 @@ static int cmd_node_set_nodeid(struct nlmsghdr *nlh, const struct cmd *cmd,
static int nodeid_get_cb(const struct nlmsghdr *nlh, void *data)
{
- struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
struct nlattr *info[TIPC_NLA_MAX + 1] = {};
struct nlattr *attrs[TIPC_NLA_NET_MAX + 1] = {};
char str[33] = {0,};
@@ -168,7 +166,7 @@ static int nodeid_get_cb(const struct nlmsghdr *nlh, void *data)
uint64_t *w0 = (uint64_t *) &id[0];
uint64_t *w1 = (uint64_t *) &id[8];
- mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
+ mnl_attr_parse(nlh, sizeof(struct genlmsghdr), parse_attrs, info);
if (!info[TIPC_NLA_NET])
return MNL_CB_ERROR;
@@ -207,11 +205,10 @@ static int cmd_node_get_nodeid(struct nlmsghdr *nlh, const struct cmd *cmd,
static int netid_get_cb(const struct nlmsghdr *nlh, void *data)
{
- struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
struct nlattr *info[TIPC_NLA_MAX + 1] = {};
struct nlattr *attrs[TIPC_NLA_NET_MAX + 1] = {};
- mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
+ mnl_attr_parse(nlh, sizeof(struct genlmsghdr), parse_attrs, info);
if (!info[TIPC_NLA_NET])
return MNL_CB_ERROR;
--
1.8.3.1

View File

@ -1,60 +0,0 @@
From 0b59d9f255a9b1c366fe5da3206d5089167277d4 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 25 Oct 2018 12:24:30 +0200
Subject: [PATCH] tc: Remove pointless assignments in batch()
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1602555
Upstream Status: iproute2.git commit 6358bbc381c6e
commit 6358bbc381c6e38465838370bcbbdeb77ec3565a
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Oct 18 15:48:48 2018 +0200
tc: Remove pointless assignments in batch()
All these assignments are later overwritten without reading in between,
so just drop them.
Fixes: 485d0c6001c4a ("tc: Add batchsize feature for filter and actions")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
tc/tc.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/tc/tc.c b/tc/tc.c
index 2e97f2b..88e22ba 100644
--- a/tc/tc.c
+++ b/tc/tc.c
@@ -322,11 +322,11 @@ static int batch(const char *name)
struct batch_buf *head = NULL, *tail = NULL, *buf_pool = NULL;
char *largv[100], *largv_next[100];
char *line, *line_next = NULL;
- bool bs_enabled_next = false;
bool bs_enabled = false;
bool lastline = false;
int largc, largc_next;
bool bs_enabled_saved;
+ bool bs_enabled_next;
int batchsize = 0;
size_t len = 0;
int ret = 0;
@@ -355,7 +355,6 @@ static int batch(const char *name)
goto Exit;
largc = makeargs(line, largv, 100);
bs_enabled = batchsize_enabled(largc, largv);
- bs_enabled_saved = bs_enabled;
do {
if (getcmdline(&line_next, &len, stdin) == -1)
lastline = true;
@@ -391,7 +390,6 @@ static int batch(const char *name)
len = 0;
bs_enabled_saved = bs_enabled;
bs_enabled = bs_enabled_next;
- bs_enabled_next = false;
if (largc == 0) {
largc = largc_next;
--
1.8.3.1

View File

@ -1,103 +0,0 @@
From 1610b7b240601085ea42848e8d86469a091e560c Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 25 Oct 2018 17:01:52 +0200
Subject: [PATCH] tc_util: Add support for showing TCA_STATS_BASIC_HW
statistics
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1637440
Upstream Status: iproute2.git commit 5ac138324e31c
commit 5ac138324e31c75edc65c69cedcf699fb624c113
Author: Eelco Chaudron <echaudro@redhat.com>
Date: Tue Oct 2 03:27:18 2018 -0400
tc_util: Add support for showing TCA_STATS_BASIC_HW statistics
Add support for showing hardware specific counters to easy
troubleshooting hardware offload.
$ tc -s filter show dev enp3s0np0 parent ffff:
filter protocol ip pref 1 flower chain 0
filter protocol ip pref 1 flower chain 0 handle 0x1
eth_type ipv4
dst_ip 2.0.0.0
src_ip 1.0.0.0
ip_flags nofrag
in_hw
action order 1: mirred (Egress Redirect to device eth1) stolen
index 1 ref 1 bind 1 installed 0 sec used 0 sec
Action statistics:
Sent 534884742 bytes 8915697 pkt (dropped 0, overlimits 0 requeues 0)
Sent software 187542 bytes 4077 pkt
Sent hardware 534697200 bytes 8911620 pkt
backlog 0b 0p requeues 0
cookie 89173e6a44447001becfd486bda17e29
Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
tc/tc_util.c | 41 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/tc/tc_util.c b/tc/tc_util.c
index d757852..5a1bbf2 100644
--- a/tc/tc_util.c
+++ b/tc/tc_util.c
@@ -800,6 +800,44 @@ void print_tm(FILE *f, const struct tcf_t *tm)
}
}
+static void print_tcstats_basic_hw(struct rtattr **tbs, char *prefix)
+{
+ struct gnet_stats_basic bs_hw;
+
+ if (!tbs[TCA_STATS_BASIC_HW])
+ return;
+
+ memcpy(&bs_hw, RTA_DATA(tbs[TCA_STATS_BASIC_HW]),
+ MIN(RTA_PAYLOAD(tbs[TCA_STATS_BASIC_HW]), sizeof(bs_hw)));
+
+ if (bs_hw.bytes == 0 && bs_hw.packets == 0)
+ return;
+
+ if (tbs[TCA_STATS_BASIC]) {
+ struct gnet_stats_basic bs;
+
+ memcpy(&bs, RTA_DATA(tbs[TCA_STATS_BASIC]),
+ MIN(RTA_PAYLOAD(tbs[TCA_STATS_BASIC]),
+ sizeof(bs)));
+
+ if (bs.bytes >= bs_hw.bytes && bs.packets >= bs_hw.packets) {
+ print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_string(PRINT_FP, NULL, "%s", prefix);
+ print_lluint(PRINT_ANY, "sw_bytes",
+ "Sent software %llu bytes",
+ bs.bytes - bs_hw.bytes);
+ print_uint(PRINT_ANY, "sw_packets", " %u pkt",
+ bs.packets - bs_hw.packets);
+ }
+ }
+
+ print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_string(PRINT_FP, NULL, "%s", prefix);
+ print_lluint(PRINT_ANY, "hw_bytes", "Sent hardware %llu bytes",
+ bs_hw.bytes);
+ print_uint(PRINT_ANY, "hw_packets", " %u pkt", bs_hw.packets);
+}
+
void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtattr **xstats)
{
SPRINT_BUF(b1);
@@ -826,6 +864,9 @@ void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtat
print_uint(PRINT_ANY, "requeues", " requeues %u) ", q.requeues);
}
+ if (tbs[TCA_STATS_BASIC_HW])
+ print_tcstats_basic_hw(tbs, prefix);
+
if (tbs[TCA_STATS_RATE_EST64]) {
struct gnet_stats_rate_est64 re = {0};
--
1.8.3.1

View File

@ -1,664 +0,0 @@
From 94b44c8f431c8d159fee6c067aded7b9c4e71104 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 25 Oct 2018 17:00:00 +0200
Subject: [PATCH] Update kernel headers
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1637440
Upstream Status: RHEL-only
This updates include/uapi/linux to the state of upstream commit
d9c0be4e9795473a73793058674c34d56cdb5eea.
---
include/uapi/linux/bpf.h | 121 ++++++++++++++++++++++++++++++++++++++++-
include/uapi/linux/btf.h | 2 +-
include/uapi/linux/can.h | 2 +-
include/uapi/linux/gen_stats.h | 1 +
include/uapi/linux/if_addr.h | 1 +
include/uapi/linux/if_arp.h | 18 +++---
include/uapi/linux/if_link.h | 15 +++++
include/uapi/linux/if_packet.h | 1 +
include/uapi/linux/in6.h | 1 +
include/uapi/linux/ip.h | 1 +
include/uapi/linux/l2tp.h | 15 ++---
include/uapi/linux/neighbour.h | 1 +
include/uapi/linux/netconf.h | 1 +
include/uapi/linux/pkt_cls.h | 34 +++++++++++-
include/uapi/linux/pkt_sched.h | 21 ++++++-
include/uapi/linux/rtnetlink.h | 7 +++
include/uapi/linux/tcp.h | 14 ++++-
include/uapi/linux/xfrm.h | 5 +-
18 files changed, 235 insertions(+), 26 deletions(-)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index b9a6367..abb7f77 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -75,6 +75,11 @@ struct bpf_lpm_trie_key {
__u8 data[0]; /* Arbitrary size */
};
+struct bpf_cgroup_storage_key {
+ __u64 cgroup_inode_id; /* cgroup inode id */
+ __u32 attach_type; /* program attach type */
+};
+
/* BPF syscall commands, see bpf(2) man-page for details. */
enum bpf_cmd {
BPF_MAP_CREATE,
@@ -120,6 +125,8 @@ enum bpf_map_type {
BPF_MAP_TYPE_CPUMAP,
BPF_MAP_TYPE_XSKMAP,
BPF_MAP_TYPE_SOCKHASH,
+ BPF_MAP_TYPE_CGROUP_STORAGE,
+ BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
};
enum bpf_prog_type {
@@ -144,6 +151,8 @@ enum bpf_prog_type {
BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
BPF_PROG_TYPE_LWT_SEG6LOCAL,
BPF_PROG_TYPE_LIRC_MODE2,
+ BPF_PROG_TYPE_SK_REUSEPORT,
+ BPF_PROG_TYPE_FLOW_DISSECTOR,
};
enum bpf_attach_type {
@@ -164,6 +173,7 @@ enum bpf_attach_type {
BPF_CGROUP_UDP4_SENDMSG,
BPF_CGROUP_UDP6_SENDMSG,
BPF_LIRC_MODE2,
+ BPF_FLOW_DISSECTOR,
__MAX_BPF_ATTACH_TYPE
};
@@ -1371,6 +1381,20 @@ union bpf_attr {
* A 8-byte long non-decreasing number on success, or 0 if the
* socket field is missing inside *skb*.
*
+ * u64 bpf_get_socket_cookie(struct bpf_sock_addr *ctx)
+ * Description
+ * Equivalent to bpf_get_socket_cookie() helper that accepts
+ * *skb*, but gets socket from **struct bpf_sock_addr** contex.
+ * Return
+ * A 8-byte long non-decreasing number.
+ *
+ * u64 bpf_get_socket_cookie(struct bpf_sock_ops *ctx)
+ * Description
+ * Equivalent to bpf_get_socket_cookie() helper that accepts
+ * *skb*, but gets socket from **struct bpf_sock_ops** contex.
+ * Return
+ * A 8-byte long non-decreasing number.
+ *
* u32 bpf_get_socket_uid(struct sk_buff *skb)
* Return
* The owner UID of the socket associated to *skb*. If the socket
@@ -2071,10 +2095,54 @@ union bpf_attr {
* Return
* The id is returned or 0 in case the id could not be retrieved.
*
+ * u64 bpf_skb_ancestor_cgroup_id(struct sk_buff *skb, int ancestor_level)
+ * Description
+ * Return id of cgroup v2 that is ancestor of cgroup associated
+ * with the *skb* at the *ancestor_level*. The root cgroup is at
+ * *ancestor_level* zero and each step down the hierarchy
+ * increments the level. If *ancestor_level* == level of cgroup
+ * associated with *skb*, then return value will be same as that
+ * of **bpf_skb_cgroup_id**\ ().
+ *
+ * The helper is useful to implement policies based on cgroups
+ * that are upper in hierarchy than immediate cgroup associated
+ * with *skb*.
+ *
+ * The format of returned id and helper limitations are same as in
+ * **bpf_skb_cgroup_id**\ ().
+ * Return
+ * The id is returned or 0 in case the id could not be retrieved.
+ *
* u64 bpf_get_current_cgroup_id(void)
* Return
* A 64-bit integer containing the current cgroup id based
* on the cgroup within which the current task is running.
+ *
+ * void* get_local_storage(void *map, u64 flags)
+ * Description
+ * Get the pointer to the local storage area.
+ * The type and the size of the local storage is defined
+ * by the *map* argument.
+ * The *flags* meaning is specific for each map type,
+ * and has to be 0 for cgroup local storage.
+ *
+ * Depending on the bpf program type, a local storage area
+ * can be shared between multiple instances of the bpf program,
+ * running simultaneously.
+ *
+ * A user should care about the synchronization by himself.
+ * For example, by using the BPF_STX_XADD instruction to alter
+ * the shared data.
+ * Return
+ * Pointer to the local storage area.
+ *
+ * int bpf_sk_select_reuseport(struct sk_reuseport_md *reuse, struct bpf_map *map, void *key, u64 flags)
+ * Description
+ * Select a SO_REUSEPORT sk from a BPF_MAP_TYPE_REUSEPORT_ARRAY map
+ * It checks the selected sk is matching the incoming
+ * request in the skb.
+ * Return
+ * 0 on success, or a negative error in case of failure.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
@@ -2157,7 +2225,10 @@ union bpf_attr {
FN(rc_repeat), \
FN(rc_keydown), \
FN(skb_cgroup_id), \
- FN(get_current_cgroup_id),
+ FN(get_current_cgroup_id), \
+ FN(get_local_storage), \
+ FN(sk_select_reuseport), \
+ FN(skb_ancestor_cgroup_id),
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
* function eBPF program intends to call
@@ -2264,6 +2335,7 @@ struct __sk_buff {
/* ... here. */
__u32 data_meta;
+ struct bpf_flow_keys *flow_keys;
};
struct bpf_tunnel_key {
@@ -2374,6 +2446,30 @@ struct sk_msg_md {
__u32 local_port; /* stored in host byte order */
};
+struct sk_reuseport_md {
+ /*
+ * Start of directly accessible data. It begins from
+ * the tcp/udp header.
+ */
+ void *data;
+ void *data_end; /* End of directly accessible data */
+ /*
+ * Total length of packet (starting from the tcp/udp header).
+ * Note that the directly accessible bytes (data_end - data)
+ * could be less than this "len". Those bytes could be
+ * indirectly read by a helper "bpf_skb_load_bytes()".
+ */
+ __u32 len;
+ /*
+ * Eth protocol in the mac header (network byte order). e.g.
+ * ETH_P_IP(0x0800) and ETH_P_IPV6(0x86DD)
+ */
+ __u32 eth_protocol;
+ __u32 ip_protocol; /* IP protocol. e.g. IPPROTO_TCP, IPPROTO_UDP */
+ __u32 bind_inany; /* Is sock bound to an INANY address? */
+ __u32 hash; /* A hash of the packet 4 tuples */
+};
+
#define BPF_TAG_SIZE 8
struct bpf_prog_info {
@@ -2685,4 +2781,27 @@ enum bpf_task_fd_type {
BPF_FD_TYPE_URETPROBE, /* filename + offset */
};
+struct bpf_flow_keys {
+ __u16 nhoff;
+ __u16 thoff;
+ __u16 addr_proto; /* ETH_P_* of valid addrs */
+ __u8 is_frag;
+ __u8 is_first_frag;
+ __u8 is_encap;
+ __u8 ip_proto;
+ __be16 n_proto;
+ __be16 sport;
+ __be16 dport;
+ union {
+ struct {
+ __be32 ipv4_src;
+ __be32 ipv4_dst;
+ };
+ struct {
+ __u32 ipv6_src[4]; /* in6_addr; network order */
+ __u32 ipv6_dst[4]; /* in6_addr; network order */
+ };
+ };
+};
+
#endif /* __LINUX_BPF_H__ */
diff --git a/include/uapi/linux/btf.h b/include/uapi/linux/btf.h
index 5dd580a..8d2a8ff 100644
--- a/include/uapi/linux/btf.h
+++ b/include/uapi/linux/btf.h
@@ -76,7 +76,7 @@ struct btf_type {
*/
#define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24)
#define BTF_INT_OFFSET(VAL) (((VAL & 0x00ff0000)) >> 16)
-#define BTF_INT_BITS(VAL) ((VAL) & 0x0000ffff)
+#define BTF_INT_BITS(VAL) ((VAL) & 0x000000ff)
/* Attributes stored in the BTF_INT_ENCODING */
#define BTF_INT_SIGNED (1 << 0)
diff --git a/include/uapi/linux/can.h b/include/uapi/linux/can.h
index 4d1ab8e..9009f0b 100644
--- a/include/uapi/linux/can.h
+++ b/include/uapi/linux/can.h
@@ -77,7 +77,7 @@ typedef __u32 canid_t;
/*
* Controller Area Network Error Message Frame Mask structure
*
- * bit 0-28 : error class mask (see include/linux/can/error.h)
+ * bit 0-28 : error class mask (see include/uapi/linux/can/error.h)
* bit 29-31 : set to zero
*/
typedef __u32 can_err_mask_t;
diff --git a/include/uapi/linux/gen_stats.h b/include/uapi/linux/gen_stats.h
index 24a861c..065408e 100644
--- a/include/uapi/linux/gen_stats.h
+++ b/include/uapi/linux/gen_stats.h
@@ -12,6 +12,7 @@ enum {
TCA_STATS_APP,
TCA_STATS_RATE_EST64,
TCA_STATS_PAD,
+ TCA_STATS_BASIC_HW,
__TCA_STATS_MAX,
};
#define TCA_STATS_MAX (__TCA_STATS_MAX - 1)
diff --git a/include/uapi/linux/if_addr.h b/include/uapi/linux/if_addr.h
index a924606..c4dd87f 100644
--- a/include/uapi/linux/if_addr.h
+++ b/include/uapi/linux/if_addr.h
@@ -34,6 +34,7 @@ enum {
IFA_MULTICAST,
IFA_FLAGS,
IFA_RT_PRIORITY, /* u32, priority/metric for prefix route */
+ IFA_TARGET_NETNSID,
__IFA_MAX,
};
diff --git a/include/uapi/linux/if_arp.h b/include/uapi/linux/if_arp.h
index cd136a6..dbfbc22 100644
--- a/include/uapi/linux/if_arp.h
+++ b/include/uapi/linux/if_arp.h
@@ -114,18 +114,18 @@
/* ARP ioctl request. */
struct arpreq {
- struct sockaddr arp_pa; /* protocol address */
- struct sockaddr arp_ha; /* hardware address */
- int arp_flags; /* flags */
- struct sockaddr arp_netmask; /* netmask (only for proxy arps) */
- char arp_dev[16];
+ struct sockaddr arp_pa; /* protocol address */
+ struct sockaddr arp_ha; /* hardware address */
+ int arp_flags; /* flags */
+ struct sockaddr arp_netmask; /* netmask (only for proxy arps) */
+ char arp_dev[IFNAMSIZ];
};
struct arpreq_old {
- struct sockaddr arp_pa; /* protocol address */
- struct sockaddr arp_ha; /* hardware address */
- int arp_flags; /* flags */
- struct sockaddr arp_netmask; /* netmask (only for proxy arps) */
+ struct sockaddr arp_pa; /* protocol address */
+ struct sockaddr arp_ha; /* hardware address */
+ int arp_flags; /* flags */
+ struct sockaddr arp_netmask; /* netmask (only for proxy arps) */
};
/* ARP Flag values. */
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 1c64ed4..9c25460 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -161,9 +161,12 @@ enum {
IFLA_EVENT,
IFLA_NEW_NETNSID,
IFLA_IF_NETNSID,
+ IFLA_TARGET_NETNSID = IFLA_IF_NETNSID, /* new alias */
IFLA_CARRIER_UP_COUNT,
IFLA_CARRIER_DOWN_COUNT,
IFLA_NEW_IFINDEX,
+ IFLA_MIN_MTU,
+ IFLA_MAX_MTU,
__IFLA_MAX
};
@@ -332,6 +335,7 @@ enum {
IFLA_BRPORT_GROUP_FWD_MASK,
IFLA_BRPORT_NEIGH_SUPPRESS,
IFLA_BRPORT_ISOLATED,
+ IFLA_BRPORT_BACKUP_PORT,
__IFLA_BRPORT_MAX
};
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
@@ -457,6 +461,16 @@ enum {
#define IFLA_MACSEC_MAX (__IFLA_MACSEC_MAX - 1)
+/* XFRM section */
+enum {
+ IFLA_XFRM_UNSPEC,
+ IFLA_XFRM_LINK,
+ IFLA_XFRM_IF_ID,
+ __IFLA_XFRM_MAX
+};
+
+#define IFLA_XFRM_MAX (__IFLA_XFRM_MAX - 1)
+
enum macsec_validation_type {
MACSEC_VALIDATE_DISABLED = 0,
MACSEC_VALIDATE_CHECK = 1,
@@ -539,6 +553,7 @@ enum {
IFLA_GENEVE_UDP_ZERO_CSUM6_TX,
IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
IFLA_GENEVE_LABEL,
+ IFLA_GENEVE_TTL_INHERIT,
__IFLA_GENEVE_MAX
};
#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)
diff --git a/include/uapi/linux/if_packet.h b/include/uapi/linux/if_packet.h
index 67b61d9..467b654 100644
--- a/include/uapi/linux/if_packet.h
+++ b/include/uapi/linux/if_packet.h
@@ -57,6 +57,7 @@ struct sockaddr_ll {
#define PACKET_QDISC_BYPASS 20
#define PACKET_ROLLOVER_STATS 21
#define PACKET_FANOUT_DATA 22
+#define PACKET_IGNORE_OUTGOING 23
#define PACKET_FANOUT_HASH 0
#define PACKET_FANOUT_LB 1
diff --git a/include/uapi/linux/in6.h b/include/uapi/linux/in6.h
index 409bb3f..2bb132a 100644
--- a/include/uapi/linux/in6.h
+++ b/include/uapi/linux/in6.h
@@ -177,6 +177,7 @@ struct in6_flowlabel_req {
#define IPV6_V6ONLY 26
#define IPV6_JOIN_ANYCAST 27
#define IPV6_LEAVE_ANYCAST 28
+#define IPV6_MULTICAST_ALL 29
/* IPV6_MTU_DISCOVER values */
#define IPV6_PMTUDISC_DONT 0
diff --git a/include/uapi/linux/ip.h b/include/uapi/linux/ip.h
index 883fd33..f4ecd2f 100644
--- a/include/uapi/linux/ip.h
+++ b/include/uapi/linux/ip.h
@@ -168,6 +168,7 @@ enum
IPV4_DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN,
IPV4_DEVCONF_DROP_UNICAST_IN_L2_MULTICAST,
IPV4_DEVCONF_DROP_GRATUITOUS_ARP,
+ IPV4_DEVCONF_BC_FORWARDING,
__IPV4_DEVCONF_MAX
};
diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h
index 1fe52a7..131c3a2 100644
--- a/include/uapi/linux/l2tp.h
+++ b/include/uapi/linux/l2tp.h
@@ -60,14 +60,14 @@ struct sockaddr_l2tpip6 {
/*
* Commands.
* Valid TLVs of each command are:-
- * TUNNEL_CREATE - CONN_ID, pw_type, netns, ifname, ipinfo, udpinfo, udpcsum, vlanid
+ * TUNNEL_CREATE - CONN_ID, pw_type, netns, ifname, ipinfo, udpinfo, udpcsum
* TUNNEL_DELETE - CONN_ID
* TUNNEL_MODIFY - CONN_ID, udpcsum
* TUNNEL_GETSTATS - CONN_ID, (stats)
* TUNNEL_GET - CONN_ID, (...)
- * SESSION_CREATE - SESSION_ID, PW_TYPE, data_seq, cookie, peer_cookie, l2spec
+ * SESSION_CREATE - SESSION_ID, PW_TYPE, cookie, peer_cookie, l2spec
* SESSION_DELETE - SESSION_ID
- * SESSION_MODIFY - SESSION_ID, data_seq
+ * SESSION_MODIFY - SESSION_ID
* SESSION_GET - SESSION_ID, (...)
* SESSION_GETSTATS - SESSION_ID, (stats)
*
@@ -95,7 +95,7 @@ enum {
L2TP_ATTR_PW_TYPE, /* u16, enum l2tp_pwtype */
L2TP_ATTR_ENCAP_TYPE, /* u16, enum l2tp_encap_type */
L2TP_ATTR_OFFSET, /* u16 (not used) */
- L2TP_ATTR_DATA_SEQ, /* u16 */
+ L2TP_ATTR_DATA_SEQ, /* u16 (not used) */
L2TP_ATTR_L2SPEC_TYPE, /* u8, enum l2tp_l2spec_type */
L2TP_ATTR_L2SPEC_LEN, /* u8 (not used) */
L2TP_ATTR_PROTO_VERSION, /* u8 */
@@ -105,7 +105,7 @@ enum {
L2TP_ATTR_SESSION_ID, /* u32 */
L2TP_ATTR_PEER_SESSION_ID, /* u32 */
L2TP_ATTR_UDP_CSUM, /* u8 */
- L2TP_ATTR_VLAN_ID, /* u16 */
+ L2TP_ATTR_VLAN_ID, /* u16 (not used) */
L2TP_ATTR_COOKIE, /* 0, 4 or 8 bytes */
L2TP_ATTR_PEER_COOKIE, /* 0, 4 or 8 bytes */
L2TP_ATTR_DEBUG, /* u32, enum l2tp_debug_flags */
@@ -119,8 +119,8 @@ enum {
L2TP_ATTR_IP_DADDR, /* u32 */
L2TP_ATTR_UDP_SPORT, /* u16 */
L2TP_ATTR_UDP_DPORT, /* u16 */
- L2TP_ATTR_MTU, /* u16 */
- L2TP_ATTR_MRU, /* u16 */
+ L2TP_ATTR_MTU, /* u16 (not used) */
+ L2TP_ATTR_MRU, /* u16 (not used) */
L2TP_ATTR_STATS, /* nested */
L2TP_ATTR_IP6_SADDR, /* struct in6_addr */
L2TP_ATTR_IP6_DADDR, /* struct in6_addr */
@@ -169,6 +169,7 @@ enum l2tp_encap_type {
L2TP_ENCAPTYPE_IP,
};
+/* For L2TP_ATTR_DATA_SEQ. Unused. */
enum l2tp_seqmode {
L2TP_SEQ_NONE = 0,
L2TP_SEQ_IP = 1,
diff --git a/include/uapi/linux/neighbour.h b/include/uapi/linux/neighbour.h
index 904db61..9981554 100644
--- a/include/uapi/linux/neighbour.h
+++ b/include/uapi/linux/neighbour.h
@@ -43,6 +43,7 @@ enum {
#define NTF_PROXY 0x08 /* == ATF_PUBL */
#define NTF_EXT_LEARNED 0x10
#define NTF_OFFLOADED 0x20
+#define NTF_STICKY 0x40
#define NTF_ROUTER 0x80
/*
diff --git a/include/uapi/linux/netconf.h b/include/uapi/linux/netconf.h
index 86ac1eb..229e885 100644
--- a/include/uapi/linux/netconf.h
+++ b/include/uapi/linux/netconf.h
@@ -18,6 +18,7 @@ enum {
NETCONFA_PROXY_NEIGH,
NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
NETCONFA_INPUT,
+ NETCONFA_BC_FORWARDING,
__NETCONFA_MAX
};
#define NETCONFA_MAX (__NETCONFA_MAX - 1)
diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index b451225..401d0c1 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -45,6 +45,7 @@ enum {
* the skb and act like everything
* is alright.
*/
+#define TC_ACT_VALUE_MAX TC_ACT_TRAP
/* There is a special kind of actions called "extended actions",
* which need a value parameter. These have a local opcode located in
@@ -55,11 +56,12 @@ enum {
#define __TC_ACT_EXT_SHIFT 28
#define __TC_ACT_EXT(local) ((local) << __TC_ACT_EXT_SHIFT)
#define TC_ACT_EXT_VAL_MASK ((1 << __TC_ACT_EXT_SHIFT) - 1)
-#define TC_ACT_EXT_CMP(combined, opcode) \
- (((combined) & (~TC_ACT_EXT_VAL_MASK)) == opcode)
+#define TC_ACT_EXT_OPCODE(combined) ((combined) & (~TC_ACT_EXT_VAL_MASK))
+#define TC_ACT_EXT_CMP(combined, opcode) (TC_ACT_EXT_OPCODE(combined) == opcode)
#define TC_ACT_JUMP __TC_ACT_EXT(1)
#define TC_ACT_GOTO_CHAIN __TC_ACT_EXT(2)
+#define TC_ACT_EXT_OPCODE_MAX TC_ACT_GOTO_CHAIN
/* Action type identifiers*/
enum {
@@ -478,12 +480,40 @@ enum {
TCA_FLOWER_KEY_ENC_IP_TTL, /* u8 */
TCA_FLOWER_KEY_ENC_IP_TTL_MASK, /* u8 */
+ TCA_FLOWER_KEY_ENC_OPTS,
+ TCA_FLOWER_KEY_ENC_OPTS_MASK,
+
+ TCA_FLOWER_IN_HW_COUNT,
+
__TCA_FLOWER_MAX,
};
#define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
enum {
+ TCA_FLOWER_KEY_ENC_OPTS_UNSPEC,
+ TCA_FLOWER_KEY_ENC_OPTS_GENEVE, /* Nested
+ * TCA_FLOWER_KEY_ENC_OPT_GENEVE_
+ * attributes
+ */
+ __TCA_FLOWER_KEY_ENC_OPTS_MAX,
+};
+
+#define TCA_FLOWER_KEY_ENC_OPTS_MAX (__TCA_FLOWER_KEY_ENC_OPTS_MAX - 1)
+
+enum {
+ TCA_FLOWER_KEY_ENC_OPT_GENEVE_UNSPEC,
+ TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS, /* u16 */
+ TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE, /* u8 */
+ TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA, /* 4 to 128 bytes */
+
+ __TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX,
+};
+
+#define TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX \
+ (__TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX - 1)
+
+enum {
TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0),
TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1),
};
diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h
index d9cc9dc..e9b7244 100644
--- a/include/uapi/linux/pkt_sched.h
+++ b/include/uapi/linux/pkt_sched.h
@@ -124,6 +124,21 @@ struct tc_fifo_qopt {
__u32 limit; /* Queue length: bytes for bfifo, packets for pfifo */
};
+/* SKBPRIO section */
+
+/*
+ * Priorities go from zero to (SKBPRIO_MAX_PRIORITY - 1).
+ * SKBPRIO_MAX_PRIORITY should be at least 64 in order for skbprio to be able
+ * to map one to one the DS field of IPV4 and IPV6 headers.
+ * Memory allocation grows linearly with SKBPRIO_MAX_PRIORITY.
+ */
+
+#define SKBPRIO_MAX_PRIORITY 64
+
+struct tc_skbprio_qopt {
+ __u32 limit; /* Queue length in packets. */
+};
+
/* PRIO section */
#define TCQ_PRIO_BANDS 16
@@ -380,9 +395,9 @@ enum {
struct tc_htb_xstats {
__u32 lends;
__u32 borrows;
- __u32 giants; /* too big packets (rate will not be accurate) */
- __u32 tokens;
- __u32 ctokens;
+ __u32 giants; /* unused since 'Make HTB scheduler work with TSO.' */
+ __s32 tokens;
+ __s32 ctokens;
};
/* HFSC section */
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index c3a7d8e..8c1d600 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -150,6 +150,13 @@ enum {
RTM_NEWCACHEREPORT = 96,
#define RTM_NEWCACHEREPORT RTM_NEWCACHEREPORT
+ RTM_NEWCHAIN = 100,
+#define RTM_NEWCHAIN RTM_NEWCHAIN
+ RTM_DELCHAIN,
+#define RTM_DELCHAIN RTM_DELCHAIN
+ RTM_GETCHAIN,
+#define RTM_GETCHAIN RTM_GETCHAIN
+
__RTM_MAX,
#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
};
diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h
index 2e766cf..6ec7766 100644
--- a/include/uapi/linux/tcp.h
+++ b/include/uapi/linux/tcp.h
@@ -127,6 +127,10 @@ enum {
#define TCP_CM_INQ TCP_INQ
+#define TCP_REPAIR_ON 1
+#define TCP_REPAIR_OFF 0
+#define TCP_REPAIR_OFF_NO_WP -1 /* Turn off without window probes */
+
struct tcp_repair_opt {
__u32 opt_code;
__u32 opt_val;
@@ -231,6 +235,11 @@ struct tcp_info {
__u32 tcpi_delivered;
__u32 tcpi_delivered_ce;
+
+ __u64 tcpi_bytes_sent; /* RFC4898 tcpEStatsPerfHCDataOctetsOut */
+ __u64 tcpi_bytes_retrans; /* RFC4898 tcpEStatsPerfOctetsRetrans */
+ __u32 tcpi_dsack_dups; /* RFC4898 tcpEStatsStackDSACKDups */
+ __u32 tcpi_reord_seen; /* reordering events seen */
};
/* netlink attributes types for SCM_TIMESTAMPING_OPT_STATS */
@@ -253,7 +262,10 @@ enum {
TCP_NLA_SND_SSTHRESH, /* Slow start size threshold */
TCP_NLA_DELIVERED, /* Data pkts delivered incl. out-of-order */
TCP_NLA_DELIVERED_CE, /* Like above but only ones w/ CE marks */
-
+ TCP_NLA_BYTES_SENT, /* Data bytes sent including retransmission */
+ TCP_NLA_BYTES_RETRANS, /* Data bytes retransmitted */
+ TCP_NLA_DSACK_DUPS, /* DSACK blocks received */
+ TCP_NLA_REORD_SEEN, /* reordering events seen */
};
/* for TCP_MD5SIG socket option */
diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h
index 93fb192..5cdda9d 100644
--- a/include/uapi/linux/xfrm.h
+++ b/include/uapi/linux/xfrm.h
@@ -305,9 +305,12 @@ enum xfrm_attr_type_t {
XFRMA_ADDRESS_FILTER, /* struct xfrm_address_filter */
XFRMA_PAD,
XFRMA_OFFLOAD_DEV, /* struct xfrm_state_offload */
- XFRMA_OUTPUT_MARK, /* __u32 */
+ XFRMA_SET_MARK, /* __u32 */
+ XFRMA_SET_MARK_MASK, /* __u32 */
+ XFRMA_IF_ID, /* __u32 */
__XFRMA_MAX
+#define XFRMA_OUTPUT_MARK XFRMA_SET_MARK /* Compatibility */
#define XFRMA_MAX (__XFRMA_MAX - 1)
};
--
1.8.3.1

View File

@ -1,46 +0,0 @@
From b99d3fd8b5a7dd140a2b4c7a7e70aea7478634f7 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Mon, 26 Nov 2018 19:11:55 +0100
Subject: [PATCH] man: ip-route.8: Document nexthop limit
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1625358
Upstream Status: iproute2.git commit 6cd959bb125c5
commit 6cd959bb125c50a04ab6671645fa38c5b07426f4
Author: Phil Sutter <phil@nwl.cc>
Date: Tue Nov 13 16:55:13 2018 +0100
man: ip-route.8: Document nexthop limit
Add a note to 'nexthop' description stating the maximum number of
nexthops per command and pointing at 'append' command as a workaround.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
man/man8/ip-route.8.in | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/man/man8/ip-route.8.in b/man/man8/ip-route.8.in
index b21a847..e464353 100644
--- a/man/man8/ip-route.8.in
+++ b/man/man8/ip-route.8.in
@@ -589,6 +589,15 @@ argument lists:
route reflecting its relative bandwidth or quality.
.in -8
+The internal buffer used in iproute2 limits the maximum number of nexthops that
+may be specified in one go. If only
+.I ADDRESS
+is given, the current buffer size allows for 144 IPv6 nexthops and 253 IPv4
+ones. For IPv4, this effectively limits the number of nexthops possible per
+route. With IPv6, further nexthops may be appended to the same route via
+.B "ip route append"
+command.
+
.TP
.BI scope " SCOPE_VAL"
the scope of the destinations covered by the route prefix.
--
1.8.3.1

View File

@ -1,101 +0,0 @@
From 06ce7afb4135de6ed92a286793cba5129f17f614 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Mon, 26 Nov 2018 19:11:55 +0100
Subject: [PATCH] ip-route: Fix nexthop encap parsing
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1625358
Upstream Status: iproute2.git commit 05d978e0850a6
commit 05d978e0850a6a3bae1e6c5392d82f7b1496f86a
Author: Phil Sutter <phil@nwl.cc>
Date: Tue Nov 13 13:39:04 2018 +0100
ip-route: Fix nexthop encap parsing
When parsing nexthop parameters, a buffer of 4k bytes is provided. Yet,
in lwt_parse_encap() and some functions called by it, buffer size was
assumed to be 1k despite the actual size was provided. This led to
spurious buffer size errors if the buffer was filled by previous nexthop
parameters to exceed that 1k boundary.
Fixes: 1e5293056a02c ("lwtunnel: Add encapsulation support to ip route")
Fixes: 5866bddd9aa9e ("ila: Add support for ILA lwtunnels")
Fixes: ed67f83806538 ("ila: Support for checksum neutral translation")
Fixes: 86905c8f057c0 ("ila: support for configuring identifier and hook types")
Fixes: b15f440e78373 ("lwt: BPF support for LWT")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/iproute_lwtunnel.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
index 4ebfaa7..388cd19 100644
--- a/ip/iproute_lwtunnel.c
+++ b/ip/iproute_lwtunnel.c
@@ -851,7 +851,7 @@ static int parse_encap_ila(struct rtattr *rta, size_t len,
argc--; argv++;
- if (rta_addattr64(rta, 1024, ILA_ATTR_LOCATOR, locator))
+ if (rta_addattr64(rta, len, ILA_ATTR_LOCATOR, locator))
return -1;
while (argc > 0) {
@@ -865,7 +865,7 @@ static int parse_encap_ila(struct rtattr *rta, size_t len,
invarg("\"csum-mode\" value is invalid\n",
*argv);
- ret = rta_addattr8(rta, 1024, ILA_ATTR_CSUM_MODE,
+ ret = rta_addattr8(rta, len, ILA_ATTR_CSUM_MODE,
(__u8)csum_mode);
argc--; argv++;
@@ -879,7 +879,7 @@ static int parse_encap_ila(struct rtattr *rta, size_t len,
invarg("\"ident-type\" value is invalid\n",
*argv);
- ret = rta_addattr8(rta, 1024, ILA_ATTR_IDENT_TYPE,
+ ret = rta_addattr8(rta, len, ILA_ATTR_IDENT_TYPE,
(__u8)ident_type);
argc--; argv++;
@@ -893,7 +893,7 @@ static int parse_encap_ila(struct rtattr *rta, size_t len,
invarg("\"hook-type\" value is invalid\n",
*argv);
- ret = rta_addattr8(rta, 1024, ILA_ATTR_HOOK_TYPE,
+ ret = rta_addattr8(rta, len, ILA_ATTR_HOOK_TYPE,
(__u8)hook_type);
argc--; argv++;
@@ -1016,7 +1016,7 @@ static int parse_encap_bpf(struct rtattr *rta, size_t len, int *argcp,
if (get_unsigned(&headroom, *argv, 0) || headroom == 0)
invarg("headroom is invalid\n", *argv);
if (!headroom_set)
- rta_addattr32(rta, 1024, LWT_BPF_XMIT_HEADROOM,
+ rta_addattr32(rta, len, LWT_BPF_XMIT_HEADROOM,
headroom);
headroom_set = 1;
} else if (strcmp(*argv, "help") == 0) {
@@ -1057,7 +1057,7 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp)
exit(-1);
}
- nest = rta_nest(rta, 1024, RTA_ENCAP);
+ nest = rta_nest(rta, len, RTA_ENCAP);
switch (type) {
case LWTUNNEL_ENCAP_MPLS:
ret = parse_encap_mpls(rta, len, &argc, &argv);
@@ -1090,7 +1090,7 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp)
rta_nest_end(rta, nest);
- ret = rta_addattr16(rta, 1024, RTA_ENCAP_TYPE, type);
+ ret = rta_addattr16(rta, len, RTA_ENCAP_TYPE, type);
*argcp = argc;
*argvp = argv;
--
1.8.3.1

View File

@ -1,64 +0,0 @@
From d2662aea40d63db11a38dc8bcbc354eafe280b8a Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 11 Dec 2018 15:03:12 +0100
Subject: [PATCH] man: rdma: Add reference to rdma-resource.8
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1610334
Upstream Status: iproute2.git commit b2ec8f431402f
commit b2ec8f431402f621ed0a2435d895df55eb1354af
Author: Phil Sutter <phil@nwl.cc>
Date: Mon Nov 26 18:58:31 2018 +0100
man: rdma: Add reference to rdma-resource.8
All rdma-related man pages list each other in SEE ALSO section, only
rdma-resource.8 is missing. Add it for the sake of consistency.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
man/man8/rdma-dev.8 | 1 +
man/man8/rdma-link.8 | 1 +
man/man8/rdma.8 | 1 +
3 files changed, 3 insertions(+)
diff --git a/man/man8/rdma-dev.8 b/man/man8/rdma-dev.8
index 461681b..b7abfe1 100644
--- a/man/man8/rdma-dev.8
+++ b/man/man8/rdma-dev.8
@@ -49,6 +49,7 @@ Shows the state of specified RDMA device.
.SH SEE ALSO
.BR rdma (8),
.BR rdma-link (8),
+.BR rdma-resource (8),
.br
.SH AUTHOR
diff --git a/man/man8/rdma-link.8 b/man/man8/rdma-link.8
index 97dd8bb..bddf347 100644
--- a/man/man8/rdma-link.8
+++ b/man/man8/rdma-link.8
@@ -49,6 +49,7 @@ Shows the state of specified rdma link.
.SH SEE ALSO
.BR rdma (8),
.BR rdma-dev (8),
+.BR rdma-resource (8),
.br
.SH AUTHOR
diff --git a/man/man8/rdma.8 b/man/man8/rdma.8
index 12aa149..b2b5aef 100644
--- a/man/man8/rdma.8
+++ b/man/man8/rdma.8
@@ -106,6 +106,7 @@ Exit status is 0 if command was successful or a positive integer upon failure.
.SH SEE ALSO
.BR rdma-dev (8),
.BR rdma-link (8),
+.BR rdma-resource (8),
.br
.SH REPORTING BUGS
--
1.8.3.1

View File

@ -1,144 +0,0 @@
From 6549ac61c997af9a96d13cb4ae94d1a7b1993762 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 18 Dec 2018 17:34:35 +0100
Subject: [PATCH] iplink: fix incorrect any address handling for ip tunnels
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1626304
Upstream Status: iproute2.git commit fa1e658e84ab2
commit fa1e658e84ab267bb98955e44774831bb36f3861
Author: Hangbin Liu <liuhangbin@gmail.com>
Date: Tue Sep 18 17:48:40 2018 +0800
iplink: fix incorrect any address handling for ip tunnels
After commit d42c7891d26e4 ("utils: Do not reset family for default, any,
all addresses"), when call get_addr() for any/all addresses, we will set
addr->flags to ADDRTYPE_INET_UNSPEC if family is AF_INET/AF_INET6, which
makes is_addrtype_inet() checking passed and assigns incorrect address
to kernel. The ip link cmd will return error like:
]# ip link add ipip1 type ipip local any remote 1.1.1.1
RTNETLINK answers: Numerical result out of range
Fix it by using is_addrtype_inet_not_unspec() to avoid unspec addresses.
geneve, vxlan are not affected as they use AF_UNSPEC family when call
get_addr()
Reported-by: Jianlin Shi <jishi@redhat.com>
Fixes: d42c7891d26e4 ("utils: Do not reset family for default, any, all addresses")
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/link_gre.c | 4 ++--
ip/link_gre6.c | 4 ++--
ip/link_ip6tnl.c | 4 ++--
ip/link_iptnl.c | 4 ++--
ip/link_vti.c | 4 ++--
ip/link_vti6.c | 4 ++--
6 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/ip/link_gre.c b/ip/link_gre.c
index ede761b..1ee7ee1 100644
--- a/ip/link_gre.c
+++ b/ip/link_gre.c
@@ -395,9 +395,9 @@ get_failed:
addattr32(n, 1024, IFLA_GRE_OKEY, okey);
addattr_l(n, 1024, IFLA_GRE_IFLAGS, &iflags, 2);
addattr_l(n, 1024, IFLA_GRE_OFLAGS, &oflags, 2);
- if (is_addrtype_inet(&saddr))
+ if (is_addrtype_inet_not_unspec(&saddr))
addattr_l(n, 1024, IFLA_GRE_LOCAL, saddr.data, saddr.bytelen);
- if (is_addrtype_inet(&daddr))
+ if (is_addrtype_inet_not_unspec(&daddr))
addattr_l(n, 1024, IFLA_GRE_REMOTE, daddr.data, daddr.bytelen);
addattr_l(n, 1024, IFLA_GRE_PMTUDISC, &pmtudisc, 1);
if (ignore_df)
diff --git a/ip/link_gre6.c b/ip/link_gre6.c
index 181b2ea..20f9305 100644
--- a/ip/link_gre6.c
+++ b/ip/link_gre6.c
@@ -424,9 +424,9 @@ get_failed:
addattr32(n, 1024, IFLA_GRE_OKEY, okey);
addattr_l(n, 1024, IFLA_GRE_IFLAGS, &iflags, 2);
addattr_l(n, 1024, IFLA_GRE_OFLAGS, &oflags, 2);
- if (is_addrtype_inet(&saddr))
+ if (is_addrtype_inet_not_unspec(&saddr))
addattr_l(n, 1024, IFLA_GRE_LOCAL, saddr.data, saddr.bytelen);
- if (is_addrtype_inet(&daddr))
+ if (is_addrtype_inet_not_unspec(&daddr))
addattr_l(n, 1024, IFLA_GRE_REMOTE, daddr.data, daddr.bytelen);
if (link)
addattr32(n, 1024, IFLA_GRE_LINK, link);
diff --git a/ip/link_ip6tnl.c b/ip/link_ip6tnl.c
index c7fef2e..cfe2c5a 100644
--- a/ip/link_ip6tnl.c
+++ b/ip/link_ip6tnl.c
@@ -320,11 +320,11 @@ get_failed:
return 0;
}
- if (is_addrtype_inet(&saddr)) {
+ if (is_addrtype_inet_not_unspec(&saddr)) {
addattr_l(n, 1024, IFLA_IPTUN_LOCAL,
saddr.data, saddr.bytelen);
}
- if (is_addrtype_inet(&daddr)) {
+ if (is_addrtype_inet_not_unspec(&daddr)) {
addattr_l(n, 1024, IFLA_IPTUN_REMOTE,
daddr.data, daddr.bytelen);
}
diff --git a/ip/link_iptnl.c b/ip/link_iptnl.c
index 57f4d0c..7ec1594 100644
--- a/ip/link_iptnl.c
+++ b/ip/link_iptnl.c
@@ -325,11 +325,11 @@ get_failed:
return 0;
}
- if (is_addrtype_inet(&saddr)) {
+ if (is_addrtype_inet_not_unspec(&saddr)) {
addattr_l(n, 1024, IFLA_IPTUN_LOCAL,
saddr.data, saddr.bytelen);
}
- if (is_addrtype_inet(&daddr)) {
+ if (is_addrtype_inet_not_unspec(&daddr)) {
addattr_l(n, 1024, IFLA_IPTUN_REMOTE,
daddr.data, daddr.bytelen);
}
diff --git a/ip/link_vti.c b/ip/link_vti.c
index 6196a1c..3fff441 100644
--- a/ip/link_vti.c
+++ b/ip/link_vti.c
@@ -157,9 +157,9 @@ get_failed:
addattr32(n, 1024, IFLA_VTI_IKEY, ikey);
addattr32(n, 1024, IFLA_VTI_OKEY, okey);
- if (is_addrtype_inet(&saddr))
+ if (is_addrtype_inet_not_unspec(&saddr))
addattr_l(n, 1024, IFLA_VTI_LOCAL, saddr.data, saddr.bytelen);
- if (is_addrtype_inet(&daddr))
+ if (is_addrtype_inet_not_unspec(&daddr))
addattr_l(n, 1024, IFLA_VTI_REMOTE, daddr.data, daddr.bytelen);
addattr32(n, 1024, IFLA_VTI_FWMARK, fwmark);
if (link)
diff --git a/ip/link_vti6.c b/ip/link_vti6.c
index 4263615..f5a267a 100644
--- a/ip/link_vti6.c
+++ b/ip/link_vti6.c
@@ -159,9 +159,9 @@ get_failed:
addattr32(n, 1024, IFLA_VTI_IKEY, ikey);
addattr32(n, 1024, IFLA_VTI_OKEY, okey);
- if (is_addrtype_inet(&saddr))
+ if (is_addrtype_inet_not_unspec(&saddr))
addattr_l(n, 1024, IFLA_VTI_LOCAL, saddr.data, saddr.bytelen);
- if (is_addrtype_inet(&daddr))
+ if (is_addrtype_inet_not_unspec(&daddr))
addattr_l(n, 1024, IFLA_VTI_REMOTE, daddr.data, daddr.bytelen);
addattr32(n, 1024, IFLA_VTI_FWMARK, fwmark);
if (link)
--
1.8.3.1

View File

@ -1,45 +0,0 @@
From 7fa3df19e2b907e09b2de902a122daaff114ee0c Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 31 Jan 2019 16:48:25 +0100
Subject: [PATCH] l2tp: Fix printing of cookie and peer_cookie values
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1643805
Upstream Status: iproute2.git commit b876b7e2b492f
commit b876b7e2b492fa14ce1f3db6c18bf22b2df10132
Author: Andrea Claudi <aclaudi@redhat.com>
Date: Fri Nov 30 15:34:24 2018 +0100
l2tp: Fix printing of cookie and peer_cookie values
print_cookie() invocations miss %s format specifier.
While at it, align printout to the previous lines.
Fixes: 98453b65800f7 ("ip/l2tp: add JSON support")
Signed-off-by: Andrea Claudi <aclaudi@redhat.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/ipl2tp.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/ip/ipl2tp.c b/ip/ipl2tp.c
index 414a9eb..87c13db 100644
--- a/ip/ipl2tp.c
+++ b/ip/ipl2tp.c
@@ -311,10 +311,11 @@ static void print_session(struct l2tp_data *data)
print_uint(PRINT_FP, "peer_offset", " peer offset %u\n", 0);
if (p->cookie_len > 0)
- print_cookie("cookie", "cookie",
+ print_cookie("cookie", " cookie %s",
p->cookie, p->cookie_len);
+
if (p->peer_cookie_len > 0)
- print_cookie("peer_cookie", "peer cookie",
+ print_cookie("peer_cookie", " peer cookie %s",
p->peer_cookie, p->peer_cookie_len);
if (p->reorder_timeout != 0)
--
1.8.3.1

View File

@ -1,403 +0,0 @@
From 9dd748cd49d15b7e90a7a65de53d431a2c515c86 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 31 Jan 2019 17:13:07 +0100
Subject: [PATCH] tc: f_flower: add geneve option match support to flower
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1654761
Upstream Status: iproute2.git commit 56155d4df86d4
commit 56155d4df86d489c4207444c8a90ce4e0e22e49f
Author: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
Date: Fri Sep 28 16:03:39 2018 +0200
tc: f_flower: add geneve option match support to flower
Allow matching on options in Geneve tunnel headers.
The options can be described in the form
CLASS:TYPE:DATA/CLASS_MASK:TYPE_MASK:DATA_MASK, where CLASS is
represented as a 16bit hexadecimal value, TYPE as an 8bit
hexadecimal value and DATA as a variable length hexadecimal value.
e.g.
# ip link add name geneve0 type geneve dstport 0 external
# tc qdisc add dev geneve0 ingress
# tc filter add dev geneve0 protocol ip parent ffff: \
flower \
enc_src_ip 10.0.99.192 \
enc_dst_ip 10.0.99.193 \
enc_key_id 11 \
geneve_opts 0102:80:1122334421314151/ffff:ff:ffffffffffffffff \
ip_proto udp \
action mirred egress redirect dev eth1
Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
Signed-off-by: Simon Horman <simon.horman@netronome.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
man/man8/tc-flower.8 | 13 ++-
tc/f_flower.c | 282 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 294 insertions(+), 1 deletion(-)
diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8
index f917f24..276b527 100644
--- a/man/man8/tc-flower.8
+++ b/man/man8/tc-flower.8
@@ -74,6 +74,8 @@ flower \- flow based traffic control filter
.IR TOS " | "
.B enc_ttl
.IR TTL " | "
+.B geneve_opts
+.IR OPTIONS " | "
.BR ip_flags
.IR IP_FLAGS
.SH DESCRIPTION
@@ -260,6 +262,8 @@ bits is assumed.
.BI enc_tos " NUMBER"
.TQ
.BI enc_ttl " NUMBER"
+.TQ
+.BI geneve_opts " OPTIONS"
Match on IP tunnel metadata. Key id
.I NUMBER
is a 32 bit tunnel key id (e.g. VNI for VXLAN tunnel).
@@ -272,7 +276,14 @@ is a 16 bit UDP dst port. Tos
.I NUMBER
is an 8 bit tos (dscp+ecn) value, ttl
.I NUMBER
-is an 8 bit time-to-live value.
+is an 8 bit time-to-live value. geneve_opts
+.I OPTIONS
+must be a valid list of comma-separated geneve options where each option
+consists of a key optionally followed by a slash and corresponding mask. If
+the masks is missing, \fBtc\fR assumes a full-length match. The options can
+be described in the form CLASS:TYPE:DATA/CLASS_MASK:TYPE_MASK:DATA_MASK,
+where CLASS is represented as a 16bit hexadecimal value, TYPE as an 8bit
+hexadecimal value and DATA as a variable length hexadecimal value.
.TP
.BI ip_flags " IP_FLAGS"
.I IP_FLAGS
diff --git a/tc/f_flower.c b/tc/f_flower.c
index cd102f2..43102c8 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -76,6 +76,7 @@ static void explain(void)
" enc_key_id [ KEY-ID ] |\n"
" enc_tos MASKED-IP_TOS |\n"
" enc_ttl MASKED-IP_TTL |\n"
+ " geneve_opts MASKED-OPTIONS |\n"
" ip_flags IP-FLAGS | \n"
" enc_dst_port [ port_number ] }\n"
" FILTERID := X:Y:Z\n"
@@ -580,6 +581,179 @@ static int flower_parse_enc_port(char *str, int type, struct nlmsghdr *n)
return 0;
}
+static int flower_parse_geneve_opts(char *str, struct nlmsghdr *n)
+{
+ struct rtattr *nest;
+ char *token;
+ int i, err;
+
+ nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS_GENEVE);
+
+ i = 1;
+ token = strsep(&str, ":");
+ while (token) {
+ switch (i) {
+ case TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS:
+ {
+ __be16 opt_class;
+
+ if (!strlen(token))
+ break;
+ err = get_be16(&opt_class, token, 16);
+ if (err)
+ return err;
+
+ addattr16(n, MAX_MSG, i, opt_class);
+ break;
+ }
+ case TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE:
+ {
+ __u8 opt_type;
+
+ if (!strlen(token))
+ break;
+ err = get_u8(&opt_type, token, 16);
+ if (err)
+ return err;
+
+ addattr8(n, MAX_MSG, i, opt_type);
+ break;
+ }
+ case TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA:
+ {
+ size_t token_len = strlen(token);
+ __u8 *opts;
+
+ if (!token_len)
+ break;
+ opts = malloc(token_len / 2);
+ if (!opts)
+ return -1;
+ if (hex2mem(token, opts, token_len / 2) < 0) {
+ free(opts);
+ return -1;
+ }
+ addattr_l(n, MAX_MSG, i, opts, token_len / 2);
+ free(opts);
+
+ break;
+ }
+ default:
+ fprintf(stderr, "Unknown \"geneve_opts\" type\n");
+ return -1;
+ }
+
+ token = strsep(&str, ":");
+ i++;
+ }
+ addattr_nest_end(n, nest);
+
+ return 0;
+}
+
+static int flower_parse_enc_opt_part(char *str, struct nlmsghdr *n)
+{
+ char *token;
+ int err;
+
+ token = strsep(&str, ",");
+ while (token) {
+ err = flower_parse_geneve_opts(token, n);
+ if (err)
+ return err;
+
+ token = strsep(&str, ",");
+ }
+
+ return 0;
+}
+
+static int flower_check_enc_opt_key(char *key)
+{
+ int key_len, col_cnt = 0;
+
+ key_len = strlen(key);
+ while ((key = strchr(key, ':'))) {
+ if (strlen(key) == key_len)
+ return -1;
+
+ key_len = strlen(key) - 1;
+ col_cnt++;
+ key++;
+ }
+
+ if (col_cnt != 2 || !key_len)
+ return -1;
+
+ return 0;
+}
+
+static int flower_parse_enc_opts(char *str, struct nlmsghdr *n)
+{
+ char key[XATTR_SIZE_MAX], mask[XATTR_SIZE_MAX];
+ int data_len, key_len, mask_len, err;
+ char *token, *slash;
+ struct rtattr *nest;
+
+ key_len = 0;
+ mask_len = 0;
+ token = strsep(&str, ",");
+ while (token) {
+ slash = strchr(token, '/');
+ if (slash)
+ *slash = '\0';
+
+ if ((key_len + strlen(token) > XATTR_SIZE_MAX) ||
+ flower_check_enc_opt_key(token))
+ return -1;
+
+ strcpy(&key[key_len], token);
+ key_len += strlen(token) + 1;
+ key[key_len - 1] = ',';
+
+ if (!slash) {
+ /* Pad out mask when not provided */
+ if (mask_len + strlen(token) > XATTR_SIZE_MAX)
+ return -1;
+
+ data_len = strlen(rindex(token, ':'));
+ sprintf(&mask[mask_len], "ffff:ff:");
+ mask_len += 8;
+ memset(&mask[mask_len], 'f', data_len - 1);
+ mask_len += data_len;
+ mask[mask_len - 1] = ',';
+ token = strsep(&str, ",");
+ continue;
+ }
+
+ if (mask_len + strlen(slash + 1) > XATTR_SIZE_MAX)
+ return -1;
+
+ strcpy(&mask[mask_len], slash + 1);
+ mask_len += strlen(slash + 1) + 1;
+ mask[mask_len - 1] = ',';
+
+ *slash = '/';
+ token = strsep(&str, ",");
+ }
+ key[key_len - 1] = '\0';
+ mask[mask_len - 1] = '\0';
+
+ nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS);
+ err = flower_parse_enc_opt_part(key, n);
+ if (err)
+ return err;
+ addattr_nest_end(n, nest);
+
+ nest = addattr_nest(n, MAX_MSG, TCA_FLOWER_KEY_ENC_OPTS_MASK);
+ err = flower_parse_enc_opt_part(mask, n);
+ if (err)
+ return err;
+ addattr_nest_end(n, nest);
+
+ return 0;
+}
+
static int flower_parse_opt(struct filter_util *qu, char *handle,
int argc, char **argv, struct nlmsghdr *n)
{
@@ -994,6 +1168,13 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
fprintf(stderr, "Illegal \"enc_ttl\"\n");
return -1;
}
+ } else if (matches(*argv, "geneve_opts") == 0) {
+ NEXT_ARG();
+ ret = flower_parse_enc_opts(*argv, n);
+ if (ret < 0) {
+ fprintf(stderr, "Illegal \"geneve_opts\"\n");
+ return -1;
+ }
} else if (matches(*argv, "action") == 0) {
NEXT_ARG();
ret = parse_action(&argc, &argv, TCA_FLOWER_ACT, n);
@@ -1291,6 +1472,105 @@ static void flower_print_key_id(const char *name, struct rtattr *attr)
print_uint(PRINT_ANY, name, namefrm, rta_getattr_be32(attr));
}
+static void flower_print_geneve_opts(const char *name, struct rtattr *attr,
+ char *strbuf)
+{
+ struct rtattr *tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX + 1];
+ int ii, data_len, offset = 0, slen = 0;
+ struct rtattr *i = RTA_DATA(attr);
+ int rem = RTA_PAYLOAD(attr);
+ __u8 type, data_r[rem];
+ char data[rem * 2 + 1];
+ __u16 class;
+
+ open_json_array(PRINT_JSON, name);
+ while (rem) {
+ parse_rtattr(tb, TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX, i, rem);
+ class = rta_getattr_be16(tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS]);
+ type = rta_getattr_u8(tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE]);
+ data_len = RTA_PAYLOAD(tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA]);
+ hexstring_n2a(RTA_DATA(tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA]),
+ data_len, data, sizeof(data));
+ hex2mem(data, data_r, data_len);
+ offset += data_len + 20;
+ rem -= data_len + 20;
+ i = RTA_DATA(attr) + offset;
+
+ open_json_object(NULL);
+ print_uint(PRINT_JSON, "class", NULL, class);
+ print_uint(PRINT_JSON, "type", NULL, type);
+ open_json_array(PRINT_JSON, "data");
+ for (ii = 0; ii < data_len; ii++)
+ print_uint(PRINT_JSON, NULL, NULL, data_r[ii]);
+ close_json_array(PRINT_JSON, "data");
+ close_json_object();
+
+ slen += sprintf(strbuf + slen, "%04x:%02x:%s",
+ class, type, data);
+ if (rem)
+ slen += sprintf(strbuf + slen, ",");
+ }
+ close_json_array(PRINT_JSON, name);
+}
+
+static void flower_print_geneve_parts(const char *name, struct rtattr *attr,
+ char *key, char *mask)
+{
+ char *namefrm = "\n geneve_opt %s";
+ char *key_token, *mask_token, *out;
+ int len;
+
+ out = malloc(RTA_PAYLOAD(attr) * 4 + 3);
+ if (!out)
+ return;
+
+ len = 0;
+ key_token = strsep(&key, ",");
+ mask_token = strsep(&mask, ",");
+ while (key_token) {
+ len += sprintf(&out[len], "%s/%s,", key_token, mask_token);
+ mask_token = strsep(&mask, ",");
+ key_token = strsep(&key, ",");
+ }
+
+ out[len - 1] = '\0';
+ print_string(PRINT_FP, name, namefrm, out);
+ free(out);
+}
+
+static void flower_print_enc_opts(const char *name, struct rtattr *attr,
+ struct rtattr *mask_attr)
+{
+ struct rtattr *key_tb[TCA_FLOWER_KEY_ENC_OPTS_MAX + 1];
+ struct rtattr *msk_tb[TCA_FLOWER_KEY_ENC_OPTS_MAX + 1];
+ char *key, *msk;
+
+ if (!attr)
+ return;
+
+ key = malloc(RTA_PAYLOAD(attr) * 2 + 1);
+ if (!key)
+ return;
+
+ msk = malloc(RTA_PAYLOAD(attr) * 2 + 1);
+ if (!msk)
+ goto err_key_free;
+
+ parse_rtattr_nested(key_tb, TCA_FLOWER_KEY_ENC_OPTS_MAX, attr);
+ flower_print_geneve_opts("geneve_opt_key",
+ key_tb[TCA_FLOWER_KEY_ENC_OPTS_GENEVE], key);
+
+ parse_rtattr_nested(msk_tb, TCA_FLOWER_KEY_ENC_OPTS_MAX, mask_attr);
+ flower_print_geneve_opts("geneve_opt_mask",
+ msk_tb[TCA_FLOWER_KEY_ENC_OPTS_GENEVE], msk);
+
+ flower_print_geneve_parts(name, attr, key, msk);
+
+ free(msk);
+err_key_free:
+ free(key);
+}
+
static void flower_print_masked_u8(const char *name, struct rtattr *attr,
struct rtattr *mask_attr,
const char *(*value_to_str)(__u8 value))
@@ -1489,6 +1769,8 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
tb[TCA_FLOWER_KEY_ENC_IP_TOS_MASK]);
flower_print_ip_attr("enc_ttl", tb[TCA_FLOWER_KEY_ENC_IP_TTL],
tb[TCA_FLOWER_KEY_ENC_IP_TTL_MASK]);
+ flower_print_enc_opts("enc_opt", tb[TCA_FLOWER_KEY_ENC_OPTS],
+ tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]);
flower_print_matching_flags("ip_flags", FLOWER_IP_FLAGS,
tb[TCA_FLOWER_KEY_FLAGS],
--
1.8.3.1

View File

@ -1,292 +0,0 @@
From d75736d332f6aa0fcd12352e2d2a5c1aa65c6464 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 31 Jan 2019 17:13:07 +0100
Subject: [PATCH] tc: m_tunnel_key: Add tunnel option support to act_tunnel_key
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1654761
Upstream Status: iproute2.git commit 6217917a38268
Conflicts: Context change due to previous backport of tos and ttl
support.
commit 6217917a382682d8e8a7ecdeb0c6626f701a0933
Author: Simon Horman <simon.horman@netronome.com>
Date: Thu Jul 5 17:12:00 2018 -0700
tc: m_tunnel_key: Add tunnel option support to act_tunnel_key
Allow setting tunnel options using the act_tunnel_key action.
Options are expressed as class:type:data and multiple options
may be listed using a comma delimiter.
# ip link add name geneve0 type geneve dstport 0 external
# tc qdisc add dev eth0 ingress
# tc filter add dev eth0 protocol ip parent ffff: \
flower indev eth0 \
ip_proto udp \
action tunnel_key \
set src_ip 10.0.99.192 \
dst_ip 10.0.99.193 \
dst_port 6081 \
id 11 \
geneve_opts 0102:80:00800022,0102:80:00800022 \
action mirred egress redirect dev geneve0
Signed-off-by: Simon Horman <simon.horman@netronome.com>
Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
man/man8/tc-tunnel_key.8 | 12 +++-
tc/m_tunnel_key.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 188 insertions(+), 1 deletion(-)
diff --git a/man/man8/tc-tunnel_key.8 b/man/man8/tc-tunnel_key.8
index 71cee5b..1e09362 100644
--- a/man/man8/tc-tunnel_key.8
+++ b/man/man8/tc-tunnel_key.8
@@ -66,7 +66,9 @@ and
.B dst_ip
options.
.B dst_port
-is optional.
+and
+.B geneve_opts
+are optional.
.RS
.TP
.B id
@@ -81,6 +83,14 @@ Outer header destination IP address (IPv4 or IPv6)
.B dst_port
Outer header destination UDP port
.TP
+.B geneve_opts
+Geneve variable length options.
+.B geneve_opts
+is specified in the form CLASS:TYPE:DATA, where CLASS is represented as a
+16bit hexadecimal value, TYPE as an 8bit hexadecimal value and DATA as a
+variable length hexadecimal value. Additionally multiple options may be
+listed using a comma delimiter.
+.TP
.B tos
Outer header TOS
.TP
diff --git a/tc/m_tunnel_key.c b/tc/m_tunnel_key.c
index 8d0a8d1..e9e71e4 100644
--- a/tc/m_tunnel_key.c
+++ b/tc/m_tunnel_key.c
@@ -29,6 +29,7 @@ static void explain(void)
"src_ip <IP> (mandatory)\n"
"dst_ip <IP> (mandatory)\n"
"dst_port <UDP_PORT>\n"
+ "geneve_opts <OPTIONS>\n"
"csum | nocsum (default is \"csum\")\n");
}
@@ -81,6 +82,114 @@ static int tunnel_key_parse_dst_port(char *str, int type, struct nlmsghdr *n)
return 0;
}
+static int tunnel_key_parse_be16(char *str, int base, int type,
+ struct nlmsghdr *n)
+{
+ int ret;
+ __be16 value;
+
+ ret = get_be16(&value, str, base);
+ if (ret)
+ return ret;
+
+ addattr16(n, MAX_MSG, type, value);
+
+ return 0;
+}
+
+static int tunnel_key_parse_u8(char *str, int base, int type,
+ struct nlmsghdr *n)
+{
+ int ret;
+ __u8 value;
+
+ ret = get_u8(&value, str, base);
+ if (ret)
+ return ret;
+
+ addattr8(n, MAX_MSG, type, value);
+
+ return 0;
+}
+
+static int tunnel_key_parse_geneve_opt(char *str, struct nlmsghdr *n)
+{
+ char *token, *saveptr = NULL;
+ struct rtattr *nest;
+ int i, ret;
+
+ nest = addattr_nest(n, MAX_MSG, TCA_TUNNEL_KEY_ENC_OPTS_GENEVE);
+
+ token = strtok_r(str, ":", &saveptr);
+ i = 1;
+ while (token) {
+ switch (i) {
+ case TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS:
+ {
+ ret = tunnel_key_parse_be16(token, 16, i, n);
+ if (ret)
+ return ret;
+ break;
+ }
+ case TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE:
+ {
+ ret = tunnel_key_parse_u8(token, 16, i, n);
+ if (ret)
+ return ret;
+ break;
+ }
+ case TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA:
+ {
+ size_t token_len = strlen(token);
+ uint8_t *opts;
+
+ opts = malloc(token_len / 2);
+ if (!opts)
+ return -1;
+ if (hex2mem(token, opts, token_len / 2) < 0) {
+ free(opts);
+ return -1;
+ }
+ addattr_l(n, MAX_MSG, i, opts, token_len / 2);
+ free(opts);
+
+ break;
+ }
+ default:
+ return -1;
+ }
+
+ token = strtok_r(NULL, ":", &saveptr);
+ i++;
+ }
+
+ addattr_nest_end(n, nest);
+
+ return 0;
+}
+
+static int tunnel_key_parse_geneve_opts(char *str, struct nlmsghdr *n)
+{
+ char *token, *saveptr = NULL;
+ struct rtattr *nest;
+ int ret;
+
+ nest = addattr_nest(n, MAX_MSG, TCA_TUNNEL_KEY_ENC_OPTS);
+
+ token = strtok_r(str, ",", &saveptr);
+ while (token) {
+ ret = tunnel_key_parse_geneve_opt(token, n);
+ if (ret)
+ return ret;
+
+ token = strtok_r(NULL, ",", &saveptr);
+ }
+
+ addattr_nest_end(n, nest);
+
+ return 0;
+}
+
static int tunnel_key_parse_tos_ttl(char *str, int type, struct nlmsghdr *n)
{
int ret;
@@ -173,6 +282,13 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p,
fprintf(stderr, "Illegal \"dst port\"\n");
return -1;
}
+ } else if (matches(*argv, "geneve_opts") == 0) {
+ NEXT_ARG();
+
+ if (tunnel_key_parse_geneve_opts(*argv, n)) {
+ fprintf(stderr, "Illegal \"geneve_opts\"\n");
+ return -1;
+ }
} else if (matches(*argv, "tos") == 0) {
NEXT_ARG();
ret = tunnel_key_parse_tos_ttl(*argv,
@@ -292,6 +408,65 @@ static void tunnel_key_print_flag(FILE *f, const char *name_on,
rta_getattr_u8(attr) ? name_on : name_off);
}
+static void tunnel_key_print_geneve_options(const char *name,
+ struct rtattr *attr)
+{
+ struct rtattr *tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX + 1];
+ struct rtattr *i = RTA_DATA(attr);
+ int ii, data_len = 0, offset = 0;
+ int rem = RTA_PAYLOAD(attr);
+ char strbuf[rem * 2 + 1];
+ char data[rem * 2 + 1];
+ uint8_t data_r[rem];
+ uint16_t clss;
+ uint8_t type;
+
+ open_json_array(PRINT_JSON, name);
+ print_string(PRINT_FP, name, "\n\t%s ", "geneve_opt");
+
+ while (rem) {
+ parse_rtattr(tb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX, i, rem);
+ clss = rta_getattr_be16(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS]);
+ type = rta_getattr_u8(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE]);
+ data_len = RTA_PAYLOAD(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]);
+ hexstring_n2a(RTA_DATA(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]),
+ data_len, data, sizeof(data));
+ hex2mem(data, data_r, data_len);
+ offset += data_len + 20;
+ rem -= data_len + 20;
+ i = RTA_DATA(attr) + offset;
+
+ open_json_object(NULL);
+ print_uint(PRINT_JSON, "class", NULL, clss);
+ print_uint(PRINT_JSON, "type", NULL, type);
+ open_json_array(PRINT_JSON, "data");
+ for (ii = 0; ii < data_len; ii++)
+ print_uint(PRINT_JSON, NULL, NULL, data_r[ii]);
+ close_json_array(PRINT_JSON, "data");
+ close_json_object();
+
+ sprintf(strbuf, "%04x:%02x:%s", clss, type, data);
+ if (rem)
+ print_string(PRINT_FP, NULL, "%s,", strbuf);
+ else
+ print_string(PRINT_FP, NULL, "%s", strbuf);
+ }
+
+ close_json_array(PRINT_JSON, name);
+}
+
+static void tunnel_key_print_key_opt(const char *name, struct rtattr *attr)
+{
+ struct rtattr *tb[TCA_TUNNEL_KEY_ENC_OPTS_MAX + 1];
+
+ if (!attr)
+ return;
+
+ parse_rtattr_nested(tb, TCA_TUNNEL_KEY_ENC_OPTS_MAX, attr);
+ tunnel_key_print_geneve_options(name,
+ tb[TCA_TUNNEL_KEY_ENC_OPTS_GENEVE]);
+}
+
static void tunnel_key_print_tos_ttl(FILE *f, char *name,
struct rtattr *attr)
{
@@ -346,6 +521,8 @@ static int print_tunnel_key(struct action_util *au, FILE *f, struct rtattr *arg)
tb[TCA_TUNNEL_KEY_ENC_KEY_ID]);
tunnel_key_print_dst_port(f, "dst_port",
tb[TCA_TUNNEL_KEY_ENC_DST_PORT]);
+ tunnel_key_print_key_opt("geneve_opts",
+ tb[TCA_TUNNEL_KEY_ENC_OPTS]);
tunnel_key_print_flag(f, "nocsum", "csum",
tb[TCA_TUNNEL_KEY_NO_CSUM]);
tunnel_key_print_tos_ttl(f, "tos",
--
1.8.3.1

View File

@ -1,121 +0,0 @@
From ec8d7120bf3b8fd47937e9297468e0bb7c1f270c Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Wed, 29 May 2019 17:40:35 +0200
Subject: [PATCH] ip rule: Add ipproto and port range to filter list
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1678111
Upstream Status: iproute2.git commit b2e8bf1584605
commit b2e8bf158460568ec5b48cba69f657f95891c901
Author: David Ahern <dsahern@gmail.com>
Date: Tue Oct 30 15:03:30 2018 -0700
ip rule: Add ipproto and port range to filter list
Allow ip rule dumps and flushes to filter based on ipproto, sport
and dport. Example:
$ ip ru ls ipproto udp
99: from all to 8.8.8.8 ipproto udp dport 53 lookup 1001
$ ip ru ls dport 53
99: from all to 8.8.8.8 ipproto udp dport 53 lookup 1001
Signed-off-by: David Ahern <dsahern@gmail.com>
---
ip/iprule.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/ip/iprule.c b/ip/iprule.c
index 744d6d88e3433..33160eafa2b33 100644
--- a/ip/iprule.c
+++ b/ip/iprule.c
@@ -78,6 +78,9 @@ static struct
inet_prefix dst;
int protocol;
int protocolmask;
+ struct fib_rule_port_range sport;
+ struct fib_rule_port_range dport;
+ __u8 ipproto;
} filter;
static inline int frh_get_table(struct fib_rule_hdr *frh, struct rtattr **tb)
@@ -174,6 +177,39 @@ static bool filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
return false;
}
+ if (filter.ipproto) {
+ __u8 ipproto = 0;
+
+ if (tb[FRA_IP_PROTO])
+ ipproto = rta_getattr_u8(tb[FRA_IP_PROTO]);
+ if (filter.ipproto != ipproto)
+ return false;
+ }
+
+ if (filter.sport.start) {
+ const struct fib_rule_port_range *r;
+
+ if (!tb[FRA_SPORT_RANGE])
+ return false;
+
+ r = RTA_DATA(tb[FRA_SPORT_RANGE]);
+ if (r->start != filter.sport.start ||
+ r->end != filter.sport.end)
+ return false;
+ }
+
+ if (filter.dport.start) {
+ const struct fib_rule_port_range *r;
+
+ if (!tb[FRA_DPORT_RANGE])
+ return false;
+
+ r = RTA_DATA(tb[FRA_DPORT_RANGE]);
+ if (r->start != filter.dport.start ||
+ r->end != filter.dport.end)
+ return false;
+ }
+
table = frh_get_table(frh, tb);
if (filter.tb > 0 && filter.tb ^ table)
return false;
@@ -604,6 +640,36 @@ static int iprule_list_flush_or_save(int argc, char **argv, int action)
filter.protocolmask = 0;
}
filter.protocol = prot;
+ } else if (strcmp(*argv, "ipproto") == 0) {
+ int ipproto;
+
+ NEXT_ARG();
+ ipproto = inet_proto_a2n(*argv);
+ if (ipproto < 0)
+ invarg("Invalid \"ipproto\" value\n", *argv);
+ filter.ipproto = ipproto;
+ } else if (strcmp(*argv, "sport") == 0) {
+ struct fib_rule_port_range r;
+ int ret;
+
+ NEXT_ARG();
+ ret = sscanf(*argv, "%hu-%hu", &r.start, &r.end);
+ if (ret == 1)
+ r.end = r.start;
+ else if (ret != 2)
+ invarg("invalid port range\n", *argv);
+ filter.sport = r;
+ } else if (strcmp(*argv, "dport") == 0) {
+ struct fib_rule_port_range r;
+ int ret;
+
+ NEXT_ARG();
+ ret = sscanf(*argv, "%hu-%hu", &r.start, &r.end);
+ if (ret == 1)
+ r.end = r.start;
+ else if (ret != 2)
+ invarg("invalid dport range\n", *argv);
+ filter.dport = r;
} else{
if (matches(*argv, "dst") == 0 ||
matches(*argv, "to") == 0) {
--
2.20.1

View File

@ -1,273 +0,0 @@
From b485126fd0a84a09f3d61bb4d634011be92fb6a4 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Wed, 29 May 2019 18:28:17 +0200
Subject: [PATCH] tc: flower: Add support for QinQ
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1615928
Upstream Status: iproute2.git commit 1f0a5dfd388cd
commit 1f0a5dfd388cd5c25f6a24247667e04b2346e568
Author: Jianbo Liu <jianbol@mellanox.com>
Date: Sat Jun 30 10:01:33 2018 +0000
tc: flower: Add support for QinQ
To support matching on both outer and inner vlan headers,
we add new cvlan_id/cvlan_prio/cvlan_ethtype for inner vlan header.
Example:
# tc filter add dev eth0 protocol 802.1ad parent ffff: \
flower vlan_id 1000 vlan_ethtype 802.1q \
cvlan_id 100 cvlan_ethtype ipv4 \
action vlan pop \
action vlan pop \
action mirred egress redirect dev eth1
# tc filter show dev eth0 ingress
filter protocol 802.1ad pref 1 flower chain 0
filter protocol 802.1ad pref 1 flower chain 0 handle 0x1
  vlan_id 1000
  vlan_ethtype 802.1Q
  cvlan_id 100
  cvlan_ethtype ip
  eth_type ipv4
  in_hw
Signed-off-by: Jianbo Liu <jianbol@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
man/man8/tc-flower.8 | 23 ++++++++++
tc/f_flower.c | 103 ++++++++++++++++++++++++++++++++++++++-----
2 files changed, 114 insertions(+), 12 deletions(-)
diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8
index 276b5271cf013..8be8882592eaa 100644
--- a/man/man8/tc-flower.8
+++ b/man/man8/tc-flower.8
@@ -34,6 +34,12 @@ flower \- flow based traffic control filter
.IR PRIORITY " | "
.BR vlan_ethtype " { " ipv4 " | " ipv6 " | "
.IR ETH_TYPE " } | "
+.B cvlan_id
+.IR VID " | "
+.B cvlan_prio
+.IR PRIORITY " | "
+.BR cvlan_ethtype " { " ipv4 " | " ipv6 " | "
+.IR ETH_TYPE " } | "
.B mpls_label
.IR LABEL " | "
.B mpls_tc
@@ -145,6 +151,23 @@ Match on layer three protocol.
.I VLAN_ETH_TYPE
may be either
.BR ipv4 ", " ipv6
+or an unsigned 16bit value in hexadecimal format. To match on QinQ packet, it must be 802.1Q or 802.1AD.
+.TP
+.BI cvlan_id " VID"
+Match on QinQ inner vlan tag id.
+.I VID
+is an unsigned 12bit value in decimal format.
+.TP
+.BI cvlan_prio " PRIORITY"
+Match on QinQ inner vlan tag priority.
+.I PRIORITY
+is an unsigned 3bit value in decimal format.
+.TP
+.BI cvlan_ethtype " VLAN_ETH_TYPE"
+Match on QinQ layer three protocol.
+.I VLAN_ETH_TYPE
+may be either
+.BR ipv4 ", " ipv6
or an unsigned 16bit value in hexadecimal format.
.TP
.BI mpls_label " LABEL"
diff --git a/tc/f_flower.c b/tc/f_flower.c
index 43102c86d1597..634bb81af7dbb 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -50,6 +50,9 @@ static void explain(void)
" vlan_id VID |\n"
" vlan_prio PRIORITY |\n"
" vlan_ethtype [ ipv4 | ipv6 | ETH-TYPE ] |\n"
+ " cvlan_id VID |\n"
+ " cvlan_prio PRIORITY |\n"
+ " cvlan_ethtype [ ipv4 | ipv6 | ETH-TYPE ] |\n"
" dst_mac MASKED-LLADDR |\n"
" src_mac MASKED-LLADDR |\n"
" ip_proto [tcp | udp | sctp | icmp | icmpv6 | IP-PROTO ] |\n"
@@ -131,15 +134,21 @@ err:
return err;
}
+static bool eth_type_vlan(__be16 ethertype)
+{
+ return ethertype == htons(ETH_P_8021Q) ||
+ ethertype == htons(ETH_P_8021AD);
+}
+
static int flower_parse_vlan_eth_type(char *str, __be16 eth_type, int type,
__be16 *p_vlan_eth_type,
struct nlmsghdr *n)
{
__be16 vlan_eth_type;
- if (eth_type != htons(ETH_P_8021Q)) {
- fprintf(stderr,
- "Can't set \"vlan_ethtype\" if ethertype isn't 802.1Q\n");
+ if (!eth_type_vlan(eth_type)) {
+ fprintf(stderr, "Can't set \"%s\" if ethertype isn't 802.1Q or 802.1AD\n",
+ type == TCA_FLOWER_KEY_VLAN_ETH_TYPE ? "vlan_ethtype" : "cvlan_ethtype");
return -1;
}
@@ -762,6 +771,7 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
struct rtattr *tail;
__be16 eth_type = TC_H_MIN(t->tcm_info);
__be16 vlan_ethtype = 0;
+ __be16 cvlan_ethtype = 0;
__u8 ip_proto = 0xff;
__u32 flags = 0;
__u32 mtf = 0;
@@ -839,9 +849,8 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
__u16 vid;
NEXT_ARG();
- if (eth_type != htons(ETH_P_8021Q)) {
- fprintf(stderr,
- "Can't set \"vlan_id\" if ethertype isn't 802.1Q\n");
+ if (!eth_type_vlan(eth_type)) {
+ fprintf(stderr, "Can't set \"vlan_id\" if ethertype isn't 802.1Q or 802.1AD\n");
return -1;
}
ret = get_u16(&vid, *argv, 10);
@@ -854,9 +863,8 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
__u8 vlan_prio;
NEXT_ARG();
- if (eth_type != htons(ETH_P_8021Q)) {
- fprintf(stderr,
- "Can't set \"vlan_prio\" if ethertype isn't 802.1Q\n");
+ if (!eth_type_vlan(eth_type)) {
+ fprintf(stderr, "Can't set \"vlan_prio\" if ethertype isn't 802.1Q or 802.1AD\n");
return -1;
}
ret = get_u8(&vlan_prio, *argv, 10);
@@ -873,6 +881,42 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
&vlan_ethtype, n);
if (ret < 0)
return -1;
+ } else if (matches(*argv, "cvlan_id") == 0) {
+ __u16 vid;
+
+ NEXT_ARG();
+ if (!eth_type_vlan(vlan_ethtype)) {
+ fprintf(stderr, "Can't set \"cvlan_id\" if inner vlan ethertype isn't 802.1Q or 802.1AD\n");
+ return -1;
+ }
+ ret = get_u16(&vid, *argv, 10);
+ if (ret < 0 || vid & ~0xfff) {
+ fprintf(stderr, "Illegal \"cvlan_id\"\n");
+ return -1;
+ }
+ addattr16(n, MAX_MSG, TCA_FLOWER_KEY_CVLAN_ID, vid);
+ } else if (matches(*argv, "cvlan_prio") == 0) {
+ __u8 cvlan_prio;
+
+ NEXT_ARG();
+ if (!eth_type_vlan(vlan_ethtype)) {
+ fprintf(stderr, "Can't set \"cvlan_prio\" if inner vlan ethertype isn't 802.1Q or 802.1AD\n");
+ return -1;
+ }
+ ret = get_u8(&cvlan_prio, *argv, 10);
+ if (ret < 0 || cvlan_prio & ~0x7) {
+ fprintf(stderr, "Illegal \"cvlan_prio\"\n");
+ return -1;
+ }
+ addattr8(n, MAX_MSG,
+ TCA_FLOWER_KEY_CVLAN_PRIO, cvlan_prio);
+ } else if (matches(*argv, "cvlan_ethtype") == 0) {
+ NEXT_ARG();
+ ret = flower_parse_vlan_eth_type(*argv, vlan_ethtype,
+ TCA_FLOWER_KEY_CVLAN_ETH_TYPE,
+ &cvlan_ethtype, n);
+ if (ret < 0)
+ return -1;
} else if (matches(*argv, "mpls_label") == 0) {
__u32 label;
@@ -959,7 +1003,8 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
}
} else if (matches(*argv, "ip_proto") == 0) {
NEXT_ARG();
- ret = flower_parse_ip_proto(*argv, vlan_ethtype ?
+ ret = flower_parse_ip_proto(*argv, cvlan_ethtype ?
+ cvlan_ethtype : vlan_ethtype ?
vlan_ethtype : eth_type,
TCA_FLOWER_KEY_IP_PROTO,
&ip_proto, n);
@@ -989,7 +1034,8 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
}
} else if (matches(*argv, "dst_ip") == 0) {
NEXT_ARG();
- ret = flower_parse_ip_addr(*argv, vlan_ethtype ?
+ ret = flower_parse_ip_addr(*argv, cvlan_ethtype ?
+ cvlan_ethtype : vlan_ethtype ?
vlan_ethtype : eth_type,
TCA_FLOWER_KEY_IPV4_DST,
TCA_FLOWER_KEY_IPV4_DST_MASK,
@@ -1002,7 +1048,8 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
}
} else if (matches(*argv, "src_ip") == 0) {
NEXT_ARG();
- ret = flower_parse_ip_addr(*argv, vlan_ethtype ?
+ ret = flower_parse_ip_addr(*argv, cvlan_ethtype ?
+ cvlan_ethtype : vlan_ethtype ?
vlan_ethtype : eth_type,
TCA_FLOWER_KEY_IPV4_SRC,
TCA_FLOWER_KEY_IPV4_SRC_MASK,
@@ -1678,6 +1725,38 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
rta_getattr_u8(attr));
}
+ if (tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]) {
+ SPRINT_BUF(buf);
+ struct rtattr *attr = tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE];
+
+ print_string(PRINT_ANY, "vlan_ethtype", "\n vlan_ethtype %s",
+ ll_proto_n2a(rta_getattr_u16(attr),
+ buf, sizeof(buf)));
+ }
+
+ if (tb[TCA_FLOWER_KEY_CVLAN_ID]) {
+ struct rtattr *attr = tb[TCA_FLOWER_KEY_CVLAN_ID];
+
+ print_uint(PRINT_ANY, "cvlan_id", "\n cvlan_id %u",
+ rta_getattr_u16(attr));
+ }
+
+ if (tb[TCA_FLOWER_KEY_CVLAN_PRIO]) {
+ struct rtattr *attr = tb[TCA_FLOWER_KEY_CVLAN_PRIO];
+
+ print_uint(PRINT_ANY, "cvlan_prio", "\n cvlan_prio %d",
+ rta_getattr_u8(attr));
+ }
+
+ if (tb[TCA_FLOWER_KEY_CVLAN_ETH_TYPE]) {
+ SPRINT_BUF(buf);
+ struct rtattr *attr = tb[TCA_FLOWER_KEY_CVLAN_ETH_TYPE];
+
+ print_string(PRINT_ANY, "cvlan_ethtype", "\n cvlan_ethtype %s",
+ ll_proto_n2a(rta_getattr_u16(attr),
+ buf, sizeof(buf)));
+ }
+
flower_print_eth_addr("dst_mac", tb[TCA_FLOWER_KEY_ETH_DST],
tb[TCA_FLOWER_KEY_ETH_DST_MASK]);
flower_print_eth_addr("src_mac", tb[TCA_FLOWER_KEY_ETH_SRC],
--
2.20.1

View File

@ -1,47 +0,0 @@
From bca44fb15b57a32a991780100171708e9e2e4960 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Wed, 29 May 2019 18:40:20 +0200
Subject: [PATCH] uapi: update ib_verbs
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1664694
Upstream Status: iproute2.git commit 27886a12416dd
commit 27886a12416dd315cf386cfbfa93c2fb2aceca98
Author: Stephen Hemminger <stephen@networkplumber.org>
Date: Fri Aug 31 15:03:49 2018 -0700
uapi: update ib_verbs
Merge current uapi from 4.19-rc1
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
rdma/include/uapi/rdma/ib_user_verbs.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/rdma/include/uapi/rdma/ib_user_verbs.h b/rdma/include/uapi/rdma/ib_user_verbs.h
index 4f9991de8e3ad..25a16760de2ad 100644
--- a/rdma/include/uapi/rdma/ib_user_verbs.h
+++ b/rdma/include/uapi/rdma/ib_user_verbs.h
@@ -279,7 +279,7 @@ struct ib_uverbs_query_port {
};
struct ib_uverbs_query_port_resp {
- __u32 port_cap_flags;
+ __u32 port_cap_flags; /* see ib_uverbs_query_port_cap_flags */
__u32 max_msg_sz;
__u32 bad_pkey_cntr;
__u32 qkey_viol_cntr;
@@ -299,7 +299,8 @@ struct ib_uverbs_query_port_resp {
__u8 active_speed;
__u8 phys_state;
__u8 link_layer;
- __u8 reserved[2];
+ __u8 flags; /* see ib_uverbs_query_port_flags */
+ __u8 reserved;
};
struct ib_uverbs_alloc_pd {
--
2.20.1

View File

@ -1,80 +0,0 @@
From e67f089156708052abeb9c67d77cb0cf966d89c6 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Wed, 29 May 2019 18:40:20 +0200
Subject: [PATCH] rdma: Fix representation of PortInfo CapabilityMask
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1664694
Upstream Status: iproute2.git commit d090fbf33bd15
commit d090fbf33bd15d82978596920b07616aa119ac2f
Author: Leon Romanovsky <leonro@mellanox.com>
Date: Sun Sep 16 20:28:13 2018 +0300
rdma: Fix representation of PortInfo CapabilityMask
The port capability mask represents IBTA PortInfo specification,
but as it is written in description of kernel commit 2f944c0fbf58
("RDMA: Fix storage of PortInfo CapabilityMask in the kernel"),
the bit 26 was mistakenly overwritten.
The rdmatool followed it too and mislead users by presenting wrong
value. Since it never showed proper value, we update the whole
port_cap_mask to comply with IBTA and show real HW values.
Fixes: da990ab40a92 ("rdma: Add link object")
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
rdma/link.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/rdma/link.c b/rdma/link.c
index 7e914c870994e..7a6d4b7e356d7 100644
--- a/rdma/link.c
+++ b/rdma/link.c
@@ -20,6 +20,7 @@ static int link_help(struct rd *rd)
static const char *caps_to_str(uint32_t idx)
{
#define RDMA_PORT_FLAGS(x) \
+ x(RESERVED, 0) \
x(SM, 1) \
x(NOTICE, 2) \
x(TRAP, 3) \
@@ -32,7 +33,9 @@ static const char *caps_to_str(uint32_t idx)
x(SM_DISABLED, 10) \
x(SYS_IMAGE_GUID, 11) \
x(PKEY_SW_EXT_PORT_TRAP, 12) \
+ x(CABLE_INFO, 13) \
x(EXTENDED_SPEEDS, 14) \
+ x(CAP_MASK2, 15) \
x(CM, 16) \
x(SNMP_TUNNEL, 17) \
x(REINIT, 18) \
@@ -43,7 +46,12 @@ static const char *caps_to_str(uint32_t idx)
x(BOOT_MGMT, 23) \
x(LINK_LATENCY, 24) \
x(CLIENT_REG, 25) \
- x(IP_BASED_GIDS, 26)
+ x(OTHER_LOCAL_CHANGES, 26) \
+ x(LINK_SPPED_WIDTH, 27) \
+ x(VENDOR_SPECIFIC_MADS, 28) \
+ x(MULT_PKER_TRAP, 29) \
+ x(MULT_FDB, 30) \
+ x(HIERARCHY_INFO, 31)
enum { RDMA_PORT_FLAGS(RDMA_BITMAP_ENUM) };
@@ -51,9 +59,7 @@ static const char *caps_to_str(uint32_t idx)
rdma_port_names[] = { RDMA_PORT_FLAGS(RDMA_BITMAP_NAMES) };
#undef RDMA_PORT_FLAGS
- if (idx < ARRAY_SIZE(rdma_port_names) && rdma_port_names[idx])
- return rdma_port_names[idx];
- return "UNKNOWN";
+ return rdma_port_names[idx];
}
static void link_print_caps(struct rd *rd, struct nlattr **tb)
--
2.20.1

View File

@ -1,702 +0,0 @@
From a126f6cc4f4d8f5f58758d673fbdb80894c5f05d Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Wed, 29 May 2019 18:55:33 +0200
Subject: [PATCH] devlink: Add param command support
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1663199
Upstream Status: iproute2.git commit 13925ae9eb38b
commit 13925ae9eb38b99107be1d3fe21a1b73cf40bd97
Author: Moshe Shemesh <moshe@mellanox.com>
Date: Wed Jul 4 17:12:06 2018 +0300
devlink: Add param command support
Add support for configuration parameters set and show.
Each parameter can be either generic or driver-specific.
The user can retrieve data on these configuration parameters by devlink
param show command and can set new value to a configuration parameter
by devlink param set command.
The configuration parameters can be set in different configuration
modes:
runtime - set while driver is running, no reset required.
driverinit - applied while driver initializes, requires restart
driver by devlink reload command.
permanent - written to device's non-volatile memory, hard reset
required to apply.
New commands added:
devlink dev param show [DEV name PARAMETER]
devlink dev param set DEV name PARAMETER value VALUE
cmode { permanent | driverinit | runtime }
Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
devlink/devlink.c | 454 +++++++++++++++++++++++++++++++++++++++++
man/man8/devlink-dev.8 | 57 ++++++
2 files changed, 511 insertions(+)
diff --git a/devlink/devlink.c b/devlink/devlink.c
index 7a5aef84f25dc..00a514f8ff666 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -35,6 +35,10 @@
#define ESWITCH_INLINE_MODE_NETWORK "network"
#define ESWITCH_INLINE_MODE_TRANSPORT "transport"
+#define PARAM_CMODE_RUNTIME_STR "runtime"
+#define PARAM_CMODE_DRIVERINIT_STR "driverinit"
+#define PARAM_CMODE_PERMANENT_STR "permanent"
+
static int g_new_line_count;
#define pr_err(args...) fprintf(stderr, ##args)
@@ -187,6 +191,9 @@ static void ifname_map_free(struct ifname_map *ifname_map)
#define DL_OPT_ESWITCH_ENCAP_MODE BIT(15)
#define DL_OPT_RESOURCE_PATH BIT(16)
#define DL_OPT_RESOURCE_SIZE BIT(17)
+#define DL_OPT_PARAM_NAME BIT(18)
+#define DL_OPT_PARAM_VALUE BIT(19)
+#define DL_OPT_PARAM_CMODE BIT(20)
struct dl_opts {
uint32_t present; /* flags of present items */
@@ -211,6 +218,9 @@ struct dl_opts {
uint32_t resource_size;
uint32_t resource_id;
bool resource_id_valid;
+ const char *param_name;
+ const char *param_value;
+ enum devlink_param_cmode cmode;
};
struct dl {
@@ -348,6 +358,12 @@ static const enum mnl_attr_data_type devlink_policy[DEVLINK_ATTR_MAX + 1] = {
[DEVLINK_ATTR_DPIPE_FIELD_ID] = MNL_TYPE_U32,
[DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH] = MNL_TYPE_U32,
[DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE] = MNL_TYPE_U32,
+ [DEVLINK_ATTR_PARAM] = MNL_TYPE_NESTED,
+ [DEVLINK_ATTR_PARAM_NAME] = MNL_TYPE_STRING,
+ [DEVLINK_ATTR_PARAM_TYPE] = MNL_TYPE_U8,
+ [DEVLINK_ATTR_PARAM_VALUES_LIST] = MNL_TYPE_NESTED,
+ [DEVLINK_ATTR_PARAM_VALUE] = MNL_TYPE_NESTED,
+ [DEVLINK_ATTR_PARAM_VALUE_CMODE] = MNL_TYPE_U8,
};
static int attr_cb(const struct nlattr *attr, void *data)
@@ -514,6 +530,34 @@ static int strtouint16_t(const char *str, uint16_t *p_val)
return 0;
}
+static int strtouint8_t(const char *str, uint8_t *p_val)
+{
+ char *endptr;
+ unsigned long int val;
+
+ val = strtoul(str, &endptr, 10);
+ if (endptr == str || *endptr != '\0')
+ return -EINVAL;
+ if (val > UCHAR_MAX)
+ return -ERANGE;
+ *p_val = val;
+ return 0;
+}
+
+static int strtobool(const char *str, bool *p_val)
+{
+ bool val;
+
+ if (!strcmp(str, "true") || !strcmp(str, "1"))
+ val = true;
+ else if (!strcmp(str, "false") || !strcmp(str, "0"))
+ val = false;
+ else
+ return -EINVAL;
+ *p_val = val;
+ return 0;
+}
+
static int __dl_argv_handle(char *str, char **p_bus_name, char **p_dev_name)
{
strslashrsplit(str, p_bus_name, p_dev_name);
@@ -792,6 +836,22 @@ static int eswitch_encap_mode_get(const char *typestr, bool *p_mode)
return 0;
}
+static int param_cmode_get(const char *cmodestr,
+ enum devlink_param_cmode *cmode)
+{
+ if (strcmp(cmodestr, PARAM_CMODE_RUNTIME_STR) == 0) {
+ *cmode = DEVLINK_PARAM_CMODE_RUNTIME;
+ } else if (strcmp(cmodestr, PARAM_CMODE_DRIVERINIT_STR) == 0) {
+ *cmode = DEVLINK_PARAM_CMODE_DRIVERINIT;
+ } else if (strcmp(cmodestr, PARAM_CMODE_PERMANENT_STR) == 0) {
+ *cmode = DEVLINK_PARAM_CMODE_PERMANENT;
+ } else {
+ pr_err("Unknown configuration mode \"%s\"\n", cmodestr);
+ return -EINVAL;
+ }
+ return 0;
+}
+
static int dl_argv_parse(struct dl *dl, uint32_t o_required,
uint32_t o_optional)
{
@@ -973,6 +1033,32 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required,
if (err)
return err;
o_found |= DL_OPT_RESOURCE_SIZE;
+ } else if (dl_argv_match(dl, "name") &&
+ (o_all & DL_OPT_PARAM_NAME)) {
+ dl_arg_inc(dl);
+ err = dl_argv_str(dl, &opts->param_name);
+ if (err)
+ return err;
+ o_found |= DL_OPT_PARAM_NAME;
+ } else if (dl_argv_match(dl, "value") &&
+ (o_all & DL_OPT_PARAM_VALUE)) {
+ dl_arg_inc(dl);
+ err = dl_argv_str(dl, &opts->param_value);
+ if (err)
+ return err;
+ o_found |= DL_OPT_PARAM_VALUE;
+ } else if (dl_argv_match(dl, "cmode") &&
+ (o_all & DL_OPT_PARAM_CMODE)) {
+ const char *cmodestr;
+
+ dl_arg_inc(dl);
+ err = dl_argv_str(dl, &cmodestr);
+ if (err)
+ return err;
+ err = param_cmode_get(cmodestr, &opts->cmode);
+ if (err)
+ return err;
+ o_found |= DL_OPT_PARAM_CMODE;
} else {
pr_err("Unknown option \"%s\"\n", dl_argv(dl));
return -EINVAL;
@@ -1057,6 +1143,24 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required,
return -EINVAL;
}
+ if ((o_required & DL_OPT_PARAM_NAME) &&
+ !(o_found & DL_OPT_PARAM_NAME)) {
+ pr_err("Parameter name expected.\n");
+ return -EINVAL;
+ }
+
+ if ((o_required & DL_OPT_PARAM_VALUE) &&
+ !(o_found & DL_OPT_PARAM_VALUE)) {
+ pr_err("Value to set expected.\n");
+ return -EINVAL;
+ }
+
+ if ((o_required & DL_OPT_PARAM_CMODE) &&
+ !(o_found & DL_OPT_PARAM_CMODE)) {
+ pr_err("Configuration mode expected.\n");
+ return -EINVAL;
+ }
+
return 0;
}
@@ -1121,6 +1225,12 @@ static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl)
if (opts->present & DL_OPT_RESOURCE_SIZE)
mnl_attr_put_u64(nlh, DEVLINK_ATTR_RESOURCE_SIZE,
opts->resource_size);
+ if (opts->present & DL_OPT_PARAM_NAME)
+ mnl_attr_put_strz(nlh, DEVLINK_ATTR_PARAM_NAME,
+ opts->param_name);
+ if (opts->present & DL_OPT_PARAM_CMODE)
+ mnl_attr_put_u8(nlh, DEVLINK_ATTR_PARAM_VALUE_CMODE,
+ opts->cmode);
}
static int dl_argv_parse_put(struct nlmsghdr *nlh, struct dl *dl,
@@ -1179,6 +1289,8 @@ static void cmd_dev_help(void)
pr_err(" [ inline-mode { none | link | network | transport } ]\n");
pr_err(" [ encap { disable | enable } ]\n");
pr_err(" devlink dev eswitch show DEV\n");
+ pr_err(" devlink dev param set DEV name PARAMETER value VALUE cmode { permanent | driverinit | runtime }\n");
+ pr_err(" devlink dev param show [DEV name PARAMETER]\n");
pr_err(" devlink dev reload DEV\n");
}
@@ -1393,6 +1505,14 @@ static void pr_out_str(struct dl *dl, const char *name, const char *val)
}
}
+static void pr_out_bool(struct dl *dl, const char *name, bool val)
+{
+ if (val)
+ pr_out_str(dl, name, "true");
+ else
+ pr_out_str(dl, name, "false");
+}
+
static void pr_out_uint(struct dl *dl, const char *name, unsigned int val)
{
if (dl->json_output) {
@@ -1475,6 +1595,19 @@ static void pr_out_entry_end(struct dl *dl)
__pr_out_newline();
}
+static const char *param_cmode_name(uint8_t cmode)
+{
+ switch (cmode) {
+ case DEVLINK_PARAM_CMODE_RUNTIME:
+ return PARAM_CMODE_RUNTIME_STR;
+ case DEVLINK_PARAM_CMODE_DRIVERINIT:
+ return PARAM_CMODE_DRIVERINIT_STR;
+ case DEVLINK_PARAM_CMODE_PERMANENT:
+ return PARAM_CMODE_PERMANENT_STR;
+ default: return "<unknown type>";
+ }
+}
+
static const char *eswitch_mode_name(uint32_t mode)
{
switch (mode) {
@@ -1593,6 +1726,304 @@ static int cmd_dev_eswitch(struct dl *dl)
return -ENOENT;
}
+static void pr_out_param_value(struct dl *dl, int nla_type, struct nlattr *nl)
+{
+ struct nlattr *nla_value[DEVLINK_ATTR_MAX + 1] = {};
+ struct nlattr *val_attr;
+ int err;
+
+ err = mnl_attr_parse_nested(nl, attr_cb, nla_value);
+ if (err != MNL_CB_OK)
+ return;
+
+ if (!nla_value[DEVLINK_ATTR_PARAM_VALUE_CMODE] ||
+ (nla_type != MNL_TYPE_FLAG &&
+ !nla_value[DEVLINK_ATTR_PARAM_VALUE_DATA]))
+ return;
+
+ pr_out_str(dl, "cmode",
+ param_cmode_name(mnl_attr_get_u8(nla_value[DEVLINK_ATTR_PARAM_VALUE_CMODE])));
+ val_attr = nla_value[DEVLINK_ATTR_PARAM_VALUE_DATA];
+
+ switch (nla_type) {
+ case MNL_TYPE_U8:
+ pr_out_uint(dl, "value", mnl_attr_get_u8(val_attr));
+ break;
+ case MNL_TYPE_U16:
+ pr_out_uint(dl, "value", mnl_attr_get_u16(val_attr));
+ break;
+ case MNL_TYPE_U32:
+ pr_out_uint(dl, "value", mnl_attr_get_u32(val_attr));
+ break;
+ case MNL_TYPE_STRING:
+ pr_out_str(dl, "value", mnl_attr_get_str(val_attr));
+ break;
+ case MNL_TYPE_FLAG:
+ pr_out_bool(dl, "value", val_attr ? true : false);
+ break;
+ }
+}
+
+static void pr_out_param(struct dl *dl, struct nlattr **tb, bool array)
+{
+ struct nlattr *nla_param[DEVLINK_ATTR_MAX + 1] = {};
+ struct nlattr *param_value_attr;
+ int nla_type;
+ int err;
+
+ err = mnl_attr_parse_nested(tb[DEVLINK_ATTR_PARAM], attr_cb, nla_param);
+ if (err != MNL_CB_OK)
+ return;
+ if (!nla_param[DEVLINK_ATTR_PARAM_NAME] ||
+ !nla_param[DEVLINK_ATTR_PARAM_TYPE] ||
+ !nla_param[DEVLINK_ATTR_PARAM_VALUES_LIST])
+ return;
+
+ if (array)
+ pr_out_handle_start_arr(dl, tb);
+ else
+ __pr_out_handle_start(dl, tb, true, false);
+
+ nla_type = mnl_attr_get_u8(nla_param[DEVLINK_ATTR_PARAM_TYPE]);
+
+ pr_out_str(dl, "name",
+ mnl_attr_get_str(nla_param[DEVLINK_ATTR_PARAM_NAME]));
+
+ if (!nla_param[DEVLINK_ATTR_PARAM_GENERIC])
+ pr_out_str(dl, "type", "driver-specific");
+ else
+ pr_out_str(dl, "type", "generic");
+
+ pr_out_array_start(dl, "values");
+ mnl_attr_for_each_nested(param_value_attr,
+ nla_param[DEVLINK_ATTR_PARAM_VALUES_LIST]) {
+ pr_out_entry_start(dl);
+ pr_out_param_value(dl, nla_type, param_value_attr);
+ pr_out_entry_end(dl);
+ }
+ pr_out_array_end(dl);
+ pr_out_handle_end(dl);
+}
+
+static int cmd_dev_param_show_cb(const struct nlmsghdr *nlh, void *data)
+{
+ struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
+ struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
+ struct dl *dl = data;
+
+ mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
+ if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
+ !tb[DEVLINK_ATTR_PARAM])
+ return MNL_CB_ERROR;
+ pr_out_param(dl, tb, true);
+ return MNL_CB_OK;
+}
+
+struct param_ctx {
+ struct dl *dl;
+ int nla_type;
+ union {
+ uint8_t vu8;
+ uint16_t vu16;
+ uint32_t vu32;
+ const char *vstr;
+ bool vbool;
+ } value;
+};
+
+static int cmd_dev_param_set_cb(const struct nlmsghdr *nlh, void *data)
+{
+ struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
+ struct nlattr *nla_param[DEVLINK_ATTR_MAX + 1] = {};
+ struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
+ struct nlattr *param_value_attr;
+ enum devlink_param_cmode cmode;
+ struct param_ctx *ctx = data;
+ struct dl *dl = ctx->dl;
+ int nla_type;
+ int err;
+
+ mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
+ if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
+ !tb[DEVLINK_ATTR_PARAM])
+ return MNL_CB_ERROR;
+
+ err = mnl_attr_parse_nested(tb[DEVLINK_ATTR_PARAM], attr_cb, nla_param);
+ if (err != MNL_CB_OK)
+ return MNL_CB_ERROR;
+
+ if (!nla_param[DEVLINK_ATTR_PARAM_TYPE] ||
+ !nla_param[DEVLINK_ATTR_PARAM_VALUES_LIST])
+ return MNL_CB_ERROR;
+
+ nla_type = mnl_attr_get_u8(nla_param[DEVLINK_ATTR_PARAM_TYPE]);
+ mnl_attr_for_each_nested(param_value_attr,
+ nla_param[DEVLINK_ATTR_PARAM_VALUES_LIST]) {
+ struct nlattr *nla_value[DEVLINK_ATTR_MAX + 1] = {};
+ struct nlattr *val_attr;
+
+ err = mnl_attr_parse_nested(param_value_attr,
+ attr_cb, nla_value);
+ if (err != MNL_CB_OK)
+ return MNL_CB_ERROR;
+
+ if (!nla_value[DEVLINK_ATTR_PARAM_VALUE_CMODE] ||
+ (nla_type != MNL_TYPE_FLAG &&
+ !nla_value[DEVLINK_ATTR_PARAM_VALUE_DATA]))
+ return MNL_CB_ERROR;
+
+ cmode = mnl_attr_get_u8(nla_value[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
+ if (cmode == dl->opts.cmode) {
+ val_attr = nla_value[DEVLINK_ATTR_PARAM_VALUE_DATA];
+ switch (nla_type) {
+ case MNL_TYPE_U8:
+ ctx->value.vu8 = mnl_attr_get_u8(val_attr);
+ break;
+ case MNL_TYPE_U16:
+ ctx->value.vu16 = mnl_attr_get_u16(val_attr);
+ break;
+ case MNL_TYPE_U32:
+ ctx->value.vu32 = mnl_attr_get_u32(val_attr);
+ break;
+ case MNL_TYPE_STRING:
+ ctx->value.vstr = mnl_attr_get_str(val_attr);
+ break;
+ case MNL_TYPE_FLAG:
+ ctx->value.vbool = val_attr ? true : false;
+ break;
+ }
+ break;
+ }
+ }
+ ctx->nla_type = nla_type;
+ return MNL_CB_OK;
+}
+
+static int cmd_dev_param_set(struct dl *dl)
+{
+ struct param_ctx ctx = {};
+ struct nlmsghdr *nlh;
+ uint32_t val_u32;
+ uint16_t val_u16;
+ uint8_t val_u8;
+ bool val_bool;
+ int err;
+
+ err = dl_argv_parse(dl, DL_OPT_HANDLE |
+ DL_OPT_PARAM_NAME |
+ DL_OPT_PARAM_VALUE |
+ DL_OPT_PARAM_CMODE, 0);
+ if (err)
+ return err;
+
+ /* Get value type */
+ nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_PARAM_GET,
+ NLM_F_REQUEST | NLM_F_ACK);
+ dl_opts_put(nlh, dl);
+
+ ctx.dl = dl;
+ err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_dev_param_set_cb, &ctx);
+ if (err)
+ return err;
+
+ nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_PARAM_SET,
+ NLM_F_REQUEST | NLM_F_ACK);
+ dl_opts_put(nlh, dl);
+
+ mnl_attr_put_u8(nlh, DEVLINK_ATTR_PARAM_TYPE, ctx.nla_type);
+ switch (ctx.nla_type) {
+ case MNL_TYPE_U8:
+ err = strtouint8_t(dl->opts.param_value, &val_u8);
+ if (err)
+ goto err_param_value_parse;
+ if (val_u8 == ctx.value.vu8)
+ return 0;
+ mnl_attr_put_u8(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, val_u8);
+ break;
+ case MNL_TYPE_U16:
+ err = strtouint16_t(dl->opts.param_value, &val_u16);
+ if (err)
+ goto err_param_value_parse;
+ if (val_u16 == ctx.value.vu16)
+ return 0;
+ mnl_attr_put_u16(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, val_u16);
+ break;
+ case MNL_TYPE_U32:
+ err = strtouint32_t(dl->opts.param_value, &val_u32);
+ if (err)
+ goto err_param_value_parse;
+ if (val_u32 == ctx.value.vu32)
+ return 0;
+ mnl_attr_put_u32(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, val_u32);
+ break;
+ case MNL_TYPE_FLAG:
+ err = strtobool(dl->opts.param_value, &val_bool);
+ if (err)
+ goto err_param_value_parse;
+ if (val_bool == ctx.value.vbool)
+ return 0;
+ if (val_bool)
+ mnl_attr_put(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA,
+ 0, NULL);
+ break;
+ case MNL_TYPE_STRING:
+ mnl_attr_put_strz(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA,
+ dl->opts.param_value);
+ if (!strcmp(dl->opts.param_value, ctx.value.vstr))
+ return 0;
+ break;
+ default:
+ printf("Value type not supported\n");
+ return -ENOTSUP;
+ }
+ return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
+
+err_param_value_parse:
+ pr_err("Value \"%s\" is not a number or not within range\n",
+ dl->opts.param_value);
+ return err;
+}
+
+static int cmd_dev_param_show(struct dl *dl)
+{
+ uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
+ struct nlmsghdr *nlh;
+ int err;
+
+ if (dl_argc(dl) == 0)
+ flags |= NLM_F_DUMP;
+
+ nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_PARAM_GET, flags);
+
+ if (dl_argc(dl) > 0) {
+ err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE |
+ DL_OPT_PARAM_NAME, 0);
+ if (err)
+ return err;
+ }
+
+ pr_out_section_start(dl, "param");
+ err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_dev_param_show_cb, dl);
+ pr_out_section_end(dl);
+ return err;
+}
+
+static int cmd_dev_param(struct dl *dl)
+{
+ if (dl_argv_match(dl, "help")) {
+ cmd_dev_help();
+ return 0;
+ } else if (dl_argv_match(dl, "show") ||
+ dl_argv_match(dl, "list") || dl_no_arg(dl)) {
+ dl_arg_inc(dl);
+ return cmd_dev_param_show(dl);
+ } else if (dl_argv_match(dl, "set")) {
+ dl_arg_inc(dl);
+ return cmd_dev_param_set(dl);
+ }
+ pr_err("Command \"%s\" not found\n", dl_argv(dl));
+ return -ENOENT;
+}
static int cmd_dev_show_cb(const struct nlmsghdr *nlh, void *data)
{
struct dl *dl = data;
@@ -1669,6 +2100,9 @@ static int cmd_dev(struct dl *dl)
} else if (dl_argv_match(dl, "reload")) {
dl_arg_inc(dl);
return cmd_dev_reload(dl);
+ } else if (dl_argv_match(dl, "param")) {
+ dl_arg_inc(dl);
+ return cmd_dev_param(dl);
}
pr_err("Command \"%s\" not found\n", dl_argv(dl));
return -ENOENT;
@@ -2632,6 +3066,10 @@ static const char *cmd_name(uint8_t cmd)
case DEVLINK_CMD_PORT_SET: return "set";
case DEVLINK_CMD_PORT_NEW: return "new";
case DEVLINK_CMD_PORT_DEL: return "del";
+ case DEVLINK_CMD_PARAM_GET: return "get";
+ case DEVLINK_CMD_PARAM_SET: return "set";
+ case DEVLINK_CMD_PARAM_NEW: return "new";
+ case DEVLINK_CMD_PARAM_DEL: return "del";
default: return "<unknown cmd>";
}
}
@@ -2650,6 +3088,11 @@ static const char *cmd_obj(uint8_t cmd)
case DEVLINK_CMD_PORT_NEW:
case DEVLINK_CMD_PORT_DEL:
return "port";
+ case DEVLINK_CMD_PARAM_GET:
+ case DEVLINK_CMD_PARAM_SET:
+ case DEVLINK_CMD_PARAM_NEW:
+ case DEVLINK_CMD_PARAM_DEL:
+ return "param";
default: return "<unknown obj>";
}
}
@@ -2706,6 +3149,17 @@ static int cmd_mon_show_cb(const struct nlmsghdr *nlh, void *data)
pr_out_mon_header(genl->cmd);
pr_out_port(dl, tb);
break;
+ case DEVLINK_CMD_PARAM_GET: /* fall through */
+ case DEVLINK_CMD_PARAM_SET: /* fall through */
+ case DEVLINK_CMD_PARAM_NEW: /* fall through */
+ case DEVLINK_CMD_PARAM_DEL:
+ mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
+ if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
+ !tb[DEVLINK_ATTR_PARAM])
+ return MNL_CB_ERROR;
+ pr_out_mon_header(genl->cmd);
+ pr_out_param(dl, tb, false);
+ break;
}
return MNL_CB_OK;
}
diff --git a/man/man8/devlink-dev.8 b/man/man8/devlink-dev.8
index 7c749ddabaeeb..d985da172aa05 100644
--- a/man/man8/devlink-dev.8
+++ b/man/man8/devlink-dev.8
@@ -42,6 +42,23 @@ devlink-dev \- devlink device configuration
.BR "devlink dev eswitch show"
.IR DEV
+.ti -8
+.BR "devlink dev param set"
+.IR DEV
+.BR name
+.IR PARAMETER
+.BR value
+.IR VALUE
+.BR cmode " { " runtime " | " driverinit " | " permanent " } "
+
+.ti -8
+.BR "devlink dev param show"
+.RI "[ "
+.IR DEV
+.BR name
+.IR PARAMETER
+.RI "]"
+
.ti -8
.BR "devlink dev reload"
.IR DEV
@@ -98,6 +115,36 @@ Set eswitch encapsulation support
.I enable
- Enable encapsulation support
+.SS devlink dev param set - set new value to devlink device configuration parameter
+
+.TP
+.BI name " PARAMETER"
+Specify parameter name to set.
+
+.TP
+.BI value " VALUE"
+New value to set.
+
+.TP
+.BR cmode " { " runtime " | " driverinit " | " permanent " } "
+Configuration mode in which the new value is set.
+
+.I runtime
+- Set new value while driver is running. This configuration mode doesn't require any reset to apply the new value.
+
+.I driverinit
+- Set new value which will be applied during driver initialization. This configuration mode requires restart driver by devlink reload command to apply the new value.
+
+.I permanent
+- New value is written to device's non-volatile memory. This configuration mode requires hard reset to apply the new value.
+
+.SS devlink dev param show - display devlink device supported configuration parameters attributes
+
+.BR name
+.IR PARAMETER
+Specify parameter name to show.
+If this argument is omitted all parameters supported by devlink devices are listed.
+
.SS devlink dev reload - perform hot reload of the driver.
.PP
@@ -126,6 +173,16 @@ devlink dev eswitch set pci/0000:01:00.0 mode switchdev
Sets the eswitch mode of specified devlink device to switchdev.
.RE
.PP
+devlink dev param show pci/0000:01:00.0 name max_macs
+.RS 4
+Shows the parameter max_macs attributes.
+.RE
+.PP
+devlink dev param set pci/0000:01:00.0 name internal_error_reset value true cmode runtime
+.RS 4
+Sets the parameter internal_error_reset of specified devlink device to true.
+.RE
+.PP
devlink dev reload pci/0000:01:00.0
.RS 4
Performs hot reload of specified devlink device.
--
2.20.1

View File

@ -1,100 +0,0 @@
From ae7cf70848d837d2ed85a21f6d7cbdf4c6ee6e4e Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Mon, 10 Jun 2019 14:25:21 +0200
Subject: [PATCH] libnetlink: Convert GETADDR dumps to use rtnl_addrdump_req
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1716772
Upstream Status: iproute2.git commit 46917d0895fb0
commit 46917d0895fb0fb1df9b3c1575ccd467b4a1f860
Author: David Ahern <dsahern@gmail.com>
Date: Sat Sep 29 08:41:46 2018 -0700
libnetlink: Convert GETADDR dumps to use rtnl_addrdump_req
Add rtnl_addrdump_req for address dumps using the proper ifaddrmsg
as the header. Convert existing RTM_GETADDR dumps to use it.
Signed-off-by: David Ahern <dsahern@gmail.com>
---
include/libnetlink.h | 4 ++++
ip/ipaddress.c | 6 +++---
lib/libnetlink.c | 16 ++++++++++++++++
3 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/include/libnetlink.h b/include/libnetlink.h
index 9d9249e634dc3..2d9f6190230c1 100644
--- a/include/libnetlink.h
+++ b/include/libnetlink.h
@@ -46,6 +46,10 @@ int rtnl_open_byproto(struct rtnl_handle *rth, unsigned int subscriptions,
__attribute__((warn_unused_result));
void rtnl_close(struct rtnl_handle *rth);
+
+int rtnl_addrdump_req(struct rtnl_handle *rth, int family)
+ __attribute__((warn_unused_result));
+
int rtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type)
__attribute__((warn_unused_result));
int rtnl_wilddump_req_filter(struct rtnl_handle *rth, int fam, int type,
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index f315a815e945d..4714bce60db1b 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -1672,7 +1672,7 @@ static int ipaddr_flush(void)
filter.flushe = sizeof(flushb);
while ((max_flush_loops == 0) || (round < max_flush_loops)) {
- if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) {
+ if (rtnl_addrdump_req(&rth, filter.family) < 0) {
perror("Cannot send dump request");
exit(1);
}
@@ -1764,7 +1764,7 @@ int ip_linkaddr_list(int family, req_filter_fn_t filter_fn,
}
if (ainfo) {
- if (rtnl_wilddump_request(&rth, family, RTM_GETADDR) < 0) {
+ if (rtnl_addrdump_req(&rth, family) < 0) {
perror("Cannot send dump request");
return 1;
}
@@ -1889,7 +1889,7 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
if (ipadd_save_prep())
exit(1);
- if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETADDR) < 0) {
+ if (rtnl_addrdump_req(&rth, preferred_family) < 0) {
perror("Cannot send dump request");
exit(1);
}
diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index a9932d423126e..db625b9bd18ca 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -199,6 +199,22 @@ int rtnl_open(struct rtnl_handle *rth, unsigned int subscriptions)
return rtnl_open_byproto(rth, subscriptions, NETLINK_ROUTE);
}
+int rtnl_addrdump_req(struct rtnl_handle *rth, int family)
+{
+ struct {
+ struct nlmsghdr nlh;
+ struct ifaddrmsg ifm;
+ } req = {
+ .nlh.nlmsg_len = sizeof(req),
+ .nlh.nlmsg_type = RTM_GETADDR,
+ .nlh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
+ .nlh.nlmsg_seq = rth->dump = ++rth->seq,
+ .ifm.ifa_family = family,
+ };
+
+ return send(rth->fd, &req, sizeof(req), 0);
+}
+
int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
{
return rtnl_wilddump_req_filter(rth, family, type, RTEXT_FILTER_VF);
--
2.20.1

View File

@ -1,43 +0,0 @@
From 0a919849a14e65e4ff4b2c71f02862598c79633b Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Mon, 10 Jun 2019 15:32:55 +0200
Subject: [PATCH] rdma: Update kernel include file to support IB device
renaming
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1663228
Upstream Status: iproute2.git commit 3fb00075d9043
commit 3fb00075d904389afce507fffe06ca3a8500ebf3
Author: Leon Romanovsky <leonro@mellanox.com>
Date: Wed Oct 31 09:17:55 2018 +0200
rdma: Update kernel include file to support IB device renaming
Bring kernel header file changes upto commit 05d940d3a3ec
("RDMA/nldev: Allow IB device rename through RDMA netlink")
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Reviewed-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
rdma/include/uapi/rdma/rdma_netlink.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/rdma/include/uapi/rdma/rdma_netlink.h b/rdma/include/uapi/rdma/rdma_netlink.h
index 6513fb89abfa1..e2228c0917154 100644
--- a/rdma/include/uapi/rdma/rdma_netlink.h
+++ b/rdma/include/uapi/rdma/rdma_netlink.h
@@ -227,8 +227,9 @@ enum rdma_nldev_command {
RDMA_NLDEV_CMD_UNSPEC,
RDMA_NLDEV_CMD_GET, /* can dump */
+ RDMA_NLDEV_CMD_SET,
- /* 2 - 4 are free to use */
+ /* 3 - 4 are free to use */
RDMA_NLDEV_CMD_PORT_GET = 5, /* can dump */
--
2.20.1

View File

@ -1,63 +0,0 @@
From 349c43f99f876e0663fb0b00396ac3d387bc32e9 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Mon, 10 Jun 2019 15:32:55 +0200
Subject: [PATCH] rdma: Introduce command execution helper with required device
name
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1663228
Upstream Status: iproute2.git commit a14ceed32524c
commit a14ceed32524c7f9c05572886cd63e921e4c0faf
Author: Leon Romanovsky <leonro@mellanox.com>
Date: Wed Oct 31 09:17:56 2018 +0200
rdma: Introduce command execution helper with required device name
In contradiction to various show commands, the set command explicitly
requires to use device name as an argument. Provide new command
execution helper which enforces it.
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Reviewed-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
rdma/rdma.h | 1 +
rdma/utils.c | 10 ++++++++++
2 files changed, 11 insertions(+)
diff --git a/rdma/rdma.h b/rdma/rdma.h
index c3b7530b6cc71..547bb5749a39f 100644
--- a/rdma/rdma.h
+++ b/rdma/rdma.h
@@ -90,6 +90,7 @@ int cmd_link(struct rd *rd);
int cmd_res(struct rd *rd);
int rd_exec_cmd(struct rd *rd, const struct rd_cmd *c, const char *str);
int rd_exec_dev(struct rd *rd, int (*cb)(struct rd *rd));
+int rd_exec_require_dev(struct rd *rd, int (*cb)(struct rd *rd));
int rd_exec_link(struct rd *rd, int (*cb)(struct rd *rd), bool strict_port);
void rd_free(struct rd *rd);
int rd_set_arg_to_devname(struct rd *rd);
diff --git a/rdma/utils.c b/rdma/utils.c
index 4840bf226d54d..61f4aeb1bcf27 100644
--- a/rdma/utils.c
+++ b/rdma/utils.c
@@ -577,6 +577,16 @@ out:
return ret;
}
+int rd_exec_require_dev(struct rd *rd, int (*cb)(struct rd *rd))
+{
+ if (rd_no_arg(rd)) {
+ pr_err("Please provide device name.\n");
+ return -EINVAL;
+ }
+
+ return rd_exec_dev(rd, cb);
+}
+
int rd_exec_cmd(struct rd *rd, const struct rd_cmd *cmds, const char *str)
{
const struct rd_cmd *c;
--
2.20.1

View File

@ -1,92 +0,0 @@
From 452611d090e456cf7b49bfbb2522df2928452e10 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Mon, 10 Jun 2019 15:32:55 +0200
Subject: [PATCH] rdma: Add an option to rename IB device interface
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1663228
Upstream Status: iproute2.git commit 4443c9c6a01ea
commit 4443c9c6a01eac8c8f2743d4d185ceb9be4d1207
Author: Leon Romanovsky <leonro@mellanox.com>
Date: Wed Oct 31 09:17:57 2018 +0200
rdma: Add an option to rename IB device interface
Enrich rdmatool with an option to rename IB devices,
the command interface follows Iproute2 convention:
"rdma dev set [OLD-DEVNAME] name NEW-DEVNAME"
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Reviewed-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
rdma/dev.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/rdma/dev.c b/rdma/dev.c
index e2eafe47311b0..760b7fb3bb18f 100644
--- a/rdma/dev.c
+++ b/rdma/dev.c
@@ -14,6 +14,7 @@
static int dev_help(struct rd *rd)
{
pr_out("Usage: %s dev show [DEV]\n", rd->filename);
+ pr_out(" %s dev set [DEV] name DEVNAME\n", rd->filename);
return 0;
}
@@ -240,17 +241,51 @@ static int dev_one_show(struct rd *rd)
return rd_exec_cmd(rd, cmds, "parameter");
}
+static int dev_set_name(struct rd *rd)
+{
+ uint32_t seq;
+
+ if (rd_no_arg(rd)) {
+ pr_err("Please provide device new name.\n");
+ return -EINVAL;
+ }
+
+ rd_prepare_msg(rd, RDMA_NLDEV_CMD_SET,
+ &seq, (NLM_F_REQUEST | NLM_F_ACK));
+ mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
+ mnl_attr_put_strz(rd->nlh, RDMA_NLDEV_ATTR_DEV_NAME, rd_argv(rd));
+
+ return rd_send_msg(rd);
+}
+
+static int dev_one_set(struct rd *rd)
+{
+ const struct rd_cmd cmds[] = {
+ { NULL, dev_help},
+ { "name", dev_set_name},
+ { 0 }
+ };
+
+ return rd_exec_cmd(rd, cmds, "parameter");
+}
+
static int dev_show(struct rd *rd)
{
return rd_exec_dev(rd, dev_one_show);
}
+static int dev_set(struct rd *rd)
+{
+ return rd_exec_require_dev(rd, dev_one_set);
+}
+
int cmd_dev(struct rd *rd)
{
const struct rd_cmd cmds[] = {
{ NULL, dev_show },
{ "show", dev_show },
{ "list", dev_show },
+ { "set", dev_set },
{ "help", dev_help },
{ 0 }
};
--
2.20.1

View File

@ -1,77 +0,0 @@
From 1857f106b1fda133918456617efe74cd068c1a86 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Mon, 10 Jun 2019 15:32:55 +0200
Subject: [PATCH] rdma: Document IB device renaming option
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1663228
Upstream Status: iproute2.git commit e89feffae3626
commit e89feffae3626da5b5fda352ae73db132ac60a47
Author: Leon Romanovsky <leonro@mellanox.com>
Date: Sun Nov 4 21:11:22 2018 +0200
rdma: Document IB device renaming option
[leonro@server /]$ lspci |grep -i Ether
00:08.0 Ethernet controller: Red Hat, Inc. Virtio network device
00:09.0 Ethernet controller: Mellanox Technologies MT27700 Family [ConnectX-4]
[leonro@server /]$ sudo rdma dev
1: mlx5_0: node_type ca fw 3.8.9999 node_guid 5254:00c0:fe12:3455
sys_image_guid 5254:00c0:fe12:3455
[leonro@server /]$ sudo rdma dev set mlx5_0 name hfi1_0
[leonro@server /]$ sudo rdma dev
1: hfi1_0: node_type ca fw 3.8.9999 node_guid 5254:00c0:fe12:3455
sys_image_guid 5254:00c0:fe12:3455
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
man/man8/rdma-dev.8 | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/man/man8/rdma-dev.8 b/man/man8/rdma-dev.8
index b7abfe1088c2f..069f471791904 100644
--- a/man/man8/rdma-dev.8
+++ b/man/man8/rdma-dev.8
@@ -1,6 +1,6 @@
.TH RDMA\-DEV 8 "06 Jul 2017" "iproute2" "Linux"
.SH NAME
-rdmak-dev \- RDMA device configuration
+rdma-dev \- RDMA device configuration
.SH SYNOPSIS
.sp
.ad l
@@ -22,10 +22,18 @@ rdmak-dev \- RDMA device configuration
.B rdma dev show
.RI "[ " DEV " ]"
+.ti -8
+.B rdma dev set
+.RI "[ " DEV " ]"
+.BR name
+.BR NEWNAME
+
.ti -8
.B rdma dev help
.SH "DESCRIPTION"
+.SS rdma dev set - rename rdma device
+
.SS rdma dev show - display rdma device attributes
.PP
@@ -45,6 +53,11 @@ rdma dev show mlx5_3
Shows the state of specified RDMA device.
.RE
.PP
+rdma dev set mlx5_3 name rdma_0
+.RS 4
+Renames the mlx5_3 device to rdma_0.
+.RE
+.PP
.SH SEE ALSO
.BR rdma (8),
--
2.20.1

View File

@ -1,210 +0,0 @@
From 907e2adbcb6e02453972d5ada93de7bbaefedb2a Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Thu, 13 Jun 2019 14:37:56 +0200
Subject: [PATCH] iplink: add support for reporting multiple XDP programs
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1716361
Upstream Status: iproute2.git commit da083b5a483bf
commit da083b5a483bfd52dfe72912f62a3bc16d775b87
Author: Jakub Kicinski <jakub.kicinski@netronome.com>
Date: Fri Jul 13 15:54:51 2018 -0700
iplink: add support for reporting multiple XDP programs
Kernel now supports attaching XDP programs in the driver
and hardware at the same time. Print that information
correctly.
In case there are multiple programs attached kernel will
not provide IFLA_XDP_PROG_ID, so don't expect it to be
there (this also improves the printing for very old kernels
slightly, as it avoids unnecessary "prog/xdp" line).
In short mode preserve the current outputs but don't print
IDs if there are multiple.
6: netdevsim0: <BROADCAST,NOARP> mtu 1500 xdpoffload/id:11 qdisc [...]
and:
6: netdevsim0: <BROADCAST,NOARP> mtu 1500 xdpmulti qdisc [...]
ip link output will keep using prog/xdp prefix if only one program
is attached, but can also print multiple program lines:
prog/xdp id 8 tag fc7a51d1a693a99e jited
vs:
prog/xdpdrv id 8 tag fc7a51d1a693a99e jited
prog/xdpoffload id 9 tag fc7a51d1a693a99e
JSON output gains a new array called "attached" which will
contain the full list of attached programs along with their
attachment modes:
"xdp": {
"mode": 3,
"prog": {
"id": 11,
"tag": "fc7a51d1a693a99e",
"jited": 0
},
"attached": [ {
"mode": 3,
"prog": {
"id": 11,
"tag": "fc7a51d1a693a99e",
"jited": 0
}
} ]
},
In case there are multiple programs attached the general "xdp"
section will not contain program information:
"xdp": {
"mode": 4,
"attached": [ {
"mode": 1,
"prog": {
"id": 10,
"tag": "fc7a51d1a693a99e",
"jited": 1
}
},{
"mode": 3,
"prog": {
"id": 11,
"tag": "fc7a51d1a693a99e",
"jited": 0
}
} ]
},
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
ip/iplink_xdp.c | 73 +++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 61 insertions(+), 12 deletions(-)
diff --git a/ip/iplink_xdp.c b/ip/iplink_xdp.c
index dd4fd1fd3a3b1..4a490bc8fb66c 100644
--- a/ip/iplink_xdp.c
+++ b/ip/iplink_xdp.c
@@ -91,6 +91,18 @@ int xdp_parse(int *argc, char ***argv, struct iplink_req *req,
return 0;
}
+static void xdp_dump_json_one(struct rtattr *tb[IFLA_XDP_MAX + 1], __u32 attr,
+ __u8 mode)
+{
+ if (!tb[attr])
+ return;
+
+ open_json_object(NULL);
+ print_uint(PRINT_JSON, "mode", NULL, mode);
+ bpf_dump_prog_info(NULL, rta_getattr_u32(tb[attr]));
+ close_json_object();
+}
+
static void xdp_dump_json(struct rtattr *tb[IFLA_XDP_MAX + 1])
{
__u32 prog_id = 0;
@@ -104,13 +116,48 @@ static void xdp_dump_json(struct rtattr *tb[IFLA_XDP_MAX + 1])
print_uint(PRINT_JSON, "mode", NULL, mode);
if (prog_id)
bpf_dump_prog_info(NULL, prog_id);
+
+ open_json_array(PRINT_JSON, "attached");
+ if (tb[IFLA_XDP_SKB_PROG_ID] ||
+ tb[IFLA_XDP_DRV_PROG_ID] ||
+ tb[IFLA_XDP_HW_PROG_ID]) {
+ xdp_dump_json_one(tb, IFLA_XDP_SKB_PROG_ID, XDP_ATTACHED_SKB);
+ xdp_dump_json_one(tb, IFLA_XDP_DRV_PROG_ID, XDP_ATTACHED_DRV);
+ xdp_dump_json_one(tb, IFLA_XDP_HW_PROG_ID, XDP_ATTACHED_HW);
+ } else if (tb[IFLA_XDP_PROG_ID]) {
+ /* Older kernel - use IFLA_XDP_PROG_ID */
+ xdp_dump_json_one(tb, IFLA_XDP_PROG_ID, mode);
+ }
+ close_json_array(PRINT_JSON, NULL);
+
close_json_object();
}
+static void xdp_dump_prog_one(FILE *fp, struct rtattr *tb[IFLA_XDP_MAX + 1],
+ __u32 attr, bool link, bool details,
+ const char *pfx)
+{
+ __u32 prog_id;
+
+ if (!tb[attr])
+ return;
+
+ prog_id = rta_getattr_u32(tb[attr]);
+ if (!details) {
+ if (prog_id && !link && attr == IFLA_XDP_PROG_ID)
+ fprintf(fp, "/id:%u", prog_id);
+ return;
+ }
+
+ if (prog_id) {
+ fprintf(fp, "%s prog/xdp%s ", _SL_, pfx);
+ bpf_dump_prog_info(fp, prog_id);
+ }
+}
+
void xdp_dump(FILE *fp, struct rtattr *xdp, bool link, bool details)
{
struct rtattr *tb[IFLA_XDP_MAX + 1];
- __u32 prog_id = 0;
__u8 mode;
parse_rtattr_nested(tb, IFLA_XDP_MAX, xdp);
@@ -124,27 +171,29 @@ void xdp_dump(FILE *fp, struct rtattr *xdp, bool link, bool details)
else if (is_json_context())
return details ? (void)0 : xdp_dump_json(tb);
else if (details && link)
- fprintf(fp, "%s prog/xdp", _SL_);
+ /* don't print mode */;
else if (mode == XDP_ATTACHED_DRV)
fprintf(fp, "xdp");
else if (mode == XDP_ATTACHED_SKB)
fprintf(fp, "xdpgeneric");
else if (mode == XDP_ATTACHED_HW)
fprintf(fp, "xdpoffload");
+ else if (mode == XDP_ATTACHED_MULTI)
+ fprintf(fp, "xdpmulti");
else
fprintf(fp, "xdp[%u]", mode);
- if (tb[IFLA_XDP_PROG_ID])
- prog_id = rta_getattr_u32(tb[IFLA_XDP_PROG_ID]);
- if (!details) {
- if (prog_id && !link)
- fprintf(fp, "/id:%u", prog_id);
- fprintf(fp, " ");
- return;
+ xdp_dump_prog_one(fp, tb, IFLA_XDP_PROG_ID, link, details, "");
+
+ if (mode == XDP_ATTACHED_MULTI) {
+ xdp_dump_prog_one(fp, tb, IFLA_XDP_SKB_PROG_ID, link, details,
+ "generic");
+ xdp_dump_prog_one(fp, tb, IFLA_XDP_DRV_PROG_ID, link, details,
+ "drv");
+ xdp_dump_prog_one(fp, tb, IFLA_XDP_HW_PROG_ID, link, details,
+ "offload");
}
- if (prog_id) {
+ if (!details || !link)
fprintf(fp, " ");
- bpf_dump_prog_info(fp, prog_id);
- }
}
--
2.20.1

View File

@ -1,43 +0,0 @@
From f6fa6c4f178d2bbd3f33cfd4c32265692b91fe5d Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Thu, 13 Jun 2019 14:37:56 +0200
Subject: [PATCH] bpf: move bpf_elf_map fixup notification under verbose
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1716361
Upstream Status: iproute2.git commit 282a1fe1f8fc8
commit 282a1fe1f8fc87b1ebca4ca6f4440d2e69cf4b8f
Author: Daniel Borkmann <daniel@iogearbox.net>
Date: Wed Jul 18 01:31:19 2018 +0200
bpf: move bpf_elf_map fixup notification under verbose
No need to spam the user with this if it can be fixed gracefully
anyway. Therefore, move it under verbose option.
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
lib/bpf.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/bpf.c b/lib/bpf.c
index 65e26989a1f30..9dc37c787d907 100644
--- a/lib/bpf.c
+++ b/lib/bpf.c
@@ -1898,9 +1898,9 @@ static int bpf_fetch_maps_end(struct bpf_elf_ctx *ctx)
}
memcpy(ctx->maps, fixup, sizeof(fixup));
-
- printf("Note: %zu bytes struct bpf_elf_map fixup performed due to size mismatch!\n",
- sizeof(struct bpf_elf_map) - ctx->map_len);
+ if (ctx->verbose)
+ printf("%zu bytes struct bpf_elf_map fixup performed due to size mismatch!\n",
+ sizeof(struct bpf_elf_map) - ctx->map_len);
return 0;
}
--
2.20.1

View File

@ -1,181 +0,0 @@
From 19729e1302017ef33e139903b28f9a778b2a8748 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Thu, 13 Jun 2019 14:37:56 +0200
Subject: [PATCH] bpf: remove strict dependency on af_alg
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1716361
Upstream Status: iproute2.git commit 6e5094dbb7c06
commit 6e5094dbb7c0682a9ca6eb2a64ec51f0a8a33a22
Author: Daniel Borkmann <daniel@iogearbox.net>
Date: Wed Jul 18 01:31:20 2018 +0200
bpf: remove strict dependency on af_alg
Do not bail out when AF_ALG is not supported by the kernel and
only do so when a map is requested in object ns where we're
calculating the hash. Otherwise, the loader can operate just
fine, therefore lets not fail early when it's not needed.
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
lib/bpf.c | 74 +++++++++++++++++++++----------------------------------
1 file changed, 28 insertions(+), 46 deletions(-)
diff --git a/lib/bpf.c b/lib/bpf.c
index 9dc37c787d907..ead8b5a7219f0 100644
--- a/lib/bpf.c
+++ b/lib/bpf.c
@@ -1130,6 +1130,7 @@ struct bpf_elf_ctx {
GElf_Ehdr elf_hdr;
Elf_Data *sym_tab;
Elf_Data *str_tab;
+ char obj_uid[64];
int obj_fd;
int map_fds[ELF_MAX_MAPS];
struct bpf_elf_map maps[ELF_MAX_MAPS];
@@ -1143,6 +1144,7 @@ struct bpf_elf_ctx {
enum bpf_prog_type type;
__u32 ifindex;
bool verbose;
+ bool noafalg;
struct bpf_elf_st stat;
struct bpf_hash_entry *ht[256];
char *log;
@@ -1258,22 +1260,15 @@ static int bpf_obj_hash(const char *object, uint8_t *out, size_t len)
return -EINVAL;
cfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
- if (cfd < 0) {
- fprintf(stderr, "Cannot get AF_ALG socket: %s\n",
- strerror(errno));
+ if (cfd < 0)
return cfd;
- }
ret = bind(cfd, (struct sockaddr *)&alg, sizeof(alg));
- if (ret < 0) {
- fprintf(stderr, "Error binding socket: %s\n", strerror(errno));
+ if (ret < 0)
goto out_cfd;
- }
ofd = accept(cfd, NULL, 0);
if (ofd < 0) {
- fprintf(stderr, "Error accepting socket: %s\n",
- strerror(errno));
ret = ofd;
goto out_cfd;
}
@@ -1318,29 +1313,7 @@ out_cfd:
return ret;
}
-static const char *bpf_get_obj_uid(const char *pathname)
-{
- static bool bpf_uid_cached;
- static char bpf_uid[64];
- uint8_t tmp[20];
- int ret;
-
- if (bpf_uid_cached)
- goto done;
-
- ret = bpf_obj_hash(pathname, tmp, sizeof(tmp));
- if (ret) {
- fprintf(stderr, "Object hashing failed!\n");
- return NULL;
- }
-
- hexstring_n2a(tmp, sizeof(tmp), bpf_uid, sizeof(bpf_uid));
- bpf_uid_cached = true;
-done:
- return bpf_uid;
-}
-
-static int bpf_init_env(const char *pathname)
+static void bpf_init_env(void)
{
struct rlimit limit = {
.rlim_cur = RLIM_INFINITY,
@@ -1350,15 +1323,8 @@ static int bpf_init_env(const char *pathname)
/* Don't bother in case we fail! */
setrlimit(RLIMIT_MEMLOCK, &limit);
- if (!bpf_get_work_dir(BPF_PROG_TYPE_UNSPEC)) {
+ if (!bpf_get_work_dir(BPF_PROG_TYPE_UNSPEC))
fprintf(stderr, "Continuing without mounted eBPF fs. Too old kernel?\n");
- return 0;
- }
-
- if (!bpf_get_obj_uid(pathname))
- return -1;
-
- return 0;
}
static const char *bpf_custom_pinning(const struct bpf_elf_ctx *ctx,
@@ -1394,7 +1360,7 @@ static void bpf_make_pathname(char *pathname, size_t len, const char *name,
case PIN_OBJECT_NS:
snprintf(pathname, len, "%s/%s/%s",
bpf_get_work_dir(ctx->type),
- bpf_get_obj_uid(NULL), name);
+ ctx->obj_uid, name);
break;
case PIN_GLOBAL_NS:
snprintf(pathname, len, "%s/%s/%s",
@@ -1427,7 +1393,7 @@ static int bpf_make_obj_path(const struct bpf_elf_ctx *ctx)
int ret;
snprintf(tmp, sizeof(tmp), "%s/%s", bpf_get_work_dir(ctx->type),
- bpf_get_obj_uid(NULL));
+ ctx->obj_uid);
ret = mkdir(tmp, S_IRWXU);
if (ret && errno != EEXIST) {
@@ -1696,6 +1662,12 @@ static int bpf_maps_attach_all(struct bpf_elf_ctx *ctx)
const char *map_name;
for (i = 0; i < ctx->map_num; i++) {
+ if (ctx->maps[i].pinning == PIN_OBJECT_NS &&
+ ctx->noafalg) {
+ fprintf(stderr, "Missing kernel AF_ALG support for PIN_OBJECT_NS!\n");
+ return -ENOTSUP;
+ }
+
map_name = bpf_map_fetch_name(ctx, i);
if (!map_name)
return -EIO;
@@ -2451,14 +2423,24 @@ static int bpf_elf_ctx_init(struct bpf_elf_ctx *ctx, const char *pathname,
enum bpf_prog_type type, __u32 ifindex,
bool verbose)
{
- int ret = -EINVAL;
+ uint8_t tmp[20];
+ int ret;
- if (elf_version(EV_CURRENT) == EV_NONE ||
- bpf_init_env(pathname))
- return ret;
+ if (elf_version(EV_CURRENT) == EV_NONE)
+ return -EINVAL;
+
+ bpf_init_env();
memset(ctx, 0, sizeof(*ctx));
bpf_get_cfg(ctx);
+
+ ret = bpf_obj_hash(pathname, tmp, sizeof(tmp));
+ if (ret)
+ ctx->noafalg = true;
+ else
+ hexstring_n2a(tmp, sizeof(tmp), ctx->obj_uid,
+ sizeof(ctx->obj_uid));
+
ctx->verbose = verbose;
ctx->type = type;
ctx->ifindex = ifindex;
--
2.20.1

View File

@ -1,460 +0,0 @@
From 80dcb40f8442f79a043c520ae9eef067519ee7ca Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Thu, 13 Jun 2019 14:37:56 +0200
Subject: [PATCH] bpf: implement bpf to bpf calls support
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1716361
Upstream Status: iproute2.git commit b5cb33aec65cb
commit b5cb33aec65cb77183abbdfa5b61ecc9877ec776
Author: Daniel Borkmann <daniel@iogearbox.net>
Date: Wed Jul 18 01:31:21 2018 +0200
bpf: implement bpf to bpf calls support
Implement missing bpf to bpf calls support. The loader will
recognize .text section and handle relocation entries that
are emitted by LLVM.
First step is processing of map related relocation entries
for .text section, and in a second step loader will copy .text
section into program section and adjust call instruction
offset accordingly.
Example with test_xdp_noinline.o from kernel selftests:
1) Every function as __attribute__ ((always_inline)), rest
left unchanged:
# ip -force link set dev lo xdp obj test_xdp_noinline.o sec xdp-test
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 xdpgeneric/id:233 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
[...]
# bpftool prog dump xlated id 233
[...]
1669: (2d) if r3 > r2 goto pc+4
1670: (79) r2 = *(u64 *)(r10 -136)
1671: (61) r2 = *(u32 *)(r2 +0)
1672: (63) *(u32 *)(r1 +0) = r2
1673: (b7) r0 = 1
1674: (95) exit <-- 1674 insns total
2) Every function as __attribute__ ((noinline)), rest
left unchanged:
# ip -force link set dev lo xdp obj test_xdp_noinline.o sec xdp-test
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 xdpgeneric/id:236 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
[...]
# bpftool prog dump xlated id 236
[...]
1000: (bf) r1 = r6
1001: (b7) r2 = 24
1002: (85) call pc+3 <-- pc-relative call insns
1003: (1f) r7 -= r0
1004: (bf) r0 = r7
1005: (95) exit
1006: (bf) r0 = r1
1007: (bf) r1 = r2
1008: (67) r1 <<= 32
1009: (77) r1 >>= 32
1010: (bf) r3 = r0
1011: (6f) r3 <<= r1
1012: (87) r2 = -r2
1013: (57) r2 &= 31
1014: (67) r0 <<= 32
1015: (77) r0 >>= 32
1016: (7f) r0 >>= r2
1017: (4f) r0 |= r3
1018: (95) exit <-- 1018 insns total
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
lib/bpf.c | 233 ++++++++++++++++++++++++++++++++++++------------------
1 file changed, 157 insertions(+), 76 deletions(-)
diff --git a/lib/bpf.c b/lib/bpf.c
index ead8b5a7219f0..1b87490555050 100644
--- a/lib/bpf.c
+++ b/lib/bpf.c
@@ -1109,7 +1109,8 @@ int bpf_prog_load(enum bpf_prog_type type, const struct bpf_insn *insns,
#ifdef HAVE_ELF
struct bpf_elf_prog {
enum bpf_prog_type type;
- const struct bpf_insn *insns;
+ struct bpf_insn *insns;
+ unsigned int insns_num;
size_t size;
const char *license;
};
@@ -1135,11 +1136,13 @@ struct bpf_elf_ctx {
int map_fds[ELF_MAX_MAPS];
struct bpf_elf_map maps[ELF_MAX_MAPS];
struct bpf_map_ext maps_ext[ELF_MAX_MAPS];
+ struct bpf_elf_prog prog_text;
int sym_num;
int map_num;
int map_len;
bool *sec_done;
int sec_maps;
+ int sec_text;
char license[ELF_MAX_LICENSE_LEN];
enum bpf_prog_type type;
__u32 ifindex;
@@ -1904,12 +1907,25 @@ static int bpf_fetch_strtab(struct bpf_elf_ctx *ctx, int section,
return 0;
}
+static int bpf_fetch_text(struct bpf_elf_ctx *ctx, int section,
+ struct bpf_elf_sec_data *data)
+{
+ ctx->sec_text = section;
+ ctx->sec_done[section] = true;
+ return 0;
+}
+
static bool bpf_has_map_data(const struct bpf_elf_ctx *ctx)
{
return ctx->sym_tab && ctx->str_tab && ctx->sec_maps;
}
-static int bpf_fetch_ancillary(struct bpf_elf_ctx *ctx)
+static bool bpf_has_call_data(const struct bpf_elf_ctx *ctx)
+{
+ return ctx->sec_text;
+}
+
+static int bpf_fetch_ancillary(struct bpf_elf_ctx *ctx, bool check_text_sec)
{
struct bpf_elf_sec_data data;
int i, ret = -1;
@@ -1925,6 +1941,11 @@ static int bpf_fetch_ancillary(struct bpf_elf_ctx *ctx)
else if (data.sec_hdr.sh_type == SHT_PROGBITS &&
!strcmp(data.sec_name, ELF_SECTION_LICENSE))
ret = bpf_fetch_license(ctx, i, &data);
+ else if (data.sec_hdr.sh_type == SHT_PROGBITS &&
+ (data.sec_hdr.sh_flags & SHF_EXECINSTR) &&
+ !strcmp(data.sec_name, ".text") &&
+ check_text_sec)
+ ret = bpf_fetch_text(ctx, i, &data);
else if (data.sec_hdr.sh_type == SHT_SYMTAB &&
!strcmp(data.sec_name, ".symtab"))
ret = bpf_fetch_symtab(ctx, i, &data);
@@ -1969,17 +1990,18 @@ static int bpf_fetch_prog(struct bpf_elf_ctx *ctx, const char *section,
ret = bpf_fill_section_data(ctx, i, &data);
if (ret < 0 ||
!(data.sec_hdr.sh_type == SHT_PROGBITS &&
- data.sec_hdr.sh_flags & SHF_EXECINSTR &&
+ (data.sec_hdr.sh_flags & SHF_EXECINSTR) &&
!strcmp(data.sec_name, section)))
continue;
*sseen = true;
memset(&prog, 0, sizeof(prog));
- prog.type = ctx->type;
- prog.insns = data.sec_data->d_buf;
- prog.size = data.sec_data->d_size;
- prog.license = ctx->license;
+ prog.type = ctx->type;
+ prog.license = ctx->license;
+ prog.size = data.sec_data->d_size;
+ prog.insns_num = prog.size / sizeof(struct bpf_insn);
+ prog.insns = data.sec_data->d_buf;
fd = bpf_prog_attach(section, &prog, ctx);
if (fd < 0)
@@ -1992,84 +2014,120 @@ static int bpf_fetch_prog(struct bpf_elf_ctx *ctx, const char *section,
return fd;
}
-struct bpf_tail_call_props {
- unsigned int total;
- unsigned int jited;
+struct bpf_relo_props {
+ struct bpf_tail_call {
+ unsigned int total;
+ unsigned int jited;
+ } tc;
+ int main_num;
};
+static int bpf_apply_relo_map(struct bpf_elf_ctx *ctx, struct bpf_elf_prog *prog,
+ GElf_Rel *relo, GElf_Sym *sym,
+ struct bpf_relo_props *props)
+{
+ unsigned int insn_off = relo->r_offset / sizeof(struct bpf_insn);
+ unsigned int map_idx = sym->st_value / ctx->map_len;
+
+ if (insn_off >= prog->insns_num)
+ return -EINVAL;
+ if (prog->insns[insn_off].code != (BPF_LD | BPF_IMM | BPF_DW)) {
+ fprintf(stderr, "ELF contains relo data for non ld64 instruction at offset %u! Compiler bug?!\n",
+ insn_off);
+ return -EINVAL;
+ }
+
+ if (map_idx >= ARRAY_SIZE(ctx->map_fds))
+ return -EINVAL;
+ if (!ctx->map_fds[map_idx])
+ return -EINVAL;
+ if (ctx->maps[map_idx].type == BPF_MAP_TYPE_PROG_ARRAY) {
+ props->tc.total++;
+ if (ctx->maps_ext[map_idx].owner.jited ||
+ (ctx->maps_ext[map_idx].owner.type == 0 &&
+ ctx->cfg.jit_enabled))
+ props->tc.jited++;
+ }
+
+ prog->insns[insn_off].src_reg = BPF_PSEUDO_MAP_FD;
+ prog->insns[insn_off].imm = ctx->map_fds[map_idx];
+ return 0;
+}
+
+static int bpf_apply_relo_call(struct bpf_elf_ctx *ctx, struct bpf_elf_prog *prog,
+ GElf_Rel *relo, GElf_Sym *sym,
+ struct bpf_relo_props *props)
+{
+ unsigned int insn_off = relo->r_offset / sizeof(struct bpf_insn);
+ struct bpf_elf_prog *prog_text = &ctx->prog_text;
+
+ if (insn_off >= prog->insns_num)
+ return -EINVAL;
+ if (prog->insns[insn_off].code != (BPF_JMP | BPF_CALL) &&
+ prog->insns[insn_off].src_reg != BPF_PSEUDO_CALL) {
+ fprintf(stderr, "ELF contains relo data for non call instruction at offset %u! Compiler bug?!\n",
+ insn_off);
+ return -EINVAL;
+ }
+
+ if (!props->main_num) {
+ struct bpf_insn *insns = realloc(prog->insns,
+ prog->size + prog_text->size);
+ if (!insns)
+ return -ENOMEM;
+
+ memcpy(insns + prog->insns_num, prog_text->insns,
+ prog_text->size);
+ props->main_num = prog->insns_num;
+ prog->insns = insns;
+ prog->insns_num += prog_text->insns_num;
+ prog->size += prog_text->size;
+ }
+
+ prog->insns[insn_off].imm += props->main_num - insn_off;
+ return 0;
+}
+
static int bpf_apply_relo_data(struct bpf_elf_ctx *ctx,
struct bpf_elf_sec_data *data_relo,
- struct bpf_elf_sec_data *data_insn,
- struct bpf_tail_call_props *props)
+ struct bpf_elf_prog *prog,
+ struct bpf_relo_props *props)
{
- Elf_Data *idata = data_insn->sec_data;
GElf_Shdr *rhdr = &data_relo->sec_hdr;
int relo_ent, relo_num = rhdr->sh_size / rhdr->sh_entsize;
- struct bpf_insn *insns = idata->d_buf;
- unsigned int num_insns = idata->d_size / sizeof(*insns);
for (relo_ent = 0; relo_ent < relo_num; relo_ent++) {
- unsigned int ioff, rmap;
GElf_Rel relo;
GElf_Sym sym;
+ int ret = -EIO;
if (gelf_getrel(data_relo->sec_data, relo_ent, &relo) != &relo)
return -EIO;
-
- ioff = relo.r_offset / sizeof(struct bpf_insn);
- if (ioff >= num_insns ||
- insns[ioff].code != (BPF_LD | BPF_IMM | BPF_DW)) {
- fprintf(stderr, "ELF contains relo data for non ld64 instruction at offset %u! Compiler bug?!\n",
- ioff);
- fprintf(stderr, " - Current section: %s\n", data_relo->sec_name);
- if (ioff < num_insns &&
- insns[ioff].code == (BPF_JMP | BPF_CALL))
- fprintf(stderr, " - Try to annotate functions with always_inline attribute!\n");
- return -EINVAL;
- }
-
if (gelf_getsym(ctx->sym_tab, GELF_R_SYM(relo.r_info), &sym) != &sym)
return -EIO;
- if (sym.st_shndx != ctx->sec_maps) {
- fprintf(stderr, "ELF contains non-map related relo data in entry %u pointing to section %u! Compiler bug?!\n",
- relo_ent, sym.st_shndx);
- return -EIO;
- }
- rmap = sym.st_value / ctx->map_len;
- if (rmap >= ARRAY_SIZE(ctx->map_fds))
- return -EINVAL;
- if (!ctx->map_fds[rmap])
- return -EINVAL;
- if (ctx->maps[rmap].type == BPF_MAP_TYPE_PROG_ARRAY) {
- props->total++;
- if (ctx->maps_ext[rmap].owner.jited ||
- (ctx->maps_ext[rmap].owner.type == 0 &&
- ctx->cfg.jit_enabled))
- props->jited++;
- }
-
- if (ctx->verbose)
- fprintf(stderr, "Map \'%s\' (%d) injected into prog section \'%s\' at offset %u!\n",
- bpf_str_tab_name(ctx, &sym), ctx->map_fds[rmap],
- data_insn->sec_name, ioff);
-
- insns[ioff].src_reg = BPF_PSEUDO_MAP_FD;
- insns[ioff].imm = ctx->map_fds[rmap];
+ if (sym.st_shndx == ctx->sec_maps)
+ ret = bpf_apply_relo_map(ctx, prog, &relo, &sym, props);
+ else if (sym.st_shndx == ctx->sec_text)
+ ret = bpf_apply_relo_call(ctx, prog, &relo, &sym, props);
+ else
+ fprintf(stderr, "ELF contains non-{map,call} related relo data in entry %u pointing to section %u! Compiler bug?!\n",
+ relo_ent, sym.st_shndx);
+ if (ret < 0)
+ return ret;
}
return 0;
}
static int bpf_fetch_prog_relo(struct bpf_elf_ctx *ctx, const char *section,
- bool *lderr, bool *sseen)
+ bool *lderr, bool *sseen, struct bpf_elf_prog *prog)
{
struct bpf_elf_sec_data data_relo, data_insn;
- struct bpf_elf_prog prog;
int ret, idx, i, fd = -1;
for (i = 1; i < ctx->elf_hdr.e_shnum; i++) {
- struct bpf_tail_call_props props = {};
+ struct bpf_relo_props props = {};
ret = bpf_fill_section_data(ctx, i, &data_relo);
if (ret < 0 || data_relo.sec_hdr.sh_type != SHT_REL)
@@ -2080,40 +2138,54 @@ static int bpf_fetch_prog_relo(struct bpf_elf_ctx *ctx, const char *section,
ret = bpf_fill_section_data(ctx, idx, &data_insn);
if (ret < 0 ||
!(data_insn.sec_hdr.sh_type == SHT_PROGBITS &&
- data_insn.sec_hdr.sh_flags & SHF_EXECINSTR &&
+ (data_insn.sec_hdr.sh_flags & SHF_EXECINSTR) &&
!strcmp(data_insn.sec_name, section)))
continue;
+ if (sseen)
+ *sseen = true;
+
+ memset(prog, 0, sizeof(*prog));
+ prog->type = ctx->type;
+ prog->license = ctx->license;
+ prog->size = data_insn.sec_data->d_size;
+ prog->insns_num = prog->size / sizeof(struct bpf_insn);
+ prog->insns = malloc(prog->size);
+ if (!prog->insns) {
+ *lderr = true;
+ return -ENOMEM;
+ }
- *sseen = true;
+ memcpy(prog->insns, data_insn.sec_data->d_buf, prog->size);
- ret = bpf_apply_relo_data(ctx, &data_relo, &data_insn, &props);
+ ret = bpf_apply_relo_data(ctx, &data_relo, prog, &props);
if (ret < 0) {
*lderr = true;
+ if (ctx->sec_text != idx)
+ free(prog->insns);
return ret;
}
+ if (ctx->sec_text == idx) {
+ fd = 0;
+ goto out;
+ }
- memset(&prog, 0, sizeof(prog));
- prog.type = ctx->type;
- prog.insns = data_insn.sec_data->d_buf;
- prog.size = data_insn.sec_data->d_size;
- prog.license = ctx->license;
-
- fd = bpf_prog_attach(section, &prog, ctx);
+ fd = bpf_prog_attach(section, prog, ctx);
+ free(prog->insns);
if (fd < 0) {
*lderr = true;
- if (props.total) {
+ if (props.tc.total) {
if (ctx->cfg.jit_enabled &&
- props.total != props.jited)
+ props.tc.total != props.tc.jited)
fprintf(stderr, "JIT enabled, but only %u/%u tail call maps in the program have JITed owner!\n",
- props.jited, props.total);
+ props.tc.jited, props.tc.total);
if (!ctx->cfg.jit_enabled &&
- props.jited)
+ props.tc.jited)
fprintf(stderr, "JIT disabled, but %u/%u tail call maps in the program have JITed owner!\n",
- props.jited, props.total);
+ props.tc.jited, props.tc.total);
}
return fd;
}
-
+out:
ctx->sec_done[i] = true;
ctx->sec_done[idx] = true;
break;
@@ -2125,10 +2197,18 @@ static int bpf_fetch_prog_relo(struct bpf_elf_ctx *ctx, const char *section,
static int bpf_fetch_prog_sec(struct bpf_elf_ctx *ctx, const char *section)
{
bool lderr = false, sseen = false;
+ struct bpf_elf_prog prog;
int ret = -1;
- if (bpf_has_map_data(ctx))
- ret = bpf_fetch_prog_relo(ctx, section, &lderr, &sseen);
+ if (bpf_has_call_data(ctx)) {
+ ret = bpf_fetch_prog_relo(ctx, ".text", &lderr, NULL,
+ &ctx->prog_text);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (bpf_has_map_data(ctx) || bpf_has_call_data(ctx))
+ ret = bpf_fetch_prog_relo(ctx, section, &lderr, &sseen, &prog);
if (ret < 0 && !lderr)
ret = bpf_fetch_prog(ctx, section, &sseen);
if (ret < 0 && !sseen)
@@ -2525,6 +2605,7 @@ static void bpf_elf_ctx_destroy(struct bpf_elf_ctx *ctx, bool failure)
bpf_hash_destroy(ctx);
+ free(ctx->prog_text.insns);
free(ctx->sec_done);
free(ctx->log);
@@ -2546,7 +2627,7 @@ static int bpf_obj_open(const char *pathname, enum bpf_prog_type type,
return ret;
}
- ret = bpf_fetch_ancillary(ctx);
+ ret = bpf_fetch_ancillary(ctx, strcmp(section, ".text"));
if (ret < 0) {
fprintf(stderr, "Error fetching ELF ancillary data!\n");
goto out;
--
2.20.1

View File

@ -1,624 +0,0 @@
From e8386c4e1fa3b5486487fa4d6c350a0d5e300aaf Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Thu, 13 Jun 2019 14:37:56 +0200
Subject: [PATCH] bpf: implement btf handling and map annotation
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1716361
Upstream Status: iproute2.git commit f823f36012fb5
commit f823f36012fb5ab4ddfca6ed4ff56188730f281e
Author: Daniel Borkmann <daniel@iogearbox.net>
Date: Wed Jul 18 01:31:22 2018 +0200
bpf: implement btf handling and map annotation
Implement loading of .BTF section from object file and build up
internal table for retrieving key/value id related to maps in
the BPF program. Latter is done by setting up struct btf_type
table.
One of the issues is that there's a disconnect between the data
types used in the map and struct bpf_elf_map, meaning the underlying
types are unknown from the map description. One way to overcome
this is to add a annotation such that the loader will recognize
the relation to both. BPF_ANNOTATE_KV_PAIR(map_foo, struct key,
struct val); has been added to the API that programs can use.
The loader will then pick the corresponding key/value type ids and
attach it to the maps for creation. This can later on be dumped via
bpftool for introspection.
Example with test_xdp_noinline.o from kernel selftests:
[...]
struct ctl_value {
union {
__u64 value;
__u32 ifindex;
__u8 mac[6];
};
};
struct bpf_map_def __attribute__ ((section("maps"), used)) ctl_array = {
.type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(__u32),
.value_size = sizeof(struct ctl_value),
.max_entries = 16,
.map_flags = 0,
};
BPF_ANNOTATE_KV_PAIR(ctl_array, __u32, struct ctl_value);
[...]
Above could also further be wrapped in a macro. Compiling through LLVM and
converting to BTF:
# llc --version
LLVM (http://llvm.org/):
LLVM version 7.0.0svn
Optimized build.
Default target: x86_64-unknown-linux-gnu
Host CPU: skylake
Registered Targets:
bpf - BPF (host endian)
bpfeb - BPF (big endian)
bpfel - BPF (little endian)
[...]
# clang [...] -O2 -target bpf -g -emit-llvm -c test_xdp_noinline.c -o - |
llc -march=bpf -mcpu=probe -mattr=dwarfris -filetype=obj -o test_xdp_noinline.o
# pahole -J test_xdp_noinline.o
Checking pahole dump of BPF object file:
# file test_xdp_noinline.o
test_xdp_noinline.o: ELF 64-bit LSB relocatable, *unknown arch 0xf7* version 1 (SYSV), with debug_info, not stripped
# pahole test_xdp_noinline.o
[...]
struct ctl_value {
union {
__u64 value; /* 0 8 */
__u32 ifindex; /* 0 4 */
__u8 mac[0]; /* 0 0 */
}; /* 0 8 */
/* size: 8, cachelines: 1, members: 1 */
/* last cacheline: 8 bytes */
};
Now loading into kernel and dumping the map via bpftool:
# ip -force link set dev lo xdp obj test_xdp_noinline.o sec xdp-test
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 xdpgeneric/id:227 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
[...]
# bpftool prog show id 227
227: xdp tag a85e060c275c5616 gpl
loaded_at 2018-07-17T14:41:29+0000 uid 0
xlated 8152B not jited memlock 12288B map_ids 381,385,386,382,384,383
# bpftool map dump id 386
[{
"key": 0,
"value": {
"": {
"value": 0,
"ifindex": 0,
"mac": []
}
}
},{
"key": 1,
"value": {
"": {
"value": 0,
"ifindex": 0,
"mac": []
}
}
},{
[...]
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
include/bpf_elf.h | 9 ++
include/bpf_util.h | 1 +
lib/bpf.c | 332 ++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 338 insertions(+), 4 deletions(-)
diff --git a/include/bpf_elf.h b/include/bpf_elf.h
index a8e360f3bbb28..84e8ae00834c8 100644
--- a/include/bpf_elf.h
+++ b/include/bpf_elf.h
@@ -41,4 +41,13 @@ struct bpf_elf_map {
__u32 inner_idx;
};
+#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \
+ struct ____btf_map_##name { \
+ type_key key; \
+ type_val value; \
+ }; \
+ struct ____btf_map_##name \
+ __attribute__ ((section(".maps." #name), used)) \
+ ____btf_map_##name = { }
+
#endif /* __BPF_ELF__ */
diff --git a/include/bpf_util.h b/include/bpf_util.h
index 219beb40cd253..63837a04e56fe 100644
--- a/include/bpf_util.h
+++ b/include/bpf_util.h
@@ -14,6 +14,7 @@
#define __BPF_UTIL__
#include <linux/bpf.h>
+#include <linux/btf.h>
#include <linux/filter.h>
#include <linux/magic.h>
#include <linux/elf-em.h>
diff --git a/lib/bpf.c b/lib/bpf.c
index 1b87490555050..d093d0bd86eae 100644
--- a/lib/bpf.c
+++ b/lib/bpf.c
@@ -393,6 +393,8 @@ struct bpf_prog_data {
struct bpf_map_ext {
struct bpf_prog_data owner;
+ unsigned int btf_id_key;
+ unsigned int btf_id_val;
};
static int bpf_derive_elf_map_from_fdinfo(int fd, struct bpf_elf_map *map,
@@ -1125,24 +1127,36 @@ struct bpf_config {
unsigned int jit_enabled;
};
+struct bpf_btf {
+ const struct btf_header *hdr;
+ const void *raw;
+ const char *strings;
+ const struct btf_type **types;
+ int types_num;
+};
+
struct bpf_elf_ctx {
struct bpf_config cfg;
Elf *elf_fd;
GElf_Ehdr elf_hdr;
Elf_Data *sym_tab;
Elf_Data *str_tab;
+ Elf_Data *btf_data;
char obj_uid[64];
int obj_fd;
+ int btf_fd;
int map_fds[ELF_MAX_MAPS];
struct bpf_elf_map maps[ELF_MAX_MAPS];
struct bpf_map_ext maps_ext[ELF_MAX_MAPS];
struct bpf_elf_prog prog_text;
+ struct bpf_btf btf;
int sym_num;
int map_num;
int map_len;
bool *sec_done;
int sec_maps;
int sec_text;
+ int sec_btf;
char license[ELF_MAX_LICENSE_LEN];
enum bpf_prog_type type;
__u32 ifindex;
@@ -1167,6 +1181,11 @@ struct bpf_map_data {
struct bpf_elf_map *ent;
};
+static bool bpf_log_has_data(struct bpf_elf_ctx *ctx)
+{
+ return ctx->log && ctx->log[0];
+}
+
static __check_format_string(2, 3) void
bpf_dump_error(struct bpf_elf_ctx *ctx, const char *format, ...)
{
@@ -1176,7 +1195,7 @@ bpf_dump_error(struct bpf_elf_ctx *ctx, const char *format, ...)
vfprintf(stderr, format, vl);
va_end(vl);
- if (ctx->log && ctx->log[0]) {
+ if (bpf_log_has_data(ctx)) {
if (ctx->verbose) {
fprintf(stderr, "%s\n", ctx->log);
} else {
@@ -1223,7 +1242,9 @@ static int bpf_log_realloc(struct bpf_elf_ctx *ctx)
static int bpf_map_create(enum bpf_map_type type, uint32_t size_key,
uint32_t size_value, uint32_t max_elem,
- uint32_t flags, int inner_fd, uint32_t ifindex)
+ uint32_t flags, int inner_fd, int btf_fd,
+ uint32_t ifindex, uint32_t btf_id_key,
+ uint32_t btf_id_val)
{
union bpf_attr attr = {};
@@ -1234,10 +1255,30 @@ static int bpf_map_create(enum bpf_map_type type, uint32_t size_key,
attr.map_flags = flags;
attr.inner_map_fd = inner_fd;
attr.map_ifindex = ifindex;
+ attr.btf_fd = btf_fd;
+ attr.btf_key_type_id = btf_id_key;
+ attr.btf_value_type_id = btf_id_val;
return bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
}
+static int bpf_btf_load(void *btf, size_t size_btf,
+ char *log, size_t size_log)
+{
+ union bpf_attr attr = {};
+
+ attr.btf = bpf_ptr_to_u64(btf);
+ attr.btf_size = size_btf;
+
+ if (size_log > 0) {
+ attr.btf_log_buf = bpf_ptr_to_u64(log);
+ attr.btf_log_size = size_log;
+ attr.btf_log_level = 1;
+ }
+
+ return bpf(BPF_BTF_LOAD, &attr, sizeof(attr));
+}
+
static int bpf_obj_pin(int fd, const char *pathname)
{
union bpf_attr attr = {};
@@ -1613,7 +1654,8 @@ static int bpf_map_attach(const char *name, struct bpf_elf_ctx *ctx,
ifindex = bpf_map_offload_neutral(map->type) ? 0 : ctx->ifindex;
errno = 0;
fd = bpf_map_create(map->type, map->size_key, map->size_value,
- map->max_elem, map->flags, map_inner_fd, ifindex);
+ map->max_elem, map->flags, map_inner_fd, ctx->btf_fd,
+ ifindex, ext->btf_id_key, ext->btf_id_val);
if (fd < 0 || ctx->verbose) {
bpf_map_report(fd, name, map, ctx, map_inner_fd);
@@ -1638,8 +1680,80 @@ static const char *bpf_str_tab_name(const struct bpf_elf_ctx *ctx,
return ctx->str_tab->d_buf + sym->st_name;
}
+static int bpf_btf_find(struct bpf_elf_ctx *ctx, const char *name)
+{
+ const struct btf_type *type;
+ const char *res;
+ int id;
+
+ for (id = 1; id < ctx->btf.types_num; id++) {
+ type = ctx->btf.types[id];
+ if (type->name_off >= ctx->btf.hdr->str_len)
+ continue;
+ res = &ctx->btf.strings[type->name_off];
+ if (!strcmp(res, name))
+ return id;
+ }
+
+ return -ENOENT;
+}
+
+static int bpf_btf_find_kv(struct bpf_elf_ctx *ctx, const struct bpf_elf_map *map,
+ const char *name, uint32_t *id_key, uint32_t *id_val)
+{
+ const struct btf_member *key, *val;
+ const struct btf_type *type;
+ char btf_name[512];
+ const char *res;
+ int id;
+
+ snprintf(btf_name, sizeof(btf_name), "____btf_map_%s", name);
+ id = bpf_btf_find(ctx, btf_name);
+ if (id < 0)
+ return id;
+
+ type = ctx->btf.types[id];
+ if (BTF_INFO_KIND(type->info) != BTF_KIND_STRUCT)
+ return -EINVAL;
+ if (BTF_INFO_VLEN(type->info) != 2)
+ return -EINVAL;
+
+ key = ((void *) type) + sizeof(*type);
+ val = key + 1;
+ if (!key->type || key->type >= ctx->btf.types_num ||
+ !val->type || val->type >= ctx->btf.types_num)
+ return -EINVAL;
+
+ if (key->name_off >= ctx->btf.hdr->str_len ||
+ val->name_off >= ctx->btf.hdr->str_len)
+ return -EINVAL;
+
+ res = &ctx->btf.strings[key->name_off];
+ if (strcmp(res, "key"))
+ return -EINVAL;
+
+ res = &ctx->btf.strings[val->name_off];
+ if (strcmp(res, "value"))
+ return -EINVAL;
+
+ *id_key = key->type;
+ *id_val = val->type;
+ return 0;
+}
+
+static void bpf_btf_annotate(struct bpf_elf_ctx *ctx, int which, const char *name)
+{
+ uint32_t id_key = 0, id_val = 0;
+
+ if (!bpf_btf_find_kv(ctx, &ctx->maps[which], name, &id_key, &id_val)) {
+ ctx->maps_ext[which].btf_id_key = id_key;
+ ctx->maps_ext[which].btf_id_val = id_val;
+ }
+}
+
static const char *bpf_map_fetch_name(struct bpf_elf_ctx *ctx, int which)
{
+ const char *name;
GElf_Sym sym;
int i;
@@ -1653,7 +1767,9 @@ static const char *bpf_map_fetch_name(struct bpf_elf_ctx *ctx, int which)
sym.st_value / ctx->map_len != which)
continue;
- return bpf_str_tab_name(ctx, &sym);
+ name = bpf_str_tab_name(ctx, &sym);
+ bpf_btf_annotate(ctx, which, name);
+ return name;
}
return NULL;
@@ -1915,11 +2031,210 @@ static int bpf_fetch_text(struct bpf_elf_ctx *ctx, int section,
return 0;
}
+static void bpf_btf_report(int fd, struct bpf_elf_ctx *ctx)
+{
+ fprintf(stderr, "\nBTF debug data section \'.BTF\' %s%s (%d)!\n",
+ fd < 0 ? "rejected: " : "loaded",
+ fd < 0 ? strerror(errno) : "",
+ fd < 0 ? errno : fd);
+
+ fprintf(stderr, " - Length: %zu\n", ctx->btf_data->d_size);
+
+ bpf_dump_error(ctx, "Verifier analysis:\n\n");
+}
+
+static int bpf_btf_attach(struct bpf_elf_ctx *ctx)
+{
+ int tries = 0, fd;
+retry:
+ errno = 0;
+ fd = bpf_btf_load(ctx->btf_data->d_buf, ctx->btf_data->d_size,
+ ctx->log, ctx->log_size);
+ if (fd < 0 || ctx->verbose) {
+ if (fd < 0 && (errno == ENOSPC || !ctx->log_size)) {
+ if (tries++ < 10 && !bpf_log_realloc(ctx))
+ goto retry;
+
+ fprintf(stderr, "Log buffer too small to dump verifier log %zu bytes (%d tries)!\n",
+ ctx->log_size, tries);
+ return fd;
+ }
+
+ if (bpf_log_has_data(ctx))
+ bpf_btf_report(fd, ctx);
+ }
+
+ return fd;
+}
+
+static int bpf_fetch_btf_begin(struct bpf_elf_ctx *ctx, int section,
+ struct bpf_elf_sec_data *data)
+{
+ ctx->btf_data = data->sec_data;
+ ctx->sec_btf = section;
+ ctx->sec_done[section] = true;
+ return 0;
+}
+
+static int bpf_btf_check_header(struct bpf_elf_ctx *ctx)
+{
+ const struct btf_header *hdr = ctx->btf_data->d_buf;
+ const char *str_start, *str_end;
+ unsigned int data_len;
+
+ if (hdr->magic != BTF_MAGIC) {
+ fprintf(stderr, "Object has wrong BTF magic: %x, expected: %x!\n",
+ hdr->magic, BTF_MAGIC);
+ return -EINVAL;
+ }
+
+ if (hdr->version != BTF_VERSION) {
+ fprintf(stderr, "Object has wrong BTF version: %u, expected: %u!\n",
+ hdr->version, BTF_VERSION);
+ return -EINVAL;
+ }
+
+ if (hdr->flags) {
+ fprintf(stderr, "Object has unsupported BTF flags %x!\n",
+ hdr->flags);
+ return -EINVAL;
+ }
+
+ data_len = ctx->btf_data->d_size - sizeof(*hdr);
+ if (data_len < hdr->type_off ||
+ data_len < hdr->str_off ||
+ data_len < hdr->type_len + hdr->str_len ||
+ hdr->type_off >= hdr->str_off ||
+ hdr->type_off + hdr->type_len != hdr->str_off ||
+ hdr->str_off + hdr->str_len != data_len ||
+ (hdr->type_off & (sizeof(uint32_t) - 1))) {
+ fprintf(stderr, "Object has malformed BTF data!\n");
+ return -EINVAL;
+ }
+
+ ctx->btf.hdr = hdr;
+ ctx->btf.raw = hdr + 1;
+
+ str_start = ctx->btf.raw + hdr->str_off;
+ str_end = str_start + hdr->str_len;
+ if (!hdr->str_len ||
+ hdr->str_len - 1 > BTF_MAX_NAME_OFFSET ||
+ str_start[0] || str_end[-1]) {
+ fprintf(stderr, "Object has malformed BTF string data!\n");
+ return -EINVAL;
+ }
+
+ ctx->btf.strings = str_start;
+ return 0;
+}
+
+static int bpf_btf_register_type(struct bpf_elf_ctx *ctx,
+ const struct btf_type *type)
+{
+ int cur = ctx->btf.types_num, num = cur + 1;
+ const struct btf_type **types;
+
+ types = realloc(ctx->btf.types, num * sizeof(type));
+ if (!types) {
+ free(ctx->btf.types);
+ ctx->btf.types = NULL;
+ ctx->btf.types_num = 0;
+ return -ENOMEM;
+ }
+
+ ctx->btf.types = types;
+ ctx->btf.types[cur] = type;
+ ctx->btf.types_num = num;
+ return 0;
+}
+
+static struct btf_type btf_type_void;
+
+static int bpf_btf_prep_type_data(struct bpf_elf_ctx *ctx)
+{
+ const void *type_cur = ctx->btf.raw + ctx->btf.hdr->type_off;
+ const void *type_end = ctx->btf.raw + ctx->btf.hdr->str_off;
+ const struct btf_type *type;
+ uint16_t var_len;
+ int ret, kind;
+
+ ret = bpf_btf_register_type(ctx, &btf_type_void);
+ if (ret < 0)
+ return ret;
+
+ while (type_cur < type_end) {
+ type = type_cur;
+ type_cur += sizeof(*type);
+
+ var_len = BTF_INFO_VLEN(type->info);
+ kind = BTF_INFO_KIND(type->info);
+
+ switch (kind) {
+ case BTF_KIND_INT:
+ type_cur += sizeof(int);
+ break;
+ case BTF_KIND_ARRAY:
+ type_cur += sizeof(struct btf_array);
+ break;
+ case BTF_KIND_STRUCT:
+ case BTF_KIND_UNION:
+ type_cur += var_len * sizeof(struct btf_member);
+ break;
+ case BTF_KIND_ENUM:
+ type_cur += var_len * sizeof(struct btf_enum);
+ break;
+ case BTF_KIND_TYPEDEF:
+ case BTF_KIND_PTR:
+ case BTF_KIND_FWD:
+ case BTF_KIND_VOLATILE:
+ case BTF_KIND_CONST:
+ case BTF_KIND_RESTRICT:
+ break;
+ default:
+ fprintf(stderr, "Object has unknown BTF type: %u!\n", kind);
+ return -EINVAL;
+ }
+
+ ret = bpf_btf_register_type(ctx, type);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int bpf_btf_prep_data(struct bpf_elf_ctx *ctx)
+{
+ int ret = bpf_btf_check_header(ctx);
+
+ if (!ret)
+ return bpf_btf_prep_type_data(ctx);
+ return ret;
+}
+
+static void bpf_fetch_btf_end(struct bpf_elf_ctx *ctx)
+{
+ int fd = bpf_btf_attach(ctx);
+
+ if (fd < 0)
+ return;
+ ctx->btf_fd = fd;
+ if (bpf_btf_prep_data(ctx) < 0) {
+ close(ctx->btf_fd);
+ ctx->btf_fd = 0;
+ }
+}
+
static bool bpf_has_map_data(const struct bpf_elf_ctx *ctx)
{
return ctx->sym_tab && ctx->str_tab && ctx->sec_maps;
}
+static bool bpf_has_btf_data(const struct bpf_elf_ctx *ctx)
+{
+ return ctx->sec_btf;
+}
+
static bool bpf_has_call_data(const struct bpf_elf_ctx *ctx)
{
return ctx->sec_text;
@@ -1952,6 +2267,9 @@ static int bpf_fetch_ancillary(struct bpf_elf_ctx *ctx, bool check_text_sec)
else if (data.sec_hdr.sh_type == SHT_STRTAB &&
!strcmp(data.sec_name, ".strtab"))
ret = bpf_fetch_strtab(ctx, i, &data);
+ else if (data.sec_hdr.sh_type == SHT_PROGBITS &&
+ !strcmp(data.sec_name, ".BTF"))
+ ret = bpf_fetch_btf_begin(ctx, i, &data);
if (ret < 0) {
fprintf(stderr, "Error parsing section %d! Perhaps check with readelf -a?\n",
i);
@@ -1959,6 +2277,8 @@ static int bpf_fetch_ancillary(struct bpf_elf_ctx *ctx, bool check_text_sec)
}
}
+ if (bpf_has_btf_data(ctx))
+ bpf_fetch_btf_end(ctx);
if (bpf_has_map_data(ctx)) {
ret = bpf_fetch_maps_end(ctx);
if (ret < 0) {
@@ -2596,6 +2916,10 @@ static void bpf_maps_teardown(struct bpf_elf_ctx *ctx)
if (ctx->map_fds[i])
close(ctx->map_fds[i]);
}
+
+ if (ctx->btf_fd)
+ close(ctx->btf_fd);
+ free(ctx->btf.types);
}
static void bpf_elf_ctx_destroy(struct bpf_elf_ctx *ctx, bool failure)
--
2.20.1

View File

@ -1,113 +0,0 @@
From 9783e8b3de077c2e6399a9aa83f93237690bd744 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Thu, 13 Jun 2019 14:37:57 +0200
Subject: [PATCH] bpf: check map symbol type properly with newer llvm compiler
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1716361
Upstream Status: iproute2.git commit 7a04dd84a7f93
commit 7a04dd84a7f938f72fcef9efe8383314b0a66274
Author: Yonghong Song <yhs@fb.com>
Date: Mon Oct 29 15:32:03 2018 -0700
bpf: check map symbol type properly with newer llvm compiler
With llvm 7.0 or earlier, the map symbol type is STT_NOTYPE.
-bash-4.4$ cat t.c
__attribute__((section("maps"))) int g;
-bash-4.4$ clang -target bpf -O2 -c t.c
-bash-4.4$ readelf -s t.o
Symbol table '.symtab' contains 2 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 3 g
The following llvm commit enables BPF target to generate
proper symbol type and size.
commit bf6ec206615b9718869d48b4e5400d0c6e3638dd
Author: Yonghong Song <yhs@fb.com>
Date: Wed Sep 19 16:04:13 2018 +0000
[bpf] Symbol sizes and types in object file
Clang-compiled object files currently don't include the symbol sizes and
types. Some tools however need that information. For example, ctfconvert
uses that information to generate FreeBSD's CTF representation from ELF
files.
With this patch, symbol sizes and types are included in object files.
Signed-off-by: Paul Chaignon <paul.chaignon@orange.com>
Reported-by: Yutaro Hayakawa <yhayakawa3720@gmail.com>
Hence, for llvm 8.0.0 (currently trunk), symbol type will be not NOTYPE, but OBJECT.
-bash-4.4$ clang -target bpf -O2 -c t.c
-bash-4.4$ readelf -s t.o
Symbol table '.symtab' contains 3 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS t.c
2: 0000000000000000 4 OBJECT GLOBAL DEFAULT 3 g
This patch makes sure bpf library accepts both NOTYPE and OBJECT types
of global map symbols.
Signed-off-by: Yonghong Song <yhs@fb.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/bpf.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/lib/bpf.c b/lib/bpf.c
index d093d0bd86eae..45f279fa4a416 100644
--- a/lib/bpf.c
+++ b/lib/bpf.c
@@ -1758,11 +1758,13 @@ static const char *bpf_map_fetch_name(struct bpf_elf_ctx *ctx, int which)
int i;
for (i = 0; i < ctx->sym_num; i++) {
+ int type = GELF_ST_TYPE(sym.st_info);
+
if (gelf_getsym(ctx->sym_tab, i, &sym) != &sym)
continue;
if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL ||
- GELF_ST_TYPE(sym.st_info) != STT_NOTYPE ||
+ (type != STT_NOTYPE && type != STT_OBJECT) ||
sym.st_shndx != ctx->sec_maps ||
sym.st_value / ctx->map_len != which)
continue;
@@ -1849,11 +1851,13 @@ static int bpf_map_num_sym(struct bpf_elf_ctx *ctx)
GElf_Sym sym;
for (i = 0; i < ctx->sym_num; i++) {
+ int type = GELF_ST_TYPE(sym.st_info);
+
if (gelf_getsym(ctx->sym_tab, i, &sym) != &sym)
continue;
if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL ||
- GELF_ST_TYPE(sym.st_info) != STT_NOTYPE ||
+ (type != STT_NOTYPE && type != STT_OBJECT) ||
sym.st_shndx != ctx->sec_maps)
continue;
num++;
@@ -1927,10 +1931,12 @@ static int bpf_map_verify_all_offs(struct bpf_elf_ctx *ctx, int end)
* the table again.
*/
for (i = 0; i < ctx->sym_num; i++) {
+ int type = GELF_ST_TYPE(sym.st_info);
+
if (gelf_getsym(ctx->sym_tab, i, &sym) != &sym)
continue;
if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL ||
- GELF_ST_TYPE(sym.st_info) != STT_NOTYPE ||
+ (type != STT_NOTYPE && type != STT_OBJECT) ||
sym.st_shndx != ctx->sec_maps)
continue;
if (sym.st_value == off)
--
2.20.1

View File

@ -1,258 +0,0 @@
From d3153cc39f5dca57e2cfc2faaefc690f64af398f Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Thu, 13 Jun 2019 14:37:57 +0200
Subject: [PATCH] Use libbsd for strlcpy if available
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1716361
Upstream Status: iproute2.git commit 508f3c231efb1
commit 508f3c231efb179fb842d222e8151b395937b136
Author: Luca Boccassi <bluca@debian.org>
Date: Wed Oct 31 18:00:11 2018 +0000
Use libbsd for strlcpy if available
If libc does not provide strlcpy check for libbsd with pkg-config to
avoid relying on inline version.
Signed-off-by: Luca Boccassi <bluca@debian.org>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
configure | 11 +++++++++--
genl/ctrl.c | 3 +++
ip/iplink.c | 3 +++
ip/ipnetns.c | 3 +++
ip/iproute_lwtunnel.c | 3 +++
ip/ipvrf.c | 3 +++
ip/ipxfrm.c | 3 +++
ip/tunnel.c | 3 +++
ip/xfrm_state.c | 3 +++
lib/bpf.c | 3 +++
lib/fs.c | 3 +++
lib/inet_proto.c | 3 +++
misc/ss.c | 3 +++
tc/em_ipset.c | 3 +++
tc/m_pedit.c | 3 +++
15 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/configure b/configure
index 5ef5cd4cf9cde..07c18f9bda4a2 100755
--- a/configure
+++ b/configure
@@ -330,8 +330,15 @@ EOF
then
echo "no"
else
- echo 'CFLAGS += -DNEED_STRLCPY' >>$CONFIG
- echo "yes"
+ if ${PKG_CONFIG} libbsd --exists
+ then
+ echo 'CFLAGS += -DHAVE_LIBBSD' `${PKG_CONFIG} libbsd --cflags` >>$CONFIG
+ echo 'LDLIBS +=' `${PKG_CONFIG} libbsd --libs` >> $CONFIG
+ echo "no"
+ else
+ echo 'CFLAGS += -DNEED_STRLCPY' >>$CONFIG
+ echo "yes"
+ fi
fi
rm -f $TMPDIR/strtest.c $TMPDIR/strtest
}
diff --git a/genl/ctrl.c b/genl/ctrl.c
index 0d9c5f2517b78..4063ec0ba474b 100644
--- a/genl/ctrl.c
+++ b/genl/ctrl.c
@@ -18,6 +18,9 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
+#ifdef HAVE_LIBBSD
+#include <bsd/string.h>
+#endif
#include "utils.h"
#include "genl_utils.h"
diff --git a/ip/iplink.c b/ip/iplink.c
index 0ba5f1af76697..2f8f3bf1f84bb 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -24,6 +24,9 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
+#ifdef HAVE_LIBBSD
+#include <bsd/string.h>
+#endif
#include <sys/ioctl.h>
#include <stdbool.h>
#include <linux/mpls.h>
diff --git a/ip/ipnetns.c b/ip/ipnetns.c
index 368be0cbc0a48..5991592e947b6 100644
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -8,6 +8,9 @@
#include <sys/syscall.h>
#include <stdio.h>
#include <string.h>
+#ifdef HAVE_LIBBSD
+#include <bsd/string.h>
+#endif
#include <sched.h>
#include <fcntl.h>
#include <dirent.h>
diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
index 388cd19a3ef0b..be9f60c3b2137 100644
--- a/ip/iproute_lwtunnel.c
+++ b/ip/iproute_lwtunnel.c
@@ -16,6 +16,9 @@
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
+#ifdef HAVE_LIBBSD
+#include <bsd/string.h>
+#endif
#include <linux/ila.h>
#include <linux/lwtunnel.h>
#include <linux/mpls_iptunnel.h>
diff --git a/ip/ipvrf.c b/ip/ipvrf.c
index 8a6b7f977b142..8572b4f23e3dc 100644
--- a/ip/ipvrf.c
+++ b/ip/ipvrf.c
@@ -21,6 +21,9 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#ifdef HAVE_LIBBSD
+#include <bsd/string.h>
+#endif
#include <dirent.h>
#include <errno.h>
#include <limits.h>
diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c
index 12c2f721571b6..5304dfc1af906 100644
--- a/ip/ipxfrm.c
+++ b/ip/ipxfrm.c
@@ -28,6 +28,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifdef HAVE_LIBBSD
+#include <bsd/string.h>
+#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <time.h>
diff --git a/ip/tunnel.c b/ip/tunnel.c
index 79de7f2406f0e..d54505d483d22 100644
--- a/ip/tunnel.c
+++ b/ip/tunnel.c
@@ -24,6 +24,9 @@
#include <stdio.h>
#include <string.h>
+#ifdef HAVE_LIBBSD
+#include <bsd/string.h>
+#endif
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c
index 85d959cc4f44f..0c8df7e6e10cd 100644
--- a/ip/xfrm_state.c
+++ b/ip/xfrm_state.c
@@ -27,6 +27,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifdef HAVE_LIBBSD
+#include <bsd/string.h>
+#endif
#include <netdb.h>
#include "utils.h"
#include "xfrm.h"
diff --git a/lib/bpf.c b/lib/bpf.c
index 45f279fa4a416..35d7c45a2924d 100644
--- a/lib/bpf.c
+++ b/lib/bpf.c
@@ -15,6 +15,9 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#ifdef HAVE_LIBBSD
+#include <bsd/string.h>
+#endif
#include <stdbool.h>
#include <stdint.h>
#include <errno.h>
diff --git a/lib/fs.c b/lib/fs.c
index 86efd4ed2ed80..af36bea0987fa 100644
--- a/lib/fs.c
+++ b/lib/fs.c
@@ -20,6 +20,9 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#ifdef HAVE_LIBBSD
+#include <bsd/string.h>
+#endif
#include <errno.h>
#include <limits.h>
diff --git a/lib/inet_proto.c b/lib/inet_proto.c
index 0836a4c96a0b4..b379d8f8e720e 100644
--- a/lib/inet_proto.c
+++ b/lib/inet_proto.c
@@ -18,6 +18,9 @@
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
+#ifdef HAVE_LIBBSD
+#include <bsd/string.h>
+#endif
#include "rt_names.h"
#include "utils.h"
diff --git a/misc/ss.c b/misc/ss.c
index 41e7762bb61f5..7e94f2c8d1baa 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -18,6 +18,9 @@
#include <sys/uio.h>
#include <netinet/in.h>
#include <string.h>
+#ifdef HAVE_LIBBSD
+#include <bsd/string.h>
+#endif
#include <errno.h>
#include <netdb.h>
#include <arpa/inet.h>
diff --git a/tc/em_ipset.c b/tc/em_ipset.c
index 48b287f5ba3b2..550b2101a0579 100644
--- a/tc/em_ipset.c
+++ b/tc/em_ipset.c
@@ -20,6 +20,9 @@
#include <netdb.h>
#include <unistd.h>
#include <string.h>
+#ifdef HAVE_LIBBSD
+#include <bsd/string.h>
+#endif
#include <stdlib.h>
#include <getopt.h>
diff --git a/tc/m_pedit.c b/tc/m_pedit.c
index 2aeb56d9615f1..baacc80dd94b7 100644
--- a/tc/m_pedit.c
+++ b/tc/m_pedit.c
@@ -23,6 +23,9 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
+#ifdef HAVE_LIBBSD
+#include <bsd/string.h>
+#endif
#include <dlfcn.h>
#include "utils.h"
#include "tc_util.h"
--
2.20.1

View File

@ -1,255 +0,0 @@
From f416b73a7f47494cf6d18cdaad5e86709bc43a63 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Thu, 13 Jun 2019 14:37:57 +0200
Subject: [PATCH] Include bsd/string.h only in include/utils.h
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1716361
Upstream Status: iproute2.git commit 6d2fd4a53f63b
commit 6d2fd4a53f63bd20667b1a8f2ec8fde1fc3a54d4
Author: Luca Boccassi <bluca@debian.org>
Date: Thu Nov 1 22:25:27 2018 +0000
Include bsd/string.h only in include/utils.h
This is simpler and cleaner, and avoids having to include the header
from every file where the functions are used. The prototypes of the
internal implementation are in this header, so utils.h will have to be
included anyway for those.
Fixes: 508f3c231efb ("Use libbsd for strlcpy if available")
Signed-off-by: Luca Boccassi <bluca@debian.org>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
genl/ctrl.c | 3 ---
include/utils.h | 4 ++++
ip/iplink.c | 3 ---
ip/ipnetns.c | 3 ---
ip/iproute_lwtunnel.c | 3 ---
ip/ipvrf.c | 3 ---
ip/ipxfrm.c | 3 ---
ip/tunnel.c | 3 ---
ip/xfrm_state.c | 3 ---
lib/bpf.c | 3 ---
lib/fs.c | 3 ---
lib/inet_proto.c | 3 ---
misc/ss.c | 3 ---
tc/em_ipset.c | 3 ---
tc/m_pedit.c | 3 ---
15 files changed, 4 insertions(+), 42 deletions(-)
diff --git a/genl/ctrl.c b/genl/ctrl.c
index 4063ec0ba474b..0d9c5f2517b78 100644
--- a/genl/ctrl.c
+++ b/genl/ctrl.c
@@ -18,9 +18,6 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
-#ifdef HAVE_LIBBSD
-#include <bsd/string.h>
-#endif
#include "utils.h"
#include "genl_utils.h"
diff --git a/include/utils.h b/include/utils.h
index 8cb4349e8a89f..c32b37a1797d8 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -9,6 +9,10 @@
#include <stdbool.h>
#include <time.h>
+#ifdef HAVE_LIBBSD
+#include <bsd/string.h>
+#endif
+
#include "libnetlink.h"
#include "ll_map.h"
#include "rtm_map.h"
diff --git a/ip/iplink.c b/ip/iplink.c
index 2f8f3bf1f84bb..0ba5f1af76697 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -24,9 +24,6 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
-#ifdef HAVE_LIBBSD
-#include <bsd/string.h>
-#endif
#include <sys/ioctl.h>
#include <stdbool.h>
#include <linux/mpls.h>
diff --git a/ip/ipnetns.c b/ip/ipnetns.c
index 5991592e947b6..368be0cbc0a48 100644
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -8,9 +8,6 @@
#include <sys/syscall.h>
#include <stdio.h>
#include <string.h>
-#ifdef HAVE_LIBBSD
-#include <bsd/string.h>
-#endif
#include <sched.h>
#include <fcntl.h>
#include <dirent.h>
diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
index be9f60c3b2137..388cd19a3ef0b 100644
--- a/ip/iproute_lwtunnel.c
+++ b/ip/iproute_lwtunnel.c
@@ -16,9 +16,6 @@
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
-#ifdef HAVE_LIBBSD
-#include <bsd/string.h>
-#endif
#include <linux/ila.h>
#include <linux/lwtunnel.h>
#include <linux/mpls_iptunnel.h>
diff --git a/ip/ipvrf.c b/ip/ipvrf.c
index 8572b4f23e3dc..8a6b7f977b142 100644
--- a/ip/ipvrf.c
+++ b/ip/ipvrf.c
@@ -21,9 +21,6 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
-#ifdef HAVE_LIBBSD
-#include <bsd/string.h>
-#endif
#include <dirent.h>
#include <errno.h>
#include <limits.h>
diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c
index 5304dfc1af906..12c2f721571b6 100644
--- a/ip/ipxfrm.c
+++ b/ip/ipxfrm.c
@@ -28,9 +28,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#ifdef HAVE_LIBBSD
-#include <bsd/string.h>
-#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <time.h>
diff --git a/ip/tunnel.c b/ip/tunnel.c
index d54505d483d22..79de7f2406f0e 100644
--- a/ip/tunnel.c
+++ b/ip/tunnel.c
@@ -24,9 +24,6 @@
#include <stdio.h>
#include <string.h>
-#ifdef HAVE_LIBBSD
-#include <bsd/string.h>
-#endif
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c
index 0c8df7e6e10cd..85d959cc4f44f 100644
--- a/ip/xfrm_state.c
+++ b/ip/xfrm_state.c
@@ -27,9 +27,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#ifdef HAVE_LIBBSD
-#include <bsd/string.h>
-#endif
#include <netdb.h>
#include "utils.h"
#include "xfrm.h"
diff --git a/lib/bpf.c b/lib/bpf.c
index 35d7c45a2924d..45f279fa4a416 100644
--- a/lib/bpf.c
+++ b/lib/bpf.c
@@ -15,9 +15,6 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
-#ifdef HAVE_LIBBSD
-#include <bsd/string.h>
-#endif
#include <stdbool.h>
#include <stdint.h>
#include <errno.h>
diff --git a/lib/fs.c b/lib/fs.c
index af36bea0987fa..86efd4ed2ed80 100644
--- a/lib/fs.c
+++ b/lib/fs.c
@@ -20,9 +20,6 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
-#ifdef HAVE_LIBBSD
-#include <bsd/string.h>
-#endif
#include <errno.h>
#include <limits.h>
diff --git a/lib/inet_proto.c b/lib/inet_proto.c
index b379d8f8e720e..0836a4c96a0b4 100644
--- a/lib/inet_proto.c
+++ b/lib/inet_proto.c
@@ -18,9 +18,6 @@
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
-#ifdef HAVE_LIBBSD
-#include <bsd/string.h>
-#endif
#include "rt_names.h"
#include "utils.h"
diff --git a/misc/ss.c b/misc/ss.c
index 7e94f2c8d1baa..41e7762bb61f5 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -18,9 +18,6 @@
#include <sys/uio.h>
#include <netinet/in.h>
#include <string.h>
-#ifdef HAVE_LIBBSD
-#include <bsd/string.h>
-#endif
#include <errno.h>
#include <netdb.h>
#include <arpa/inet.h>
diff --git a/tc/em_ipset.c b/tc/em_ipset.c
index 550b2101a0579..48b287f5ba3b2 100644
--- a/tc/em_ipset.c
+++ b/tc/em_ipset.c
@@ -20,9 +20,6 @@
#include <netdb.h>
#include <unistd.h>
#include <string.h>
-#ifdef HAVE_LIBBSD
-#include <bsd/string.h>
-#endif
#include <stdlib.h>
#include <getopt.h>
diff --git a/tc/m_pedit.c b/tc/m_pedit.c
index baacc80dd94b7..2aeb56d9615f1 100644
--- a/tc/m_pedit.c
+++ b/tc/m_pedit.c
@@ -23,9 +23,6 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
-#ifdef HAVE_LIBBSD
-#include <bsd/string.h>
-#endif
#include <dlfcn.h>
#include "utils.h"
#include "tc_util.h"
--
2.20.1

View File

@ -1,90 +0,0 @@
From 9348ded117d05ba1d54a748173db009d473c707c Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Thu, 13 Jun 2019 14:37:57 +0200
Subject: [PATCH] bpf: initialise map symbol before retrieving and comparing
its type
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1716361
Upstream Status: iproute2.git commit 1a7d3ad8a5862
commit 1a7d3ad8a5862ca9ce9dd19326faeea77e5e6142
Author: Quentin Monnet <quentin.monnet@netronome.com>
Date: Tue Nov 20 01:26:27 2018 +0000
bpf: initialise map symbol before retrieving and comparing its type
In order to compare BPF map symbol type correctly in regard to the
latest LLVM, commit 7a04dd84a7f9 ("bpf: check map symbol type properly
with newer llvm compiler") compares map symbol type to both NOTYPE and
OBJECT. To do so, it first retrieves the type from "sym.st_info" and
stores it into a temporary variable.
However, the type is collected from the symbol "sym" before this latter
symbol is actually updated. gelf_getsym() is called after that and
updates "sym", and when comparison with OBJECT or NOTYPE happens it is
done on the type of the symbol collected in the previous passage of the
loop (or on an uninitialised symbol on the first passage). This may
eventually break map collection from the ELF file.
Fix this by assigning the type to the temporary variable only after the
call to gelf_getsym().
Fixes: 7a04dd84a7f9 ("bpf: check map symbol type properly with newer llvm compiler")
Reported-by: Ron Philip <ron.philip@netronome.com>
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Reviewed-by: Jiong Wang <jiong.wang@netronome.com>
Acked-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/bpf.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/lib/bpf.c b/lib/bpf.c
index 45f279fa4a416..6aff8f7bad7fb 100644
--- a/lib/bpf.c
+++ b/lib/bpf.c
@@ -1758,11 +1758,12 @@ static const char *bpf_map_fetch_name(struct bpf_elf_ctx *ctx, int which)
int i;
for (i = 0; i < ctx->sym_num; i++) {
- int type = GELF_ST_TYPE(sym.st_info);
+ int type;
if (gelf_getsym(ctx->sym_tab, i, &sym) != &sym)
continue;
+ type = GELF_ST_TYPE(sym.st_info);
if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL ||
(type != STT_NOTYPE && type != STT_OBJECT) ||
sym.st_shndx != ctx->sec_maps ||
@@ -1851,11 +1852,12 @@ static int bpf_map_num_sym(struct bpf_elf_ctx *ctx)
GElf_Sym sym;
for (i = 0; i < ctx->sym_num; i++) {
- int type = GELF_ST_TYPE(sym.st_info);
+ int type;
if (gelf_getsym(ctx->sym_tab, i, &sym) != &sym)
continue;
+ type = GELF_ST_TYPE(sym.st_info);
if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL ||
(type != STT_NOTYPE && type != STT_OBJECT) ||
sym.st_shndx != ctx->sec_maps)
@@ -1931,10 +1933,12 @@ static int bpf_map_verify_all_offs(struct bpf_elf_ctx *ctx, int end)
* the table again.
*/
for (i = 0; i < ctx->sym_num; i++) {
- int type = GELF_ST_TYPE(sym.st_info);
+ int type;
if (gelf_getsym(ctx->sym_tab, i, &sym) != &sym)
continue;
+
+ type = GELF_ST_TYPE(sym.st_info);
if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL ||
(type != STT_NOTYPE && type != STT_OBJECT) ||
sym.st_shndx != ctx->sec_maps)
--
2.20.1

View File

@ -1,57 +0,0 @@
From ac8f163e0b2e14afdc8a1a1d449f1e5db07075ba Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Thu, 13 Jun 2019 14:37:57 +0200
Subject: [PATCH] lib/bpf: fix build warning if no elf
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1716361
Upstream Status: iproute2.git commit 33fde2b60081e
commit 33fde2b60081ed9ac16f7dd81c48233803855689
Author: Stephen Hemminger <stephen@networkplumber.org>
Date: Mon Dec 10 13:50:17 2018 -0800
lib/bpf: fix build warning if no elf
Function was not used unlesss HAVE_ELF causing:
bpf.c:105:13: warning: bpf_map_offload_neutral defined but not used [-Wunused-function]
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/bpf.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/lib/bpf.c b/lib/bpf.c
index 6aff8f7bad7fb..5e85cfc0bdd5b 100644
--- a/lib/bpf.c
+++ b/lib/bpf.c
@@ -102,11 +102,6 @@ static const struct bpf_prog_meta __bpf_prog_meta[] = {
},
};
-static bool bpf_map_offload_neutral(enum bpf_map_type type)
-{
- return type == BPF_MAP_TYPE_PERF_EVENT_ARRAY;
-}
-
static const char *bpf_prog_to_subdir(enum bpf_prog_type type)
{
assert(type < ARRAY_SIZE(__bpf_prog_meta) &&
@@ -1610,6 +1605,11 @@ static bool bpf_is_map_in_map_type(const struct bpf_elf_map *map)
map->type == BPF_MAP_TYPE_HASH_OF_MAPS;
}
+static bool bpf_map_offload_neutral(enum bpf_map_type type)
+{
+ return type == BPF_MAP_TYPE_PERF_EVENT_ARRAY;
+}
+
static int bpf_map_attach(const char *name, struct bpf_elf_ctx *ctx,
const struct bpf_elf_map *map, struct bpf_map_ext *ext,
int *have_map_in_map)
--
2.20.1

View File

@ -1,61 +0,0 @@
From 5c940644dfc632f1270f39ee909e1abb877ff081 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Thu, 13 Jun 2019 14:37:57 +0200
Subject: [PATCH] bpf: add btf func and func_proto kind support
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1716361
Upstream Status: iproute2.git commit 3da6d055d93fe
commit 3da6d055d93fefe40bf88a9bc37b4ce3433696ee
Author: Yonghong Song <yhs@fb.com>
Date: Thu Jan 24 16:41:07 2019 -0800
bpf: add btf func and func_proto kind support
The issue is discovered for bpf selftest test_skb_cgroup.sh.
Currently we have,
$ ./test_skb_cgroup_id.sh
Wait for testing link-local IP to become available ... OK
Object has unknown BTF type: 13!
[PASS]
In the above the BTF type 13 refers to BTF kind
BTF_KIND_FUNC_PROTO.
This patch added support of BTF_KIND_FUNC_PROTO and
BTF_KIND_FUNC during type parsing.
With this patch, I got
$ ./test_skb_cgroup_id.sh
Wait for testing link-local IP to become available ... OK
[PASS]
Signed-off-by: Yonghong Song <yhs@fb.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/bpf.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lib/bpf.c b/lib/bpf.c
index 5e85cfc0bdd5b..762f8857453ff 100644
--- a/lib/bpf.c
+++ b/lib/bpf.c
@@ -2193,12 +2193,16 @@ static int bpf_btf_prep_type_data(struct bpf_elf_ctx *ctx)
case BTF_KIND_ENUM:
type_cur += var_len * sizeof(struct btf_enum);
break;
+ case BTF_KIND_FUNC_PROTO:
+ type_cur += var_len * sizeof(struct btf_param);
+ break;
case BTF_KIND_TYPEDEF:
case BTF_KIND_PTR:
case BTF_KIND_FWD:
case BTF_KIND_VOLATILE:
case BTF_KIND_CONST:
case BTF_KIND_RESTRICT:
+ case BTF_KIND_FUNC:
break;
default:
fprintf(stderr, "Object has unknown BTF type: %u!\n", kind);
--
2.20.1

View File

@ -1,282 +0,0 @@
From 3caa0fed6aa58a8f7a05486f98572878a8ad5b30 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Thu, 13 Jun 2019 14:37:57 +0200
Subject: [PATCH] uapi: update headers to 4.20-rc1
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1716361
Upstream Status: iproute2.git commit 39776a8665f2d
commit 39776a8665f2db1255ebed1f7cc992f69437bc36
Author: Stephen Hemminger <stephen@networkplumber.org>
Date: Mon Nov 5 08:37:41 2018 -0800
uapi: update headers to 4.20-rc1
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
include/uapi/linux/bpf.h | 142 ++++++++++++++++++++++++++++++++++-
include/uapi/linux/elf-em.h | 1 +
include/uapi/linux/if_link.h | 1 +
include/uapi/linux/magic.h | 1 +
include/uapi/linux/netlink.h | 1 +
include/uapi/linux/sctp.h | 1 +
6 files changed, 145 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index abb7f7748c2de..2bbe33db8aefa 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -103,6 +103,7 @@ enum bpf_cmd {
BPF_BTF_LOAD,
BPF_BTF_GET_FD_BY_ID,
BPF_TASK_FD_QUERY,
+ BPF_MAP_LOOKUP_AND_DELETE_ELEM,
};
enum bpf_map_type {
@@ -127,6 +128,9 @@ enum bpf_map_type {
BPF_MAP_TYPE_SOCKHASH,
BPF_MAP_TYPE_CGROUP_STORAGE,
BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
+ BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE,
+ BPF_MAP_TYPE_QUEUE,
+ BPF_MAP_TYPE_STACK,
};
enum bpf_prog_type {
@@ -461,6 +465,28 @@ union bpf_attr {
* Return
* 0 on success, or a negative error in case of failure.
*
+ * int bpf_map_push_elem(struct bpf_map *map, const void *value, u64 flags)
+ * Description
+ * Push an element *value* in *map*. *flags* is one of:
+ *
+ * **BPF_EXIST**
+ * If the queue/stack is full, the oldest element is removed to
+ * make room for this.
+ * Return
+ * 0 on success, or a negative error in case of failure.
+ *
+ * int bpf_map_pop_elem(struct bpf_map *map, void *value)
+ * Description
+ * Pop an element from *map*.
+ * Return
+ * 0 on success, or a negative error in case of failure.
+ *
+ * int bpf_map_peek_elem(struct bpf_map *map, void *value)
+ * Description
+ * Get an element from *map* without removing it.
+ * Return
+ * 0 on success, or a negative error in case of failure.
+ *
* int bpf_probe_read(void *dst, u32 size, const void *src)
* Description
* For tracing programs, safely attempt to read *size* bytes from
@@ -1432,7 +1458,7 @@ union bpf_attr {
* Return
* 0 on success, or a negative error in case of failure.
*
- * int bpf_skb_adjust_room(struct sk_buff *skb, u32 len_diff, u32 mode, u64 flags)
+ * int bpf_skb_adjust_room(struct sk_buff *skb, s32 len_diff, u32 mode, u64 flags)
* Description
* Grow or shrink the room for data in the packet associated to
* *skb* by *len_diff*, and according to the selected *mode*.
@@ -2143,6 +2169,94 @@ union bpf_attr {
* request in the skb.
* Return
* 0 on success, or a negative error in case of failure.
+ *
+ * struct bpf_sock *bpf_sk_lookup_tcp(void *ctx, struct bpf_sock_tuple *tuple, u32 tuple_size, u32 netns, u64 flags)
+ * Description
+ * Look for TCP socket matching *tuple*, optionally in a child
+ * network namespace *netns*. The return value must be checked,
+ * and if non-NULL, released via **bpf_sk_release**\ ().
+ *
+ * The *ctx* should point to the context of the program, such as
+ * the skb or socket (depending on the hook in use). This is used
+ * to determine the base network namespace for the lookup.
+ *
+ * *tuple_size* must be one of:
+ *
+ * **sizeof**\ (*tuple*\ **->ipv4**)
+ * Look for an IPv4 socket.
+ * **sizeof**\ (*tuple*\ **->ipv6**)
+ * Look for an IPv6 socket.
+ *
+ * If the *netns* is zero, then the socket lookup table in the
+ * netns associated with the *ctx* will be used. For the TC hooks,
+ * this in the netns of the device in the skb. For socket hooks,
+ * this in the netns of the socket. If *netns* is non-zero, then
+ * it specifies the ID of the netns relative to the netns
+ * associated with the *ctx*.
+ *
+ * All values for *flags* are reserved for future usage, and must
+ * be left at zero.
+ *
+ * This helper is available only if the kernel was compiled with
+ * **CONFIG_NET** configuration option.
+ * Return
+ * Pointer to *struct bpf_sock*, or NULL in case of failure.
+ *
+ * struct bpf_sock *bpf_sk_lookup_udp(void *ctx, struct bpf_sock_tuple *tuple, u32 tuple_size, u32 netns, u64 flags)
+ * Description
+ * Look for UDP socket matching *tuple*, optionally in a child
+ * network namespace *netns*. The return value must be checked,
+ * and if non-NULL, released via **bpf_sk_release**\ ().
+ *
+ * The *ctx* should point to the context of the program, such as
+ * the skb or socket (depending on the hook in use). This is used
+ * to determine the base network namespace for the lookup.
+ *
+ * *tuple_size* must be one of:
+ *
+ * **sizeof**\ (*tuple*\ **->ipv4**)
+ * Look for an IPv4 socket.
+ * **sizeof**\ (*tuple*\ **->ipv6**)
+ * Look for an IPv6 socket.
+ *
+ * If the *netns* is zero, then the socket lookup table in the
+ * netns associated with the *ctx* will be used. For the TC hooks,
+ * this in the netns of the device in the skb. For socket hooks,
+ * this in the netns of the socket. If *netns* is non-zero, then
+ * it specifies the ID of the netns relative to the netns
+ * associated with the *ctx*.
+ *
+ * All values for *flags* are reserved for future usage, and must
+ * be left at zero.
+ *
+ * This helper is available only if the kernel was compiled with
+ * **CONFIG_NET** configuration option.
+ * Return
+ * Pointer to *struct bpf_sock*, or NULL in case of failure.
+ *
+ * int bpf_sk_release(struct bpf_sock *sk)
+ * Description
+ * Release the reference held by *sock*. *sock* must be a non-NULL
+ * pointer that was returned from bpf_sk_lookup_xxx\ ().
+ * Return
+ * 0 on success, or a negative error in case of failure.
+ *
+ * int bpf_msg_push_data(struct sk_buff *skb, u32 start, u32 len, u64 flags)
+ * Description
+ * For socket policies, insert *len* bytes into msg at offset
+ * *start*.
+ *
+ * If a program of type **BPF_PROG_TYPE_SK_MSG** is run on a
+ * *msg* it may want to insert metadata or options into the msg.
+ * This can later be read and used by any of the lower layer BPF
+ * hooks.
+ *
+ * This helper may fail if under memory pressure (a malloc
+ * fails) in these cases BPF programs will get an appropriate
+ * error and BPF programs will need to handle them.
+ *
+ * Return
+ * 0 on success, or a negative error in case of failure.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
@@ -2228,7 +2342,14 @@ union bpf_attr {
FN(get_current_cgroup_id), \
FN(get_local_storage), \
FN(sk_select_reuseport), \
- FN(skb_ancestor_cgroup_id),
+ FN(skb_ancestor_cgroup_id), \
+ FN(sk_lookup_tcp), \
+ FN(sk_lookup_udp), \
+ FN(sk_release), \
+ FN(map_push_elem), \
+ FN(map_pop_elem), \
+ FN(map_peek_elem), \
+ FN(msg_push_data),
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
* function eBPF program intends to call
@@ -2398,6 +2519,23 @@ struct bpf_sock {
*/
};
+struct bpf_sock_tuple {
+ union {
+ struct {
+ __be32 saddr;
+ __be32 daddr;
+ __be16 sport;
+ __be16 dport;
+ } ipv4;
+ struct {
+ __be32 saddr[4];
+ __be32 daddr[4];
+ __be16 sport;
+ __be16 dport;
+ } ipv6;
+ };
+};
+
#define XDP_PACKET_HEADROOM 256
/* User return codes for XDP prog type.
diff --git a/include/uapi/linux/elf-em.h b/include/uapi/linux/elf-em.h
index 31aa101783351..93722e60204c6 100644
--- a/include/uapi/linux/elf-em.h
+++ b/include/uapi/linux/elf-em.h
@@ -41,6 +41,7 @@
#define EM_TILEPRO 188 /* Tilera TILEPro */
#define EM_MICROBLAZE 189 /* Xilinx MicroBlaze */
#define EM_TILEGX 191 /* Tilera TILE-Gx */
+#define EM_RISCV 243 /* RISC-V */
#define EM_BPF 247 /* Linux BPF - in-kernel virtual machine */
#define EM_FRV 0x5441 /* Fujitsu FR-V */
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 9c254603ebdad..52e95197e0790 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -285,6 +285,7 @@ enum {
IFLA_BR_MCAST_STATS_ENABLED,
IFLA_BR_MCAST_IGMP_VERSION,
IFLA_BR_MCAST_MLD_VERSION,
+ IFLA_BR_VLAN_STATS_PER_PORT,
__IFLA_BR_MAX,
};
diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h
index 1a6fee974116a..96c24478d8ced 100644
--- a/include/uapi/linux/magic.h
+++ b/include/uapi/linux/magic.h
@@ -29,6 +29,7 @@
#define HPFS_SUPER_MAGIC 0xf995e849
#define ISOFS_SUPER_MAGIC 0x9660
#define JFFS2_SUPER_MAGIC 0x72b6
+#define XFS_SUPER_MAGIC 0x58465342 /* "XFSB" */
#define PSTOREFS_MAGIC 0x6165676C
#define EFIVARFS_MAGIC 0xde5e81e4
#define HOSTFS_SUPER_MAGIC 0x00c0ffee
diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h
index 0b2c29bd081fa..2966171b9b95c 100644
--- a/include/uapi/linux/netlink.h
+++ b/include/uapi/linux/netlink.h
@@ -153,6 +153,7 @@ enum nlmsgerr_attrs {
#define NETLINK_LIST_MEMBERSHIPS 9
#define NETLINK_CAP_ACK 10
#define NETLINK_EXT_ACK 11
+#define NETLINK_DUMP_STRICT_CHK 12
struct nl_pktinfo {
__u32 group;
diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
index dd164d7f4f41a..626480b68fb59 100644
--- a/include/uapi/linux/sctp.h
+++ b/include/uapi/linux/sctp.h
@@ -301,6 +301,7 @@ enum sctp_sinfo_flags {
SCTP_SACK_IMMEDIATELY = (1 << 3), /* SACK should be sent without delay. */
/* 2 bits here have been used by SCTP_PR_SCTP_MASK */
SCTP_SENDALL = (1 << 6),
+ SCTP_PR_SCTP_ALL = (1 << 7),
SCTP_NOTIFICATION = MSG_NOTIFICATION, /* Next message is not user msg but notification. */
SCTP_EOF = MSG_FIN, /* Initiate graceful shutdown process. */
};
--
2.20.1

View File

@ -1,155 +0,0 @@
From 415044d7e6f956daec990a7ae358f9f324bd2dcd Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Thu, 13 Jun 2019 14:37:57 +0200
Subject: [PATCH] uapi: update bpf header
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1716361
Upstream Status: iproute2.git commit 028766aed21a4
commit 028766aed21a4d8eb2e60c9ef667f75f9354a104
Author: Stephen Hemminger <stephen@networkplumber.org>
Date: Mon Dec 10 09:22:23 2018 -0800
uapi: update bpf header
Changes from 4.20-rc6
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
include/uapi/linux/bpf.h | 56 ++++++++++++++++++++++++++--------------
1 file changed, 37 insertions(+), 19 deletions(-)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 2bbe33db8aefa..ff651ca661308 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -2170,7 +2170,7 @@ union bpf_attr {
* Return
* 0 on success, or a negative error in case of failure.
*
- * struct bpf_sock *bpf_sk_lookup_tcp(void *ctx, struct bpf_sock_tuple *tuple, u32 tuple_size, u32 netns, u64 flags)
+ * struct bpf_sock *bpf_sk_lookup_tcp(void *ctx, struct bpf_sock_tuple *tuple, u32 tuple_size, u64 netns, u64 flags)
* Description
* Look for TCP socket matching *tuple*, optionally in a child
* network namespace *netns*. The return value must be checked,
@@ -2187,12 +2187,14 @@ union bpf_attr {
* **sizeof**\ (*tuple*\ **->ipv6**)
* Look for an IPv6 socket.
*
- * If the *netns* is zero, then the socket lookup table in the
- * netns associated with the *ctx* will be used. For the TC hooks,
- * this in the netns of the device in the skb. For socket hooks,
- * this in the netns of the socket. If *netns* is non-zero, then
- * it specifies the ID of the netns relative to the netns
- * associated with the *ctx*.
+ * If the *netns* is a negative signed 32-bit integer, then the
+ * socket lookup table in the netns associated with the *ctx* will
+ * will be used. For the TC hooks, this is the netns of the device
+ * in the skb. For socket hooks, this is the netns of the socket.
+ * If *netns* is any other signed 32-bit value greater than or
+ * equal to zero then it specifies the ID of the netns relative to
+ * the netns associated with the *ctx*. *netns* values beyond the
+ * range of 32-bit integers are reserved for future use.
*
* All values for *flags* are reserved for future usage, and must
* be left at zero.
@@ -2201,8 +2203,10 @@ union bpf_attr {
* **CONFIG_NET** configuration option.
* Return
* Pointer to *struct bpf_sock*, or NULL in case of failure.
+ * For sockets with reuseport option, the *struct bpf_sock*
+ * result is from reuse->socks[] using the hash of the tuple.
*
- * struct bpf_sock *bpf_sk_lookup_udp(void *ctx, struct bpf_sock_tuple *tuple, u32 tuple_size, u32 netns, u64 flags)
+ * struct bpf_sock *bpf_sk_lookup_udp(void *ctx, struct bpf_sock_tuple *tuple, u32 tuple_size, u64 netns, u64 flags)
* Description
* Look for UDP socket matching *tuple*, optionally in a child
* network namespace *netns*. The return value must be checked,
@@ -2219,12 +2223,14 @@ union bpf_attr {
* **sizeof**\ (*tuple*\ **->ipv6**)
* Look for an IPv6 socket.
*
- * If the *netns* is zero, then the socket lookup table in the
- * netns associated with the *ctx* will be used. For the TC hooks,
- * this in the netns of the device in the skb. For socket hooks,
- * this in the netns of the socket. If *netns* is non-zero, then
- * it specifies the ID of the netns relative to the netns
- * associated with the *ctx*.
+ * If the *netns* is a negative signed 32-bit integer, then the
+ * socket lookup table in the netns associated with the *ctx* will
+ * will be used. For the TC hooks, this is the netns of the device
+ * in the skb. For socket hooks, this is the netns of the socket.
+ * If *netns* is any other signed 32-bit value greater than or
+ * equal to zero then it specifies the ID of the netns relative to
+ * the netns associated with the *ctx*. *netns* values beyond the
+ * range of 32-bit integers are reserved for future use.
*
* All values for *flags* are reserved for future usage, and must
* be left at zero.
@@ -2233,6 +2239,8 @@ union bpf_attr {
* **CONFIG_NET** configuration option.
* Return
* Pointer to *struct bpf_sock*, or NULL in case of failure.
+ * For sockets with reuseport option, the *struct bpf_sock*
+ * result is from reuse->socks[] using the hash of the tuple.
*
* int bpf_sk_release(struct bpf_sock *sk)
* Description
@@ -2405,6 +2413,9 @@ enum bpf_func_id {
/* BPF_FUNC_perf_event_output for sk_buff input context. */
#define BPF_F_CTXLEN_MASK (0xfffffULL << 32)
+/* Current network namespace */
+#define BPF_F_CURRENT_NETNS (-1L)
+
/* Mode for BPF_FUNC_skb_adjust_room helper. */
enum bpf_adj_room_mode {
BPF_ADJ_ROOM_NET,
@@ -2422,6 +2433,12 @@ enum bpf_lwt_encap_mode {
BPF_LWT_ENCAP_SEG6_INLINE
};
+#define __bpf_md_ptr(type, name) \
+union { \
+ type name; \
+ __u64 :64; \
+} __attribute__((aligned(8)))
+
/* user accessible mirror of in-kernel sk_buff.
* new fields can only be added to the end of this structure
*/
@@ -2456,7 +2473,7 @@ struct __sk_buff {
/* ... here. */
__u32 data_meta;
- struct bpf_flow_keys *flow_keys;
+ __bpf_md_ptr(struct bpf_flow_keys *, flow_keys);
};
struct bpf_tunnel_key {
@@ -2572,8 +2589,8 @@ enum sk_action {
* be added to the end of this structure
*/
struct sk_msg_md {
- void *data;
- void *data_end;
+ __bpf_md_ptr(void *, data);
+ __bpf_md_ptr(void *, data_end);
__u32 family;
__u32 remote_ip4; /* Stored in network byte order */
@@ -2589,8 +2606,9 @@ struct sk_reuseport_md {
* Start of directly accessible data. It begins from
* the tcp/udp header.
*/
- void *data;
- void *data_end; /* End of directly accessible data */
+ __bpf_md_ptr(void *, data);
+ /* End of directly accessible data */
+ __bpf_md_ptr(void *, data_end);
/*
* Total length of packet (starting from the tcp/udp header).
* Note that the directly accessible bytes (data_end - data)
--
2.20.1

View File

@ -1,492 +0,0 @@
From 356758b3303ab24b6fe8dccf94ed98ed7cbad224 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Thu, 13 Jun 2019 14:37:57 +0200
Subject: [PATCH] Update kernel headers
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1716361
Upstream Status: iproute2.git commit 17689d3075c8b
commit 17689d3075c8b9a29b8f398a57defb9dcabafe81
Author: David Ahern <dsahern@gmail.com>
Date: Wed Dec 19 12:47:29 2018 -0800
Update kernel headers
Update kernel headers to commit
055722716c39 ("tipc: fix uninitialized value for broadcast retransmission")
Signed-off-by: David Ahern <dsahern@gmail.com>
---
include/uapi/linux/bpf.h | 175 +++++++++++++++++++++--------
include/uapi/linux/btf.h | 18 ++-
include/uapi/linux/if_bridge.h | 21 ++++
include/uapi/linux/if_link.h | 1 +
include/uapi/linux/if_tun.h | 1 +
include/uapi/linux/neighbour.h | 1 +
include/uapi/linux/net_namespace.h | 2 +
include/uapi/linux/snmp.h | 1 +
8 files changed, 171 insertions(+), 49 deletions(-)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index ff651ca661308..960a7f0a4d99b 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -232,6 +232,20 @@ enum bpf_attach_type {
*/
#define BPF_F_STRICT_ALIGNMENT (1U << 0)
+/* If BPF_F_ANY_ALIGNMENT is used in BPF_PROF_LOAD command, the
+ * verifier will allow any alignment whatsoever. On platforms
+ * with strict alignment requirements for loads ands stores (such
+ * as sparc and mips) the verifier validates that all loads and
+ * stores provably follow this requirement. This flag turns that
+ * checking and enforcement off.
+ *
+ * It is mostly used for testing when we want to validate the
+ * context and memory access aspects of the verifier, but because
+ * of an unaligned access the alignment check would trigger before
+ * the one we are interested in.
+ */
+#define BPF_F_ANY_ALIGNMENT (1U << 1)
+
/* when bpf_ldimm64->src_reg == BPF_PSEUDO_MAP_FD, bpf_ldimm64->imm == fd */
#define BPF_PSEUDO_MAP_FD 1
@@ -257,9 +271,6 @@ enum bpf_attach_type {
/* Specify numa node during map creation */
#define BPF_F_NUMA_NODE (1U << 2)
-/* flags for BPF_PROG_QUERY */
-#define BPF_F_QUERY_EFFECTIVE (1U << 0)
-
#define BPF_OBJ_NAME_LEN 16U
/* Flags for accessing BPF object */
@@ -269,6 +280,12 @@ enum bpf_attach_type {
/* Flag for stack_map, store build_id+offset instead of pointer */
#define BPF_F_STACK_BUILD_ID (1U << 5)
+/* Zero-initialize hash function seed. This should only be used for testing. */
+#define BPF_F_ZERO_SEED (1U << 6)
+
+/* flags for BPF_PROG_QUERY */
+#define BPF_F_QUERY_EFFECTIVE (1U << 0)
+
enum bpf_stack_build_id_status {
/* user space need an empty entry to identify end of a trace */
BPF_STACK_BUILD_ID_EMPTY = 0,
@@ -335,6 +352,13 @@ union bpf_attr {
* (context accesses, allowed helpers, etc).
*/
__u32 expected_attach_type;
+ __u32 prog_btf_fd; /* fd pointing to BTF type data */
+ __u32 func_info_rec_size; /* userspace bpf_func_info size */
+ __aligned_u64 func_info; /* func info */
+ __u32 func_info_cnt; /* number of bpf_func_info records */
+ __u32 line_info_rec_size; /* userspace bpf_line_info size */
+ __aligned_u64 line_info; /* line info */
+ __u32 line_info_cnt; /* number of bpf_line_info records */
};
struct { /* anonymous struct used by BPF_OBJ_* commands */
@@ -353,8 +377,11 @@ union bpf_attr {
struct { /* anonymous struct used by BPF_PROG_TEST_RUN command */
__u32 prog_fd;
__u32 retval;
- __u32 data_size_in;
- __u32 data_size_out;
+ __u32 data_size_in; /* input: len of data_in */
+ __u32 data_size_out; /* input/output: len of data_out
+ * returns ENOSPC if data_out
+ * is too small.
+ */
__aligned_u64 data_in;
__aligned_u64 data_out;
__u32 repeat;
@@ -475,18 +502,6 @@ union bpf_attr {
* Return
* 0 on success, or a negative error in case of failure.
*
- * int bpf_map_pop_elem(struct bpf_map *map, void *value)
- * Description
- * Pop an element from *map*.
- * Return
- * 0 on success, or a negative error in case of failure.
- *
- * int bpf_map_peek_elem(struct bpf_map *map, void *value)
- * Description
- * Get an element from *map* without removing it.
- * Return
- * 0 on success, or a negative error in case of failure.
- *
* int bpf_probe_read(void *dst, u32 size, const void *src)
* Description
* For tracing programs, safely attempt to read *size* bytes from
@@ -1910,9 +1925,9 @@ union bpf_attr {
* is set to metric from route (IPv4/IPv6 only), and ifindex
* is set to the device index of the nexthop from the FIB lookup.
*
- * *plen* argument is the size of the passed in struct.
- * *flags* argument can be a combination of one or more of the
- * following values:
+ * *plen* argument is the size of the passed in struct.
+ * *flags* argument can be a combination of one or more of the
+ * following values:
*
* **BPF_FIB_LOOKUP_DIRECT**
* Do a direct table lookup vs full lookup using FIB
@@ -1921,9 +1936,9 @@ union bpf_attr {
* Perform lookup from an egress perspective (default is
* ingress).
*
- * *ctx* is either **struct xdp_md** for XDP programs or
- * **struct sk_buff** tc cls_act programs.
- * Return
+ * *ctx* is either **struct xdp_md** for XDP programs or
+ * **struct sk_buff** tc cls_act programs.
+ * Return
* * < 0 if any input argument is invalid
* * 0 on success (packet is forwarded, nexthop neighbor exists)
* * > 0 one of **BPF_FIB_LKUP_RET_** codes explaining why the
@@ -2068,8 +2083,8 @@ union bpf_attr {
* translated to a keycode using the rc keymap, and reported as
* an input key down event. After a period a key up event is
* generated. This period can be extended by calling either
- * **bpf_rc_keydown** () again with the same values, or calling
- * **bpf_rc_repeat** ().
+ * **bpf_rc_keydown**\ () again with the same values, or calling
+ * **bpf_rc_repeat**\ ().
*
* Some protocols include a toggle bit, in case the button was
* released and pressed again between consecutive scancodes.
@@ -2152,21 +2167,22 @@ union bpf_attr {
* The *flags* meaning is specific for each map type,
* and has to be 0 for cgroup local storage.
*
- * Depending on the bpf program type, a local storage area
- * can be shared between multiple instances of the bpf program,
+ * Depending on the BPF program type, a local storage area
+ * can be shared between multiple instances of the BPF program,
* running simultaneously.
*
* A user should care about the synchronization by himself.
- * For example, by using the BPF_STX_XADD instruction to alter
+ * For example, by using the **BPF_STX_XADD** instruction to alter
* the shared data.
* Return
- * Pointer to the local storage area.
+ * A pointer to the local storage area.
*
* int bpf_sk_select_reuseport(struct sk_reuseport_md *reuse, struct bpf_map *map, void *key, u64 flags)
* Description
- * Select a SO_REUSEPORT sk from a BPF_MAP_TYPE_REUSEPORT_ARRAY map
- * It checks the selected sk is matching the incoming
- * request in the skb.
+ * Select a **SO_REUSEPORT** socket from a
+ * **BPF_MAP_TYPE_REUSEPORT_ARRAY** *map*.
+ * It checks the selected socket is matching the incoming
+ * request in the socket buffer.
* Return
* 0 on success, or a negative error in case of failure.
*
@@ -2174,7 +2190,7 @@ union bpf_attr {
* Description
* Look for TCP socket matching *tuple*, optionally in a child
* network namespace *netns*. The return value must be checked,
- * and if non-NULL, released via **bpf_sk_release**\ ().
+ * and if non-**NULL**, released via **bpf_sk_release**\ ().
*
* The *ctx* should point to the context of the program, such as
* the skb or socket (depending on the hook in use). This is used
@@ -2202,15 +2218,15 @@ union bpf_attr {
* This helper is available only if the kernel was compiled with
* **CONFIG_NET** configuration option.
* Return
- * Pointer to *struct bpf_sock*, or NULL in case of failure.
- * For sockets with reuseport option, the *struct bpf_sock*
- * result is from reuse->socks[] using the hash of the tuple.
+ * Pointer to **struct bpf_sock**, or **NULL** in case of failure.
+ * For sockets with reuseport option, the **struct bpf_sock**
+ * result is from **reuse->socks**\ [] using the hash of the tuple.
*
* struct bpf_sock *bpf_sk_lookup_udp(void *ctx, struct bpf_sock_tuple *tuple, u32 tuple_size, u64 netns, u64 flags)
* Description
* Look for UDP socket matching *tuple*, optionally in a child
* network namespace *netns*. The return value must be checked,
- * and if non-NULL, released via **bpf_sk_release**\ ().
+ * and if non-**NULL**, released via **bpf_sk_release**\ ().
*
* The *ctx* should point to the context of the program, such as
* the skb or socket (depending on the hook in use). This is used
@@ -2238,33 +2254,71 @@ union bpf_attr {
* This helper is available only if the kernel was compiled with
* **CONFIG_NET** configuration option.
* Return
- * Pointer to *struct bpf_sock*, or NULL in case of failure.
- * For sockets with reuseport option, the *struct bpf_sock*
- * result is from reuse->socks[] using the hash of the tuple.
+ * Pointer to **struct bpf_sock**, or **NULL** in case of failure.
+ * For sockets with reuseport option, the **struct bpf_sock**
+ * result is from **reuse->socks**\ [] using the hash of the tuple.
*
- * int bpf_sk_release(struct bpf_sock *sk)
+ * int bpf_sk_release(struct bpf_sock *sock)
* Description
- * Release the reference held by *sock*. *sock* must be a non-NULL
- * pointer that was returned from bpf_sk_lookup_xxx\ ().
+ * Release the reference held by *sock*. *sock* must be a
+ * non-**NULL** pointer that was returned from
+ * **bpf_sk_lookup_xxx**\ ().
* Return
* 0 on success, or a negative error in case of failure.
*
+ * int bpf_map_pop_elem(struct bpf_map *map, void *value)
+ * Description
+ * Pop an element from *map*.
+ * Return
+ * 0 on success, or a negative error in case of failure.
+ *
+ * int bpf_map_peek_elem(struct bpf_map *map, void *value)
+ * Description
+ * Get an element from *map* without removing it.
+ * Return
+ * 0 on success, or a negative error in case of failure.
+ *
* int bpf_msg_push_data(struct sk_buff *skb, u32 start, u32 len, u64 flags)
* Description
- * For socket policies, insert *len* bytes into msg at offset
+ * For socket policies, insert *len* bytes into *msg* at offset
* *start*.
*
* If a program of type **BPF_PROG_TYPE_SK_MSG** is run on a
- * *msg* it may want to insert metadata or options into the msg.
+ * *msg* it may want to insert metadata or options into the *msg*.
* This can later be read and used by any of the lower layer BPF
* hooks.
*
* This helper may fail if under memory pressure (a malloc
* fails) in these cases BPF programs will get an appropriate
* error and BPF programs will need to handle them.
+ * Return
+ * 0 on success, or a negative error in case of failure.
*
+ * int bpf_msg_pop_data(struct sk_msg_buff *msg, u32 start, u32 pop, u64 flags)
+ * Description
+ * Will remove *pop* bytes from a *msg* starting at byte *start*.
+ * This may result in **ENOMEM** errors under certain situations if
+ * an allocation and copy are required due to a full ring buffer.
+ * However, the helper will try to avoid doing the allocation
+ * if possible. Other errors can occur if input parameters are
+ * invalid either due to *start* byte not being valid part of *msg*
+ * payload and/or *pop* value being to large.
* Return
* 0 on success, or a negative error in case of failure.
+ *
+ * int bpf_rc_pointer_rel(void *ctx, s32 rel_x, s32 rel_y)
+ * Description
+ * This helper is used in programs implementing IR decoding, to
+ * report a successfully decoded pointer movement.
+ *
+ * The *ctx* should point to the lirc sample as passed into
+ * the program.
+ *
+ * This helper is only available is the kernel was compiled with
+ * the **CONFIG_BPF_LIRC_MODE2** configuration option set to
+ * "**y**".
+ * Return
+ * 0
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
@@ -2357,7 +2411,9 @@ union bpf_attr {
FN(map_push_elem), \
FN(map_pop_elem), \
FN(map_peek_elem), \
- FN(msg_push_data),
+ FN(msg_push_data), \
+ FN(msg_pop_data), \
+ FN(rc_pointer_rel),
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
* function eBPF program intends to call
@@ -2474,6 +2530,8 @@ struct __sk_buff {
__u32 data_meta;
__bpf_md_ptr(struct bpf_flow_keys *, flow_keys);
+ __u64 tstamp;
+ __u32 wire_len;
};
struct bpf_tunnel_key {
@@ -2649,6 +2707,16 @@ struct bpf_prog_info {
__u32 nr_jited_func_lens;
__aligned_u64 jited_ksyms;
__aligned_u64 jited_func_lens;
+ __u32 btf_id;
+ __u32 func_info_rec_size;
+ __aligned_u64 func_info;
+ __u32 nr_func_info;
+ __u32 nr_line_info;
+ __aligned_u64 line_info;
+ __aligned_u64 jited_line_info;
+ __u32 nr_jited_line_info;
+ __u32 line_info_rec_size;
+ __u32 jited_line_info_rec_size;
} __attribute__((aligned(8)));
struct bpf_map_info {
@@ -2960,4 +3028,19 @@ struct bpf_flow_keys {
};
};
+struct bpf_func_info {
+ __u32 insn_off;
+ __u32 type_id;
+};
+
+#define BPF_LINE_INFO_LINE_NUM(line_col) ((line_col) >> 10)
+#define BPF_LINE_INFO_LINE_COL(line_col) ((line_col) & 0x3ff)
+
+struct bpf_line_info {
+ __u32 insn_off;
+ __u32 file_name_off;
+ __u32 line_off;
+ __u32 line_col;
+};
+
#endif /* __LINUX_BPF_H__ */
diff --git a/include/uapi/linux/btf.h b/include/uapi/linux/btf.h
index 8d2a8ffad56f9..f43d5a8e13d31 100644
--- a/include/uapi/linux/btf.h
+++ b/include/uapi/linux/btf.h
@@ -40,7 +40,8 @@ struct btf_type {
/* "size" is used by INT, ENUM, STRUCT and UNION.
* "size" tells the size of the type it is describing.
*
- * "type" is used by PTR, TYPEDEF, VOLATILE, CONST and RESTRICT.
+ * "type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT,
+ * FUNC and FUNC_PROTO.
* "type" is a type_id referring to another type.
*/
union {
@@ -64,8 +65,10 @@ struct btf_type {
#define BTF_KIND_VOLATILE 9 /* Volatile */
#define BTF_KIND_CONST 10 /* Const */
#define BTF_KIND_RESTRICT 11 /* Restrict */
-#define BTF_KIND_MAX 11
-#define NR_BTF_KINDS 12
+#define BTF_KIND_FUNC 12 /* Function */
+#define BTF_KIND_FUNC_PROTO 13 /* Function Proto */
+#define BTF_KIND_MAX 13
+#define NR_BTF_KINDS 14
/* For some specific BTF_KIND, "struct btf_type" is immediately
* followed by extra data.
@@ -110,4 +113,13 @@ struct btf_member {
__u32 offset; /* offset in bits */
};
+/* BTF_KIND_FUNC_PROTO is followed by multiple "struct btf_param".
+ * The exact number of btf_param is stored in the vlen (of the
+ * info in "struct btf_type").
+ */
+struct btf_param {
+ __u32 name_off;
+ __u32 type;
+};
+
#endif /* __LINUX_BTF_H__ */
diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
index bdfecf9411320..04f763cf53029 100644
--- a/include/uapi/linux/if_bridge.h
+++ b/include/uapi/linux/if_bridge.h
@@ -292,4 +292,25 @@ struct br_mcast_stats {
__u64 mcast_bytes[BR_MCAST_DIR_SIZE];
__u64 mcast_packets[BR_MCAST_DIR_SIZE];
};
+
+/* bridge boolean options
+ * BR_BOOLOPT_NO_LL_LEARN - disable learning from link-local packets
+ *
+ * IMPORTANT: if adding a new option do not forget to handle
+ * it in br_boolopt_toggle/get and bridge sysfs
+ */
+enum br_boolopt_id {
+ BR_BOOLOPT_NO_LL_LEARN,
+ BR_BOOLOPT_MAX
+};
+
+/* struct br_boolopt_multi - change multiple bridge boolean options
+ *
+ * @optval: new option values (bit per option)
+ * @optmask: options to change (bit per option)
+ */
+struct br_boolopt_multi {
+ __u32 optval;
+ __u32 optmask;
+};
#endif /* _LINUX_IF_BRIDGE_H */
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 52e95197e0790..8e6087aee2c29 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -286,6 +286,7 @@ enum {
IFLA_BR_MCAST_IGMP_VERSION,
IFLA_BR_MCAST_MLD_VERSION,
IFLA_BR_VLAN_STATS_PER_PORT,
+ IFLA_BR_MULTI_BOOLOPT,
__IFLA_BR_MAX,
};
diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h
index be9b744a16458..2f01165514a77 100644
--- a/include/uapi/linux/if_tun.h
+++ b/include/uapi/linux/if_tun.h
@@ -59,6 +59,7 @@
#define TUNGETVNETBE _IOR('T', 223, int)
#define TUNSETSTEERINGEBPF _IOR('T', 224, int)
#define TUNSETFILTEREBPF _IOR('T', 225, int)
+#define TUNSETCARRIER _IOW('T', 226, int)
/* TUNSETIFF ifr flags */
#define IFF_TUN 0x0001
diff --git a/include/uapi/linux/neighbour.h b/include/uapi/linux/neighbour.h
index 998155444e0db..cd144e3099a3c 100644
--- a/include/uapi/linux/neighbour.h
+++ b/include/uapi/linux/neighbour.h
@@ -28,6 +28,7 @@ enum {
NDA_MASTER,
NDA_LINK_NETNSID,
NDA_SRC_VNI,
+ NDA_PROTOCOL, /* Originator of entry */
__NDA_MAX
};
diff --git a/include/uapi/linux/net_namespace.h b/include/uapi/linux/net_namespace.h
index 6d64d0716800f..fa81f1e5ffa8f 100644
--- a/include/uapi/linux/net_namespace.h
+++ b/include/uapi/linux/net_namespace.h
@@ -16,6 +16,8 @@ enum {
NETNSA_NSID,
NETNSA_PID,
NETNSA_FD,
+ NETNSA_TARGET_NSID,
+ NETNSA_CURRENT_NSID,
__NETNSA_MAX,
};
diff --git a/include/uapi/linux/snmp.h b/include/uapi/linux/snmp.h
index f80135e5feaa8..86dc24a96c90a 100644
--- a/include/uapi/linux/snmp.h
+++ b/include/uapi/linux/snmp.h
@@ -243,6 +243,7 @@ enum
LINUX_MIB_TCPREQQFULLDROP, /* TCPReqQFullDrop */
LINUX_MIB_TCPRETRANSFAIL, /* TCPRetransFail */
LINUX_MIB_TCPRCVCOALESCE, /* TCPRcvCoalesce */
+ LINUX_MIB_TCPBACKLOGCOALESCE, /* TCPBacklogCoalesce */
LINUX_MIB_TCPOFOQUEUE, /* TCPOFOQueue */
LINUX_MIB_TCPOFODROP, /* TCPOFODrop */
LINUX_MIB_TCPOFOMERGE, /* TCPOFOMerge */
--
2.20.1

View File

@ -1,104 +0,0 @@
From 2f95b860ca09f8dc798204514b06b69cdfa0bd61 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Fri, 14 Jun 2019 11:04:17 +0200
Subject: [PATCH] ip-xfrm: Respect family in deleteall and list commands
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1656717
Upstream Status: iproute2.git commit cd21ae40130b4
Conflicts: on ip xfrm manpage due to missing commit a6af9f2e6195d
("xfrm: add option to hide keys in state output")
commit cd21ae40130b4d1ddb3ef500800840e35e7bfad1
Author: Phil Sutter <phil@nwl.cc>
Date: Mon May 6 19:09:56 2019 +0200
ip-xfrm: Respect family in deleteall and list commands
Allow to limit 'ip xfrm {state|policy} list' output to a certain address
family and to delete all states/policies by family.
Although preferred_family was already set in filters, the filter
function ignored it. To enable filtering despite the lack of other
selectors, filter.use has to be set if family is not AF_UNSPEC.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/xfrm_policy.c | 6 +++++-
ip/xfrm_state.c | 6 +++++-
man/man8/ip-xfrm.8 | 4 ++--
3 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c
index d54402691ca0a..5bb3e873d2e8c 100644
--- a/ip/xfrm_policy.c
+++ b/ip/xfrm_policy.c
@@ -400,6 +400,10 @@ static int xfrm_policy_filter_match(struct xfrm_userpolicy_info *xpinfo,
if (!filter.use)
return 1;
+ if (filter.xpinfo.sel.family != AF_UNSPEC &&
+ filter.xpinfo.sel.family != xpinfo->sel.family)
+ return 0;
+
if ((xpinfo->dir^filter.xpinfo.dir)&filter.dir_mask)
return 0;
@@ -773,7 +777,7 @@ static int xfrm_policy_list_or_deleteall(int argc, char **argv, int deleteall)
char *selp = NULL;
struct rtnl_handle rth;
- if (argc > 0)
+ if (argc > 0 || preferred_family != AF_UNSPEC)
filter.use = 1;
filter.xpinfo.sel.family = preferred_family;
diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c
index 85d959cc4f44f..2441959e98992 100644
--- a/ip/xfrm_state.c
+++ b/ip/xfrm_state.c
@@ -876,6 +876,10 @@ static int xfrm_state_filter_match(struct xfrm_usersa_info *xsinfo)
if (!filter.use)
return 1;
+ if (filter.xsinfo.family != AF_UNSPEC &&
+ filter.xsinfo.family != xsinfo->family)
+ return 0;
+
if (filter.id_src_mask)
if (xfrm_addr_match(&xsinfo->saddr, &filter.xsinfo.saddr,
filter.id_src_mask))
@@ -1140,7 +1144,7 @@ static int xfrm_state_list_or_deleteall(int argc, char **argv, int deleteall)
char *idp = NULL;
struct rtnl_handle rth;
- if (argc > 0)
+ if (argc > 0 || preferred_family != AF_UNSPEC)
filter.use = 1;
filter.xsinfo.family = preferred_family;
diff --git a/man/man8/ip-xfrm.8 b/man/man8/ip-xfrm.8
index 988cc6aa61d14..d5b9f083147c4 100644
--- a/man/man8/ip-xfrm.8
+++ b/man/man8/ip-xfrm.8
@@ -87,7 +87,7 @@ ip-xfrm \- transform configuration
.IR MASK " ] ]"
.ti -8
-.BR "ip xfrm state" " { " deleteall " | " list " } ["
+.BR ip " [ " -4 " | " -6 " ] " "xfrm state" " { " deleteall " | " list " } ["
.IR ID " ]"
.RB "[ " mode
.IR MODE " ]"
@@ -244,7 +244,7 @@ ip-xfrm \- transform configuration
.IR PTYPE " ]"
.ti -8
-.BR "ip xfrm policy" " { " deleteall " | " list " }"
+.BR ip " [ " -4 " | " -6 " ] " "xfrm policy" " { " deleteall " | " list " }"
.RB "[ " nosock " ]"
.RI "[ " SELECTOR " ]"
.RB "[ " dir
--
2.20.1

View File

@ -1,137 +0,0 @@
From da77e40e234599218a3d61434abb5af2815d72a7 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Sun, 2 Jun 2019 16:06:23 +0200
Subject: [PATCH] ss: Review ssfilter
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1698401
Upstream Status: iproute2.git commit 38d209ecf2ae9
commit 38d209ecf2ae966b9b25de4acb60cdffb0e06ced
Author: Phil Sutter <phil@nwl.cc>
Date: Tue Aug 14 14:18:06 2018 +0200
ss: Review ssfilter
The original problem was ssfilter rejecting single expressions if
enclosed in braces, such as:
| sport = 22 or ( dport = 22 )
This is fixed by allowing 'expr' to be an 'exprlist' enclosed in braces.
The no longer required recursion in 'exprlist' being an 'exprlist'
enclosed in braces is dropped.
In addition to that, a few other things are changed:
* Remove pointless 'null' prefix in 'appled' before 'exprlist'.
* For simple equals matches, '=' operator was required for ports but not
allowed for hosts. Make this consistent by making '=' operator
optional in both cases.
Reported-by: Samuel Mannehed <samuel@cendio.se>
Fixes: b2038cc0b2403 ("ssfilter: Eliminate shift/reduce conflicts")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
misc/ssfilter.y | 36 +++++++++++++++++++++---------------
1 file changed, 21 insertions(+), 15 deletions(-)
diff --git a/misc/ssfilter.y b/misc/ssfilter.y
index 88d4229a9b241..0413dddaa7584 100644
--- a/misc/ssfilter.y
+++ b/misc/ssfilter.y
@@ -42,24 +42,22 @@ static void yyerror(char *s)
%nonassoc '!'
%%
-applet: null exprlist
+applet: exprlist
{
- *yy_ret = $2;
- $$ = $2;
+ *yy_ret = $1;
+ $$ = $1;
}
| null
;
+
null: /* NOTHING */ { $$ = NULL; }
;
+
exprlist: expr
| '!' expr
{
$$ = alloc_node(SSF_NOT, $2);
}
- | '(' exprlist ')'
- {
- $$ = $2;
- }
| exprlist '|' expr
{
$$ = alloc_node(SSF_OR, $1);
@@ -77,13 +75,21 @@ exprlist: expr
}
;
-expr: DCOND HOSTCOND
+eq: '='
+ | /* nothing */
+ ;
+
+expr: '(' exprlist ')'
+ {
+ $$ = $2;
+ }
+ | DCOND eq HOSTCOND
{
- $$ = alloc_node(SSF_DCOND, $2);
+ $$ = alloc_node(SSF_DCOND, $3);
}
- | SCOND HOSTCOND
+ | SCOND eq HOSTCOND
{
- $$ = alloc_node(SSF_SCOND, $2);
+ $$ = alloc_node(SSF_SCOND, $3);
}
| DPORT GEQ HOSTCOND
{
@@ -101,7 +107,7 @@ expr: DCOND HOSTCOND
{
$$ = alloc_node(SSF_NOT, alloc_node(SSF_D_GE, $3));
}
- | DPORT '=' HOSTCOND
+ | DPORT eq HOSTCOND
{
$$ = alloc_node(SSF_DCOND, $3);
}
@@ -126,7 +132,7 @@ expr: DCOND HOSTCOND
{
$$ = alloc_node(SSF_NOT, alloc_node(SSF_S_GE, $3));
}
- | SPORT '=' HOSTCOND
+ | SPORT eq HOSTCOND
{
$$ = alloc_node(SSF_SCOND, $3);
}
@@ -134,7 +140,7 @@ expr: DCOND HOSTCOND
{
$$ = alloc_node(SSF_NOT, alloc_node(SSF_SCOND, $3));
}
- | DEVNAME '=' DEVCOND
+ | DEVNAME eq DEVCOND
{
$$ = alloc_node(SSF_DEVCOND, $3);
}
@@ -142,7 +148,7 @@ expr: DCOND HOSTCOND
{
$$ = alloc_node(SSF_NOT, alloc_node(SSF_DEVCOND, $3));
}
- | FWMARK '=' MARKMASK
+ | FWMARK eq MARKMASK
{
$$ = alloc_node(SSF_MARKMASK, $3);
}
--
2.20.1

View File

@ -1,186 +0,0 @@
From e94d7e4519668e840f1c768a569486eebdc3825d Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Tue, 25 Jun 2019 19:03:18 +0200
Subject: [PATCH] ip: reset netns after each command in batch mode
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1671016
Upstream Status: iproute2.git commit 80a931d41c058
Conflicts: on ip/ipnetns.c due to missing commit e3dbcb2a12ab1
("netns: add subcommand to attach an existing network namespace")
commit 80a931d41c0587a4f5bfc1ece7eddac3442b5d9a
Author: Matteo Croce <mcroce@redhat.com>
Date: Fri Jun 7 22:41:22 2019 +0200
ip: reset netns after each command in batch mode
When creating a new netns or executing a program into an existing one,
the unshare() or setns() calls will change the current netns.
In batch mode, this can run commands on the wrong interfaces, as the
ifindex value is meaningful only in the current netns. For example, this
command fails because veth-c doesn't exists in the init netns:
# ip -b - <<-'EOF'
netns add client
link add name veth-c type veth peer veth-s netns client
addr add 192.168.2.1/24 dev veth-c
EOF
Cannot find device "veth-c"
Command failed -:7
But if there are two devices with the same name in the init and new netns,
ip will build a wrong ll_map with indexes belonging to the new netns,
and will execute actions in the init netns using this wrong mapping.
This script will flush all eth0 addresses and bring it down, as it has
the same ifindex of veth0 in the new netns:
# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.76/24 brd 192.168.122.255 scope global dynamic eth0
valid_lft 3598sec preferred_lft 3598sec
# ip -b - <<-'EOF'
netns add client
link add name veth0 type veth peer name veth1
link add name veth-ns type veth peer name veth0 netns client
link set veth0 down
address flush veth0
EOF
# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc mq state DOWN group default qlen 1000
link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
3: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether c2:db:d0:34:13:4a brd ff:ff:ff:ff:ff:ff
4: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether ca:9d:6b:5f:5f:8f brd ff:ff:ff:ff:ff:ff
5: veth-ns@if2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 32:ef:22:df:51:0a brd ff:ff:ff:ff:ff:ff link-netns client
The same issue can be triggered by the netns exec subcommand with a
sligthy different script:
# ip netns add client
# ip -b - <<-'EOF'
netns exec client true
link add name veth0 type veth peer name veth1
link add name veth-ns type veth peer name veth0 netns client
link set veth0 down
address flush veth0
EOF
Fix this by adding two netns_{save,reset} functions, which are used
to get a file descriptor for the init netns, and restore it after
each batch command.
netns_save() is called before the unshare() or setns(),
while netns_restore() is called after each command.
Fixes: 0dc34c7713bb ("iproute2: Add processless network namespace support")
Reviewed-and-tested-by: Andrea Claudi <aclaudi@redhat.com>
Signed-off-by: Matteo Croce <mcroce@redhat.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
include/namespace.h | 2 ++
ip/ip.c | 1 +
ip/ipnetns.c | 1 +
lib/namespace.c | 31 +++++++++++++++++++++++++++++++
4 files changed, 35 insertions(+)
diff --git a/include/namespace.h b/include/namespace.h
index e47f9b5d49d12..89cdda11782e8 100644
--- a/include/namespace.h
+++ b/include/namespace.h
@@ -49,6 +49,8 @@ static inline int setns(int fd, int nstype)
}
#endif /* HAVE_SETNS */
+void netns_save(void);
+void netns_restore(void);
int netns_switch(char *netns);
int netns_get_fd(const char *netns);
int netns_foreach(int (*func)(char *nsname, void *arg), void *arg);
diff --git a/ip/ip.c b/ip/ip.c
index 2ca55e37a4c62..6e8230b3ee584 100644
--- a/ip/ip.c
+++ b/ip/ip.c
@@ -158,6 +158,7 @@ static int batch(const char *name)
if (!force)
break;
}
+ netns_restore();
}
if (line)
free(line);
diff --git a/ip/ipnetns.c b/ip/ipnetns.c
index 368be0cbc0a48..a6e3ea575c363 100644
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -689,6 +689,7 @@ static int netns_add(int argc, char **argv)
return -1;
}
close(fd);
+ netns_save();
if (unshare(CLONE_NEWNET) < 0) {
fprintf(stderr, "Failed to create a new network namespace \"%s\": %s\n",
name, strerror(errno));
diff --git a/lib/namespace.c b/lib/namespace.c
index 06ae0a48c2243..a2aea57ad4109 100644
--- a/lib/namespace.c
+++ b/lib/namespace.c
@@ -15,6 +15,35 @@
#include "utils.h"
#include "namespace.h"
+static int saved_netns = -1;
+
+/* Obtain a FD for the current namespace, so we can reenter it later */
+void netns_save(void)
+{
+ if (saved_netns != -1)
+ return;
+
+ saved_netns = open("/proc/self/ns/net", O_RDONLY | O_CLOEXEC);
+ if (saved_netns == -1) {
+ perror("Cannot open init namespace");
+ exit(1);
+ }
+}
+
+void netns_restore(void)
+{
+ if (saved_netns == -1)
+ return;
+
+ if (setns(saved_netns, CLONE_NEWNET)) {
+ perror("setns");
+ exit(1);
+ }
+
+ close(saved_netns);
+ saved_netns = -1;
+}
+
static void bind_etc(const char *name)
{
char etc_netns_path[sizeof(NETNS_ETC_DIR) + NAME_MAX];
@@ -61,6 +90,8 @@ int netns_switch(char *name)
return -1;
}
+ netns_save();
+
if (setns(netns, CLONE_NEWNET) < 0) {
fprintf(stderr, "setting the network namespace \"%s\" failed: %s\n",
name, strerror(errno));
--
2.20.1

View File

@ -1,379 +0,0 @@
From 24ad28e010f1888e431631ef2179f9284b4aed43 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Wed, 26 Jun 2019 16:59:54 +0200
Subject: [PATCH] tc: introduce support for chain templates
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1710291
Upstream Status: iproute2.git commit afcd06991db26
commit afcd06991db267db2d0d4733da34c5c508d30532
Author: Jiri Pirko <jiri@mellanox.com>
Date: Mon Jul 23 09:24:40 2018 +0200
tc: introduce support for chain templates
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
man/man8/tc.8 | 26 ++++++++++
tc/tc.c | 5 +-
tc/tc_common.h | 1 +
tc/tc_filter.c | 131 ++++++++++++++++++++++++++++++++++--------------
tc/tc_monitor.c | 5 +-
5 files changed, 128 insertions(+), 40 deletions(-)
diff --git a/man/man8/tc.8 b/man/man8/tc.8
index 840880fbdba63..8a50f57fbfb2d 100644
--- a/man/man8/tc.8
+++ b/man/man8/tc.8
@@ -58,6 +58,22 @@ tc \- show / manipulate traffic control settings
.B flowid
\fIflow-id\fR
+.B tc
+.RI "[ " OPTIONS " ]"
+.B chain [ add | delete | get ] dev
+\fIDEV\fR
+.B [ parent
+\fIqdisc-id\fR
+.B | root ]\fR filtertype
+[ filtertype specific parameters ]
+
+.B tc
+.RI "[ " OPTIONS " ]"
+.B chain [ add | delete | get ] block
+\fIBLOCK_INDEX\fR filtertype
+[ filtertype specific parameters ]
+
+
.B tc
.RI "[ " OPTIONS " ]"
.RI "[ " FORMAT " ]"
@@ -80,6 +96,16 @@ tc \- show / manipulate traffic control settings
.RI "[ " OPTIONS " ]"
.B filter show block
\fIBLOCK_INDEX\fR
+.P
+.B tc
+.RI "[ " OPTIONS " ]"
+.B chain show dev
+\fIDEV\fR
+.P
+.B tc
+.RI "[ " OPTIONS " ]"
+.B chain show block
+\fIBLOCK_INDEX\fR
.P
.B tc
diff --git a/tc/tc.c b/tc/tc.c
index 88e22ba6bcd0b..1fcb3afa727f0 100644
--- a/tc/tc.c
+++ b/tc/tc.c
@@ -196,7 +196,8 @@ static void usage(void)
fprintf(stderr,
"Usage: tc [ OPTIONS ] OBJECT { COMMAND | help }\n"
" tc [-force] -batch filename\n"
- "where OBJECT := { qdisc | class | filter | action | monitor | exec }\n"
+ "where OBJECT := { qdisc | class | filter | chain |\n"
+ " action | monitor | exec }\n"
" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[aw] |\n"
" -o[neline] | -j[son] | -p[retty] | -c[olor]\n"
" -b[atch] [filename] | -n[etns] name |\n"
@@ -211,6 +212,8 @@ static int do_cmd(int argc, char **argv, void *buf, size_t buflen)
return do_class(argc-1, argv+1);
if (matches(*argv, "filter") == 0)
return do_filter(argc-1, argv+1, buf, buflen);
+ if (matches(*argv, "chain") == 0)
+ return do_chain(argc-1, argv+1, buf, buflen);
if (matches(*argv, "actions") == 0)
return do_action(argc-1, argv+1, buf, buflen);
if (matches(*argv, "monitor") == 0)
diff --git a/tc/tc_common.h b/tc/tc_common.h
index 49c24616c2c35..272d1727027d4 100644
--- a/tc/tc_common.h
+++ b/tc/tc_common.h
@@ -8,6 +8,7 @@ extern struct rtnl_handle rth;
extern int do_qdisc(int argc, char **argv);
extern int do_class(int argc, char **argv);
extern int do_filter(int argc, char **argv, void *buf, size_t buflen);
+extern int do_chain(int argc, char **argv, void *buf, size_t buflen);
extern int do_action(int argc, char **argv, void *buf, size_t buflen);
extern int do_tcmonitor(int argc, char **argv);
extern int do_exec(int argc, char **argv);
diff --git a/tc/tc_filter.c b/tc/tc_filter.c
index c5bb0bffe19b2..15044b4bc6ed9 100644
--- a/tc/tc_filter.c
+++ b/tc/tc_filter.c
@@ -45,6 +45,13 @@ static void usage(void)
"OPTIONS := ... try tc filter add <desired FILTER_KIND> help\n");
}
+static void chain_usage(void)
+{
+ fprintf(stderr,
+ "Usage: tc chain [ add | del | get | show ] [ dev STRING ]\n"
+ " tc chain [ add | del | get | show ] [ block BLOCK_INDEX ] ]\n");
+}
+
struct tc_filter_req {
struct nlmsghdr n;
struct tcmsg t;
@@ -85,7 +92,8 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv,
req->n.nlmsg_type = cmd;
req->t.tcm_family = AF_UNSPEC;
- if (cmd == RTM_NEWTFILTER && flags & NLM_F_CREATE)
+ if ((cmd == RTM_NEWTFILTER || cmd == RTM_NEWCHAIN) &&
+ flags & NLM_F_CREATE)
protocol = htons(ETH_P_ALL);
while (argc > 0) {
@@ -261,7 +269,10 @@ int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
if (n->nlmsg_type != RTM_NEWTFILTER &&
n->nlmsg_type != RTM_GETTFILTER &&
- n->nlmsg_type != RTM_DELTFILTER) {
+ n->nlmsg_type != RTM_DELTFILTER &&
+ n->nlmsg_type != RTM_NEWCHAIN &&
+ n->nlmsg_type != RTM_GETCHAIN &&
+ n->nlmsg_type != RTM_DELCHAIN) {
fprintf(stderr, "Not a filter(cmd %d)\n", n->nlmsg_type);
return 0;
}
@@ -273,27 +284,36 @@ int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
parse_rtattr(tb, TCA_MAX, TCA_RTA(t), len);
- if (tb[TCA_KIND] == NULL) {
+ if (tb[TCA_KIND] == NULL && (n->nlmsg_type == RTM_NEWTFILTER ||
+ n->nlmsg_type == RTM_GETTFILTER ||
+ n->nlmsg_type == RTM_DELTFILTER)) {
fprintf(stderr, "print_filter: NULL kind\n");
return -1;
}
open_json_object(NULL);
- if (n->nlmsg_type == RTM_DELTFILTER)
+ if (n->nlmsg_type == RTM_DELTFILTER || n->nlmsg_type == RTM_DELCHAIN)
print_bool(PRINT_ANY, "deleted", "deleted ", true);
- if (n->nlmsg_type == RTM_NEWTFILTER &&
+ if ((n->nlmsg_type == RTM_NEWTFILTER ||
+ n->nlmsg_type == RTM_NEWCHAIN) &&
(n->nlmsg_flags & NLM_F_CREATE) &&
!(n->nlmsg_flags & NLM_F_EXCL))
print_bool(PRINT_ANY, "replaced", "replaced ", true);
- if (n->nlmsg_type == RTM_NEWTFILTER &&
+ if ((n->nlmsg_type == RTM_NEWTFILTER ||
+ n->nlmsg_type == RTM_NEWCHAIN) &&
(n->nlmsg_flags & NLM_F_CREATE) &&
(n->nlmsg_flags & NLM_F_EXCL))
print_bool(PRINT_ANY, "added", "added ", true);
- print_string(PRINT_FP, NULL, "filter ", NULL);
+ if (n->nlmsg_type == RTM_NEWTFILTER ||
+ n->nlmsg_type == RTM_GETTFILTER ||
+ n->nlmsg_type == RTM_DELTFILTER)
+ print_string(PRINT_FP, NULL, "filter ", NULL);
+ else
+ print_string(PRINT_FP, NULL, "chain ", NULL);
if (t->tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK) {
if (!filter_block_index ||
filter_block_index != t->tcm_block_index)
@@ -317,7 +337,9 @@ int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
}
}
- if (t->tcm_info) {
+ if (t->tcm_info && (n->nlmsg_type == RTM_NEWTFILTER ||
+ n->nlmsg_type == RTM_DELTFILTER ||
+ n->nlmsg_type == RTM_GETTFILTER)) {
f_proto = TC_H_MIN(t->tcm_info);
__u32 prio = TC_H_MAJ(t->tcm_info)>>16;
@@ -334,7 +356,8 @@ int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
print_uint(PRINT_ANY, "pref", "pref %u ", prio);
}
}
- print_string(PRINT_ANY, "kind", "%s ", rta_getattr_str(tb[TCA_KIND]));
+ if (tb[TCA_KIND])
+ print_string(PRINT_ANY, "kind", "%s ", rta_getattr_str(tb[TCA_KIND]));
if (tb[TCA_CHAIN]) {
__u32 chain_index = rta_getattr_u32(tb[TCA_CHAIN]);
@@ -345,15 +368,17 @@ int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
chain_index);
}
- q = get_filter_kind(RTA_DATA(tb[TCA_KIND]));
- if (tb[TCA_OPTIONS]) {
- open_json_object("options");
- if (q)
- q->print_fopt(q, fp, tb[TCA_OPTIONS], t->tcm_handle);
- else
- print_string(PRINT_FP, NULL,
- "[cannot parse parameters]", NULL);
- close_json_object();
+ if (tb[TCA_KIND]) {
+ q = get_filter_kind(RTA_DATA(tb[TCA_KIND]));
+ if (tb[TCA_OPTIONS]) {
+ open_json_object("options");
+ if (q)
+ q->print_fopt(q, fp, tb[TCA_OPTIONS], t->tcm_handle);
+ else
+ print_string(PRINT_FP, NULL,
+ "[cannot parse parameters]", NULL);
+ close_json_object();
+ }
}
print_string(PRINT_FP, NULL, "\n", NULL);
@@ -496,17 +521,19 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv)
argc--; argv++;
}
- if (!protocol_set) {
- fprintf(stderr, "Must specify filter protocol\n");
- return -1;
- }
+ if (cmd == RTM_GETTFILTER) {
+ if (!protocol_set) {
+ fprintf(stderr, "Must specify filter protocol\n");
+ return -1;
+ }
- if (!prio) {
- fprintf(stderr, "Must specify filter priority\n");
- return -1;
- }
+ if (!prio) {
+ fprintf(stderr, "Must specify filter priority\n");
+ return -1;
+ }
- req.t.tcm_info = TC_H_MAKE(prio<<16, protocol);
+ req.t.tcm_info = TC_H_MAKE(prio<<16, protocol);
+ }
if (chain_index_set)
addattr32(&req.n, sizeof(req), TCA_CHAIN, chain_index);
@@ -516,11 +543,13 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv)
return -1;
}
- if (k[0])
- addattr_l(&req.n, sizeof(req), TCA_KIND, k, strlen(k)+1);
- else {
- fprintf(stderr, "Must specify filter type\n");
- return -1;
+ if (cmd == RTM_GETTFILTER) {
+ if (k[0])
+ addattr_l(&req.n, sizeof(req), TCA_KIND, k, strlen(k)+1);
+ else {
+ fprintf(stderr, "Must specify filter type\n");
+ return -1;
+ }
}
if (d[0]) {
@@ -539,10 +568,11 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv)
return -1;
}
- if (q->parse_fopt(q, fhandle, argc, argv, &req.n))
+ if (cmd == RTM_GETTFILTER &&
+ q->parse_fopt(q, fhandle, argc, argv, &req.n))
return 1;
- if (!fhandle) {
+ if (!fhandle && cmd == RTM_GETTFILTER) {
fprintf(stderr, "Must specify filter \"handle\"\n");
return -1;
}
@@ -569,7 +599,7 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv)
return 0;
}
-static int tc_filter_list(int argc, char **argv)
+static int tc_filter_list(int cmd, int argc, char **argv)
{
struct {
struct nlmsghdr n;
@@ -577,7 +607,7 @@ static int tc_filter_list(int argc, char **argv)
char buf[MAX_MSG];
} req = {
.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)),
- .n.nlmsg_type = RTM_GETTFILTER,
+ .n.nlmsg_type = cmd,
.t.tcm_parent = TC_H_UNSPEC,
.t.tcm_family = AF_UNSPEC,
};
@@ -725,7 +755,7 @@ static int tc_filter_list(int argc, char **argv)
int do_filter(int argc, char **argv, void *buf, size_t buflen)
{
if (argc < 1)
- return tc_filter_list(0, NULL);
+ return tc_filter_list(RTM_GETTFILTER, 0, NULL);
if (matches(*argv, "add") == 0)
return tc_filter_modify(RTM_NEWTFILTER, NLM_F_EXCL|NLM_F_CREATE,
argc-1, argv+1, buf, buflen);
@@ -742,7 +772,7 @@ int do_filter(int argc, char **argv, void *buf, size_t buflen)
return tc_filter_get(RTM_GETTFILTER, 0, argc-1, argv+1);
if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
|| matches(*argv, "lst") == 0)
- return tc_filter_list(argc-1, argv+1);
+ return tc_filter_list(RTM_GETTFILTER, argc-1, argv+1);
if (matches(*argv, "help") == 0) {
usage();
return 0;
@@ -751,3 +781,28 @@ int do_filter(int argc, char **argv, void *buf, size_t buflen)
*argv);
return -1;
}
+
+int do_chain(int argc, char **argv, void *buf, size_t buflen)
+{
+ if (argc < 1)
+ return tc_filter_list(RTM_GETCHAIN, 0, NULL);
+ if (matches(*argv, "add") == 0) {
+ return tc_filter_modify(RTM_NEWCHAIN, NLM_F_EXCL | NLM_F_CREATE,
+ argc - 1, argv + 1, buf, buflen);
+ } else if (matches(*argv, "delete") == 0) {
+ return tc_filter_modify(RTM_DELCHAIN, 0,
+ argc - 1, argv + 1, buf, buflen);
+ } else if (matches(*argv, "get") == 0) {
+ return tc_filter_get(RTM_GETCHAIN, 0,
+ argc - 1, argv + 1);
+ } else if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0 ||
+ matches(*argv, "lst") == 0) {
+ return tc_filter_list(RTM_GETCHAIN, argc - 1, argv + 1);
+ } else if (matches(*argv, "help") == 0) {
+ chain_usage();
+ return 0;
+ }
+ fprintf(stderr, "Command \"%s\" is unknown, try \"tc chain help\".\n",
+ *argv);
+ return -1;
+}
diff --git a/tc/tc_monitor.c b/tc/tc_monitor.c
index 077b138d1ec58..1f1ee08fb9cf8 100644
--- a/tc/tc_monitor.c
+++ b/tc/tc_monitor.c
@@ -43,7 +43,10 @@ static int accept_tcmsg(const struct sockaddr_nl *who,
if (timestamp)
print_timestamp(fp);
- if (n->nlmsg_type == RTM_NEWTFILTER || n->nlmsg_type == RTM_DELTFILTER) {
+ if (n->nlmsg_type == RTM_NEWTFILTER ||
+ n->nlmsg_type == RTM_DELTFILTER ||
+ n->nlmsg_type == RTM_NEWCHAIN ||
+ n->nlmsg_type == RTM_DELCHAIN) {
print_filter(who, n, arg);
return 0;
}
--
2.20.1

View File

@ -1,46 +0,0 @@
From a298548e9cf58ea7dcaaefd29926bbbc4a1473b4 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Wed, 26 Jun 2019 18:18:04 +0200
Subject: [PATCH] m_mirred: don't bail if the control action is missing
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1711760
Upstream Status: iproute2.git commit 6eccf7ecdb010
commit 6eccf7ecdb010a90e5271942748ef4338ddb61ae
Author: Paolo Abeni <pabeni@redhat.com>
Date: Mon May 20 11:56:52 2019 +0200
m_mirred: don't bail if the control action is missing
The mirred act admits an optional control action, defaulting
to TC_ACT_PIPE. The parsing code currently emits an error message
if the control action is not provided on the command line, even
if the command itself completes with no error.
This change shuts down the error message, using the appropriate
parsing helper.
Fixes: e67aba559581 ("tc: actions: add helpers to parse and print control actions")
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
tc/m_mirred.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tc/m_mirred.c b/tc/m_mirred.c
index c7f7318b8413f..23ba638a234d1 100644
--- a/tc/m_mirred.c
+++ b/tc/m_mirred.c
@@ -202,7 +202,8 @@ parse_direction(struct action_util *a, int *argc_p, char ***argv_p,
if (p.eaction == TCA_EGRESS_MIRROR || p.eaction == TCA_INGRESS_MIRROR)
- parse_action_control(&argc, &argv, &p.action, false);
+ parse_action_control_dflt(&argc, &argv, &p.action, false,
+ TC_ACT_PIPE);
if (argc) {
if (iok && matches(*argv, "index") == 0) {
--
2.20.1

View File

@ -1,225 +0,0 @@
From 95436dbf882f32ed98f73ec080021daf3841f4a9 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Fri, 28 Jun 2019 14:12:36 +0200
Subject: [PATCH] netns: switch netns in the child when executing commands
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1719759
Upstream Status: iproute2.git commit 903818fbf9c73
commit 903818fbf9c73dd71793e5829775d2ccc1775af5
Author: Matteo Croce <mcroce@redhat.com>
Date: Tue Jun 18 16:49:33 2019 +0200
netns: switch netns in the child when executing commands
'ip netns exec' changes the current netns just before executing a child
process, and restores it after forking. This is needed if we're running
in batch or do_all mode.
Some cleanups must be done both in the parent and in the child: the
parent must restore the previous netns, while the child must reset any
VRF association.
Unfortunately, if do_all is set, the VRF are not reset in the child, and
the spawned processes are started with the wrong VRF context. This can
be triggered with this script:
# ip -b - <<-'EOF'
link add type vrf table 100
link set vrf0 up
link add type dummy
link set dummy0 vrf vrf0 up
netns add ns1
EOF
# ip -all -b - <<-'EOF'
vrf exec vrf0 true
netns exec setsid -f sleep 1h
EOF
# ip vrf pids vrf0
314 sleep
# ps 314
PID TTY STAT TIME COMMAND
314 ? Ss 0:00 sleep 1h
Refactor cmd_exec() and pass to it a function pointer which is called in
the child before the final exec. In the netns exec case the function just
resets the VRF and switches netns.
Doing it in the child is less error prone and safer, because the parent
environment is always kept unaltered.
After this refactor some utility functions became unused, so remove them.
Signed-off-by: Matteo Croce <mcroce@redhat.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
include/utils.h | 6 ++----
ip/ipnetns.c | 30 ++++++++++++++++--------------
ip/ipvrf.c | 2 +-
lib/exec.c | 7 ++++++-
lib/utils.c | 27 ---------------------------
5 files changed, 25 insertions(+), 47 deletions(-)
diff --git a/include/utils.h b/include/utils.h
index c32b37a1797d8..f00e7742b3c2a 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -292,14 +292,12 @@ extern int cmdlineno;
ssize_t getcmdline(char **line, size_t *len, FILE *in);
int makeargs(char *line, char *argv[], int maxargs);
-int do_each_netns(int (*func)(char *nsname, void *arg), void *arg,
- bool show_label);
-
char *int_to_str(int val, char *buf);
int get_guid(__u64 *guid, const char *arg);
int get_real_family(int rtm_type, int rtm_family);
-int cmd_exec(const char *cmd, char **argv, bool do_fork);
+int cmd_exec(const char *cmd, char **argv, bool do_fork,
+ int (*setup)(void *), void *arg);
int make_path(const char *path, mode_t mode);
char *find_cgroup2_mount(void);
int get_command_name(const char *pid, char *comm, size_t len);
diff --git a/ip/ipnetns.c b/ip/ipnetns.c
index a6e3ea575c363..10bfe2eb69e0b 100644
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -395,11 +395,24 @@ static int netns_list(int argc, char **argv)
return 0;
}
+static int do_switch(void *arg)
+{
+ char *netns = arg;
+
+ /* we just changed namespaces. clear any vrf association
+ * with prior namespace before exec'ing command
+ */
+ vrf_reset();
+
+ return netns_switch(netns);
+}
+
static int on_netns_exec(char *nsname, void *arg)
{
char **argv = arg;
- cmd_exec(argv[1], argv + 1, true);
+ printf("\nnetns: %s\n", nsname);
+ cmd_exec(argv[0], argv, true, do_switch, nsname);
return 0;
}
@@ -408,8 +421,6 @@ static int netns_exec(int argc, char **argv)
/* Setup the proper environment for apps that are not netns
* aware, and execute a program in that environment.
*/
- const char *cmd;
-
if (argc < 1 && !do_all) {
fprintf(stderr, "No netns name specified\n");
return -1;
@@ -420,22 +431,13 @@ static int netns_exec(int argc, char **argv)
}
if (do_all)
- return do_each_netns(on_netns_exec, --argv, 1);
-
- if (netns_switch(argv[0]))
- return -1;
-
- /* we just changed namespaces. clear any vrf association
- * with prior namespace before exec'ing command
- */
- vrf_reset();
+ return netns_foreach(on_netns_exec, argv);
/* ip must return the status of the child,
* but do_cmd() will add a minus to this,
* so let's add another one here to cancel it.
*/
- cmd = argv[1];
- return -cmd_exec(cmd, argv + 1, !!batch_mode);
+ return -cmd_exec(argv[1], argv + 1, !!batch_mode, do_switch, argv[0]);
}
static int is_pid(const char *str)
diff --git a/ip/ipvrf.c b/ip/ipvrf.c
index 8a6b7f977b142..c93ff71b39070 100644
--- a/ip/ipvrf.c
+++ b/ip/ipvrf.c
@@ -455,7 +455,7 @@ static int ipvrf_exec(int argc, char **argv)
if (vrf_switch(argv[0]))
return -1;
- return -cmd_exec(argv[1], argv + 1, !!batch_mode);
+ return -cmd_exec(argv[1], argv + 1, !!batch_mode, NULL, NULL);
}
/* reset VRF association of current process to default VRF;
diff --git a/lib/exec.c b/lib/exec.c
index eb36b59dee7f4..9b1c8f4a13960 100644
--- a/lib/exec.c
+++ b/lib/exec.c
@@ -5,8 +5,10 @@
#include <unistd.h>
#include "utils.h"
+#include "namespace.h"
-int cmd_exec(const char *cmd, char **argv, bool do_fork)
+int cmd_exec(const char *cmd, char **argv, bool do_fork,
+ int (*setup)(void *), void *arg)
{
fflush(stdout);
if (do_fork) {
@@ -34,6 +36,9 @@ int cmd_exec(const char *cmd, char **argv, bool do_fork)
}
}
+ if (setup && setup(arg))
+ return -1;
+
if (execvp(cmd, argv) < 0)
fprintf(stderr, "exec of \"%s\" failed: %s\n",
cmd, strerror(errno));
diff --git a/lib/utils.c b/lib/utils.c
index 7be2d6bec5215..5f229a9a4f584 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -1455,33 +1455,6 @@ void print_nlmsg_timestamp(FILE *fp, const struct nlmsghdr *n)
fprintf(fp, "Timestamp: %s %lu us\n", tstr, usecs);
}
-static int on_netns(char *nsname, void *arg)
-{
- struct netns_func *f = arg;
-
- if (netns_switch(nsname))
- return -1;
-
- return f->func(nsname, f->arg);
-}
-
-static int on_netns_label(char *nsname, void *arg)
-{
- printf("\nnetns: %s\n", nsname);
- return on_netns(nsname, arg);
-}
-
-int do_each_netns(int (*func)(char *nsname, void *arg), void *arg,
- bool show_label)
-{
- struct netns_func nsf = { .func = func, .arg = arg };
-
- if (show_label)
- return netns_foreach(on_netns_label, &nsf);
-
- return netns_foreach(on_netns, &nsf);
-}
-
char *int_to_str(int val, char *buf)
{
sprintf(buf, "%d", val);
--
2.20.1

View File

@ -1,57 +0,0 @@
From 1a9c12f737e86a7905cd123f364af053dc0c7491 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Fri, 28 Jun 2019 14:12:36 +0200
Subject: [PATCH] ip vrf: use hook to change VRF in the child
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1719759
Upstream Status: iproute2.git commit d81d4ba15d74a
commit d81d4ba15d74a51f23f61a2ddb792689e5db95f0
Author: Matteo Croce <mcroce@redhat.com>
Date: Tue Jun 18 16:49:34 2019 +0200
ip vrf: use hook to change VRF in the child
On vrf exec, reset the VRF associations in the child process, via the
new hook added to cmd_exec(). In this way, the parent doesn't have to
reset the VRF associations before spawning other processes.
Signed-off-by: Matteo Croce <mcroce@redhat.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/ipvrf.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/ip/ipvrf.c b/ip/ipvrf.c
index c93ff71b39070..aba8639501139 100644
--- a/ip/ipvrf.c
+++ b/ip/ipvrf.c
@@ -441,6 +441,13 @@ out:
return rc;
}
+static int do_switch(void *arg)
+{
+ char *vrf = arg;
+
+ return vrf_switch(vrf);
+}
+
static int ipvrf_exec(int argc, char **argv)
{
if (argc < 1) {
@@ -452,10 +459,7 @@ static int ipvrf_exec(int argc, char **argv)
return -1;
}
- if (vrf_switch(argv[0]))
- return -1;
-
- return -cmd_exec(argv[1], argv + 1, !!batch_mode, NULL, NULL);
+ return -cmd_exec(argv[1], argv + 1, !!batch_mode, do_switch, argv[0]);
}
/* reset VRF association of current process to default VRF;
--
2.20.1

View File

@ -1,164 +0,0 @@
From 56dfe34480259eebd91c9a4dc57a6fe15c07e60a Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Fri, 28 Jun 2019 14:12:36 +0200
Subject: [PATCH] netns: make netns_{save,restore} static
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1719759
Upstream Status: iproute2.git commit b2e2922373a6c
Conflicts: context change due to missing commit e3dbcb2a12ab1
("netns: add subcommand to attach an existing network namespace")
commit b2e2922373a6c65ed08b57926e61f3621d89a70a
Author: Matteo Croce <mcroce@redhat.com>
Date: Tue Jun 18 16:49:35 2019 +0200
netns: make netns_{save,restore} static
The netns_{save,restore} functions are only used in ipnetns.c now, since
the restore is not needed anymore after the netns exec command.
Move them in ipnetns.c, and make them static.
Signed-off-by: Matteo Croce <mcroce@redhat.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
include/namespace.h | 2 --
ip/ip.c | 1 -
ip/ipnetns.c | 31 +++++++++++++++++++++++++++++++
lib/namespace.c | 31 -------------------------------
4 files changed, 31 insertions(+), 34 deletions(-)
diff --git a/include/namespace.h b/include/namespace.h
index 89cdda11782e8..e47f9b5d49d12 100644
--- a/include/namespace.h
+++ b/include/namespace.h
@@ -49,8 +49,6 @@ static inline int setns(int fd, int nstype)
}
#endif /* HAVE_SETNS */
-void netns_save(void);
-void netns_restore(void);
int netns_switch(char *netns);
int netns_get_fd(const char *netns);
int netns_foreach(int (*func)(char *nsname, void *arg), void *arg);
diff --git a/ip/ip.c b/ip/ip.c
index 6e8230b3ee584..2ca55e37a4c62 100644
--- a/ip/ip.c
+++ b/ip/ip.c
@@ -158,7 +158,6 @@ static int batch(const char *name)
if (!force)
break;
}
- netns_restore();
}
if (line)
free(line);
diff --git a/ip/ipnetns.c b/ip/ipnetns.c
index 10bfe2eb69e0b..40848a5cf10ac 100644
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -42,6 +42,7 @@ static int usage(void)
static struct rtnl_handle rtnsh = { .fd = -1 };
static int have_rtnl_getnsid = -1;
+static int saved_netns = -1;
static int ipnetns_accept_msg(const struct sockaddr_nl *who,
struct rtnl_ctrl_data *ctrl,
@@ -634,6 +635,33 @@ static int create_netns_dir(void)
return 0;
}
+/* Obtain a FD for the current namespace, so we can reenter it later */
+static void netns_save(void)
+{
+ if (saved_netns != -1)
+ return;
+
+ saved_netns = open("/proc/self/ns/net", O_RDONLY | O_CLOEXEC);
+ if (saved_netns == -1) {
+ perror("Cannot open init namespace");
+ exit(1);
+ }
+}
+
+static void netns_restore(void)
+{
+ if (saved_netns == -1)
+ return;
+
+ if (setns(saved_netns, CLONE_NEWNET)) {
+ perror("setns");
+ exit(1);
+ }
+
+ close(saved_netns);
+ saved_netns = -1;
+}
+
static int netns_add(int argc, char **argv)
{
/* This function creates a new network namespace and
@@ -704,8 +732,11 @@ static int netns_add(int argc, char **argv)
netns_path, strerror(errno));
goto out_delete;
}
+ netns_restore();
+
return 0;
out_delete:
+ netns_restore();
netns_delete(argc, argv);
return -1;
}
diff --git a/lib/namespace.c b/lib/namespace.c
index a2aea57ad4109..06ae0a48c2243 100644
--- a/lib/namespace.c
+++ b/lib/namespace.c
@@ -15,35 +15,6 @@
#include "utils.h"
#include "namespace.h"
-static int saved_netns = -1;
-
-/* Obtain a FD for the current namespace, so we can reenter it later */
-void netns_save(void)
-{
- if (saved_netns != -1)
- return;
-
- saved_netns = open("/proc/self/ns/net", O_RDONLY | O_CLOEXEC);
- if (saved_netns == -1) {
- perror("Cannot open init namespace");
- exit(1);
- }
-}
-
-void netns_restore(void)
-{
- if (saved_netns == -1)
- return;
-
- if (setns(saved_netns, CLONE_NEWNET)) {
- perror("setns");
- exit(1);
- }
-
- close(saved_netns);
- saved_netns = -1;
-}
-
static void bind_etc(const char *name)
{
char etc_netns_path[sizeof(NETNS_ETC_DIR) + NAME_MAX];
@@ -90,8 +61,6 @@ int netns_switch(char *name)
return -1;
}
- netns_save();
-
if (setns(netns, CLONE_NEWNET) < 0) {
fprintf(stderr, "setting the network namespace \"%s\" failed: %s\n",
name, strerror(errno));
--
2.20.1

View File

@ -1,7 +1,5 @@
%global cbq_version v0.7.3
%define rpmversion 4.18.0
%define specrelease 15%{?dist}
%define rpmversion 5.3.0
%define specrelease 1%{?dist}
%define pkg_release %{specrelease}%{?buildid}
Summary: Advanced IP routing and network device configuration tools
@ -14,82 +12,6 @@ Source0: http://kernel.org/pub/linux/utils/net/%{name}2/%{name}2-%{ve
Source1: cbq-0000.example
Source2: avpkt
Source3: rt_dsfield.deprecated
Patch0: 0001-man-bridge.8-Document-oneline-option.patch
Patch1: 0002-bridge-trivial-Make-help-text-consistent.patch
Patch2: 0003-devlink-trivial-Make-help-text-consistent.patch
Patch3: 0004-man-devlink.8-Document-verbose-option.patch
Patch4: 0005-genl-Fix-help-text.patch
Patch5: 0006-man-ifstat.8-Document-json-and-pretty-options.patch
Patch6: 0007-man-rtacct.8-Fix-nstat-options.patch
Patch7: 0008-rtmon-List-options-in-help-text.patch
Patch8: 0009-man-ss.8-Describe-events-option.patch
Patch9: 0010-ip-Add-missing-M-flag-to-help-text.patch
Patch10: 0011-iprule-Fix-destination-prefix-output.patch
Patch11: 0012-tc-act_tunnel_key-Enable-setup-of-tos-and-ttl.patch
Patch12: 0013-tc-flower-Add-match-on-encapsulating-tos-ttl.patch
Patch13: 0014-Update-kernel-headers.patch
Patch14: 0015-ip-route-Fix-segfault-with-many-nexthops.patch
Patch15: 0016-bridge-mdb-fix-missing-new-line-when-show-bridge-mdb.patch
Patch16: 0017-lib-introduce-print_nl.patch
Patch17: 0018-bridge-fdb-Fix-for-missing-keywords-in-non-JSON-outp.patch
Patch18: 0019-ip-addrlabel-Fix-printing-of-label-value.patch
Patch19: 0020-iplink_vxlan-take-into-account-preferred_family-crea.patch
Patch20: 0021-json-make-0xhex-handle-u64.patch
Patch21: 0022-macsec-fix-off-by-one-when-parsing-attributes.patch
Patch22: 0023-uapi-add-snmp-header-file.patch
Patch23: 0024-utils-fix-get_rtnl_link_stats_rta-stats-parsing.patch
Patch24: 0025-tc-htb-Print-default-value-in-hex.patch
Patch25: 0026-libnetlink-fix-leak-and-using-unused-memory-on-error.patch
Patch26: 0027-libnetlink-don-t-return-error-on-success.patch
Patch27: 0028-libnetlink-fix-use-after-free-of-message-buf.patch
Patch28: 0029-devlink-Fix-error-reporting-in-cmd_resource_set.patch
Patch29: 0030-rdma-Fix-for-ineffective-check-in-add_filter.patch
Patch30: 0031-ip-route-Fix-for-memleak-in-error-path.patch
Patch31: 0032-rdma-Don-t-pass-garbage-to-rd_check_is_filtered.patch
Patch32: 0033-ip-route-Fix-parse_encap_seg6-srh-parsing.patch
Patch33: 0034-tipc-Drop-unused-variable-genl.patch
Patch34: 0035-tc-Remove-pointless-assignments-in-batch.patch
Patch35: 0036-tc_util-Add-support-for-showing-TCA_STATS_BASIC_HW-s.patch
Patch36: 0037-Update-kernel-headers.patch
Patch37: 0038-man-ip-route.8-Document-nexthop-limit.patch
Patch38: 0039-ip-route-Fix-nexthop-encap-parsing.patch
Patch39: 0040-man-rdma-Add-reference-to-rdma-resource.8.patch
Patch40: 0041-iplink-fix-incorrect-any-address-handling-for-ip-tun.patch
Patch41: 0042-l2tp-Fix-printing-of-cookie-and-peer_cookie-values.patch
Patch42: 0043-tc-f_flower-add-geneve-option-match-support-to-flowe.patch
Patch43: 0044-tc-m_tunnel_key-Add-tunnel-option-support-to-act_tun.patch
Patch44: 0045-ip-rule-Add-ipproto-and-port-range-to-filter-list.patch
Patch45: 0046-tc-flower-Add-support-for-QinQ.patch
Patch46: 0047-uapi-update-ib_verbs.patch
Patch47: 0048-rdma-Fix-representation-of-PortInfo-CapabilityMask.patch
Patch48: 0049-devlink-Add-param-command-support.patch
Patch49: 0050-libnetlink-Convert-GETADDR-dumps-to-use-rtnl_addrdum.patch
Patch50: 0051-rdma-Update-kernel-include-file-to-support-IB-device.patch
Patch51: 0052-rdma-Introduce-command-execution-helper-with-require.patch
Patch52: 0053-rdma-Add-an-option-to-rename-IB-device-interface.patch
Patch53: 0054-rdma-Document-IB-device-renaming-option.patch
Patch54: 0055-iplink-add-support-for-reporting-multiple-XDP-progra.patch
Patch55: 0056-bpf-move-bpf_elf_map-fixup-notification-under-verbos.patch
Patch56: 0057-bpf-remove-strict-dependency-on-af_alg.patch
Patch57: 0058-bpf-implement-bpf-to-bpf-calls-support.patch
Patch58: 0059-bpf-implement-btf-handling-and-map-annotation.patch
Patch59: 0060-bpf-check-map-symbol-type-properly-with-newer-llvm-c.patch
Patch60: 0061-Use-libbsd-for-strlcpy-if-available.patch
Patch61: 0062-Include-bsd-string.h-only-in-include-utils.h.patch
Patch62: 0063-bpf-initialise-map-symbol-before-retrieving-and-comp.patch
Patch63: 0064-lib-bpf-fix-build-warning-if-no-elf.patch
Patch64: 0065-bpf-add-btf-func-and-func_proto-kind-support.patch
Patch65: 0066-uapi-update-headers-to-4.20-rc1.patch
Patch66: 0067-uapi-update-bpf-header.patch
Patch67: 0068-Update-kernel-headers.patch
Patch68: 0069-ip-xfrm-Respect-family-in-deleteall-and-list-command.patch
Patch69: 0070-ss-Review-ssfilter.patch
Patch70: 0071-ip-reset-netns-after-each-command-in-batch-mode.patch
Patch71: 0072-tc-introduce-support-for-chain-templates.patch
Patch72: 0073-m_mirred-don-t-bail-if-the-control-action-is-missing.patch
Patch73: 0074-netns-switch-netns-in-the-child-when-executing-comma.patch
Patch74: 0075-ip-vrf-use-hook-to-change-VRF-in-the-child.patch
Patch75: 0076-netns-make-netns_-save-restore-static.patch
License: GPLv2+ and Public Domain
BuildRequires: bison
BuildRequires: elfutils-libelf-devel
@ -168,7 +90,7 @@ export CONFDIR='%{_sysconfdir}/iproute2'
export DOCDIR='%{_docdir}'
%make_install
install -m755 examples/cbq.init-%{cbq_version} ${DESTDIR}/${SBINDIR}/cbq
install -m755 examples/cbqinit.eth1 ${DESTDIR}/${SBINDIR}/cbq
echo '.so man8/tc-cbq.8' > %{buildroot}%{_mandir}/man8/cbq.8
install -d -m755 %{buildroot}%{_sysconfdir}/sysconfig/cbq
@ -192,7 +114,7 @@ cat %{SOURCE3} >>%{buildroot}%{_sysconfdir}/iproute2/rt_dsfield
%dir %{_sysconfdir}/iproute2
%{!?_licensedir:%global license %%doc}
%license COPYING
%doc README README.decnet README.iproute2+tc README.distribution README.lnstat
%doc README README.iproute2+tc README.distribution README.lnstat
%{_mandir}/man7/*
%exclude %{_mandir}/man7/tc-*
%{_mandir}/man8/*
@ -234,6 +156,9 @@ cat %{SOURCE3} >>%{buildroot}%{_sysconfdir}/iproute2/rt_dsfield
%{_includedir}/iproute2/bpf_elf.h
%changelog
* Tue Oct 15 2019 Andrea Claudi <aclaudi@redhat.com> [5.3.0-1.el8]
- New version 5.3.0 [1752857]
* Thu Jul 04 2019 Andrea Claudi <aclaudi@redhat.com> [4.18.0-15.el8]
- netns: make netns_{save,restore} static (Andrea Claudi) [1719759]
- ip vrf: use hook to change VRF in the child (Andrea Claudi) [1719759]