summaryrefslogtreecommitdiffstats
path: root/lib/route
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-04-15 10:50:46 (GMT)
committerThomas Haller <thaller@redhat.com>2020-04-15 16:42:38 (GMT)
commit17e09aaa1b70be6166797df3716302197a0b7105 (patch)
tree4fa3e613a559a8e1798bfeaf01ef51268e54037d /lib/route
parentb50be8fa869b256bd4f3eb455f33d408e0880fd3 (diff)
downloadlibnl-17e09aaa1b70be6166797df3716302197a0b7105.zip
libnl-17e09aaa1b70be6166797df3716302197a0b7105.tar.gz
libnl-17e09aaa1b70be6166797df3716302197a0b7105.tar.bz2
rtnl/route: use cleanup attribute in "lib/route/link.c"
Diffstat (limited to 'lib/route')
-rw-r--r--lib/route/link.c247
1 files changed, 98 insertions, 149 deletions
diff --git a/lib/route/link.c b/lib/route/link.c
index c544e35..72a9a8d 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -223,22 +223,19 @@ static int af_dump_stats(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
static int do_foreach_af(struct rtnl_link *link,
int (*cb)(struct rtnl_link *,
- struct rtnl_link_af_ops *, void *, void *),
+ struct rtnl_link_af_ops *, void *, void *),
void *arg)
{
int i, err;
for (i = 0; i < AF_MAX; i++) {
if (link->l_af_data[i]) {
- struct rtnl_link_af_ops *ops;
+ _nl_auto_rtnl_link_af_ops struct rtnl_link_af_ops *ops = NULL;
if (!(ops = rtnl_link_af_ops_lookup(i)))
BUG();
err = cb(link, ops, link->l_af_data[i], arg);
-
- rtnl_link_af_ops_put(ops);
-
if (err < 0)
return err;
}
@@ -580,28 +577,22 @@ int rtnl_link_info_parse(struct rtnl_link *link, struct nlattr **tb)
static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *n, struct nl_parser_param *pp)
{
- struct rtnl_link *link;
+ _nl_auto_rtnl_link struct rtnl_link *link = NULL;
struct ifinfomsg *ifi;
struct nlattr *tb[IFLA_MAX+1];
- struct rtnl_link_af_ops *af_ops = NULL;
- struct rtnl_link_af_ops *af_ops_family;
int err, family;
struct nla_policy real_link_policy[IFLA_MAX+1];
memcpy(&real_link_policy, rtln_link_policy, sizeof(rtln_link_policy));
link = rtnl_link_alloc();
- if (link == NULL) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (link == NULL)
+ return -NLE_NOMEM;
link->ce_msgtype = n->nlmsg_type;
- if (!nlmsg_valid_hdr(n, sizeof(*ifi))) {
- err = -NLE_MSG_TOOSHORT;
- goto errout;
- }
+ if (!nlmsg_valid_hdr(n, sizeof(*ifi)))
+ return -NLE_MSG_TOOSHORT;
ifi = nlmsg_data(n);
link->l_family = family = ifi->ifi_family;
@@ -613,31 +604,28 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
LINK_ATTR_ARPTYPE| LINK_ATTR_IFINDEX |
LINK_ATTR_FLAGS | LINK_ATTR_CHANGE);
- if ((af_ops_family = af_ops = af_lookup_and_alloc(link, family))) {
- if (af_ops->ao_protinfo_policy) {
+ if ((link->l_af_ops = af_lookup_and_alloc(link, family))) {
+ if (link->l_af_ops->ao_protinfo_policy) {
memcpy(&real_link_policy[IFLA_PROTINFO],
- af_ops->ao_protinfo_policy,
+ link->l_af_ops->ao_protinfo_policy,
sizeof(struct nla_policy));
}
-
- link->l_af_ops = af_ops;
}
err = nlmsg_parse(n, sizeof(*ifi), tb, IFLA_MAX, real_link_policy);
if (err < 0)
- goto errout;
+ return err;
err = rtnl_link_info_parse(link, tb);
if (err < 0)
- goto errout;
+ return err;
if (tb[IFLA_NUM_VF]) {
link->l_num_vf = nla_get_u32(tb[IFLA_NUM_VF]);
link->ce_mask |= LINK_ATTR_NUM_VF;
if (link->l_num_vf && tb[IFLA_VFINFO_LIST]) {
- if ((err = rtnl_link_sriov_parse_vflist(link, tb)) < 0) {
- goto errout;
- }
+ if ((err = rtnl_link_sriov_parse_vflist(link, tb)) < 0)
+ return err;
link->ce_mask |= LINK_ATTR_VF_LIST;
}
}
@@ -648,7 +636,7 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
err = nla_parse_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO],
link_info_policy);
if (err < 0)
- goto errout;
+ return err;
if (li[IFLA_INFO_KIND]) {
struct rtnl_link_info_ops *ops;
@@ -657,16 +645,14 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
err = rtnl_link_set_type(link, kind);
if (err < 0)
- goto errout;
-
- if ((af = nl_str2af(kind)) >= 0 &&
- !af_ops && (af_ops = af_lookup_and_alloc(link, af))) {
+ return err;
- if (af_ops->ao_protinfo_policy) {
- tb[IFLA_PROTINFO] = (struct nlattr *)af_ops->ao_protinfo_policy;
- }
+ if ( (af = nl_str2af(kind)) >= 0
+ && !link->l_af_ops
+ && (link->l_af_ops = af_lookup_and_alloc(link, af))) {
link->l_family = af;
- link->l_af_ops = af_ops;
+ if (link->l_af_ops->ao_protinfo_policy)
+ tb[IFLA_PROTINFO] = (struct nlattr *)link->l_af_ops->ao_protinfo_policy;
}
ops = rtnl_link_info_ops_lookup(kind);
@@ -678,7 +664,7 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
err = ops->io_parse(link, li[IFLA_INFO_DATA],
li[IFLA_INFO_XSTATS]);
if (err < 0)
- goto errout;
+ return err;
} else {
/* XXX: Warn about unparsed info? */
}
@@ -692,17 +678,19 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
err = rtnl_link_set_slave_type(link, kind);
if (err < 0)
- goto errout;
+ return err;
link->ce_mask |= LINK_ATTR_LINKINFO_SLAVE_KIND;
}
}
- if (tb[IFLA_PROTINFO] && af_ops && af_ops->ao_parse_protinfo) {
- err = af_ops->ao_parse_protinfo(link, tb[IFLA_PROTINFO],
- link->l_af_data[link->l_family]);
+ if ( tb[IFLA_PROTINFO]
+ && link->l_af_ops
+ && link->l_af_ops->ao_parse_protinfo) {
+ err = link->l_af_ops->ao_parse_protinfo(link, tb[IFLA_PROTINFO],
+ link->l_af_data[link->l_family]);
if (err < 0)
- goto errout;
+ return err;
link->ce_mask |= LINK_ATTR_PROTINFO;
}
@@ -710,12 +698,13 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
/* parsing of IFLA_AF_SPEC is dependent on the family used
* in the request message.
*/
- if (af_ops_family && af_ops_family->ao_parse_af_full) {
- err = af_ops_family->ao_parse_af_full(link,
- tb[IFLA_AF_SPEC],
- link->l_af_data[af_ops_family->ao_family]);
+ if ( link->l_af_ops
+ && link->l_af_ops->ao_parse_af_full) {
+ err = link->l_af_ops->ao_parse_af_full(link,
+ tb[IFLA_AF_SPEC],
+ link->l_af_data[link->l_af_ops->ao_family]);
if (err < 0)
- goto errout;
+ return err;
link->ce_mask |= LINK_ATTR_AF_SPEC;
} else if (family == AF_UNSPEC) {
struct nlattr *af_attr;
@@ -772,10 +761,8 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
if (tb[IFLA_PHYS_PORT_ID]) {
link->l_phys_port_id = nl_data_alloc_attr(tb[IFLA_PHYS_PORT_ID]);
- if (link->l_phys_port_id == NULL) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (link->l_phys_port_id == NULL)
+ return -NLE_NOMEM;
link->ce_mask |= LINK_ATTR_PHYS_PORT_ID;
}
@@ -786,26 +773,20 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
if (tb[IFLA_PHYS_SWITCH_ID]) {
link->l_phys_switch_id = nl_data_alloc_attr(tb[IFLA_PHYS_SWITCH_ID]);
- if (link->l_phys_switch_id == NULL) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (link->l_phys_switch_id == NULL)
+ return -NLE_NOMEM;
link->ce_mask |= LINK_ATTR_PHYS_SWITCH_ID;
}
- err = pp->pp_cb((struct nl_object *) link, pp);
-errout:
- rtnl_link_af_ops_put(af_ops);
- rtnl_link_put(link);
- return err;
+ return pp->pp_cb((struct nl_object *) link, pp);
}
static int link_request_update(struct nl_cache *cache, struct nl_sock *sk)
{
+ _nl_auto_nl_msg struct nl_msg *msg = NULL;
int family = cache->c_iarg1;
struct ifinfomsg hdr = { .ifi_family = family };
struct rtnl_link_af_ops *ops;
- struct nl_msg *msg;
int err;
__u32 ext_filter_mask = RTEXT_FILTER_VF;
@@ -813,30 +794,27 @@ static int link_request_update(struct nl_cache *cache, struct nl_sock *sk)
if (!msg)
return -NLE_NOMEM;
- err = -NLE_MSGSIZE;
if (nlmsg_append(msg, &hdr, sizeof(hdr), NLMSG_ALIGNTO) < 0)
- goto nla_put_failure;
+ return -NLE_MSGSIZE;
ops = rtnl_link_af_ops_lookup(family);
if (ops && ops->ao_get_af) {
err = ops->ao_get_af(msg, &ext_filter_mask);
if (err < 0)
- goto nla_put_failure;
+ return err;
}
if (ext_filter_mask) {
err = nla_put(msg, IFLA_EXT_MASK, sizeof(ext_filter_mask), &ext_filter_mask);
if (err < 0)
- goto nla_put_failure;
+ return err;
}
err = nl_send_auto(sk, msg);
- if (err > 0)
- err = 0;
+ if (err < 0)
+ return 0;
-nla_put_failure:
- nlmsg_free(msg);
- return err;
+ return 0;
}
static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p)
@@ -862,10 +840,9 @@ static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p)
if (link->ce_mask & LINK_ATTR_MASTER) {
if (cache) {
- struct rtnl_link *master = rtnl_link_get(cache, link->l_master);
+ _nl_auto_rtnl_link struct rtnl_link *master = rtnl_link_get(cache, link->l_master);
+
nl_dump(p, "master %s ", master ? master->l_name : "inv");
- if (master)
- rtnl_link_put(master);
} else
nl_dump(p, "master %d ", link->l_master);
}
@@ -877,10 +854,9 @@ static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p)
if (link->ce_mask & LINK_ATTR_LINK) {
if ( cache
&& !(link->ce_mask & LINK_ATTR_LINK_NETNSID)) {
- struct rtnl_link *ll = rtnl_link_get(cache, link->l_link);
+ _nl_auto_rtnl_link struct rtnl_link *ll = rtnl_link_get(cache, link->l_link);
+
nl_dump(p, "slave-of %s ", ll ? ll->l_name : "NONE");
- if (ll)
- rtnl_link_put(ll);
} else
nl_dump(p, "slave-of %d ", link->l_link);
}
@@ -1371,10 +1347,9 @@ struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *cache,
int rtnl_link_build_get_request(int ifindex, const char *name,
struct nl_msg **result)
{
+ _nl_auto_nl_msg struct nl_msg *msg = NULL;
struct ifinfomsg ifi;
- struct nl_msg *msg;
__u32 vf_mask = RTEXT_FILTER_VF;
- int err = -NLE_MSGSIZE;
if (ifindex <= 0 && !name) {
APPBUG("ifindex or name must be specified");
@@ -1389,24 +1364,15 @@ int rtnl_link_build_get_request(int ifindex, const char *name,
if (ifindex > 0)
ifi.ifi_index = ifindex;
- if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0) {
- err = -NLE_MSGSIZE;
- goto nla_put_failure;
- }
+ _NL_RETURN_ON_PUT_ERR(nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO));
if (name)
- NLA_PUT_STRING(msg, IFLA_IFNAME, name);
+ _NL_RETURN_ON_PUT_ERR(nla_put_string(msg, IFLA_IFNAME, name));
- err = nla_put(msg, IFLA_EXT_MASK, sizeof(vf_mask), &vf_mask);
- if (err < 0)
- goto nla_put_failure;
+ _NL_RETURN_ON_PUT_ERR(nla_put(msg, IFLA_EXT_MASK, sizeof(vf_mask), &vf_mask));
- *result = msg;
+ *result = _nl_steal_pointer(&msg);
return 0;
-
-nla_put_failure:
- nlmsg_free(msg);
- return err;
}
/**
@@ -1433,8 +1399,8 @@ nla_put_failure:
int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name,
struct rtnl_link **result)
{
- struct nl_msg *msg = NULL;
- struct nl_object *obj;
+ _nl_auto_rtnl_link struct rtnl_link *link = NULL;
+ _nl_auto_nl_msg struct nl_msg *msg = NULL;
int err;
int syserr;
@@ -1442,14 +1408,15 @@ int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name,
return err;
err = nl_send_auto(sk, msg);
- nlmsg_free(msg);
if (err < 0)
return err;
- if ((err = nl_pickup_keep_syserr(sk, link_msg_parser, &obj, &syserr)) < 0) {
- if (syserr == -EINVAL &&
- ifindex <= 0 &&
- name && *name) {
+ err = nl_pickup_keep_syserr(sk, link_msg_parser, (struct nl_object **) &link, &syserr);
+ if (err < 0) {
+ if ( syserr == -EINVAL
+ && ifindex <= 0
+ && name
+ && *name) {
/* Older kernels do not support lookup by ifname. This was added
* by commit kernel a3d1289126e7b14307074b76bf1677015ea5036f .
* Detect this error case and return NLE_OPNOTSUPP instead of
@@ -1459,13 +1426,11 @@ int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name,
return err;
}
- /* We have used link_msg_parser(), object is definitely a link */
- *result = (struct rtnl_link *) obj;
-
/* If an object has been returned, we also need to wait for the ACK */
- if (err == 0 && obj)
+ if (err == 0 && link)
wait_for_ack(sk);
+ *result = _nl_steal_pointer(&link);
return 0;
}
@@ -1486,11 +1451,11 @@ int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name,
char * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst,
size_t len)
{
- struct rtnl_link *link = rtnl_link_get(cache, ifindex);
+ _nl_auto_rtnl_link struct rtnl_link *link = NULL;
+ link = rtnl_link_get(cache, ifindex);
if (link) {
_nl_strncpy_trunc(dst, link->l_name, len);
- rtnl_link_put(link);
return dst;
}
@@ -1508,16 +1473,13 @@ char * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst,
*/
int rtnl_link_name2i(struct nl_cache *cache, const char *name)
{
- int ifindex = 0;
- struct rtnl_link *link;
+ _nl_auto_rtnl_link struct rtnl_link *link = NULL;
link = rtnl_link_get_by_name(cache, name);
- if (link) {
- ifindex = link->l_index;
- rtnl_link_put(link);
- }
+ if (link)
+ return link->l_index;
- return ifindex;
+ return 0;
}
/** @} */
@@ -1584,7 +1546,7 @@ nla_put_failure:
static int build_link_msg(int cmd, struct ifinfomsg *hdr,
struct rtnl_link *link, int flags, struct nl_msg **result)
{
- struct nl_msg *msg;
+ _nl_auto_nl_msg struct nl_msg *msg = NULL;
struct nlattr *af_spec;
msg = nlmsg_alloc_simple(cmd, flags);
@@ -1639,11 +1601,10 @@ static int build_link_msg(int cmd, struct ifinfomsg *hdr,
nla_nest_end(msg, af_spec);
- *result = msg;
+ *result = _nl_steal_pointer(&msg);
return 0;
nla_put_failure:
- nlmsg_free(msg);
return -NLE_MSGSIZE;
}
@@ -1761,12 +1722,9 @@ int rtnl_link_build_change_request(struct rtnl_link *orig,
rt = af_request_type(orig->l_family, changes);
if ((err = build_link_msg(rt, &ifi, changes, flags, result)) < 0)
- goto errout;
+ return err;
return 0;
-
-errout:
- return err;
}
/**
@@ -1807,7 +1765,7 @@ errout:
int rtnl_link_change(struct nl_sock *sk, struct rtnl_link *orig,
struct rtnl_link *changes, int flags)
{
- struct nl_msg *msg;
+ _nl_auto_nl_msg struct nl_msg *msg = NULL;
int err;
err = rtnl_link_build_change_request(orig, changes, flags, &msg);
@@ -1818,18 +1776,20 @@ int rtnl_link_change(struct nl_sock *sk, struct rtnl_link *orig,
retry:
err = nl_send_auto_complete(sk, msg);
if (err < 0)
- goto errout;
+ return err;
err = wait_for_ack(sk);
- if (err == -NLE_OPNOTSUPP && msg->nm_nlh->nlmsg_type == RTM_NEWLINK) {
+ if ( err == -NLE_OPNOTSUPP
+ && msg->nm_nlh->nlmsg_type == RTM_NEWLINK) {
msg->nm_nlh->nlmsg_type = RTM_SETLINK;
msg->nm_nlh->nlmsg_seq = NL_AUTO_SEQ;
goto retry;
}
-errout:
- nlmsg_free(msg);
- return err;
+ if (err < 0)
+ return err;
+
+ return 0;
}
/** @} */
@@ -1855,7 +1815,7 @@ errout:
int rtnl_link_build_delete_request(const struct rtnl_link *link,
struct nl_msg **result)
{
- struct nl_msg *msg;
+ _nl_auto_nl_msg struct nl_msg *msg = NULL;
struct ifinfomsg ifi = {
.ifi_index = link->l_index,
};
@@ -1868,18 +1828,13 @@ int rtnl_link_build_delete_request(const struct rtnl_link *link,
if (!(msg = nlmsg_alloc_simple(RTM_DELLINK, 0)))
return -NLE_NOMEM;
- if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0)
- goto nla_put_failure;
+ _NL_RETURN_ON_PUT_ERR(nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO));
if (link->ce_mask & LINK_ATTR_IFNAME)
- NLA_PUT_STRING(msg, IFLA_IFNAME, link->l_name);
+ _NL_RETURN_ON_PUT_ERR(nla_put_string(msg, IFLA_IFNAME, link->l_name));
- *result = msg;
+ *result = _nl_steal_pointer(&msg);
return 0;
-
-nla_put_failure:
- nlmsg_free(msg);
- return -NLE_MSGSIZE;
}
/**
@@ -2570,8 +2525,8 @@ int rtnl_link_set_stat(struct rtnl_link *link, rtnl_link_stat_id_t id,
int rtnl_link_set_type(struct rtnl_link *link, const char *type)
{
struct rtnl_link_info_ops *io;
+ _nl_auto_free char *kind = NULL;
int err;
- char *kind;
free(link->l_info_kind);
link->ce_mask &= ~LINK_ATTR_LINKINFO;
@@ -2586,20 +2541,17 @@ int rtnl_link_set_type(struct rtnl_link *link, const char *type)
io = rtnl_link_info_ops_lookup(type);
if (io) {
- if (io->io_alloc && (err = io->io_alloc(link)) < 0)
- goto errout;
+ if ( io->io_alloc
+ && (err = io->io_alloc(link)) < 0)
+ return err;
link->l_info_ops = io;
}
- link->l_info_kind = kind;
+ link->l_info_kind = _nl_steal_pointer(&kind);
link->ce_mask |= LINK_ATTR_LINKINFO;
return 0;
-
-errout:
- free(kind);
- return err;
}
/**
@@ -2859,7 +2811,7 @@ pid_t rtnl_link_get_ns_pid(struct rtnl_link *link)
*/
int rtnl_link_enslave_ifindex(struct nl_sock *sock, int master, int slave)
{
- struct rtnl_link *link;
+ _nl_auto_rtnl_link struct rtnl_link *link = NULL;
int err;
if (!(link = rtnl_link_alloc()))
@@ -2869,12 +2821,12 @@ int rtnl_link_enslave_ifindex(struct nl_sock *sock, int master, int slave)
rtnl_link_set_master(link, master);
if ((err = rtnl_link_change(sock, link, link, 0)) < 0)
- goto errout;
+ return err;
- rtnl_link_put(link);
+ _nl_clear_pointer(&link, rtnl_link_put);
/*
- * Due to the kernel not signaling whether this opertion is
+ * Due to the kernel not signaling whether this operation is
* supported or not, we will retrieve the attribute to see if the
* request was successful. If the master assigned remains unchanged
* we will return NLE_OPNOTSUPP to allow performing backwards
@@ -2884,12 +2836,9 @@ int rtnl_link_enslave_ifindex(struct nl_sock *sock, int master, int slave)
return err;
if (rtnl_link_get_master(link) != master)
- err = -NLE_OPNOTSUPP;
-
-errout:
- rtnl_link_put(link);
+ return -NLE_OPNOTSUPP;
- return err;
+ return 0;
}
/**