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>
#include <linux/if.h>
#include <linux/ip.h>
+#include <linux/if_link.h>
#include <linux/if_tunnel.h>
#include "macro.h"
[VETH_INFO_PEER] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
};
+static const NLType rtnl_link_info_data_ipvlan_types[IFLA_IPVLAN_MAX + 1] = {
+ [IFLA_IPVLAN_MODE] = { .type = NLA_U16 },
+};
static const NLType rtnl_link_info_data_macvlan_types[IFLA_MACVLAN_MAX + 1] = {
[IFLA_MACVLAN_MODE] = { .type = NLA_U32 },
static const NLType rtnl_link_info_data_bond_types[IFLA_BOND_MAX + 1] = {
[IFLA_BOND_MODE] = { .type = NLA_U8 },
[IFLA_BOND_ACTIVE_SLAVE] = { .type = NLA_U32 },
-#ifdef IFLA_BOND_MIIMON
[IFLA_BOND_MIIMON] = { .type = NLA_U32 },
[IFLA_BOND_UPDELAY] = { .type = NLA_U32 },
[IFLA_BOND_DOWNDELAY] = { .type = NLA_U32 },
[IFLA_BOND_USE_CARRIER] = { .type = NLA_U8 },
[IFLA_BOND_ARP_INTERVAL] = { .type = NLA_U32 },
-/*
[IFLA_BOND_ARP_IP_TARGET] = { .type = NLA_NESTED },
-*/
[IFLA_BOND_ARP_VALIDATE] = { .type = NLA_U32 },
[IFLA_BOND_ARP_ALL_TARGETS] = { .type = NLA_U32 },
[IFLA_BOND_PRIMARY] = { .type = NLA_U32 },
[IFLA_BOND_PACKETS_PER_SLAVE] = { .type = NLA_U32 },
[IFLA_BOND_AD_LACP_RATE] = { .type = NLA_U8 },
[IFLA_BOND_AD_SELECT] = { .type = NLA_U8 },
-/*
[IFLA_BOND_AD_INFO] = { .type = NLA_NESTED },
-*/
-#endif
};
static const NLType rtnl_link_info_data_iptun_types[IFLA_IPTUN_MAX + 1] = {
[IFLA_VTI_REMOTE] = { .type = NLA_IN_ADDR },
};
-typedef enum NLUnionLinkInfoData {
- NL_UNION_LINK_INFO_DATA_BOND,
- NL_UNION_LINK_INFO_DATA_BRIDGE,
- NL_UNION_LINK_INFO_DATA_VLAN,
- NL_UNION_LINK_INFO_DATA_VETH,
- NL_UNION_LINK_INFO_DATA_MACVLAN,
- NL_UNION_LINK_INFO_DATA_VXLAN,
- NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL,
- NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL,
- NL_UNION_LINK_INFO_DATA_SIT_TUNNEL,
- NL_UNION_LINK_INFO_DATA_VTI_TUNNEL,
- _NL_UNION_LINK_INFO_DATA_MAX,
- _NL_UNION_LINK_INFO_DATA_INVALID = -1
-} NLUnionLinkInfoData;
-
-const char *nl_union_link_info_data_to_string(NLUnionLinkInfoData p) _const_;
-NLUnionLinkInfoData nl_union_link_info_data_from_string(const char *p) _pure_;
+static const NLType rtnl_link_info_data_ip6tnl_types[IFLA_IPTUN_MAX + 1] = {
+ [IFLA_IPTUN_LINK] = { .type = NLA_U32 },
+ [IFLA_IPTUN_LOCAL] = { .type = NLA_IN_ADDR },
+ [IFLA_IPTUN_REMOTE] = { .type = NLA_IN_ADDR },
+ [IFLA_IPTUN_TTL] = { .type = NLA_U8 },
+ [IFLA_IPTUN_FLAGS] = { .type = NLA_U32 },
+ [IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
+ [IFLA_IPTUN_ENCAP_LIMIT] = { .type = NLA_U8 },
+ [IFLA_IPTUN_FLOWINFO] = { .type = NLA_U32},
+};
/* these strings must match the .kind entries in the kernel */
static const char* const nl_union_link_info_data_table[_NL_UNION_LINK_INFO_DATA_MAX] = {
[NL_UNION_LINK_INFO_DATA_BRIDGE] = "bridge",
[NL_UNION_LINK_INFO_DATA_VLAN] = "vlan",
[NL_UNION_LINK_INFO_DATA_VETH] = "veth",
+ [NL_UNION_LINK_INFO_DATA_DUMMY] = "dummy",
[NL_UNION_LINK_INFO_DATA_MACVLAN] = "macvlan",
+ [NL_UNION_LINK_INFO_DATA_IPVLAN] = "ipvlan",
[NL_UNION_LINK_INFO_DATA_VXLAN] = "vxlan",
[NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = "ipip",
[NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = "gre",
+ [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = "gretap",
+ [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = "ip6gre",
+ [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = "ip6gretap",
[NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = "sit",
[NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = "vti",
+ [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = "ip6tnl",
};
DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData);
.types = rtnl_link_info_data_veth_types },
[NL_UNION_LINK_INFO_DATA_MACVLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_macvlan_types) - 1,
.types = rtnl_link_info_data_macvlan_types },
+ [NL_UNION_LINK_INFO_DATA_IPVLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvlan_types) - 1,
+ .types = rtnl_link_info_data_ipvlan_types },
[NL_UNION_LINK_INFO_DATA_VXLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_vxlan_types) - 1,
.types = rtnl_link_info_data_vxlan_types },
[NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1,
.types = rtnl_link_info_data_iptun_types },
[NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
.types = rtnl_link_info_data_ipgre_types },
+ [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
+ .types = rtnl_link_info_data_ipgre_types },
+ [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
+ .types = rtnl_link_info_data_ipgre_types },
+ [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
+ .types = rtnl_link_info_data_ipgre_types },
[NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1,
.types = rtnl_link_info_data_iptun_types },
[NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvti_types) - 1,
.types = rtnl_link_info_data_ipvti_types },
+ [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types) - 1,
+ .types = rtnl_link_info_data_ip6tnl_types },
+
};
static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = {
.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 NLType rtnl_link_types[IFLA_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_MODE] = { .type = NLA_U8 },
+ [IFLA_BRPORT_GUARD] = { .type = NLA_U8 },
+ [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 },
+ [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 },
+ [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 },
+};
+
+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_ADDRESS] = { .type = NLA_ETHER_ADDR, },
[IFLA_BROADCAST] = { .type = NLA_ETHER_ADDR, },
[IFLA_IFNAME] = { .type = NLA_STRING, .size = IFNAMSIZ - 1, },
[IFLA_MASTER] = { .type = NLA_U32 },
/*
[IFLA_WIRELESS],
- [IFLA_PROTINFO],
*/
+ [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],
.types = rtnl_route_types,
};
+static const NLType rtnl_neigh_types[NDA_MAX + 1] = {
+ [NDA_DST] = { .type = NLA_IN_ADDR },
+ [NDA_LLADDR] = { .type = NLA_ETHER_ADDR },
+ [NDA_CACHEINFO] = { .type = NLA_CACHE_INFO, .size = sizeof(struct nda_cacheinfo) },
+ [NDA_PROBES] = { .type = NLA_U32 },
+ [NDA_VLAN] = { .type = NLA_U16 },
+ [NDA_PORT] = { .type = NLA_U16 },
+ [NDA_VNI] = { .type = NLA_U32 },
+ [NDA_IFINDEX] = { .type = NLA_U32 },
+};
+
+static const NLTypeSystem rtnl_neigh_type_system = {
+ .max = ELEMENTSOF(rtnl_neigh_types) - 1,
+ .types = rtnl_neigh_types,
+};
+
static const NLType rtnl_types[RTM_MAX + 1] = {
[NLMSG_ERROR] = { .type = NLA_META, .size = sizeof(struct nlmsgerr) },
[RTM_NEWLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
[RTM_NEWROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
[RTM_DELROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
[RTM_GETROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
+ [RTM_NEWNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
+ [RTM_DELNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
+ [RTM_GETNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
};
const NLTypeSystem rtnl_type_system = {
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);
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 -ENOTSUP;
+
+ type_system = &type_system_union->type_systems[protocol];
+ if (type_system->max == 0)
+ return -ENOTSUP;
+
+ *ret = type_system;
+
+ return 0;
+}