[PATCH 2/4] Get link information only from specified interface

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Leo Ruan <tingquan.ruan@xxxxxxxxxxxx>

libsocketcan always retrieves link information from all interfaces
instead of only specified one. This commit fixes the issue by appending
an interface information to dump request netlink message.
See man 7 rtnetlink for detail description in section 'RTM_GETLINK'.

Signed-off-by: Leo Ruan <tingquan.ruan@xxxxxxxxxxxx>
Signed-off-by: Mark Jonas <mark.jonas@xxxxxxxxxxxx>
---
 src/libsocketcan.c | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/src/libsocketcan.c b/src/libsocketcan.c
index 95409dd..04e6647 100644
--- a/src/libsocketcan.c
+++ b/src/libsocketcan.c
@@ -57,7 +57,7 @@
 
 struct get_req {
 	struct nlmsghdr n;
-	struct rtgenmsg g;
+	struct ifinfomsg i;
 };
 
 struct set_req {
@@ -228,13 +228,14 @@ static int send_mod_request(int fd, struct nlmsghdr *n)
  * @brief send_dump_request - send a dump linkinfo request
  *
  * @param fd decriptor to a priorly opened netlink socket
+ * @param name network interface name, null means all interfaces
  * @param family rt_gen message family
  * @param type netlink message header type
  *
  * @return 0 if success
  * @return negativ if failed
  */
-static int send_dump_request(int fd, int family, int type)
+static int send_dump_request(int fd, const char *name, int family, int type)
 {
 	struct get_req req;
 
@@ -242,11 +243,22 @@ static int send_dump_request(int fd, int family, int type)
 
 	req.n.nlmsg_len = sizeof(req);
 	req.n.nlmsg_type = type;
-	req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
+	req.n.nlmsg_flags = NLM_F_REQUEST;
 	req.n.nlmsg_pid = 0;
 	req.n.nlmsg_seq = 0;
 
-	req.g.rtgen_family = family;
+	req.i.ifi_family = family;
+	/* If name is null, set flag to dump link information from all interfaces
+	 * otherwise, just dump specified interface's link information. */
+	if (name == NULL) {
+		req.n.nlmsg_flags |= NLM_F_DUMP;
+	} else {
+		req.i.ifi_index = if_nametoindex(name);
+		if (req.i.ifi_index == 0) {
+			fprintf(stderr, "Cannot find device \"%s\"\n", name);
+			return -1;
+		}
+	}
 
 	return send(fd, (void *)&req, sizeof(req), 0);
 }
@@ -352,7 +364,7 @@ static int do_get_nl_link(int fd, __u8 acquire, const char *name, void *res)
 	struct rtattr *linkinfo[IFLA_INFO_MAX + 1];
 	struct rtattr *can_attr[IFLA_CAN_MAX + 1];
 
-	if (send_dump_request(fd, AF_PACKET, RTM_GETLINK) < 0) {
+	if (send_dump_request(fd, name, AF_PACKET, RTM_GETLINK) < 0) {
 		perror("Cannot send dump request");
 		return ret;
 	}
@@ -386,8 +398,10 @@ static int do_get_nl_link(int fd, __u8 acquire, const char *name, void *res)
 				nl_msg->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifaddrmsg));
 			parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
 
-			if (strcmp
-			    ((char *)RTA_DATA(tb[IFLA_IFNAME]), name) != 0)
+			/* Finish process if the reply message is matched */
+			if (strcmp((char *)RTA_DATA(tb[IFLA_IFNAME]), name) == 0)
+				done++;
+			else
 				continue;
 
 			if (tb[IFLA_LINKINFO])
-- 
2.7.4

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



[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux