lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1409913328-9003-1-git-send-email-vadim4j@gmail.com>
Date:	Fri,  5 Sep 2014 13:35:28 +0300
From:	Vadim Kochan <vadim4j@...il.com>
To:	netdev@...r.kernel.org
Cc:	Vadim Kochan <vadim4j@...il.com>
Subject: [PATCH v2] iproute2: Refactor: using new nl_msg struct for the all Netlink handlers

It will easy to extend with new parameters in future.

Signed-off-by: Vadim Kochan <vadim4j@...il.com>
---
 bridge/br_common.h   | 10 +++------
 bridge/fdb.c         |  5 +++--
 bridge/link.c        |  6 +++---
 bridge/mdb.c         |  5 +++--
 bridge/monitor.c     | 12 +++++------
 bridge/vlan.c        |  7 +++----
 genl/ctrl.c          | 10 +++++----
 genl/genl.c          |  5 ++---
 genl/genl_utils.h    |  2 +-
 include/libnetlink.h |  9 ++++++--
 include/ll_map.h     |  3 +--
 ip/ip_common.h       | 32 +++++++++--------------------
 ip/ipaddress.c       | 52 ++++++++++++++++++++++++----------------------
 ip/ipaddrlabel.c     |  8 +++++---
 ip/ipl2tp.c          |  8 ++++----
 ip/iplink.c          |  8 +++++---
 ip/ipmonitor.c       | 26 +++++++++++------------
 ip/ipmroute.c        |  5 +++--
 ip/ipneigh.c         |  5 +++--
 ip/ipnetconf.c       |  5 +++--
 ip/ipntable.c        |  5 +++--
 ip/ipprefix.c        |  5 +++--
 ip/iproute.c         | 28 ++++++++++++++++---------
 ip/iprule.c          |  8 +++++---
 ip/iptoken.c         |  3 ++-
 ip/rtmon.c           |  6 +++---
 ip/tcp_metrics.c     | 10 +++++----
 ip/xfrm.h            |  6 ++----
 ip/xfrm_monitor.c    | 58 ++++++++++++++++++++++++++--------------------------
 ip/xfrm_policy.c     | 15 +++++++-------
 ip/xfrm_state.c      | 19 +++++++++--------
 lib/libnetlink.c     | 16 ++++++++++++---
 lib/ll_map.c         |  4 ++--
 misc/ifstat.c        |  4 ++--
 tc/m_action.c        | 17 ++++++++-------
 tc/tc_class.c        |  6 +++---
 tc/tc_common.h       |  8 ++++----
 tc/tc_filter.c       |  7 +++----
 tc/tc_monitor.c      | 14 ++++++-------
 tc/tc_qdisc.c        |  7 +++----
 40 files changed, 248 insertions(+), 221 deletions(-)

diff --git a/bridge/br_common.h b/bridge/br_common.h
index 12fce3e..620c045 100644
--- a/bridge/br_common.h
+++ b/bridge/br_common.h
@@ -1,10 +1,6 @@
-extern int print_linkinfo(const struct sockaddr_nl *who,
-			  struct nlmsghdr *n,
-			  void *arg);
-extern int print_fdb(const struct sockaddr_nl *who,
-		     struct nlmsghdr *n, void *arg);
-extern int print_mdb(const struct sockaddr_nl *who,
-		     struct nlmsghdr *n, void *arg);
+extern int print_linkinfo(struct nl_msg *msg, void *arg);
+extern int print_fdb(struct nl_msg *msg, void *arg);
+extern int print_mdb(struct nl_msg *msg, void *arg);
 
 extern int do_fdb(int argc, char **argv);
 extern int do_mdb(int argc, char **argv);
diff --git a/bridge/fdb.c b/bridge/fdb.c
index a55fac1..1b66d48 100644
--- a/bridge/fdb.c
+++ b/bridge/fdb.c
@@ -58,9 +58,10 @@ static const char *state_n2a(unsigned s)
 	return buf;
 }
 
-int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+int print_fdb(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct ndmsg *r = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr * tb[NDA_MAX+1];
diff --git a/bridge/link.c b/bridge/link.c
index 90d9e7f..67ad8da 100644
--- a/bridge/link.c
+++ b/bridge/link.c
@@ -96,10 +96,10 @@ static void print_hwmode(FILE *f, __u16 mode)
 		fprintf(f, "hwmode %s ", hw_mode[mode]);
 }
 
-int print_linkinfo(const struct sockaddr_nl *who,
-		   struct nlmsghdr *n, void *arg)
+int print_linkinfo(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	int len = n->nlmsg_len;
 	struct ifinfomsg *ifi = NLMSG_DATA(n);
 	struct rtattr * tb[IFLA_MAX+1];
diff --git a/bridge/mdb.c b/bridge/mdb.c
index 6c1c938..3678045 100644
--- a/bridge/mdb.c
+++ b/bridge/mdb.c
@@ -77,9 +77,10 @@ static void br_print_mdb_entry(FILE *f, int ifindex, struct rtattr *attr)
 	}
 }
 
-int print_mdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+int print_mdb(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct br_port_msg *r = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr * tb[MDBA_MAX+1];
diff --git a/bridge/monitor.c b/bridge/monitor.c
index 76e7d47..e1a5c2b 100644
--- a/bridge/monitor.c
+++ b/bridge/monitor.c
@@ -46,10 +46,10 @@ static int show_mark(FILE *fp, const struct nlmsghdr *n)
 	return 0;
 }
 
-static int accept_msg(const struct sockaddr_nl *who,
-		      struct nlmsghdr *n, void *arg)
+static int accept_msg(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 
 	if (timestamp)
 		print_timestamp(fp);
@@ -60,19 +60,19 @@ static int accept_msg(const struct sockaddr_nl *who,
 		if (prefix_banner)
 			fprintf(fp, "[LINK]");
 
-		return print_linkinfo(who, n, arg);
+		return print_linkinfo(msg, arg);
 
 	case RTM_NEWNEIGH:
 	case RTM_DELNEIGH:
 		if (prefix_banner)
 			fprintf(fp, "[NEIGH]");
-		return print_fdb(who, n, arg);
+		return print_fdb(msg, arg);
 
 	case RTM_NEWMDB:
 	case RTM_DELMDB:
 		if (prefix_banner)
 			fprintf(fp, "[MDB]");
-		return print_mdb(who, n, arg);
+		return print_mdb(msg, arg);
 
 	case 15:
 		return show_mark(fp, n);
diff --git a/bridge/vlan.c b/bridge/vlan.c
index 3bd7b0d..c8ba98d 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -101,11 +101,10 @@ static int vlan_modify(int cmd, int argc, char **argv)
 	return 0;
 }
 
-static int print_vlan(const struct sockaddr_nl *who,
-		      struct nlmsghdr *n,
-		      void *arg)
+static int print_vlan(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct ifinfomsg *ifm = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr * tb[IFLA_MAX+1];
diff --git a/genl/ctrl.c b/genl/ctrl.c
index 3546129..f8a3ce5 100644
--- a/genl/ctrl.c
+++ b/genl/ctrl.c
@@ -177,14 +177,14 @@ static int print_ctrl_grp(FILE *fp, struct rtattr *arg, __u32 ctrl_ver)
 /*
  * The controller sends one nlmsg per family
 */
-static int print_ctrl(const struct sockaddr_nl *who, struct nlmsghdr *n,
-		      void *arg)
+static int print_ctrl(struct nl_msg *msg, void *arg)
 {
+	struct nlmsghdr *n = msg->n;
 	struct rtattr *tb[CTRL_ATTR_MAX + 1];
 	struct genlmsghdr *ghdr = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr *attrs;
-	FILE *fp = (FILE *) arg;
+	FILE *fp = (FILE *)arg;
 	__u32 ctrl_v = 0x1;
 
 	if (n->nlmsg_type !=  GENL_ID_CTRL) {
@@ -292,6 +292,7 @@ static int ctrl_list(int cmd, int argc, char **argv)
 		struct nlmsghdr         n;
 		char                    buf[4096];
 	} req;
+	struct nl_msg msg = {};
 
 	memset(&req, 0, sizeof(req));
 
@@ -339,7 +340,8 @@ static int ctrl_list(int cmd, int argc, char **argv)
 			goto ctrl_done;
 		}
 
-		if (print_ctrl(NULL, nlh, (void *) stdout) < 0) {
+		msg.n = nlh;
+		if (print_ctrl(&msg, (void *)stdout) < 0) {
 			fprintf(stderr, "Dump terminated\n");
 			goto ctrl_done;
 		}
diff --git a/genl/genl.c b/genl/genl.c
index 49b6596..4d643d5 100644
--- a/genl/genl.c
+++ b/genl/genl.c
@@ -36,10 +36,9 @@ static void *BODY;
 static struct genl_util * genl_list;
 
 
-static int print_nofopt(const struct sockaddr_nl *who, struct nlmsghdr *n,
-			void *arg)
+static int print_nofopt(struct nl_msg *msg, void *arg)
 {
-	fprintf((FILE *) arg, "unknown genl type ..\n");
+	fprintf((FILE *)arg, "unknown genl type ..\n");
 	return 0;
 }
 
diff --git a/genl/genl_utils.h b/genl/genl_utils.h
index 85b5183..fd04de2 100644
--- a/genl/genl_utils.h
+++ b/genl/genl_utils.h
@@ -9,7 +9,7 @@ struct genl_util
 	struct  genl_util *next;
 	char	name[16];
 	int	(*parse_genlopt)(struct genl_util *fu, int argc, char **argv);
-	int	(*print_genlopt)(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
+	int	(*print_genlopt)(struct nl_msg *msg, void *arg);
 };
 
 extern int genl_ctrl_resolve_family(const char *family);
diff --git a/include/libnetlink.h b/include/libnetlink.h
index fe7d5d3..da476a1 100644
--- a/include/libnetlink.h
+++ b/include/libnetlink.h
@@ -39,8 +39,13 @@ extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req,
 			     int len)
 	__attribute__((warn_unused_result));
 
-typedef int (*rtnl_filter_t)(const struct sockaddr_nl *,
-			     struct nlmsghdr *n, void *);
+struct nl_msg
+{
+	struct sockaddr_nl *who;
+	struct nlmsghdr *n;
+};
+
+typedef int (*rtnl_filter_t)(struct nl_msg *msg, void *arg);
 
 struct rtnl_dump_filter_arg
 {
diff --git a/include/ll_map.h b/include/ll_map.h
index 4c78498..075e4b4 100644
--- a/include/ll_map.h
+++ b/include/ll_map.h
@@ -1,8 +1,7 @@
 #ifndef __LL_MAP_H__
 #define __LL_MAP_H__ 1
 
-extern int ll_remember_index(const struct sockaddr_nl *who,
-			     struct nlmsghdr *n, void *arg);
+extern int ll_remember_index(struct nl_msg *msg, void *arg);
 
 extern void ll_init_map(struct rtnl_handle *rth);
 extern unsigned ll_name_to_index(const char *name);
diff --git a/ip/ip_common.h b/ip/ip_common.h
index e56d1ac..8aaa770 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -1,16 +1,9 @@
 extern int get_operstate(const char *name);
-extern int print_linkinfo(const struct sockaddr_nl *who,
-			  struct nlmsghdr *n,
-			  void *arg);
-extern int print_addrinfo(const struct sockaddr_nl *who,
-			  struct nlmsghdr *n,
-			  void *arg);
-extern int print_addrlabel(const struct sockaddr_nl *who,
-			   struct nlmsghdr *n, void *arg);
-extern int print_neigh(const struct sockaddr_nl *who,
-		       struct nlmsghdr *n, void *arg);
-extern int print_ntable(const struct sockaddr_nl *who,
-			struct nlmsghdr *n, void *arg);
+extern int print_linkinfo(struct nl_msg *msg, void *arg);
+extern int print_addrinfo(struct nl_msg *msg, void *arg);
+extern int print_addrlabel(struct nl_msg *msg, void *arg);
+extern int print_neigh(struct nl_msg *msg, void *arg);
+extern int print_ntable(struct nl_msg *msg, void *arg);
 extern int ipaddr_list(int argc, char **argv);
 extern int ipaddr_list_link(int argc, char **argv);
 extern int iproute_monitor(int argc, char **argv);
@@ -21,16 +14,11 @@ void ipaddr_get_vf_rate(int, int *, int *, int);
 extern void ipaddr_reset_filter(int);
 extern void ipneigh_reset_filter(void);
 extern void ipntable_reset_filter(void);
-extern int print_route(const struct sockaddr_nl *who,
-		       struct nlmsghdr *n, void *arg);
-extern int print_mroute(const struct sockaddr_nl *who,
-			struct nlmsghdr *n, void *arg);
-extern int print_prefix(const struct sockaddr_nl *who,
-			struct nlmsghdr *n, void *arg);
-extern int print_rule(const struct sockaddr_nl *who,
-		      struct nlmsghdr *n, void *arg);
-extern int print_netconf(const struct sockaddr_nl *who,
-			 struct nlmsghdr *n, void *arg);
+extern int print_route(struct nl_msg *msg, void *arg);
+extern int print_mroute(struct nl_msg *msg, void *arg);
+extern int print_prefix(struct nl_msg *msg, void *arg);
+extern int print_rule(struct nl_msg *msg, void *arg);
+extern int print_netconf(struct nl_msg *msg, void *arg);
 extern int do_ipaddr(int argc, char **argv);
 extern int do_ipaddrlabel(int argc, char **argv);
 extern int do_iproute(int argc, char **argv);
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 245df39..3e28b03 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -425,10 +425,10 @@ static void print_link_stats(FILE *fp, const struct rtnl_link_stats *s,
 	}
 }
 
-int print_linkinfo(const struct sockaddr_nl *who,
-		   struct nlmsghdr *n, void *arg)
+int print_linkinfo(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct ifinfomsg *ifi = NLMSG_DATA(n);
 	struct rtattr * tb[IFLA_MAX+1];
 	int len = n->nlmsg_len;
@@ -597,10 +597,10 @@ static unsigned int get_ifa_flags(struct ifaddrmsg *ifa,
 				ifa->ifa_flags;
 }
 
-int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
-		   void *arg)
+int print_addrinfo(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct ifaddrmsg *ifa = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	int deprecated = 0;
@@ -796,26 +796,24 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
 	return 0;
 }
 
-static int print_addrinfo_primary(const struct sockaddr_nl *who,
-				  struct nlmsghdr *n, void *arg)
+static int print_addrinfo_primary(struct nl_msg *msg, void *arg)
 {
-	struct ifaddrmsg *ifa = NLMSG_DATA(n);
+	struct ifaddrmsg *ifa = NLMSG_DATA(msg->n);
 
 	if (ifa->ifa_flags & IFA_F_SECONDARY)
 		return 0;
 
-	return print_addrinfo(who, n, arg);
+	return print_addrinfo(msg, arg);
 }
 
-static int print_addrinfo_secondary(const struct sockaddr_nl *who,
-				    struct nlmsghdr *n, void *arg)
+static int print_addrinfo_secondary(struct nl_msg *msg, void *arg)
 {
-	struct ifaddrmsg *ifa = NLMSG_DATA(n);
+	struct ifaddrmsg *ifa = NLMSG_DATA(msg->n);
 
 	if (!(ifa->ifa_flags & IFA_F_SECONDARY))
 		return 0;
 
-	return print_addrinfo(who, n, arg);
+	return print_addrinfo(msg, arg);
 }
 
 struct nlmsg_list
@@ -835,6 +833,7 @@ static int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *
 	for ( ;ainfo ;  ainfo = ainfo->next) {
 		struct nlmsghdr *n = &ainfo->h;
 		struct ifaddrmsg *ifa = NLMSG_DATA(n);
+		struct nl_msg msg = { .n = n };
 
 		if (n->nlmsg_type != RTM_NEWADDR)
 			continue;
@@ -846,15 +845,15 @@ static int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *
 		    (filter.family && filter.family != ifa->ifa_family))
 			continue;
 
-		print_addrinfo(NULL, n, fp);
+		print_addrinfo(&msg, fp);
 	}
 	return 0;
 }
 
 
