ip address: Set device index in dump request
Add a filter function to rtnl_addrdump_req to set device index in the address dump request if the user is filtering addresses by device. In addition, add a new ipaddr_link_get to do a single RTM_GETLINK request instead of a device dump yet still store the data in the linfo list. Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
parent
7ca9cee8d8
commit
8847097850
|
|
@ -49,7 +49,8 @@ void rtnl_close(struct rtnl_handle *rth);
|
|||
|
||||
typedef int (*req_filter_fn_t)(struct nlmsghdr *nlh, int reqlen);
|
||||
|
||||
int rtnl_addrdump_req(struct rtnl_handle *rth, int family)
|
||||
int rtnl_addrdump_req(struct rtnl_handle *rth, int family,
|
||||
req_filter_fn_t filter_fn)
|
||||
__attribute__((warn_unused_result));
|
||||
int rtnl_addrlbldump_req(struct rtnl_handle *rth, int family)
|
||||
__attribute__((warn_unused_result));
|
||||
|
|
|
|||
|
|
@ -1679,6 +1679,15 @@ static void ipaddr_filter(struct nlmsg_chain *linfo, struct nlmsg_chain *ainfo)
|
|||
}
|
||||
}
|
||||
|
||||
static int ipaddr_dump_filter(struct nlmsghdr *nlh, int reqlen)
|
||||
{
|
||||
struct ifaddrmsg *ifa = NLMSG_DATA(nlh);
|
||||
|
||||
ifa->ifa_index = filter.ifindex;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ipaddr_flush(void)
|
||||
{
|
||||
int round = 0;
|
||||
|
|
@ -1689,7 +1698,8 @@ static int ipaddr_flush(void)
|
|||
filter.flushe = sizeof(flushb);
|
||||
|
||||
while ((max_flush_loops == 0) || (round < max_flush_loops)) {
|
||||
if (rtnl_addrdump_req(&rth, filter.family) < 0) {
|
||||
if (rtnl_addrdump_req(&rth, filter.family,
|
||||
ipaddr_dump_filter) < 0) {
|
||||
perror("Cannot send dump request");
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -1762,6 +1772,36 @@ static int iplink_filter_req(struct nlmsghdr *nlh, int reqlen)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ipaddr_link_get(int index, struct nlmsg_chain *linfo)
|
||||
{
|
||||
struct iplink_req req = {
|
||||
.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
|
||||
.n.nlmsg_flags = NLM_F_REQUEST,
|
||||
.n.nlmsg_type = RTM_GETLINK,
|
||||
.i.ifi_family = filter.family,
|
||||
.i.ifi_index = index,
|
||||
};
|
||||
__u32 filt_mask = RTEXT_FILTER_VF;
|
||||
struct nlmsghdr *answer;
|
||||
|
||||
if (!show_stats)
|
||||
filt_mask |= RTEXT_FILTER_SKIP_STATS;
|
||||
|
||||
addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filt_mask);
|
||||
|
||||
if (rtnl_talk(&rth, &req.n, &answer) < 0) {
|
||||
perror("Cannot send link request");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (store_nlmsg(answer, linfo) < 0) {
|
||||
fprintf(stderr, "Failed to process link information\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fills in linfo with link data and optionally ainfo with address info
|
||||
* caller can walk lists as desired and must call free_nlmsg_chain for
|
||||
* both when done
|
||||
|
|
@ -1784,7 +1824,7 @@ int ip_link_list(req_filter_fn_t filter_fn, struct nlmsg_chain *linfo)
|
|||
|
||||
static int ip_addr_list(struct nlmsg_chain *ainfo)
|
||||
{
|
||||
if (rtnl_addrdump_req(&rth, filter.family) < 0) {
|
||||
if (rtnl_addrdump_req(&rth, filter.family, ipaddr_dump_filter) < 0) {
|
||||
perror("Cannot send dump request");
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -1908,7 +1948,8 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
|
|||
if (ipadd_save_prep())
|
||||
exit(1);
|
||||
|
||||
if (rtnl_addrdump_req(&rth, preferred_family) < 0) {
|
||||
if (rtnl_addrdump_req(&rth, preferred_family,
|
||||
ipaddr_dump_filter) < 0) {
|
||||
perror("Cannot send dump request");
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -1942,8 +1983,13 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (ip_link_list(iplink_filter_req, &linfo) != 0)
|
||||
goto out;
|
||||
if (filter.ifindex) {
|
||||
if (ipaddr_link_get(filter.ifindex, &linfo) != 0)
|
||||
goto out;
|
||||
} else {
|
||||
if (ip_link_list(iplink_filter_req, &linfo) != 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (filter.family != AF_PACKET) {
|
||||
if (filter.oneline)
|
||||
|
|
@ -1972,8 +2018,7 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
|
|||
fflush(stdout);
|
||||
|
||||
out:
|
||||
if (ainfo)
|
||||
free_nlmsg_chain(ainfo);
|
||||
free_nlmsg_chain(ainfo);
|
||||
free_nlmsg_chain(&linfo);
|
||||
delete_json_obj();
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -234,11 +234,13 @@ int rtnl_open(struct rtnl_handle *rth, unsigned int subscriptions)
|
|||
return rtnl_open_byproto(rth, subscriptions, NETLINK_ROUTE);
|
||||
}
|
||||
|
||||
int rtnl_addrdump_req(struct rtnl_handle *rth, int family)
|
||||
int rtnl_addrdump_req(struct rtnl_handle *rth, int family,
|
||||
req_filter_fn_t filter_fn)
|
||||
{
|
||||
struct {
|
||||
struct nlmsghdr nlh;
|
||||
struct ifaddrmsg ifm;
|
||||
char buf[128];
|
||||
} req = {
|
||||
.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)),
|
||||
.nlh.nlmsg_type = RTM_GETADDR,
|
||||
|
|
@ -247,6 +249,14 @@ int rtnl_addrdump_req(struct rtnl_handle *rth, int family)
|
|||
.ifm.ifa_family = family,
|
||||
};
|
||||
|
||||
if (filter_fn) {
|
||||
int err;
|
||||
|
||||
err = filter_fn(&req.nlh, sizeof(req));
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return send(rth->fd, &req, sizeof(req), 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue