All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH iproute2-next 0/1] ip: add NLM_F_ECHO support
@ 2022-09-16  3:34 Hangbin Liu
  2022-09-16  3:34 ` [PATCH iproute2-next 1/1] " Hangbin Liu
  0 siblings, 1 reply; 4+ messages in thread
From: Hangbin Liu @ 2022-09-16  3:34 UTC (permalink / raw)
  To: netdev; +Cc: David Ahern, Stephen Hemminger, Guillaume Nault, Hangbin Liu

Hi,

As the patch did, here I just pust the test result for each commands

# ip -echo addr add 192.168.0.1/24 dev eth1
3: eth1    inet 192.168.0.1/24 scope global eth1
       valid_lft forever preferred_lft forever
# ip -j -p -echo addr del 192.168.0.1/24 dev eth1
[ {
        "deleted": true,
        "index": 3,
        "dev": "eth1",
        "family": "inet",
        "local": "192.168.0.1",
        "prefixlen": 24,
        "scope": "global",
        "label": "eth1",
        "valid_life_time": 4294967295,
        "preferred_life_time": 4294967295
    } ]
# ip -o -echo addr add 192.168.0.1/24 dev eth1
3: eth1    inet 192.168.0.1/24 scope global eth1\       valid_lft forever preferred_lft forever
# ip -br -echo addr del 192.168.0.1/24 dev eth1
Deleted 192.168.0.1/24

# ip -echo nexthop add id 1 via 192.168.0.254 dev eth1
id 1 via 192.168.0.254 dev eth1 scope link
# ip -j -p -echo nexthop del id 1
[ {{
            "deleted": true,
            "id": 1,
            "gateway": "192.168.0.254",
            "dev": "eth1",
            "scope": "link",
            "flags": [ ]
        }
    } ]

# ip -echo -6 route add 2022::1/64 via 2000::254 dev eth1
2022::/64 via 2000::254 dev eth1 metric 1024 pref medium
# ip -j -p -echo -6 route del 2022::1/64 via 2000::254 dev eth1
[ {{
            "deleted": true,
            "dst": "2022::/64",
            "gateway": "2000::254",
            "dev": "eth1",
            "metric": 1024,
            "flags": [ ],
            "pref": "medium"
        }
    } ]

# ip -echo rule add from 192.168.1.10 table 10
32765:  from 192.168.1.10 lookup 10
# ip -j -p -echo rule del table 10
[ {{
            "deleted": true,
            "priority": 32765,
            "src": "192.168.1.10",
            "table": "10"
        }
    } ]

# test if the cmd doesn't support -echo
# ip -echo neigh add 192.168.0.2 dev eth1 lladdr 00:00:00:00:00:01
# ip -echo neigh del 192.168.0.2 dev eth1 lladdr 00:00:00:00:00:01

Hangbin Liu (1):
  ip: add NLM_F_ECHO support

 include/utils.h |  1 +
 ip/ip.c         |  3 +++
 ip/ipaddress.c  | 23 +++++++++++++++++++++--
 ip/iplink.c     | 20 +++++++++++++++++++-
 ip/ipnexthop.c  | 21 ++++++++++++++++++++-
 ip/iproute.c    | 21 ++++++++++++++++++++-
 ip/iprule.c     | 21 ++++++++++++++++++++-
 man/man8/ip.8   |  4 ++++
 8 files changed, 108 insertions(+), 6 deletions(-)

-- 
2.37.2


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

* [PATCH iproute2-next 1/1] ip: add NLM_F_ECHO support
  2022-09-16  3:34 [PATCH iproute2-next 0/1] ip: add NLM_F_ECHO support Hangbin Liu
@ 2022-09-16  3:34 ` Hangbin Liu
  2022-09-22 23:17   ` David Ahern
  0 siblings, 1 reply; 4+ messages in thread
From: Hangbin Liu @ 2022-09-16  3:34 UTC (permalink / raw)
  To: netdev; +Cc: David Ahern, Stephen Hemminger, Guillaume Nault, Hangbin Liu

When user space configures the kernel with netlink messages, it can set the
NLM_F_ECHO flag to request the kernel to send the applied configuration back
to the caller. This allows user space to retrieve configuration information
that are filled by the kernel (either because these parameters can only be
set by the kernel or because user space let the kernel choose a default
value).

NLM_F_ACK is also supplied incase the kernel doesn't support NLM_F_ECHO
and we will wait for the reply forever. Just like the update in
iplink.c, which I plan to post a patch to kernel later.

A new parameter -echo is added when user want to get feedback from kernel.
e.g.

  # ip -echo addr add 192.168.0.1/24 dev eth1
  3: eth1    inet 192.168.0.1/24 scope global eth1
         valid_lft forever preferred_lft forever
  # ip -j -p -echo addr del 192.168.0.1/24 dev eth1
  [ {
          "deleted": true,
          "index": 3,
          "dev": "eth1",
          "family": "inet",
          "local": "192.168.0.1",
          "prefixlen": 24,
          "scope": "global",
          "label": "eth1",
          "valid_life_time": 4294967295,
          "preferred_life_time": 4294967295
      } ]

Suggested-by: Guillaume Nault <gnault@redhat.com>
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
---
 include/utils.h |  1 +
 ip/ip.c         |  3 +++
 ip/ipaddress.c  | 23 +++++++++++++++++++++--
 ip/iplink.c     | 20 +++++++++++++++++++-
 ip/ipnexthop.c  | 21 ++++++++++++++++++++-
 ip/iproute.c    | 21 ++++++++++++++++++++-
 ip/iprule.c     | 21 ++++++++++++++++++++-
 man/man8/ip.8   |  4 ++++
 8 files changed, 108 insertions(+), 6 deletions(-)

diff --git a/include/utils.h b/include/utils.h
index eeb23a64..2eb80b3e 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -36,6 +36,7 @@ extern int max_flush_loops;
 extern int batch_mode;
 extern int numeric;
 extern bool do_all;
+extern int echo_request;
 
 #ifndef CONFDIR
 #define CONFDIR		"/etc/iproute2"
diff --git a/ip/ip.c b/ip/ip.c
index 82282bab..863e42aa 100644
--- a/ip/ip.c
+++ b/ip/ip.c
@@ -39,6 +39,7 @@ int oneline;
 int brief;
 int json;
 int timestamp;
+int echo_request;
 int force;
 int max_flush_loops = 10;
 int batch_mode;
@@ -293,6 +294,8 @@ int main(int argc, char **argv)
 			++numeric;
 		} else if (matches(opt, "-all") == 0) {
 			do_all = true;
+		} else if (strcmp(opt, "-echo") == 0) {
+			++echo_request;
 		} else {
 			fprintf(stderr,
 				"Option \"%s\" is unknown, try \"ip -help\".\n",
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 45955e1c..3a30c9c0 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -1586,7 +1586,7 @@ int print_addrinfo(struct nlmsghdr *n, void *arg)
 	if (!brief) {
 		const char *name;
 
-		if (filter.oneline || filter.flushb) {
+		if (filter.oneline || filter.flushb || echo_request) {
 			const char *dev = ll_index_to_name(ifa->ifa_index);
 
 			if (is_json_context()) {
@@ -2416,6 +2416,11 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
 	__u32 preferred_lft = INFINITY_LIFE_TIME;
 	__u32 valid_lft = INFINITY_LIFE_TIME;
 	unsigned int ifa_flags = 0;
+	struct nlmsghdr *answer;
+	int ret;
+
+	if (echo_request)
+		req.n.nlmsg_flags |= NLM_F_ECHO|NLM_F_ACK;
 
 	while (argc > 0) {
 		if (strcmp(*argv, "peer") == 0 ||
@@ -2597,9 +2602,23 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
 		return -1;
 	}
 
-	if (rtnl_talk(&rth, &req.n, NULL) < 0)
+	if (echo_request)
+		ret = rtnl_talk(&rth, &req.n, &answer);
+	else
+		ret = rtnl_talk(&rth, &req.n, NULL);
+
+	if (ret < 0)
 		return -2;
 
+	if (echo_request) {
+		new_json_obj(json);
+		open_json_object(NULL);
+		print_addrinfo(answer, stdout);
+		close_json_object();
+		delete_json_obj();
+		free(answer);
+	}
+
 	return 0;
 }
 
diff --git a/ip/iplink.c b/ip/iplink.c
index b98c1694..15214f47 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -1073,12 +1073,16 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
 		.n.nlmsg_type = cmd,
 		.i.ifi_family = preferred_family,
 	};
+	struct nlmsghdr *answer;
 	int ret;
 
 	ret = iplink_parse(argc, argv, &req, &type);
 	if (ret < 0)
 		return ret;
 
+	if (echo_request)
+		req.n.nlmsg_flags |= NLM_F_ECHO|NLM_F_ACK;
+
 	if (type) {
 		struct link_util *lu;
 		struct rtattr *linkinfo;
@@ -1123,9 +1127,23 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
 		return -1;
 	}
 
-	if (rtnl_talk(&rth, &req.n, NULL) < 0)
+	if (echo_request)
+		ret = rtnl_talk(&rth, &req.n, &answer);
+	else
+		ret = rtnl_talk(&rth, &req.n, NULL);
+
+	if (ret < 0)
 		return -2;
 
+	if (echo_request) {
+		new_json_obj(json);
+		open_json_object(NULL);
+		print_linkinfo(answer, stdout);
+		close_json_object();
+		delete_json_obj();
+		free(answer);
+	}
+
 	/* remove device from cache; next use can refresh with new data */
 	ll_drop_by_index(req.i.ifi_index);
 
diff --git a/ip/ipnexthop.c b/ip/ipnexthop.c
index 2f448449..7523e490 100644
--- a/ip/ipnexthop.c
+++ b/ip/ipnexthop.c
@@ -919,7 +919,12 @@ static int ipnh_modify(int cmd, unsigned int flags, int argc, char **argv)
 		.n.nlmsg_type = cmd,
 		.nhm.nh_family = preferred_family,
 	};
+	struct nlmsghdr *answer;
 	__u32 nh_flags = 0;
+	int ret;
+
+	if (echo_request)
+		req.n.nlmsg_flags |= NLM_F_ECHO|NLM_F_ACK;
 
 	while (argc > 0) {
 		if (!strcmp(*argv, "id")) {
@@ -999,9 +1004,23 @@ static int ipnh_modify(int cmd, unsigned int flags, int argc, char **argv)
 
 	req.nhm.nh_flags = nh_flags;
 
-	if (rtnl_talk(&rth, &req.n, NULL) < 0)
+	if (echo_request)
+		ret = rtnl_talk(&rth, &req.n, &answer);
+	else
+		ret = rtnl_talk(&rth, &req.n, NULL);
+
+	if (ret < 0)
 		return -2;
 
+	if (echo_request) {
+		new_json_obj(json);
+		open_json_object(NULL);
+		print_nexthop_nocache(answer, (void *)stdout);
+		close_json_object();
+		delete_json_obj();
+		free(answer);
+	}
+
 	return 0;
 }
 
diff --git a/ip/iproute.c b/ip/iproute.c
index a1cdf953..42035d21 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -1121,6 +1121,7 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv)
 	};
 	char  mxbuf[256];
 	struct rtattr *mxrta = (void *)mxbuf;
+	struct nlmsghdr *answer;
 	unsigned int mxlock = 0;
 	char  *d = NULL;
 	int gw_ok = 0;
@@ -1131,6 +1132,7 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv)
 	int raw = 0;
 	int type_ok = 0;
 	__u32 nhid = 0;
+	int ret;
 
 	if (cmd != RTM_DELROUTE) {
 		req.r.rtm_protocol = RTPROT_BOOT;
@@ -1138,6 +1140,9 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv)
 		req.r.rtm_type = RTN_UNICAST;
 	}
 
+	if (echo_request)
+		req.n.nlmsg_flags |= NLM_F_ECHO|NLM_F_ACK;
+
 	mxrta->rta_type = RTA_METRICS;
 	mxrta->rta_len = RTA_LENGTH(0);
 
@@ -1584,9 +1589,23 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv)
 	if (!type_ok && req.r.rtm_family == AF_MPLS)
 		req.r.rtm_type = RTN_UNICAST;
 
-	if (rtnl_talk(&rth, &req.n, NULL) < 0)
+	if (echo_request)
+		ret = rtnl_talk(&rth, &req.n, &answer);
+	else
+		ret = rtnl_talk(&rth, &req.n, NULL);
+
+	if (ret < 0)
 		return -2;
 
+	if (echo_request) {
+		new_json_obj(json);
+		open_json_object(NULL);
+		print_route(answer, (void *)stdout);
+		close_json_object();
+		delete_json_obj();
+		free(answer);
+	}
+
 	return 0;
 }
 
diff --git a/ip/iprule.c b/ip/iprule.c
index 2d39e01b..2b4ce7fa 100644
--- a/ip/iprule.c
+++ b/ip/iprule.c
@@ -787,6 +787,11 @@ static int iprule_modify(int cmd, int argc, char **argv)
 		.frh.family = preferred_family,
 		.frh.action = FR_ACT_UNSPEC,
 	};
+	struct nlmsghdr *answer;
+	int ret;
+
+	if (echo_request)
+		req.n.nlmsg_flags |= NLM_F_ECHO|NLM_F_ACK;
 
 	if (cmd == RTM_NEWRULE) {
 		if (argc == 0) {
@@ -1016,9 +1021,23 @@ static int iprule_modify(int cmd, int argc, char **argv)
 	if (!table_ok && cmd == RTM_NEWRULE)
 		req.frh.table = RT_TABLE_MAIN;
 
-	if (rtnl_talk(&rth, &req.n, NULL) < 0)
+	if (echo_request)
+		ret = rtnl_talk(&rth, &req.n, &answer);
+	else
+		ret = rtnl_talk(&rth, &req.n, NULL);
+
+	if (ret < 0)
 		return -2;
 
+	if (echo_request) {
+		new_json_obj(json);
+		open_json_object(NULL);
+		print_rule(answer, stdout);
+		close_json_object();
+		delete_json_obj();
+		free(answer);
+	}
+
 	return 0;
 }
 
diff --git a/man/man8/ip.8 b/man/man8/ip.8
index f6adbc77..72227d44 100644
--- a/man/man8/ip.8
+++ b/man/man8/ip.8
@@ -237,6 +237,10 @@ The default JSON format is compact and more efficient to parse but
 hard for most users to read.  This flag adds indentation for
 readability.
 
+.TP
+.BR "\-echo"
+Request the kernel to send the applied configuration back.
+
 .SH IP - COMMAND SYNTAX
 
 .SS
-- 
2.37.2


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

* Re: [PATCH iproute2-next 1/1] ip: add NLM_F_ECHO support
  2022-09-16  3:34 ` [PATCH iproute2-next 1/1] " Hangbin Liu