-static int store_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n,
-		       void *arg)
+static int store_nlmsg(struct nl_msg *msg, void *arg)
 {
+	struct nlmsghdr *n = msg->n;
 	struct nlmsg_chain *lchain = (struct nlmsg_chain *)arg;
 	struct nlmsg_list *h;
 
@@ -871,7 +870,7 @@ static int store_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n,
 		lchain->head = h;
 	lchain->tail = h;
 
-	ll_remember_index(who, n, NULL);
+	ll_remember_index(msg, arg);
 	return 0;
 }
 
@@ -914,9 +913,9 @@ static int ipadd_dump_check_magic(void)
 	return 0;
 }
 
-static int save_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n,
-		       void *arg)
+static int save_nlmsg(struct nl_msg *msg, void *arg)
 {
+	struct nlmsghdr *n = msg->n;
 	int ret;
 
 	ret = write(STDOUT_FILENO, n, n->nlmsg_len);
@@ -928,12 +927,12 @@ static int save_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n,
 	return ret == n->nlmsg_len ? 0 : ret;
 }
 
-static int show_handler(const struct sockaddr_nl *nl, struct nlmsghdr *n, void *arg)
+static int show_handler(struct nl_msg *msg, void *arg)
 {
-	struct ifaddrmsg *ifa = NLMSG_DATA(n);
+	struct ifaddrmsg *ifa = NLMSG_DATA(msg->n);
 
 	printf("if%d:\n", ifa->ifa_index);
-	print_addrinfo(NULL, n, stdout);
+	print_addrinfo(msg, (void *)stdout);
 	return 0;
 }
 
@@ -945,8 +944,9 @@ static int ipaddr_showdump(void)
 	exit(rtnl_from_file(stdin, &show_handler, NULL));
 }
 
