All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nikolay Aleksandrov <razor@blackwall.org>
To: netdev@vger.kernel.org
Cc: roopa@nvidia.com, donaldsharp72@gmail.com, dsahern@gmail.com,
	idosch@idosch.org, Nikolay Aleksandrov <nikolay@nvidia.com>
Subject: [PATCH iproute2-next 12/12] ip: nexthop: add print_cache_nexthop which prints and manages the nh cache
Date: Thu, 30 Sep 2021 14:38:44 +0300	[thread overview]
Message-ID: <20210930113844.1829373-13-razor@blackwall.org> (raw)
In-Reply-To: <20210930113844.1829373-1-razor@blackwall.org>

From: Nikolay Aleksandrov <nikolay@nvidia.com>

Add a new helper print_cache_nexthop replacing print_nexthop which can
update the nexthop cache if the process_cache argument is true. It is
used when monitoring netlink messages to keep the nexthop cache up to
date with nexthop changes happening. For the old callers and anyone
who's just dumping nexthops its _nocache version is used which is a
wrapper for print_cache_nexthop.

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
---
 ip/ip_common.h |  1 -
 ip/ipmonitor.c |  3 ++-
 ip/ipnexthop.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++----
 ip/nh_common.h |  1 +
 4 files changed, 52 insertions(+), 6 deletions(-)

diff --git a/ip/ip_common.h b/ip/ip_common.h
index a02a3b96f7fd..ea04c8ff3dea 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -53,7 +53,6 @@ int print_prefix(struct nlmsghdr *n, void *arg);
 int print_rule(struct nlmsghdr *n, void *arg);
 int print_netconf(struct rtnl_ctrl_data *ctrl,
 		  struct nlmsghdr *n, void *arg);
-int print_nexthop(struct nlmsghdr *n, void *arg);
 int print_nexthop_bucket(struct nlmsghdr *n, void *arg);
 void netns_map_init(void);
 void netns_nsid_socket_init(void);
diff --git a/ip/ipmonitor.c b/ip/ipmonitor.c
index ab1af2ebd6df..0badda4e7812 100644
--- a/ip/ipmonitor.c
+++ b/ip/ipmonitor.c
@@ -22,6 +22,7 @@
 
 #include "utils.h"
 #include "ip_common.h"
+#include "nh_common.h"
 
 static void usage(void) __attribute__((noreturn));
 static int prefix_banner;
@@ -88,7 +89,7 @@ static int accept_msg(struct rtnl_ctrl_data *ctrl,
 	case RTM_NEWNEXTHOP:
 	case RTM_DELNEXTHOP:
 		print_headers(fp, "[NEXTHOP]", ctrl);
-		print_nexthop(n, arg);
+		print_cache_nexthop(n, arg, true);
 		return 0;
 
 	case RTM_NEWNEXTHOPBUCKET:
diff --git a/ip/ipnexthop.c b/ip/ipnexthop.c
index 31462c57d299..b4d44a86429c 100644
--- a/ip/ipnexthop.c
+++ b/ip/ipnexthop.c
@@ -602,6 +602,42 @@ static void ipnh_cache_del(struct nh_entry *nhe)
 	free(nhe);
 }
 