@ 2022-09-22 23:17   ` David Ahern
  2022-09-23  4:15     ` Hangbin Liu
  0 siblings, 1 reply; 4+ messages in thread
From: David Ahern @ 2022-09-22 23:17 UTC (permalink / raw)
  To: Hangbin Liu, netdev; +Cc: Stephen Hemminger, Guillaume Nault

On 9/15/22 9:34 PM, Hangbin Liu wrote:
> When user space configures the kernel with netlink messages, it can set the
> NLM_F_ECHO flag to request the kernel to send the applied configuration back
> to the caller. This allows user space to retrieve configuration information
> that are filled by the kernel (either because these parameters can only be
> set by the kernel or because user space let the kernel choose a default
> value).
> 
> NLM_F_ACK is also supplied incase the kernel doesn't support NLM_F_ECHO
> and we will wait for the reply forever. Just like the update in
> iplink.c, which I plan to post a patch to kernel later.
> 
> A new parameter -echo is added when user want to get feedback from kernel.
> e.g.
> 
>   # ip -echo addr add 192.168.0.1/24 dev eth1
>   3: eth1    inet 192.168.0.1/24 scope global eth1
>          valid_lft forever preferred_lft forever
>   # ip -j -p -echo addr del 192.168.0.1/24 dev eth1
>   [ {
>           "deleted": true,
>           "index": 3,
>           "dev": "eth1",
>           "family": "inet",
>           "local": "192.168.0.1",
>           "prefixlen": 24,
>           "scope": "global",
>           "label": "eth1",
>           "valid_life_time": 4294967295,
>           "preferred_life_time": 4294967295
>       } ]
> 
> Suggested-by: Guillaume Nault <gnault@redhat.com>
> Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
> ---
>  include/utils.h |  1 +
>  ip/ip.c         |  3 +++
>  ip/ipaddress.c  | 23 +++++++++++++++++++++--
>  ip/iplink.c     | 20 +++++++++++++++++++-
>  ip/ipnexthop.c  | 21 ++++++++++++++++++++-
>  ip/iproute.c    | 21 ++++++++++++++++++++-
>  ip/iprule.c     | 21 ++++++++++++++++++++-
>  man/man8/ip.8   |  4 ++++
>  8 files changed, 108 insertions(+), 6 deletions(-)
> 

