diff --git a/include/netlink-private/route/link/api.h b/include/netlink-private/route/link/api.h index 85f83f395..2d5665821 100644 --- a/include/netlink-private/route/link/api.h +++ b/include/netlink-private/route/link/api.h @@ -119,6 +119,10 @@ struct rtnl_link_af_ops int (*ao_fill_af)(struct rtnl_link *, struct nl_msg *msg, void *); + /** Called for GETLINK message to the kernel. Used to append + * link address family specific attributes to the request message. */ + int (*ao_get_af)(struct nl_msg *msg); + /** Dump address family specific link attributes */ void (*ao_dump[NL_DUMP_MAX+1])(struct rtnl_link *, struct nl_dump_params *, diff --git a/lib/route/link.c b/lib/route/link.c index cfe3779f4..768b8998a 100644 --- a/lib/route/link.c +++ b/lib/route/link.c @@ -657,8 +657,32 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, static int link_request_update(struct nl_cache *cache, struct nl_sock *sk) { int family = cache->c_iarg1; + struct ifinfomsg hdr = { .ifi_family = family }; + struct rtnl_link_af_ops *ops; + struct nl_msg *msg; + int err; + + msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_DUMP); + if (!msg) + return -NLE_NOMEM; + + err = -NLE_MSGSIZE; + if (nlmsg_append(msg, &hdr, sizeof(hdr), NLMSG_ALIGNTO) < 0) + goto nla_put_failure; - return nl_rtgen_request(sk, RTM_GETLINK, family, NLM_F_DUMP); + ops = rtnl_link_af_ops_lookup(family); + if (ops && ops->ao_get_af) { + err = ops->ao_get_af(msg); + if (err) + goto nla_put_failure; + } + err = nl_send_auto(sk, msg); + if (err > 0) + err = 0; + +nla_put_failure: + nlmsg_free(msg); + return err; } static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p)