along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stddef.h>
#include <stdint.h>
#include <sys/socket.h>
#include <linux/netlink.h>
.num = _NL_UNION_LINK_INFO_DATA_MAX,
.lookup = nl_union_link_info_data_from_string,
.type_systems = rtnl_link_info_data_type_systems,
+ .match_type = NL_MATCH_SIBLING,
.match = IFLA_INFO_KIND,
};
.types = rtnl_link_info_types,
};
-static const struct NLType rtnl_bridge_port_types[IFLA_BRPORT_MAX + 1] = {
+static const struct NLType rtnl_prot_info_bridge_port_types[IFLA_BRPORT_MAX + 1] = {
[IFLA_BRPORT_STATE] = { .type = NLA_U8 },
[IFLA_BRPORT_COST] = { .type = NLA_U32 },
[IFLA_BRPORT_PRIORITY] = { .type = NLA_U16 },
[IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 },
};
-static const NLTypeSystem rtnl_bridge_port_type_system = {
- .max = ELEMENTSOF(rtnl_bridge_port_types) - 1,
- .types = rtnl_bridge_port_types,
+static const NLTypeSystem rtnl_prot_info_type_systems[AF_MAX] = {
+ [AF_BRIDGE] = { .max = ELEMENTSOF(rtnl_prot_info_bridge_port_types) - 1,
+ .types = rtnl_prot_info_bridge_port_types },
+};
+
+static const NLTypeSystemUnion rtnl_prot_info_type_system_union = {
+ .num = AF_MAX,
+ .type_systems = rtnl_prot_info_type_systems,
+ .match_type = NL_MATCH_PROTOCOL,
+};
+
+static const struct NLType rtnl_af_spec_inet6_types[IFLA_INET6_MAX + 1] = {
+ [IFLA_INET6_FLAGS] = { .type = NLA_U32 },
+/*
+ IFLA_INET6_CONF,
+ IFLA_INET6_STATS,
+ IFLA_INET6_MCAST,
+ IFLA_INET6_CACHEINFO,
+ IFLA_INET6_ICMP6STATS,
+*/
+ [IFLA_INET6_TOKEN] = { .type = NLA_IN_ADDR },
+ [IFLA_INET6_ADDR_GEN_MODE] = { .type = NLA_U8 },
+};
+
+static const NLTypeSystem rtnl_af_spec_inet6_type_system = {
+ .max = ELEMENTSOF(rtnl_af_spec_inet6_types) - 1,
+ .types = rtnl_af_spec_inet6_types,
+};
+
+static const NLType rtnl_af_spec_types[AF_MAX + 1] = {
+ [AF_INET6] = { .type = NLA_NESTED, .type_system = &rtnl_af_spec_inet6_type_system },
+};
+
+static const NLTypeSystem rtnl_af_spec_type_system = {
+ .max = ELEMENTSOF(rtnl_af_spec_types) - 1,
+ .types = rtnl_af_spec_types,
};
static const NLType rtnl_link_types[IFLA_MAX + 1 ] = {
[IFLA_MASTER] = { .type = NLA_U32 },
/*
[IFLA_WIRELESS],
- [IFLA_PROTINFO],
*/
- [IFLA_PROTINFO] = { .type = NLA_NESTED, .type_system = &rtnl_bridge_port_type_system },
+ [IFLA_PROTINFO] = { .type = NLA_UNION, .type_system_union = &rtnl_prot_info_type_system_union },
[IFLA_TXQLEN] = { .type = NLA_U32 },
/*
[IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) },
[IFLA_STATS64],
[IFLA_VF_PORTS] = { .type = NLA_NESTED },
[IFLA_PORT_SELF] = { .type = NLA_NESTED },
- [IFLA_AF_SPEC] = { .type = NLA_NESTED },
+*/
+ [IFLA_AF_SPEC] = { .type = NLA_NESTED, .type_system = &rtnl_af_spec_type_system },
+/*
[IFLA_VF_PORTS],
[IFLA_PORT_SELF],
[IFLA_AF_SPEC],
assert(type_system->types);
if (type > type_system->max)
- return -ENOTSUP;
+ return -EOPNOTSUPP;
nl_type = &type_system->types[type];
if (nl_type->type == NLA_UNSPEC)
- return -ENOTSUP;
+ return -EOPNOTSUPP;
*ret = nl_type;
if (r < 0)
return r;
- assert_return(nl_type->type == NLA_NESTED, -EINVAL);
-
+ assert(nl_type->type == NLA_NESTED);
assert(nl_type->type_system);
*ret = nl_type->type_system;
if (r < 0)
return r;
- assert_return(nl_type->type == NLA_UNION, -EINVAL);
-
+ assert(nl_type->type == NLA_UNION);
assert(nl_type->type_system_union);
*ret = nl_type->type_system_union;
int type;
assert(type_system_union);
+ assert(type_system_union->match_type == NL_MATCH_SIBLING);
assert(type_system_union->lookup);
assert(type_system_union->type_systems);
assert(ret);
type = type_system_union->lookup(key);
if (type < 0)
- return -ENOTSUP;
+ return -EOPNOTSUPP;
assert(type < type_system_union->num);
return 0;
}
+
+int type_system_union_protocol_get_type_system(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, uint16_t protocol) {
+ const NLTypeSystem *type_system;
+
+ assert(type_system_union);
+ assert(type_system_union->type_systems);
+ assert(type_system_union->match_type == NL_MATCH_PROTOCOL);
+ assert(ret);
+
+ if (protocol >= type_system_union->num)
+ return -EOPNOTSUPP;
+
+ type_system = &type_system_union->type_systems[protocol];
+ if (type_system->max == 0)
+ return -EOPNOTSUPP;
+
+ *ret = type_system;
+
+ return 0;
+}