+/* update, add or delete a nexthop entry based on nlmsghdr */
+static int ipnh_cache_process_nlmsg(const struct nlmsghdr *n,
+				    struct nh_entry *new_nhe)
+{
+	struct nh_entry *nhe;
+
+	nhe = ipnh_cache_get(new_nhe->nh_id);
+	switch (n->nlmsg_type) {
+	case RTM_DELNEXTHOP:
+		if (nhe)
+			ipnh_cache_del(nhe);
+		ipnh_destroy_entry(new_nhe);
+		break;
+	case RTM_NEWNEXTHOP:
+		if (!nhe) {
+			nhe = malloc(sizeof(*nhe));
+			if (!nhe) {
+				ipnh_destroy_entry(new_nhe);
+				return -1;
+			}
+		} else {
+			/* this allows us to save 1 allocation on updates by
+			 * reusing the old nh entry, but we need to cleanup its
+			 * internal storage
+			 */
+			ipnh_cache_unlink_entry(nhe);
+			ipnh_destroy_entry(nhe);
+		}
+		memcpy(nhe, new_nhe, sizeof(*nhe));
+		ipnh_cache_link_entry(nhe);
+		break;
+	}
+
+	return 0;
+}
+
 void print_cache_nexthop_id(FILE *fp, const char *fp_prefix, const char *jsobj,
 			    __u32 nh_id)
 {
@@ -618,7 +654,7 @@ void print_cache_nexthop_id(FILE *fp, const char *fp_prefix, const char *jsobj,
 	__print_nexthop_entry(fp, jsobj, nhe, false);
 }
 
-int print_nexthop(struct nlmsghdr *n, void *arg)
+int print_cache_nexthop(struct nlmsghdr *n, void *arg, bool process_cache)
 {
 	struct nhmsg *nhm = NLMSG_DATA(n);
 	FILE *fp = (FILE *)arg;
@@ -651,11 +687,20 @@ int print_nexthop(struct nlmsghdr *n, void *arg)
 	__print_nexthop_entry(fp, NULL, &nhe, n->nlmsg_type == RTM_DELNEXTHOP);
 	print_string(PRINT_FP, NULL, "%s", "\n");
 	fflush(fp);
-	ipnh_destroy_entry(&nhe);
+
+	if (process_cache)
+		ipnh_cache_process_nlmsg(n, &nhe);
+	else
+		ipnh_destroy_entry(&nhe);
 
 	return 0;
 }
 
+static int print_nexthop_nocache(struct nlmsghdr *n, void *arg)
+{
+	return print_cache_nexthop(n, arg, false);
+}
+
 int print_nexthop_bucket(struct nlmsghdr *n, void *arg)
 {
 	struct nhmsg *nhm = NLMSG_DATA(n);
@@ -967,7 +1012,7 @@ static int ipnh_get_id(__u32 id)
 
 	new_json_obj(json);
 
-	if (print_nexthop(answer, (void *)stdout) < 0) {
+	if (print_nexthop_nocache(answer, (void *)stdout) < 0) {
 		free(answer);
 		return -1;
 	}
@@ -1052,7 +1097,7 @@ static int ipnh_list_flush(int argc, char **argv, int action)
 
 	new_json_obj(json);
 
-	if (rtnl_dump_filter(&rth, print_nexthop, stdout) < 0) {
+	if (rtnl_dump_filter(&rth, print_nexthop_nocache, stdout) < 0) {
 		fprintf(stderr, "Dump terminated\n");
 		return -2;
 	}
diff --git a/ip/nh_common.h b/ip/nh_common.h
index b448f1b5530b..4d6677e62e33 100644
--- a/ip/nh_common.h
+++ b/ip/nh_common.h
@@ -48,5 +48,6 @@ struct nh_entry {
 
 void print_cache_nexthop_id(FILE *fp, const char *fp_prefix, const char *jsobj,
 			    __u32 nh_id);
+int print_cache_nexthop(struct nlmsghdr *n, void *arg, bool process_cache);
 
 #endif /* __NH_COMMON_H__ */
-- 
2.31.1


  parent reply	other threads:[~2021-09-30 11:39 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-30 11:38 [PATCH iproute2-next 00/12] ip: nexthop: cache nexthops and print routes' nh info Nikolay Aleksandrov
2021-09-30 11:38 ` [PATCH iproute2-next 01/12] ip: print_rta_if takes ifindex as device argument instead of attribute Nikolay Aleksandrov
2021-09-30 11:38 ` [PATCH iproute2-next 02/12] ip: export print_rta_gateway version which outputs prepared gateway string Nikolay Aleksandrov
2021-09-30 11:38 ` [PATCH iproute2-next 03/12] ip: nexthop: add resilient group structure Nikolay Aleksandrov
2021-09-30 11:38 ` [PATCH iproute2-next 04/12] ip: nexthop: split print_nh_res_group into parse and print parts Nikolay Aleksandrov
2021-09-30 11:38 ` [PATCH iproute2-next 05/12] ip: nexthop: add nh entry structure Nikolay Aleksandrov
2021-09-30 11:38 ` [PATCH iproute2-next 06/12] ip: nexthop: parse attributes into nh entry structure before printing Nikolay Aleksandrov
2021-09-30 11:38 ` [PATCH iproute2-next 07/12] ip: nexthop: factor out print_nexthop's nh entry printing Nikolay Aleksandrov
2021-09-30 11:38 ` [PATCH iproute2-next 08/12] ip: nexthop: factor out ipnh_get_id rtnl talk into a helper Nikolay Aleksandrov
2021-09-30 11:38 ` [PATCH iproute2-next 09/12] ip: nexthop: add cache helpers Nikolay Aleksandrov
2021-10-04  0:33   ` David Ahern
2021-10-04  9:03     ` [PATCH iproute2-next] ip: nexthop: keep cache netlink socket open Nikolay Aleksandrov
2021-10-05 14:35       ` David Ahern
2021-09-30 11:38 ` [PATCH iproute2-next 10/12] ip: nexthop: add a helper which retrieves and prints cached nh entry Nikolay Aleksandrov
2021-09-30 11:38 ` [PATCH iproute2-next 11/12] ip: route: print and cache detailed nexthop information when requested Nikolay Aleksandrov
2021-09-30 11:38 ` Nikolay Aleksandrov [this message]
2021-10-04  0:40 ` [PATCH iproute2-next 00/12] ip: nexthop: cache nexthops and print routes' nh info patchwork-bot+netdevbpf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210930113844.1829373-13-razor@blackwall.org \
    --to=razor@blackwall.org \
    --cc=donaldsharp72@gmail.com \
    --cc=dsahern@gmail.com \
    --cc=idosch@idosch.org \
    --cc=netdev@vger.kernel.org \
    --cc=nikolay@nvidia.com \
    --cc=roopa@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.