diff options
author | Thomas Haller <thaller@redhat.com> | 2020-04-15 10:50:46 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-04-15 16:42:38 (GMT) |
commit | 17e09aaa1b70be6166797df3716302197a0b7105 (patch) | |
tree | 4fa3e613a559a8e1798bfeaf01ef51268e54037d /lib/route | |
parent | b50be8fa869b256bd4f3eb455f33d408e0880fd3 (diff) | |
download | libnl-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.c | 247 |
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; } /** |