diff options
author | David Ahern <dsahern@kernel.org> | 2024-01-30 15:49:23 +0000 |
---|---|---|
committer | David Ahern <dsahern@kernel.org> | 2024-01-30 15:49:23 +0000 |
commit | 91e3be8fdf1b9c48c7bfc98516aac3d51858a9a5 (patch) | |
tree | 73c3e7e8f8043e4c7bb1ac7d04ac23129d64b785 | |
parent | 139a74134c52a7f96cc7b16a53988097dd2d4175 (diff) | |
parent | cf0eae9a9fc4a40e98bac883919dc872244ee570 (diff) | |
download | iproute2-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.8 | 6 | ||||
-rw-r--r-- | tc/m_action.c | 25 | ||||
-rw-r--r-- | tc/tc.c | 6 | ||||
-rw-r--r-- | tc/tc_filter.c | 8 |
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; } @@ -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; } |