> @@ -2416,6 +2416,11 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
>  	__u32 preferred_lft = INFINITY_LIFE_TIME;
>  	__u32 valid_lft = INFINITY_LIFE_TIME;
>  	unsigned int ifa_flags = 0;
> +	struct nlmsghdr *answer;
> +	int ret;
> +
> +	if (echo_request)
> +		req.n.nlmsg_flags |= NLM_F_ECHO|NLM_F_ACK;

fixed the spacing on the flags (all locations) and applied to iproute2-next.


>  
>  	while (argc > 0) {
>  		if (strcmp(*argv, "peer") == 0 ||
> @@ -2597,9 +2602,23 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
>  		return -1;
>  	}
>  
> -	if (rtnl_talk(&rth, &req.n, NULL) < 0)
> +	if (echo_request)
> +		ret = rtnl_talk(&rth, &req.n, &answer);
> +	else
> +		ret = rtnl_talk(&rth, &req.n, NULL);
> +
> +	if (ret < 0)
>  		return -2;
>  
> +	if (echo_request) {
> +		new_json_obj(json);
> +		open_json_object(NULL);
> +		print_addrinfo(answer, stdout);
> +		close_json_object();
> +		delete_json_obj();
> +		free(answer);
> +	}

That list is redundant. I think it can be turned into a util function
that takes an the print function as an input argument.



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

* Re: [PATCH iproute2-next 1/1] ip: add NLM_F_ECHO support
  2022-09-22 23:17   ` David Ahern
@ 2022-09-23  4:15     ` Hangbin Liu
  0 siblings, 0 replies; 4+ messages in thread
From: Hangbin Liu @ 2022-09-23  4:15 UTC (permalink / raw)
  To: David Ahern; +Cc: netdev, Stephen Hemminger, Guillaume Nault

On Thu, Sep 22, 2022 at 04:17:08PM -0700, David Ahern wrote:
> > +	if (echo_request)
> > +		req.n.nlmsg_flags |= NLM_F_ECHO|NLM_F_ACK;
> 
> fixed the spacing on the flags (all locations) and applied to iproute2-next.

Thanks for the fixing!
> >  
> > +	if (echo_request) {
> > +		new_json_obj(json);
> > +		open_json_object(NULL);
> > +		print_addrinfo(answer, stdout);
> > +		close_json_object();
> > +		delete_json_obj();
> > +		free(answer);
> > +	}
> 
> That list is redundant. I think it can be turned into a util function
> that takes an the print function as an input argument.

I will post a patch to remove the redundant code.

Hangbin

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

end of thread, other threads:[~2022-09-23  4:15 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-16  3:34 [PATCH iproute2-next 0/1] ip: add NLM_F_ECHO support Hangbin Liu
2022-09-16  3:34 ` [PATCH iproute2-next 1/1] " Hangbin Liu
2022-09-22 23:17   ` David Ahern
2022-09-23  4:15     ` Hangbin Liu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.