-static int restore_handler(const struct sockaddr_nl *nl, struct nlmsghdr *n, void *arg)
+static int restore_handler(struct nl_msg *msg, void *arg)
 {
+	struct nlmsghdr *n = msg->n;
 	int ret;
 
 	n->nlmsg_flags |= NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
@@ -1282,7 +1282,9 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 	}
 
 	for (l = linfo.head; l; l = l->next) {
-		if (no_link || print_linkinfo(NULL, &l->h, stdout) == 0) {
+		struct nl_msg msg = { .n = &l->h };
+
+		if (no_link || print_linkinfo(&msg, (void *)stdout) == 0) {
 			struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
 			if (filter.family != AF_PACKET)
 				print_selected_addrinfo(ifi->ifi_index,
diff --git a/ip/ipaddrlabel.c b/ip/ipaddrlabel.c
index b34dd8b..c46ad41 100644
--- a/ip/ipaddrlabel.c
+++ b/ip/ipaddrlabel.c
@@ -53,9 +53,10 @@ static void usage(void)
 	exit(-1);
 }
 
-int print_addrlabel(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+int print_addrlabel(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct ifaddrlblmsg *ifal = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr *tb[IFAL_MAX+1];
@@ -189,8 +190,9 @@ static int ipaddrlabel_modify(int cmd, int argc, char **argv)
 }
 
 
-static int flush_addrlabel(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+static int flush_addrlabel(struct nl_msg *msg, void *arg)
 {
+	struct nlmsghdr *n = msg->n;
 	struct rtnl_handle rth2;
 	struct rtmsg *r = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
diff --git a/ip/ipl2tp.c b/ip/ipl2tp.c
index 5cd8632..eef4428 100644
--- a/ip/ipl2tp.c
+++ b/ip/ipl2tp.c
@@ -354,9 +354,9 @@ static int get_response(struct nlmsghdr *n, void *arg)
 	return 0;
 }
 
-static int session_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+static int session_nlmsg(struct nl_msg *msg, void *arg)
 {
-	int ret = get_response(n, arg);
+	int ret = get_response(msg->n, arg);
 
 	if (ret == 0)
 		print_session(arg);
@@ -388,9 +388,9 @@ static int get_session(struct l2tp_data *p)
 	return 0;
 }
 
-static int tunnel_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+static int tunnel_nlmsg(struct nl_msg *msg, void *arg)
 {
-	int ret = get_response(n, arg);
+	int ret = get_response(msg->n, arg);
 
 	if (ret == 0)
 		print_tunnel(arg);
diff --git a/ip/iplink.c b/ip/iplink.c
index ea06871..121e405 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -174,9 +174,9 @@ static int get_addr_gen_mode(const char *mode)
 #if IPLINK_IOCTL_COMPAT
 static int have_rtnl_newlink = -1;
 
-static int accept_msg(const struct sockaddr_nl *who,
-		      struct nlmsghdr *n, void *arg)
+static int accept_msg(struct nl_msg *msg, void *arg)
 {
+	struct nlmsghdr *n = msg->n;
 	struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(n);
 
 	if (n->nlmsg_type == NLMSG_ERROR &&
@@ -734,6 +734,7 @@ int iplink_get(unsigned int flags, char *name, __u32 filt_mask)
 	int len;
 	struct iplink_req req;
 	char answer[16384];
+	struct nl_msg msg = {};
 
 	memset(&req, 0, sizeof(req));
 
@@ -756,7 +757,8 @@ int iplink_get(unsigned int flags, char *name, __u32 filt_mask)
 	if (rtnl_talk(&rth, &req.n, 0, 0, (struct nlmsghdr *)answer) < 0)
 		return -2;
 
-	print_linkinfo(NULL, (struct nlmsghdr *)answer, stdout);
+	msg.n = (struct nlmsghdr *)answer;
+	print_linkinfo(&msg, (void *)stdout);
 
 	return 0;
 }
diff --git a/ip/ipmonitor.c b/ip/ipmonitor.c
index 70f2a7a..c7de38f 100644
--- a/ip/ipmonitor.c
+++ b/ip/ipmonitor.c
@@ -36,10 +36,10 @@ static void usage(void)
 	exit(-1);
 }
 
-static int accept_msg(const struct sockaddr_nl *who,
-		      struct nlmsghdr *n, void *arg)
+static int accept_msg(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 
 	if (timestamp)
 		print_timestamp(fp);
@@ -57,32 +57,32 @@ static int accept_msg(const struct sockaddr_nl *who,
 		    r->rtm_family == RTNL_FAMILY_IP6MR) {
 			if (prefix_banner)
 				fprintf(fp, "[MROUTE]");
-			print_mroute(who, n, arg);
+			print_mroute(msg, arg);
 			return 0;
 		} else {
 			if (prefix_banner)
 				fprintf(fp, "[ROUTE]");
-			print_route(who, n, arg);
+			print_route(msg, arg);
 			return 0;
 		}
 	}
 	if (n->nlmsg_type == RTM_NEWLINK || n->nlmsg_type == RTM_DELLINK) {
-		ll_remember_index(who, n, NULL);
+		ll_remember_index(msg, arg);
 		if (prefix_banner)
 			fprintf(fp, "[LINK]");
-		print_linkinfo(who, n, arg);
+		print_linkinfo(msg, arg);
 		return 0;
 	}
 	if (n->nlmsg_type == RTM_NEWADDR || n->nlmsg_type == RTM_DELADDR) {
 		if (prefix_banner)
 			fprintf(fp, "[ADDR]");
-		print_addrinfo(who, n, arg);
+		print_addrinfo(msg, arg);
 		return 0;
 	}
 	if (n->nlmsg_type == RTM_NEWADDRLABEL || n->nlmsg_type == RTM_DELADDRLABEL) {
 		if (prefix_banner)
 			fprintf(fp, "[ADDRLABEL]");
-		print_addrlabel(who, n, arg);
+		print_addrlabel(msg, arg);
 		return 0;
 	}
 	if (n->nlmsg_type == RTM_NEWNEIGH || n->nlmsg_type == RTM_DELNEIGH ||
@@ -96,25 +96,25 @@ static int accept_msg(const struct sockaddr_nl *who,
 
 		if (prefix_banner)
 			fprintf(fp, "[NEIGH]");
-		print_neigh(who, n, arg);
+		print_neigh(msg, arg);
 		return 0;
 	}
 	if (n->nlmsg_type == RTM_NEWPREFIX) {
 		if (prefix_banner)
 			fprintf(fp, "[PREFIX]");
-		print_prefix(who, n, arg);
+		print_prefix(msg, arg);
 		return 0;
 	}
 	if (n->nlmsg_type == RTM_NEWRULE || n->nlmsg_type == RTM_DELRULE) {
 		if (prefix_banner)
 			fprintf(fp, "[RULE]");
-		print_rule(who, n, arg);
+		print_rule(msg, arg);
 		return 0;
 	}
 	if (n->nlmsg_type == RTM_NEWNETCONF) {
 		if (prefix_banner)
 			fprintf(fp, "[NETCONF]");
-		print_netconf(who, n, arg);
+		print_netconf(msg, arg);
 		return 0;
 	}
 	if (n->nlmsg_type == 15) {
diff --git a/ip/ipmroute.c b/ip/ipmroute.c
index be93a98..97d74f4 100644
--- a/ip/ipmroute.c
+++ b/ip/ipmroute.c
@@ -53,9 +53,10 @@ struct rtfilter
 	inet_prefix msrc;
 } filter;
 
-int print_mroute(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+int print_mroute(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct rtmsg *r = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr * tb[RTA_MAX+1];
diff --git a/ip/ipneigh.c b/ip/ipneigh.c
index 71a4100..311336f 100644
--- a/ip/ipneigh.c
+++ b/ip/ipneigh.c
@@ -181,9 +181,10 @@ static int ipneigh_modify(int cmd, int flags, int argc, char **argv)
 }
 
 
-int print_neigh(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+int print_neigh(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct ndmsg *r = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr * tb[NDA_MAX+1];
diff --git a/ip/ipnetconf.c b/ip/ipnetconf.c
index 0e44cc8..d7c79dc 100644
--- a/ip/ipnetconf.c
+++ b/ip/ipnetconf.c
@@ -40,9 +40,10 @@ static void usage(void)
 
 #define NETCONF_RTA(r)	((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct netconfmsg))))
 
-int print_netconf(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+int print_netconf(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct netconfmsg *ncm = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr *tb[NETCONFA_MAX+1];
diff --git a/ip/ipntable.c b/ip/ipntable.c
index ea7ca2d..0ca0d29 100644
--- a/ip/ipntable.c
+++ b/ip/ipntable.c
@@ -349,9 +349,10 @@ static const char *ntable_strtime_delta(__u32 msec)
 	return str;
 }
 
-int print_ntable(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+int print_ntable(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct ndtmsg *ndtm = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr *tb[NDTA_MAX+1];
diff --git a/ip/ipprefix.c b/ip/ipprefix.c
index 02c0efc..ffec211 100644
--- a/ip/ipprefix.c
+++ b/ip/ipprefix.c
@@ -35,9 +35,10 @@
 #define IF_PREFIX_ONLINK	0x01
 #define IF_PREFIX_AUTOCONF	0x02
 
-int print_prefix(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+int print_prefix(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct prefixmsg *prefix = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr * tb[RTA_MAX+1];
diff --git a/ip/iproute.c b/ip/iproute.c
index d77b1e3..4eee858 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -280,9 +280,10 @@ static int calc_host_len(const struct rtmsg *r)
 		return -1;
 }
 
-int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+int print_route(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct rtmsg *r = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr * tb[RTA_MAX+1];
@@ -1078,9 +1079,9 @@ static int iproute_flush_cache(void)
 
 static __u32 route_dump_magic = 0x45311224;
 
-static int save_route(const struct sockaddr_nl *who, struct nlmsghdr *n,
-		      void *arg)
+static int save_route(struct nl_msg *msg, void *arg)
 {
+	struct nlmsghdr *n = msg->n;
 	int ret;
 	int len = n->nlmsg_len;
 	struct rtmsg *r = NLMSG_DATA(n);
@@ -1382,6 +1383,7 @@ static int iproute_get(int argc, char **argv)
 	int connected = 0;
 	int from_ok = 0;
 	unsigned int mark = 0;
+	struct nl_msg msg = {};
 
 	memset(&req, 0, sizeof(req));
 
@@ -1483,12 +1485,13 @@ static int iproute_get(int argc, char **argv)
 	if (rtnl_talk(&rth, &req.n, 0, 0, &req.n) < 0)
 		exit(2);
 
+	msg.n = &req.n;
 	if (connected && !from_ok) {
 		struct rtmsg *r = NLMSG_DATA(&req.n);
 		int len = req.n.nlmsg_len;
 		struct rtattr * tb[RTA_MAX+1];
 
-		if (print_route(NULL, &req.n, (void*)stdout) < 0) {
+		if (print_route(&msg, (void *)stdout) < 0) {
 			fprintf(stderr, "An error :-)\n");
 			exit(1);
 		}
@@ -1525,7 +1528,7 @@ static int iproute_get(int argc, char **argv)
 			exit(2);
 	}
 
-	if (print_route(NULL, &req.n, (void*)stdout) < 0) {
+	if (print_route(&msg, (void *)stdout) < 0) {
 		fprintf(stderr, "An error :-)\n");
 		exit(1);
 	}
@@ -1533,9 +1536,9 @@ static int iproute_get(int argc, char **argv)
 	exit(0);
 }
 
-static int restore_handler(const struct sockaddr_nl *nl, struct nlmsghdr *n,
-			   void *arg)
+static int restore_handler(struct nl_msg *msg, void *arg)
 {
+	struct nlmsghdr *n = msg->n;
 	int ret;
 
 	n->nlmsg_flags |= NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
@@ -1576,9 +1579,14 @@ static int iproute_restore(void)
 	exit(rtnl_from_file(stdin, &restore_handler, NULL));
 }
 
-static int show_handler(const struct sockaddr_nl *nl, struct nlmsghdr *n, void *arg)
+static int show_handler(struct nl_msg *msg, void *arg)
 {
-	print_route(nl, n, stdout);
+	struct nl_msg rt_param = {};
+
+	rt_param.n = msg->n;
+       	rt_param.who = msg->who;
+
+	print_route(&rt_param, (void *)stdout);
 	return 0;
 }
 
diff --git a/ip/iprule.c b/ip/iprule.c
index 366878e..a272795 100644
--- a/ip/iprule.c
+++ b/ip/iprule.c
@@ -46,9 +46,10 @@ static void usage(void)
 	exit(-1);
 }
 
-int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+int print_rule(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct rtmsg *r = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	int host_len = -1;
@@ -392,8 +393,9 @@ static int iprule_modify(int cmd, int argc, char **argv)
 }
 
 
-static int flush_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+static int flush_rule(struct nl_msg *msg, void *arg)
 {
+	struct nlmsghdr *n = msg->n;
 	struct rtnl_handle rth2;
 	struct rtmsg *r = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
diff --git a/ip/iptoken.c b/ip/iptoken.c
index 5689c2e..f8bf02c 100644
--- a/ip/iptoken.c
+++ b/ip/iptoken.c
@@ -42,8 +42,9 @@ static void usage(void)
 	exit(-1);
 }
 
-static int print_token(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+static int print_token(struct nl_msg *msg, void *arg)
 {
+	struct nlmsghdr *n = msg->n;
 	struct rtnl_dump_args *args = arg;
 	FILE *fp = args->fp;
 	int ifindex = args->ifindex;
diff --git a/ip/rtmon.c b/ip/rtmon.c
index 9227eac..e43dcc7 100644
--- a/ip/rtmon.c
+++ b/ip/rtmon.c
@@ -45,10 +45,10 @@ static void write_stamp(FILE *fp)
 	fwrite((void*)n1, 1, NLMSG_ALIGN(n1->nlmsg_len), fp);
 }
 
-static int dump_msg(const struct sockaddr_nl *who, struct nlmsghdr *n,
-		    void *arg)
+static int dump_msg(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	if (!init_phase)
 		write_stamp(fp);
 	fwrite((void*)n, 1, NLMSG_ALIGN(n->nlmsg_len), fp);
diff --git a/ip/tcp_metrics.c b/ip/tcp_metrics.c
index e0f0344..d25a657 100644
--- a/ip/tcp_metrics.c
+++ b/ip/tcp_metrics.c
@@ -88,10 +88,10 @@ static int flush_update(void)
 	return 0;
 }
 
-static int process_msg(const struct sockaddr_nl *who, struct nlmsghdr *n,
-		       void *arg)
+static int process_msg(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE *) arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct genlmsghdr *ghdr;
 	struct rtattr *attrs[TCP_METRICS_ATTR_MAX + 1], *a;
 	int len = n->nlmsg_len;
@@ -295,6 +295,7 @@ static int tcpm_do_cmd(int cmd, int argc, char **argv)
 	TCPM_REQUEST(req, 1024, TCP_METRICS_CMD_GET, NLM_F_REQUEST);
 	int atype = -1, stype = -1;
 	int ack;
+	struct nl_msg msg = {};
 
 	memset(&f, 0, sizeof(f));
 	f.daddr.bitlen = -1;
@@ -455,7 +456,8 @@ static int tcpm_do_cmd(int cmd, int argc, char **argv)
 	} else if (atype >= 0) {
 		if (rtnl_talk(&grth, &req.n, 0, 0, &req.n) < 0)
 			return -2;
-		if (process_msg(NULL, &req.n, stdout) < 0) {
+		msg.n = &req.n;
+		if (process_msg(&msg, (void *)stdout) < 0) {
 			fprintf(stderr, "Dump terminated\n");
 			exit(1);
 		}
diff --git a/ip/xfrm.h b/ip/xfrm.h
index 773c92e..1b170f5 100644
--- a/ip/xfrm.h
+++ b/ip/xfrm.h
@@ -107,10 +107,8 @@ struct xfrm_filter {
 
 extern struct xfrm_filter filter;
 
-int xfrm_state_print(const struct sockaddr_nl *who, struct nlmsghdr *n,
-		     void *arg);
-int xfrm_policy_print(const struct sockaddr_nl *who, struct nlmsghdr *n,
-		      void *arg);
+int xfrm_state_print(struct nl_msg *msg, void *arg);
+int xfrm_policy_print(struct nl_msg *msg, void *arg);
 int do_xfrm_state(int argc, char **argv);
 int do_xfrm_policy(int argc, char **argv);
 int do_xfrm_monitor(int argc, char **argv);
diff --git a/ip/xfrm_monitor.c b/ip/xfrm_monitor.c
index 79453e4..01b20e0 100644
--- a/ip/xfrm_monitor.c
+++ b/ip/xfrm_monitor.c
@@ -40,10 +40,10 @@ static void usage(void)
 	exit(-1);
 }
 
-static int xfrm_acquire_print(const struct sockaddr_nl *who,
-			      struct nlmsghdr *n, void *arg)
+static int xfrm_acquire_print(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct xfrm_user_acquire *xacq = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr * tb[XFRMA_MAX+1];
@@ -101,10 +101,10 @@ static int xfrm_acquire_print(const struct sockaddr_nl *who,
 	return 0;
 }
 
-static int xfrm_state_flush_print(const struct sockaddr_nl *who,
-				  struct nlmsghdr *n, void *arg)
+static int xfrm_state_flush_print(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct xfrm_usersa_flush *xsf = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	const char *str;
@@ -131,11 +131,11 @@ static int xfrm_state_flush_print(const struct sockaddr_nl *who,
 	return 0;
 }
 
-static int xfrm_policy_flush_print(const struct sockaddr_nl *who,
-				   struct nlmsghdr *n, void *arg)
+static int xfrm_policy_flush_print(struct nl_msg *msg, void *arg)
 {
+	struct nlmsghdr *n = msg->n;
 	struct rtattr * tb[XFRMA_MAX+1];
-	FILE *fp = (FILE*)arg;
+	FILE *fp = (FILE *)arg;
 	int len = n->nlmsg_len;
 
 	len -= NLMSG_SPACE(0);
@@ -169,10 +169,10 @@ static int xfrm_policy_flush_print(const struct sockaddr_nl *who,
 	return 0;
 }
 
-static int xfrm_report_print(const struct sockaddr_nl *who,
-			     struct nlmsghdr *n, void *arg)
+static int xfrm_report_print(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct xfrm_user_report *xrep = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr * tb[XFRMA_MAX+1];
@@ -234,10 +234,10 @@ static void xfrm_usersa_print(const struct xfrm_usersa_id *sa_id, __u32 reqid, F
 	fprintf(fp, " SPI 0x%x", ntohl(sa_id->spi));
 }
 
-static int xfrm_ae_print(const struct sockaddr_nl *who,
-			     struct nlmsghdr *n, void *arg)
+static int xfrm_ae_print(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct xfrm_aevent_id *id = NLMSG_DATA(n);
 	char abuf[256];
 
@@ -264,10 +264,10 @@ static void xfrm_print_addr(FILE *fp, int family, xfrm_address_t *a)
 	fprintf(fp, "%s", rt_addr_n2a(family, a, buf, sizeof(buf)));
 }
 
-static int xfrm_mapping_print(const struct sockaddr_nl *who,
-			     struct nlmsghdr *n, void *arg)
+static int xfrm_mapping_print(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct xfrm_user_mapping *map = NLMSG_DATA(n);
 
 	fprintf(fp, "Mapping change ");
@@ -284,10 +284,10 @@ static int xfrm_mapping_print(const struct sockaddr_nl *who,
 	return 0;
 }
 
-static int xfrm_accept_msg(const struct sockaddr_nl *who,
-			   struct nlmsghdr *n, void *arg)
+static int xfrm_accept_msg(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 
 	if (timestamp)
 		print_timestamp(fp);
@@ -297,31 +297,31 @@ static int xfrm_accept_msg(const struct sockaddr_nl *who,
 	case XFRM_MSG_DELSA:
 	case XFRM_MSG_UPDSA:
 	case XFRM_MSG_EXPIRE:
-		xfrm_state_print(who, n, arg);
+		xfrm_state_print(msg, arg);
 		return 0;
 	case XFRM_MSG_NEWPOLICY:
 	case XFRM_MSG_DELPOLICY:
 	case XFRM_MSG_UPDPOLICY:
 	case XFRM_MSG_POLEXPIRE:
-		xfrm_policy_print(who, n, arg);
+		xfrm_policy_print(msg, arg);
 		return 0;
 	case XFRM_MSG_ACQUIRE:
-		xfrm_acquire_print(who, n, arg);
+		xfrm_acquire_print(msg, arg);
 		return 0;
 	case XFRM_MSG_FLUSHSA:
-		xfrm_state_flush_print(who, n, arg);
+		xfrm_state_flush_print(msg, arg);
 		return 0;
 	case XFRM_MSG_FLUSHPOLICY:
-		xfrm_policy_flush_print(who, n, arg);
+		xfrm_policy_flush_print(msg, arg);
 		return 0;
 	case XFRM_MSG_REPORT:
-		xfrm_report_print(who, n, arg);
+		xfrm_report_print(msg, arg);
 		return 0;
 	case XFRM_MSG_NEWAE:
-		xfrm_ae_print(who, n, arg);
+		xfrm_ae_print(msg, arg);
 		return 0;
 	case XFRM_MSG_MAPPING:
-		xfrm_mapping_print(who, n, arg);
+		xfrm_mapping_print(msg, arg);
 		return 0;
 	default:
 		break;
diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c
index 2337d35..9c4a31b 100644
--- a/ip/xfrm_policy.c
+++ b/ip/xfrm_policy.c
@@ -456,16 +456,16 @@ static int xfrm_policy_filter_match(struct xfrm_userpolicy_info *xpinfo,
 	return 1;
 }
 
-int xfrm_policy_print(const struct sockaddr_nl *who, struct nlmsghdr *n,
-		      void *arg)
+int xfrm_policy_print(struct nl_msg *msg, void *arg)
 {
+	struct nlmsghdr *n = msg->n;
 	struct rtattr * tb[XFRMA_MAX+1];
 	struct rtattr * rta;
 	struct xfrm_userpolicy_info *xpinfo = NULL;
 	struct xfrm_user_polexpire *xpexp = NULL;
 	struct xfrm_userpolicy_id *xpid = NULL;
 	__u8 ptype = XFRM_POLICY_TYPE_MAIN;
-	FILE *fp = (FILE*)arg;
+	FILE *fp = (FILE *)arg;
 	int len = n->nlmsg_len;
 
 	if (n->nlmsg_type != XFRM_MSG_NEWPOLICY &&
@@ -686,12 +686,14 @@ static int xfrm_policy_get(int argc, char **argv)
 {
 	char buf[NLMSG_BUF_SIZE];
 	struct nlmsghdr *n = (struct nlmsghdr *)buf;
+	struct nl_msg msg = {};
 
 	memset(buf, 0, sizeof(buf));
 
 	xfrm_policy_get_or_delete(argc, argv, 0, n);
 
-	if (xfrm_policy_print(NULL, n, (void*)stdout) < 0) {
+	msg.n = n;
+	if (xfrm_policy_print(&msg, (void *)stdout) < 0) {
 		fprintf(stderr, "An error :-)\n");
 		exit(1);
 	}
@@ -703,10 +705,9 @@ static int xfrm_policy_get(int argc, char **argv)
  * With an existing policy of nlmsg, make new nlmsg for deleting the policy
  * and store it to buffer.
  */
-static int xfrm_policy_keep(const struct sockaddr_nl *who,
-			    struct nlmsghdr *n,
-			    void *arg)
+static int xfrm_policy_keep(struct nl_msg *msg, void *arg)
 {
+	struct nlmsghdr *n = msg->n;
 	struct xfrm_buffer *xb = (struct xfrm_buffer *)arg;
 	struct rtnl_handle *rth = xb->rth;
 	struct xfrm_userpolicy_info *xpinfo = NLMSG_DATA(n);
diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c
index fe7708e..8b315a4 100644
--- a/ip/xfrm_state.c
+++ b/ip/xfrm_state.c
@@ -665,6 +665,7 @@ static int xfrm_state_allocspi(int argc, char **argv)
 	struct xfrm_mark mark = {0, 0};
 	char res_buf[NLMSG_BUF_SIZE];
 	struct nlmsghdr *res_n = (struct nlmsghdr *)res_buf;
+	struct nl_msg msg = {};
 
 	memset(res_buf, 0, sizeof(res_buf));
 
@@ -783,7 +784,8 @@ static int xfrm_state_allocspi(int argc, char **argv)
 	if (rtnl_talk(&rth, &req.n, 0, 0, res_n) < 0)
 		exit(2);
 
-	if (xfrm_state_print(NULL, res_n, (void*)stdout) < 0) {
+	msg.n = res_n;
+	if (xfrm_state_print(&msg, (void *)stdout) < 0) {
 		fprintf(stderr, "An error :-)\n");
 		exit(1);
 	}
@@ -821,10 +823,10 @@ static int xfrm_state_filter_match(struct xfrm_usersa_info *xsinfo)
 	return 1;
 }
 
-int xfrm_state_print(const struct sockaddr_nl *who, struct nlmsghdr *n,
-		     void *arg)
+int xfrm_state_print(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct rtattr * tb[XFRMA_MAX+1];
 	struct rtattr * rta;
 	struct xfrm_usersa_info *xsinfo = NULL;
@@ -975,13 +977,15 @@ static int xfrm_state_get_or_delete(int argc, char **argv, int delete)
 	} else {
 		char buf[NLMSG_BUF_SIZE];
 		struct nlmsghdr *res_n = (struct nlmsghdr *)buf;
+		struct nl_msg msg = {};
 
 		memset(buf, 0, sizeof(buf));
 
 		if (rtnl_talk(&rth, &req.n, 0, 0, res_n) < 0)
 			exit(2);
 
-		if (xfrm_state_print(NULL, res_n, (void*)stdout) < 0) {
+		msg.n = res_n;
+		if (xfrm_state_print(&msg, (void *)stdout) < 0) {
 			fprintf(stderr, "An error :-)\n");
 			exit(1);
 		}
@@ -996,10 +1000,9 @@ static int xfrm_state_get_or_delete(int argc, char **argv, int delete)
  * With an existing state of nlmsg, make new nlmsg for deleting the state
  * and store it to buffer.
  */
-static int xfrm_state_keep(const struct sockaddr_nl *who,
-			   struct nlmsghdr *n,
-			   void *arg)
+static int xfrm_state_keep(struct nl_msg *msg, void *arg)
 {
+	struct nlmsghdr *n = msg->n;
 	struct xfrm_buffer *xb = (struct xfrm_buffer *)arg;
 	struct rtnl_handle *rth = xb->rth;
 	struct xfrm_usersa_info *xsinfo = NLMSG_DATA(n);
diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index 9e2a795..d9a9756 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -220,6 +220,7 @@ int rtnl_dump_filter_l(struct rtnl_handle *rth,
 		}
 
 		for (a = arg; a->filter; a++) {
+			struct nl_msg msg = {};
 			struct nlmsghdr *h = (struct nlmsghdr*)buf;
 			msglen = status;
 
@@ -249,7 +250,10 @@ int rtnl_dump_filter_l(struct rtnl_handle *rth,
 					}
 					return -1;
 				}
-				err = a->filter(&nladdr, h, a->arg1);
+
+				msg.who = &nladdr;
+				msg.n = h;
+				err = a->filter(&msg, a->arg1);
 				if (err < 0)
 					return err;
 
@@ -450,6 +454,7 @@ int rtnl_listen(struct rtnl_handle *rtnl,
 			exit(1);
 		}
 		for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) {
+			struct nl_msg m = {};
 			int err;
 			int len = h->nlmsg_len;
 			int l = len - sizeof(*h);
@@ -463,7 +468,9 @@ int rtnl_listen(struct rtnl_handle *rtnl,
 				exit(1);
 			}
 
-			err = handler(&nladdr, h, jarg);
+			m.who = &nladdr;
+			m.n = h;
+			err = handler(&m, jarg);
 			if (err < 0)
 				return err;
 
@@ -495,6 +502,7 @@ int rtnl_from_file(FILE *rtnl, rtnl_filter_t handler,
 	nladdr.nl_groups = 0;
 
 	while (1) {
+		struct nl_msg msg = {};
 		int err, len;
 		int l;
 
@@ -529,7 +537,9 @@ int rtnl_from_file(FILE *rtnl, rtnl_filter_t handler,
 			return -1;
 		}
 
-		err = handler(&nladdr, h, jarg);
+		msg.who = &nladdr;
+		msg.n = h;
+		err = handler(&msg, jarg);
 		if (err < 0)
 			return err;
 	}
diff --git a/lib/ll_map.c b/lib/ll_map.c
index db34a2a..b3308c7 100644
--- a/lib/ll_map.c
+++ b/lib/ll_map.c
@@ -78,9 +78,9 @@ static struct ll_cache *ll_get_by_name(const char *name)
 	return NULL;
 }
 
-int ll_remember_index(const struct sockaddr_nl *who,
-		      struct nlmsghdr *n, void *arg)
+int ll_remember_index(struct nl_msg *msg, void *arg)
 {
+	struct nlmsghdr *n = msg->n;
 	unsigned int h;
 	const char *ifname;
 	struct ifinfomsg *ifi = NLMSG_DATA(n);
diff --git a/misc/ifstat.c b/misc/ifstat.c
index a47c046..0807905 100644
--- a/misc/ifstat.c
+++ b/misc/ifstat.c
@@ -105,9 +105,9 @@ static int match(const char *id)
 	return 0;
 }
 
-static int get_nlmsg(const struct sockaddr_nl *who,
-		     struct nlmsghdr *m, void *arg)
+static int get_nlmsg(struct nl_msg *msg, void *arg)
 {
+	struct nlmsghdr *m = msg->n;
 	struct ifinfomsg *ifi = NLMSG_DATA(m);
 	struct rtattr * tb[IFLA_MAX+1];
 	int len = m->nlmsg_len;
diff --git a/tc/m_action.c b/tc/m_action.c
index 7dbcf5b..55fa50d 100644
--- a/tc/m_action.c
+++ b/tc/m_action.c
@@ -319,11 +319,10 @@ tc_print_action(FILE * f, const struct rtattr *arg)
 	return 0;
 }
 
-int print_action(const struct sockaddr_nl *who,
-			   struct nlmsghdr *n,
-			   void *arg)
+int print_action(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct tcamsg *t = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr * tb[TCAA_MAX+1];
@@ -460,9 +459,13 @@ static int tc_action_gd(int cmd, unsigned flags, int *argc_p, char ***argv_p)
 		return 1;
 	}
 
-	if (ans && print_action(NULL, &req.n, (void*)stdout) < 0) {
-		fprintf(stderr, "Dump terminated\n");
-		return 1;
+	if (ans) {
+		struct nl_msg msg = {};
+		msg.n = &req.n;
+		if (print_action(&msg, (void *)stdout) < 0) {
+			fprintf(stderr, "Dump terminated\n");
+			return 1;
+		}
 	}
 
 	*argc_p = argc;
diff --git a/tc/tc_class.c b/tc/tc_class.c
index e56bf07..2d6c138 100644
--- a/tc/tc_class.c
+++ b/tc/tc_class.c
@@ -148,10 +148,10 @@ int filter_ifindex;
 __u32 filter_qdisc;
 __u32 filter_classid;
 
-int print_class(const struct sockaddr_nl *who,
-		       struct nlmsghdr *n, void *arg)
+int print_class(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct tcmsg *t = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr * tb[TCA_MAX+1];
diff --git a/tc/tc_common.h b/tc/tc_common.h
index 4f88856..df56ffa 100644
--- a/tc/tc_common.h
+++ b/tc/tc_common.h
@@ -7,10 +7,10 @@ extern int do_class(int argc, char **argv);
 extern int do_filter(int argc, char **argv);
 extern int do_action(int argc, char **argv);
 extern int do_tcmonitor(int argc, char **argv);
-extern int print_action(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
-extern int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
-extern int print_qdisc(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
-extern int print_class(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
+extern int print_action(struct nl_msg *msg, void *arg);
+extern int print_filter(struct nl_msg *msg, void *arg);
+extern int print_qdisc(struct nl_msg *msg, void *arg);
+extern int print_class(struct nl_msg *msg, void *arg);
 extern void print_size_table(FILE *fp, const char *prefix, struct rtattr *rta);
 
 struct tc_estimator;
diff --git a/tc/tc_filter.c b/tc/tc_filter.c
index c3f2d5f..7f1c73b 100644
--- a/tc/tc_filter.c
+++ b/tc/tc_filter.c
@@ -181,11 +181,10 @@ static __u32 filter_prio;
 static __u32 filter_protocol;
 __u16 f_proto = 0;
 
-int print_filter(const struct sockaddr_nl *who,
-			struct nlmsghdr *n,
-			void *arg)
+int print_filter(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct tcmsg *t = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr * tb[TCA_MAX+1];
diff --git a/tc/tc_monitor.c b/tc/tc_monitor.c
index 0efe034..4734529 100644
--- a/tc/tc_monitor.c
+++ b/tc/tc_monitor.c
@@ -35,26 +35,26 @@ static void usage(void)
 }
 
 
-static int accept_tcmsg(const struct sockaddr_nl *who,
-			struct nlmsghdr *n, void *arg)
+static int accept_tcmsg(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 
 	if (n->nlmsg_type == RTM_NEWTFILTER || n->nlmsg_type == RTM_DELTFILTER) {
-		print_filter(who, n, arg);
+		print_filter(msg, arg);
 		return 0;
 	}
 	if (n->nlmsg_type == RTM_NEWTCLASS || n->nlmsg_type == RTM_DELTCLASS) {
-		print_class(who, n, arg);
+		print_class(msg, arg);
 		return 0;
 	}
 	if (n->nlmsg_type == RTM_NEWQDISC || n->nlmsg_type == RTM_DELQDISC) {
-		print_qdisc(who, n, arg);
+		print_qdisc(msg, arg);
 		return 0;
 	}
 	if (n->nlmsg_type == RTM_GETACTION || n->nlmsg_type == RTM_NEWACTION ||
 	    n->nlmsg_type == RTM_DELACTION) {
-		print_action(who, n, arg);
+		print_action(msg, arg);
 		return 0;
 	}
 	if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP &&
diff --git a/tc/tc_qdisc.c b/tc/tc_qdisc.c
index e304858..ce0be74 100644
--- a/tc/tc_qdisc.c
+++ b/tc/tc_qdisc.c
@@ -195,11 +195,10 @@ static int tc_qdisc_modify(int cmd, unsigned flags, int argc, char **argv)
 
 static int filter_ifindex;
 
-int print_qdisc(const struct sockaddr_nl *who,
-		       struct nlmsghdr *n,
-		       void *arg)
+int print_qdisc(struct nl_msg *msg, void *arg)
 {
-	FILE *fp = (FILE*)arg;
+	struct nlmsghdr *n = msg->n;
+	FILE *fp = (FILE *)arg;
 	struct tcmsg *t = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr * tb[TCA_MAX+1];
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