chiark / gitweb /
sd-netlink: don't export internal type-system details
[elogind.git] / src / libsystemd / sd-netlink / netlink-types.c
index 72799da8870c94382289b14b8f87058f04abc725..74ac2ab344d7f271a831b24a8f0e6175b98a2797 100644 (file)
 #include "netlink-types.h"
 #include "missing.h"
 
+/* Maximum ARP IP target defined in kernel */
+#define BOND_MAX_ARP_TARGETS    16
+
+typedef enum {
+        BOND_ARP_TARGETS_0,
+        BOND_ARP_TARGETS_1,
+        BOND_ARP_TARGETS_2,
+        BOND_ARP_TARGETS_3,
+        BOND_ARP_TARGETS_4,
+        BOND_ARP_TARGETS_5,
+        BOND_ARP_TARGETS_6,
+        BOND_ARP_TARGETS_7,
+        BOND_ARP_TARGETS_8,
+        BOND_ARP_TARGETS_9,
+        BOND_ARP_TARGETS_10,
+        BOND_ARP_TARGETS_11,
+        BOND_ARP_TARGETS_12,
+        BOND_ARP_TARGETS_13,
+        BOND_ARP_TARGETS_14,
+        BOND_ARP_TARGETS_MAX = BOND_MAX_ARP_TARGETS,
+} BondArpTargets;
+
+struct NLType {
+        uint16_t type;
+        size_t size;
+        const NLTypeSystem *type_system;
+        const NLTypeSystemUnion *type_system_union;
+};
+
+struct NLTypeSystem {
+        uint16_t count;
+        const NLType *types;
+};
+
 static const NLTypeSystem rtnl_link_type_system;
 
+static const NLType empty_types[1] = {
+        /* fake array to avoid .types==NULL, which denotes invalid type-systems */
+};
+
+static const NLTypeSystem empty_type_system = {
+        .count = 0,
+        .types = empty_types,
+};
+
 static const NLType rtnl_link_info_data_veth_types[VETH_INFO_MAX + 1] = {
         [VETH_INFO_PEER]  = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
 };
@@ -110,7 +153,7 @@ static const NLType rtnl_bond_arp_target_types[BOND_ARP_TARGETS_MAX + 1] = {
 };
 
 static const NLTypeSystem rtnl_bond_arp_type_system = {
-        .max = ELEMENTSOF(rtnl_bond_arp_target_types) - 1,
+        .count = ELEMENTSOF(rtnl_bond_arp_target_types),
         .types = rtnl_bond_arp_target_types,
 };
 
@@ -211,37 +254,37 @@ static const char* const nl_union_link_info_data_table[_NL_UNION_LINK_INFO_DATA_
 DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData);
 
 static const NLTypeSystem rtnl_link_info_data_type_systems[_NL_UNION_LINK_INFO_DATA_MAX] = {
-        [NL_UNION_LINK_INFO_DATA_BOND] =        { .max = ELEMENTSOF(rtnl_link_info_data_bond_types) - 1,
+        [NL_UNION_LINK_INFO_DATA_BOND] =        { .count = ELEMENTSOF(rtnl_link_info_data_bond_types),
                                                   .types = rtnl_link_info_data_bond_types },
-        [NL_UNION_LINK_INFO_DATA_BRIDGE] =      { .max = ELEMENTSOF(rtnl_link_info_data_bridge_types) - 1,
+        [NL_UNION_LINK_INFO_DATA_BRIDGE] =      { .count = ELEMENTSOF(rtnl_link_info_data_bridge_types),
                                                   .types = rtnl_link_info_data_bridge_types },
-        [NL_UNION_LINK_INFO_DATA_VLAN] =        { .max = ELEMENTSOF(rtnl_link_info_data_vlan_types) - 1,
+        [NL_UNION_LINK_INFO_DATA_VLAN] =        { .count = ELEMENTSOF(rtnl_link_info_data_vlan_types),
                                                   .types = rtnl_link_info_data_vlan_types },
-        [NL_UNION_LINK_INFO_DATA_VETH] =        { .max = ELEMENTSOF(rtnl_link_info_data_veth_types) - 1,
+        [NL_UNION_LINK_INFO_DATA_VETH] =        { .count = ELEMENTSOF(rtnl_link_info_data_veth_types),
                                                   .types = rtnl_link_info_data_veth_types },
-        [NL_UNION_LINK_INFO_DATA_MACVLAN] =     { .max = ELEMENTSOF(rtnl_link_info_data_macvlan_types) - 1,
+        [NL_UNION_LINK_INFO_DATA_MACVLAN] =     { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types),
                                                   .types = rtnl_link_info_data_macvlan_types },
-        [NL_UNION_LINK_INFO_DATA_IPVLAN] =      { .max = ELEMENTSOF(rtnl_link_info_data_ipvlan_types) - 1,
+        [NL_UNION_LINK_INFO_DATA_IPVLAN] =      { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types),
                                                   .types = rtnl_link_info_data_ipvlan_types },
-        [NL_UNION_LINK_INFO_DATA_VXLAN] =       { .max = ELEMENTSOF(rtnl_link_info_data_vxlan_types) - 1,
+        [NL_UNION_LINK_INFO_DATA_VXLAN] =       { .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types),
                                                   .types = rtnl_link_info_data_vxlan_types },
-        [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1,
+        [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types),
                                                   .types = rtnl_link_info_data_iptun_types },
-        [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] =  { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
+        [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
                                                     .types = rtnl_link_info_data_ipgre_types },
-        [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] =  { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
+        [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
                                                     .types = rtnl_link_info_data_ipgre_types },
-        [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] =  { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
+        [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
                                                     .types = rtnl_link_info_data_ipgre_types },
-        [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] =  { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
+        [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
                                                     .types = rtnl_link_info_data_ipgre_types },
-        [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] =  { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1,
+        [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types),
                                                   .types = rtnl_link_info_data_iptun_types },
-        [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] =  { .max = ELEMENTSOF(rtnl_link_info_data_ipvti_types) - 1,
+        [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types),
                                                   .types = rtnl_link_info_data_ipvti_types },
-        [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] =  { .max = ELEMENTSOF(rtnl_link_info_data_ipvti_types) - 1,
+        [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types),
                                                   .types = rtnl_link_info_data_ipvti_types },
-        [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] =  { .max = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types) - 1,
+        [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types),
                                                      .types = rtnl_link_info_data_ip6tnl_types },
 
 };
@@ -265,7 +308,7 @@ static const NLType rtnl_link_info_types[IFLA_INFO_MAX + 1] = {
 };
 
 static const NLTypeSystem rtnl_link_info_type_system = {
-        .max = ELEMENTSOF(rtnl_link_info_types) - 1,
+        .count = ELEMENTSOF(rtnl_link_info_types),
         .types = rtnl_link_info_types,
 };
 
@@ -281,7 +324,7 @@ static const struct NLType rtnl_prot_info_bridge_port_types[IFLA_BRPORT_MAX + 1]
 };
 
 static const NLTypeSystem rtnl_prot_info_type_systems[AF_MAX] = {
-        [AF_BRIDGE] =   { .max = ELEMENTSOF(rtnl_prot_info_bridge_port_types) - 1,
+        [AF_BRIDGE] =   { .count = ELEMENTSOF(rtnl_prot_info_bridge_port_types),
                           .types = rtnl_prot_info_bridge_port_types },
 };
 
@@ -305,7 +348,7 @@ static const struct NLType rtnl_af_spec_inet6_types[IFLA_INET6_MAX + 1] = {
 };
 
 static const NLTypeSystem rtnl_af_spec_inet6_type_system = {
-        .max = ELEMENTSOF(rtnl_af_spec_inet6_types) - 1,
+        .count = ELEMENTSOF(rtnl_af_spec_inet6_types),
         .types = rtnl_af_spec_inet6_types,
 };
 
@@ -314,7 +357,7 @@ static const NLType rtnl_af_spec_types[AF_MAX + 1] = {
 };
 
 static const NLTypeSystem rtnl_af_spec_type_system = {
-        .max = ELEMENTSOF(rtnl_af_spec_types) - 1,
+        .count = ELEMENTSOF(rtnl_af_spec_types),
         .types = rtnl_af_spec_types,
 };
 
@@ -371,7 +414,7 @@ static const NLType rtnl_link_types[IFLA_MAX + 1 ] = {
 };
 
 static const NLTypeSystem rtnl_link_type_system = {
-        .max = ELEMENTSOF(rtnl_link_types) - 1,
+        .count = ELEMENTSOF(rtnl_link_types),
         .types = rtnl_link_types,
 };
 
@@ -391,7 +434,7 @@ static const NLType rtnl_address_types[CONST_MAX(IFA_MAX, IFA_FLAGS) + 1] = {
 };
 
 static const NLTypeSystem rtnl_address_type_system = {
-        .max = ELEMENTSOF(rtnl_address_types) - 1,
+        .count = ELEMENTSOF(rtnl_address_types),
         .types = rtnl_address_types,
 };
 
@@ -417,7 +460,7 @@ static const NLType rtnl_route_types[RTA_MAX + 1] = {
 };
 
 static const NLTypeSystem rtnl_route_type_system = {
-        .max = ELEMENTSOF(rtnl_route_types) - 1,
+        .count = ELEMENTSOF(rtnl_route_types),
         .types = rtnl_route_types,
 };
 
@@ -433,13 +476,13 @@ static const NLType rtnl_neigh_types[NDA_MAX + 1] = {
 };
 
 static const NLTypeSystem rtnl_neigh_type_system = {
-        .max = ELEMENTSOF(rtnl_neigh_types) - 1,
+        .count = ELEMENTSOF(rtnl_neigh_types),
         .types = rtnl_neigh_types,
 };
 
 static const NLType rtnl_types[RTM_MAX + 1] = {
-        [NLMSG_DONE]   = { .type = NETLINK_TYPE_META, .size = 0 },
-        [NLMSG_ERROR]  = { .type = NETLINK_TYPE_META, .size = sizeof(struct nlmsgerr) },
+        [NLMSG_DONE]   = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 },
+        [NLMSG_ERROR]  = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = sizeof(struct nlmsgerr) },
         [RTM_NEWLINK]  = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
         [RTM_DELLINK]  = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
         [RTM_GETLINK]  = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
@@ -455,22 +498,52 @@ static const NLType rtnl_types[RTM_MAX + 1] = {
         [RTM_GETNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
 };
 
-const NLTypeSystem rtnl_type_system = {
-        .max = ELEMENTSOF(rtnl_types) - 1,
+const NLTypeSystem type_system_root = {
+        .count = ELEMENTSOF(rtnl_types),
         .types = rtnl_types,
 };
 
-int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) {
-        const NLType *nl_type;
+uint16_t type_get_type(const NLType *type) {
+        assert(type);
+        return type->type;
+}
+
+size_t type_get_size(const NLType *type) {
+        assert(type);
+        return type->size;
+}
 
+void type_get_type_system(const NLType *nl_type, const NLTypeSystem **ret) {
+        assert(nl_type);
         assert(ret);
+        assert(nl_type->type == NETLINK_TYPE_NESTED);
+        assert(nl_type->type_system);
 
-        if (!type_system)
-                type_system = &rtnl_type_system;
+        *ret = nl_type->type_system;
+}
 
+void type_get_type_system_union(const NLType *nl_type, const NLTypeSystemUnion **ret) {
+        assert(nl_type);
+        assert(ret);
+        assert(nl_type->type == NETLINK_TYPE_UNION);
+        assert(nl_type->type_system_union);
+
+        *ret = nl_type->type_system_union;
+}
+
+uint16_t type_system_get_count(const NLTypeSystem *type_system) {
+        assert(type_system);
+        return type_system->count;
+}
+
+int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) {
+        const NLType *nl_type;
+
+        assert(ret);
+        assert(type_system);
         assert(type_system->types);
 
-        if (type > type_system->max)
+        if (type >= type_system->count)
                 return -EOPNOTSUPP;
 
         nl_type = &type_system->types[type];
@@ -493,11 +566,7 @@ int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSys
         if (r < 0)
                 return r;
 
-        assert(nl_type->type == NETLINK_TYPE_NESTED);
-        assert(nl_type->type_system);
-
-        *ret = nl_type->type_system;
-
+        type_get_type_system(nl_type, ret);
         return 0;
 }
 
@@ -511,11 +580,7 @@ int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLT
         if (r < 0)
                 return r;
 
-        assert(nl_type->type == NETLINK_TYPE_UNION);
-        assert(nl_type->type_system_union);
-
-        *ret = nl_type->type_system_union;
-
+        type_get_type_system_union(nl_type, ret);
         return 0;
 }
 
@@ -552,7 +617,7 @@ int type_system_union_protocol_get_type_system(const NLTypeSystemUnion *type_sys
                 return -EOPNOTSUPP;
 
         type_system = &type_system_union->type_systems[protocol];
-        if (type_system->max == 0)
+        if (!type_system->types)
                 return -EOPNOTSUPP;
 
         *ret = type_system;