mirror of
https://gitee.com/openharmony/third_party_libnl
synced 2024-11-30 21:50:54 +00:00
link: Support for IFLA_AF_SPEC
This feature isn't upstream yet. It's required to test a patch in my local tree. Makes the link parser understand IFLA_AF_SPEC and call the address family specific parser.
This commit is contained in:
parent
a4efc65c3a
commit
2e3ca4db0c
@ -80,6 +80,24 @@ struct rtnl_link_ifmap {
|
||||
__u8 port;
|
||||
};
|
||||
|
||||
/*
|
||||
* IFLA_AF_SPEC
|
||||
* Contains nested attributes for address family specific attributes.
|
||||
* Each address family may create a attribute with the address family
|
||||
* number as type and create its own attribute structure in it.
|
||||
*
|
||||
* Example:
|
||||
* [IFLA_AF_SPEC] = {
|
||||
* [AF_INET6] = {
|
||||
* [IFLA_INET6_FLAGS] = ...,
|
||||
* [IFLA_INET6_CONF] = ...,
|
||||
* },
|
||||
* [AF_BRIDGE] = {
|
||||
* [IFLA_BRIDGE_PORT] = ...
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
enum {
|
||||
IFLA_UNSPEC,
|
||||
IFLA_ADDRESS,
|
||||
@ -116,6 +134,7 @@ enum {
|
||||
IFLA_STATS64,
|
||||
IFLA_VF_PORTS,
|
||||
IFLA_PORT_SELF,
|
||||
IFLA_AF_SPEC,
|
||||
__IFLA_MAX
|
||||
};
|
||||
|
||||
|
@ -105,6 +105,11 @@ struct rtnl_link_af_ops
|
||||
int (*ao_parse_protinfo)(struct rtnl_link *,
|
||||
struct nlattr *, void *);
|
||||
|
||||
/** Called if a IFLA_AF_SPEC attribute needs to be parsed. Typically
|
||||
* stores the parsed data in the address family specific buffer. */
|
||||
int (*ao_parse_af)(struct rtnl_link *,
|
||||
struct nlattr *, void *);
|
||||
|
||||
/** Dump address family specific link attributes */
|
||||
void (*ao_dump[NL_DUMP_MAX+1])(struct rtnl_link *,
|
||||
struct nl_dump_params *,
|
||||
|
@ -183,6 +183,26 @@ static struct nl_cache_ops rtnl_link_ops;
|
||||
static struct nl_object_ops link_obj_ops;
|
||||
/** @endcond */
|
||||
|
||||
static struct rtnl_link_af_ops *af_lookup_and_alloc(struct rtnl_link *link,
|
||||
int family)
|
||||
{
|
||||
struct rtnl_link_af_ops *af_ops;
|
||||
|
||||
af_ops = rtnl_link_af_ops_lookup(family);
|
||||
if (!af_ops)
|
||||
return NULL;
|
||||
|
||||
if (!link->l_af_data[family] && af_ops->ao_alloc) {
|
||||
link->l_af_data[family] = af_ops->ao_alloc(link);
|
||||
if (!link->l_af_data[family]) {
|
||||
rtnl_link_af_ops_put(af_ops);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return af_ops;
|
||||
}
|
||||
|
||||
static int af_free(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
|
||||
void *data, void *arg)
|
||||
{
|
||||
@ -339,6 +359,7 @@ static struct nla_policy link_policy[IFLA_MAX+1] = {
|
||||
[IFLA_MAP] = { .minlen = sizeof(struct rtnl_link_ifmap) },
|
||||
[IFLA_IFALIAS] = { .type = NLA_STRING, .maxlen = IFALIASZ },
|
||||
[IFLA_NUM_VF] = { .type = NLA_U32 },
|
||||
[IFLA_AF_SPEC] = { .type = NLA_NESTED },
|
||||
};
|
||||
|
||||
static struct nla_policy link_info_policy[IFLA_INFO_MAX+1] = {
|
||||
@ -377,15 +398,7 @@ 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 = rtnl_link_af_ops_lookup(family))) {
|
||||
if (af_ops->ao_alloc) {
|
||||
link->l_af_data[family] = af_ops->ao_alloc(link);
|
||||
if (!link->l_af_data[family]) {
|
||||
err = -NLE_NOMEM;
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
if ((af_ops = af_lookup_and_alloc(link, family))) {
|
||||
if (af_ops->ao_protinfo_policy) {
|
||||
memcpy(&link_policy[IFLA_PROTINFO],
|
||||
af_ops->ao_protinfo_policy,
|
||||
@ -588,6 +601,26 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (tb[IFLA_AF_SPEC]) {
|
||||
struct nlattr *af_attr;
|
||||
int remaining;
|
||||
|
||||
nla_for_each_nested(af_attr, tb[IFLA_AF_SPEC], remaining) {
|
||||
af_ops = af_lookup_and_alloc(link, nla_type(af_attr));
|
||||
if (af_ops && af_ops->ao_parse_af) {
|
||||
char *af_data = link->l_af_data[nla_type(af_attr)];
|
||||
|
||||
err = af_ops->ao_parse_af(link, af_attr, af_data);
|
||||
|
||||
rtnl_link_af_ops_put(af_ops);
|
||||
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
err = pp->pp_cb((struct nl_object *) link, pp);
|
||||
errout:
|
||||
rtnl_link_af_ops_put(af_ops);
|
||||
|
@ -311,6 +311,7 @@ static struct rtnl_link_af_ops inet6_ops = {
|
||||
.ao_clone = &inet6_clone,
|
||||
.ao_free = &inet6_free,
|
||||
.ao_parse_protinfo = &inet6_parse_protinfo,
|
||||
.ao_parse_af = &inet6_parse_protinfo,
|
||||
.ao_dump[NL_DUMP_DETAILS] = &inet6_dump_details,
|
||||
.ao_dump[NL_DUMP_STATS] = &inet6_dump_stats,
|
||||
.ao_protinfo_policy = &protinfo_policy,
|
||||
|
Loading…
Reference in New Issue
Block a user