aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Ahern <dsahern@kernel.org>2024-01-30 15:49:23 +0000
committerDavid Ahern <dsahern@kernel.org>2024-01-30 15:49:23 +0000
commit91e3be8fdf1b9c48c7bfc98516aac3d51858a9a5 (patch)
tree73c3e7e8f8043e4c7bb1ac7d04ac23129d64b785
parent139a74134c52a7f96cc7b16a53988097dd2d4175 (diff)
parentcf0eae9a9fc4a40e98bac883919dc872244ee570 (diff)
downloadiproute2-next-91e3be8fdf1b9c48c7bfc98516aac3d51858a9a5.tar.gz
Merge branch 'echo-tc-filter-actions' into next
Victor Nogueira says: ==================== Continuing on what Hangbin Liu started [1], this patch set adds support for the NLM_F_ECHO flag for tc actions and filters. For qdiscs it will require some kernel surgery, and we'll send it soon after this surgery is merged. When user space configures the kernel with netlink messages, it can set NLM_F_ECHO flag to request the kernel to send the applied configuration back to the caller. This allows user space to receive back configuration information that is populated by the kernel. Often because there are parameters that can only be set by the kernel which become visible with the echo, or because user space lets the kernel choose a default value. To illustrate a use case where the kernel will give us a default value, the example below shows the user not specifying the action index: tc -echo actions add action mirred egress mirror dev lo total acts 0 Added action action order 1: mirred (Egress Mirror to device lo) pipe index 1 ref 1 bind 0 not_in_hw Note that the echoed response indicates that the kernel gave us a value of index 1 [1] https://lore.kernel.org/netdev/20220916033428.400131-2-liuhangbin@gmail.com/ ==================== Signed-off-by: David Ahern <dsahern@kernel.org>
-rw-r--r--man/man8/tc.86
-rw-r--r--tc/m_action.c25
-rw-r--r--tc/tc.c6
-rw-r--r--tc/tc_filter.c8
4 files changed, 39 insertions, 6 deletions
diff --git a/man/man8/tc.8 b/man/man8/tc.8
index 3175454b9..dce58af17 100644
--- a/man/man8/tc.8
+++ b/man/man8/tc.8
@@ -127,7 +127,7 @@ tc \- show / manipulate traffic control settings
\fB[ \fB-nm \fR| \fB-nam\fR[\fIes\fR] \fB] \fR|
\fB[ \fR{ \fB-cf \fR| \fB-c\fR[\fIonf\fR] \fR} \fB[ filename ] \fB] \fR
\fB[ -t\fR[imestamp\fR] \fB\] \fR| \fB[ -t\fR[short\fR] \fR| \fB[
--o\fR[neline\fR] \fB]\fR }
+-o\fR[neline\fR] \fB] \fR| \fB[ -echo ]\fR }
.ti 8
.IR FORMAT " := {"
@@ -743,6 +743,10 @@ When\fB\ tc monitor\fR\ runs, print timestamp before the event message in format
When\fB\ tc monitor\fR\ runs, prints short timestamp before the event message in format:
[<YYYY>-<MM>-<DD>T<hh:mm:ss>.<ms>]
+.TP
+.BR "\-echo"
+Request the kernel to send the applied configuration back.
+
.SH FORMAT
The show command has additional formatting options:
diff --git a/tc/m_action.c b/tc/m_action.c
index 16474c561..fd9621e1b 100644
--- a/tc/m_action.c
+++ b/tc/m_action.c
@@ -688,7 +688,16 @@ static int tc_action_gd(int cmd, unsigned int flags,
req.n.nlmsg_seq = rth.dump = ++rth.seq;
- if (rtnl_talk(&rth, &req.n, cmd == RTM_DELACTION ? NULL : &ans) < 0) {
+ if (cmd == RTM_DELACTION) {
+ if (echo_request)
+ ret = rtnl_echo_talk(&rth, &req.n, json, print_action);
+ else
+ ret = rtnl_talk(&rth, &req.n, NULL);
+ } else {
+ ret = rtnl_talk(&rth, &req.n, &ans);
+ }
+
+ if (ret < 0) {
fprintf(stderr, "We have an error talking to the kernel\n");
return 1;
}
@@ -738,7 +747,12 @@ static int tc_action_modify(int cmd, unsigned int flags,
}
tail->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail;
- if (rtnl_talk(&rth, &req.n, NULL) < 0) {
+ if (echo_request)
+ ret = rtnl_echo_talk(&rth, &req.n, json, print_action);
+ else
+ ret = rtnl_talk(&rth, &req.n, NULL);
+
+ if (ret < 0) {
fprintf(stderr, "We have an error talking to the kernel\n");
ret = -1;
}
@@ -836,7 +850,12 @@ static int tc_act_list_or_flush(int *argc_p, char ***argv_p, int event)
req.n.nlmsg_type = RTM_DELACTION;
req.n.nlmsg_flags |= NLM_F_ROOT;
req.n.nlmsg_flags |= NLM_F_REQUEST;
- if (rtnl_talk(&rth, &req.n, NULL) < 0) {
+
+ if (echo_request)
+ ret = rtnl_echo_talk(&rth, &req.n, json, print_action);
+ else
+ ret = rtnl_talk(&rth, &req.n, NULL);
+ if (ret < 0) {
fprintf(stderr, "We have an error flushing\n");
return 1;
}
diff --git a/tc/tc.c b/tc/tc.c
index 575157a86..7a746cf51 100644
--- a/tc/tc.c
+++ b/tc/tc.c
@@ -38,6 +38,8 @@ int json;
int oneline;
int brief;
+int echo_request;
+
static char *conf_file;
struct rtnl_handle rth;
@@ -196,7 +198,7 @@ static void usage(void)
" -o[neline] | -j[son] | -p[retty] | -c[olor]\n"
" -b[atch] [filename] | -n[etns] name | -N[umeric] |\n"
" -nm | -nam[es] | { -cf | -conf } path\n"
- " -br[ief] }\n");
+ " -br[ief] | -echo }\n");
}
static int do_cmd(int argc, char **argv)
@@ -314,6 +316,8 @@ int main(int argc, char **argv)
++oneline;
} else if (matches(argv[1], "-brief") == 0) {
++brief;
+ } else if (strcmp(argv[1], "-echo") == 0) {
+ ++echo_request;
} else {
fprintf(stderr,
"Option \"%s\" is unknown, try \"tc -help\".\n",
diff --git a/tc/tc_filter.c b/tc/tc_filter.c
index eb45c5887..54790ddc6 100644
--- a/tc/tc_filter.c
+++ b/tc/tc_filter.c
@@ -76,6 +76,7 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv)
char d[IFNAMSIZ] = {};
char k[FILTER_NAMESZ] = {};
struct tc_estimator est = {};
+ int ret;
if (cmd == RTM_NEWTFILTER && flags & NLM_F_CREATE)
protocol = htons(ETH_P_ALL);
@@ -221,7 +222,12 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv)
if (est.ewma_log)
addattr_l(&req.n, sizeof(req), TCA_RATE, &est, sizeof(est));
- if (rtnl_talk(&rth, &req.n, NULL) < 0) {
+ if (echo_request)
+ ret = rtnl_echo_talk(&rth, &req.n, json, print_filter);
+ else
+ ret = rtnl_talk(&rth, &req.n, NULL);
+
+ if (ret < 0) {
fprintf(stderr, "We have an error talking to the kernel\n");
return 2;
}