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