LCOV - code coverage report
Current view: top level - libsystemd/sd-netlink - netlink-types.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 70 80 87.5 %
Date: 2019-08-22 15:41:25 Functions: 12 13 92.3 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include <netinet/in.h>
       4             : #include <stdint.h>
       5             : #include <sys/socket.h>
       6             : #include <linux/can/vxcan.h>
       7             : #include <linux/netlink.h>
       8             : #include <linux/rtnetlink.h>
       9             : #include <linux/genetlink.h>
      10             : #include <linux/ip.h>
      11             : #include <linux/if.h>
      12             : #include <linux/can/netlink.h>
      13             : #include <linux/fib_rules.h>
      14             : #include <linux/fou.h>
      15             : #include <linux/if_addr.h>
      16             : #include <linux/if_addrlabel.h>
      17             : #include <linux/if_bridge.h>
      18             : #include <linux/if_link.h>
      19             : #include <linux/if_macsec.h>
      20             : #include <linux/if_tunnel.h>
      21             : #include <linux/l2tp.h>
      22             : #include <linux/veth.h>
      23             : #include <linux/wireguard.h>
      24             : 
      25             : #include "macro.h"
      26             : #include "missing.h"
      27             : #include "netlink-types.h"
      28             : #include "sd-netlink.h"
      29             : #include "string-table.h"
      30             : #include "util.h"
      31             : 
      32             : /* Maximum ARP IP target defined in kernel */
      33             : #define BOND_MAX_ARP_TARGETS    16
      34             : 
      35             : typedef enum {
      36             :         BOND_ARP_TARGETS_0,
      37             :         BOND_ARP_TARGETS_1,
      38             :         BOND_ARP_TARGETS_2,
      39             :         BOND_ARP_TARGETS_3,
      40             :         BOND_ARP_TARGETS_4,
      41             :         BOND_ARP_TARGETS_5,
      42             :         BOND_ARP_TARGETS_6,
      43             :         BOND_ARP_TARGETS_7,
      44             :         BOND_ARP_TARGETS_8,
      45             :         BOND_ARP_TARGETS_9,
      46             :         BOND_ARP_TARGETS_10,
      47             :         BOND_ARP_TARGETS_11,
      48             :         BOND_ARP_TARGETS_12,
      49             :         BOND_ARP_TARGETS_13,
      50             :         BOND_ARP_TARGETS_14,
      51             :         BOND_ARP_TARGETS_MAX = BOND_MAX_ARP_TARGETS,
      52             : } BondArpTargets;
      53             : 
      54             : struct NLType {
      55             :         uint16_t type;
      56             :         size_t size;
      57             :         const NLTypeSystem *type_system;
      58             :         const NLTypeSystemUnion *type_system_union;
      59             : };
      60             : 
      61             : struct NLTypeSystem {
      62             :         uint16_t count;
      63             :         const NLType *types;
      64             : };
      65             : 
      66             : static const NLTypeSystem rtnl_link_type_system;
      67             : 
      68             : static const NLType empty_types[1] = {
      69             :         /* fake array to avoid .types==NULL, which denotes invalid type-systems */
      70             : };
      71             : 
      72             : static const NLTypeSystem empty_type_system = {
      73             :         .count = 0,
      74             :         .types = empty_types,
      75             : };
      76             : 
      77             : static const NLType rtnl_link_info_data_veth_types[] = {
      78             :         [VETH_INFO_PEER]  = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
      79             : };
      80             : 
      81             : static const NLType rtnl_link_info_data_vxcan_types[] = {
      82             :         [VXCAN_INFO_PEER]  = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
      83             : };
      84             : 
      85             : static const NLType rtnl_link_info_data_ipvlan_types[] = {
      86             :         [IFLA_IPVLAN_MODE]  = { .type = NETLINK_TYPE_U16 },
      87             :         [IFLA_IPVLAN_FLAGS]  = { .type = NETLINK_TYPE_U16 },
      88             : };
      89             : 
      90             : static const NLType rtnl_link_info_data_macvlan_types[] = {
      91             :         [IFLA_MACVLAN_MODE]  = { .type = NETLINK_TYPE_U32 },
      92             :         [IFLA_MACVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 },
      93             : };
      94             : 
      95             : static const NLType rtnl_link_info_data_bridge_types[] = {
      96             :         [IFLA_BR_FORWARD_DELAY]              = { .type = NETLINK_TYPE_U32 },
      97             :         [IFLA_BR_HELLO_TIME]                 = { .type = NETLINK_TYPE_U32 },
      98             :         [IFLA_BR_MAX_AGE]                    = { .type = NETLINK_TYPE_U32 },
      99             :         [IFLA_BR_AGEING_TIME]                = { .type = NETLINK_TYPE_U32 },
     100             :         [IFLA_BR_STP_STATE]                  = { .type = NETLINK_TYPE_U32 },
     101             :         [IFLA_BR_PRIORITY]                   = { .type = NETLINK_TYPE_U16 },
     102             :         [IFLA_BR_VLAN_FILTERING]             = { .type = NETLINK_TYPE_U8 },
     103             :         [IFLA_BR_VLAN_PROTOCOL]              = { .type = NETLINK_TYPE_U16 },
     104             :         [IFLA_BR_GROUP_FWD_MASK]             = { .type = NETLINK_TYPE_U16 },
     105             :         [IFLA_BR_ROOT_PORT]                  = { .type = NETLINK_TYPE_U16 },
     106             :         [IFLA_BR_ROOT_PATH_COST]             = { .type = NETLINK_TYPE_U32 },
     107             :         [IFLA_BR_TOPOLOGY_CHANGE]            = { .type = NETLINK_TYPE_U8 },
     108             :         [IFLA_BR_TOPOLOGY_CHANGE_DETECTED]   = { .type = NETLINK_TYPE_U8 },
     109             :         [IFLA_BR_HELLO_TIMER]                = { .type = NETLINK_TYPE_U16 },
     110             :         [IFLA_BR_TCN_TIMER]                  = { .type = NETLINK_TYPE_U16 },
     111             :         [IFLA_BR_TOPOLOGY_CHANGE_TIMER]      = { .type = NETLINK_TYPE_U16 },
     112             :         [IFLA_BR_GC_TIMER]                   = { .type = NETLINK_TYPE_U64 },
     113             :         [IFLA_BR_GROUP_ADDR]                 = { .type = NETLINK_TYPE_U16 },
     114             :         [IFLA_BR_FDB_FLUSH]                  = { .type = NETLINK_TYPE_U16 },
     115             :         [IFLA_BR_MCAST_ROUTER]               = { .type = NETLINK_TYPE_U8 },
     116             :         [IFLA_BR_MCAST_SNOOPING]             = { .type = NETLINK_TYPE_U8 },
     117             :         [IFLA_BR_MCAST_QUERY_USE_IFADDR]     = { .type = NETLINK_TYPE_U8 },
     118             :         [IFLA_BR_MCAST_QUERIER]              = { .type = NETLINK_TYPE_U8 },
     119             :         [IFLA_BR_MCAST_HASH_ELASTICITY]      = { .type = NETLINK_TYPE_U32 },
     120             :         [IFLA_BR_MCAST_HASH_MAX]             = { .type = NETLINK_TYPE_U16 },
     121             :         [IFLA_BR_MCAST_LAST_MEMBER_CNT]      = { .type = NETLINK_TYPE_U32 },
     122             :         [IFLA_BR_MCAST_STARTUP_QUERY_CNT]    = { .type = NETLINK_TYPE_U16 },
     123             :         [IFLA_BR_MCAST_LAST_MEMBER_INTVL]    = { .type = NETLINK_TYPE_U64 },
     124             :         [IFLA_BR_MCAST_MEMBERSHIP_INTVL]     = { .type = NETLINK_TYPE_U64 },
     125             :         [IFLA_BR_MCAST_QUERIER_INTVL]        = { .type = NETLINK_TYPE_U64 },
     126             :         [IFLA_BR_MCAST_QUERY_INTVL]          = { .type = NETLINK_TYPE_U64 },
     127             :         [IFLA_BR_MCAST_QUERY_RESPONSE_INTVL] = { .type = NETLINK_TYPE_U64 },
     128             :         [IFLA_BR_MCAST_STARTUP_QUERY_INTVL]  = { .type = NETLINK_TYPE_U64 },
     129             :         [IFLA_BR_NF_CALL_IPTABLES]           = { .type = NETLINK_TYPE_U8 },
     130             :         [IFLA_BR_NF_CALL_IP6TABLES]          = { .type = NETLINK_TYPE_U8 },
     131             :         [IFLA_BR_NF_CALL_ARPTABLES]          = { .type = NETLINK_TYPE_U8 },
     132             :         [IFLA_BR_VLAN_DEFAULT_PVID]          = { .type = NETLINK_TYPE_U16 },
     133             :         [IFLA_BR_MCAST_IGMP_VERSION]         = { .type = NETLINK_TYPE_U8 },
     134             : };
     135             : 
     136             : static const NLType rtnl_link_info_data_vlan_types[] = {
     137             :         [IFLA_VLAN_ID]          = { .type = NETLINK_TYPE_U16 },
     138             : /*
     139             :         [IFLA_VLAN_FLAGS]       = { .len = sizeof(struct ifla_vlan_flags) },
     140             :         [IFLA_VLAN_EGRESS_QOS]  = { .type = NETLINK_TYPE_NESTED },
     141             :         [IFLA_VLAN_INGRESS_QOS] = { .type = NETLINK_TYPE_NESTED },
     142             : */
     143             :         [IFLA_VLAN_PROTOCOL]    = { .type = NETLINK_TYPE_U16 },
     144             : };
     145             : 
     146             : static const NLType rtnl_link_info_data_vxlan_types[] = {
     147             :         [IFLA_VXLAN_ID]                = { .type = NETLINK_TYPE_U32 },
     148             :         [IFLA_VXLAN_GROUP]             = { .type = NETLINK_TYPE_IN_ADDR },
     149             :         [IFLA_VXLAN_LINK]              = { .type = NETLINK_TYPE_U32 },
     150             :         [IFLA_VXLAN_LOCAL]             = { .type = NETLINK_TYPE_IN_ADDR },
     151             :         [IFLA_VXLAN_TTL]               = { .type = NETLINK_TYPE_U8 },
     152             :         [IFLA_VXLAN_TOS]               = { .type = NETLINK_TYPE_U8 },
     153             :         [IFLA_VXLAN_LEARNING]          = { .type = NETLINK_TYPE_U8 },
     154             :         [IFLA_VXLAN_AGEING]            = { .type = NETLINK_TYPE_U32 },
     155             :         [IFLA_VXLAN_LIMIT]             = { .type = NETLINK_TYPE_U32 },
     156             :         [IFLA_VXLAN_PORT_RANGE]        = { .type = NETLINK_TYPE_U32},
     157             :         [IFLA_VXLAN_PROXY]             = { .type = NETLINK_TYPE_U8 },
     158             :         [IFLA_VXLAN_RSC]               = { .type = NETLINK_TYPE_U8 },
     159             :         [IFLA_VXLAN_L2MISS]            = { .type = NETLINK_TYPE_U8 },
     160             :         [IFLA_VXLAN_L3MISS]            = { .type = NETLINK_TYPE_U8 },
     161             :         [IFLA_VXLAN_PORT]              = { .type = NETLINK_TYPE_U16 },
     162             :         [IFLA_VXLAN_GROUP6]            = { .type = NETLINK_TYPE_IN_ADDR },
     163             :         [IFLA_VXLAN_LOCAL6]            = { .type = NETLINK_TYPE_IN_ADDR },
     164             :         [IFLA_VXLAN_UDP_CSUM]          = { .type = NETLINK_TYPE_U8 },
     165             :         [IFLA_VXLAN_UDP_ZERO_CSUM6_TX] = { .type = NETLINK_TYPE_U8 },
     166             :         [IFLA_VXLAN_UDP_ZERO_CSUM6_RX] = { .type = NETLINK_TYPE_U8 },
     167             :         [IFLA_VXLAN_REMCSUM_TX]        = { .type = NETLINK_TYPE_U8 },
     168             :         [IFLA_VXLAN_REMCSUM_RX]        = { .type = NETLINK_TYPE_U8 },
     169             :         [IFLA_VXLAN_GBP]               = { .type = NETLINK_TYPE_FLAG },
     170             :         [IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NETLINK_TYPE_FLAG },
     171             :         [IFLA_VXLAN_COLLECT_METADATA]  = { .type = NETLINK_TYPE_U8 },
     172             :         [IFLA_VXLAN_LABEL]             = { .type = NETLINK_TYPE_U32 },
     173             :         [IFLA_VXLAN_GPE]               = { .type = NETLINK_TYPE_FLAG },
     174             :         [IFLA_VXLAN_TTL_INHERIT]       = { .type = NETLINK_TYPE_FLAG },
     175             :         [IFLA_VXLAN_DF]                = { .type = NETLINK_TYPE_U8 },
     176             : };
     177             : 
     178             : static const NLType rtnl_bond_arp_target_types[] = {
     179             :         [BOND_ARP_TARGETS_0]        = { .type = NETLINK_TYPE_U32 },
     180             :         [BOND_ARP_TARGETS_1]        = { .type = NETLINK_TYPE_U32 },
     181             :         [BOND_ARP_TARGETS_2]        = { .type = NETLINK_TYPE_U32 },
     182             :         [BOND_ARP_TARGETS_3]        = { .type = NETLINK_TYPE_U32 },
     183             :         [BOND_ARP_TARGETS_4]        = { .type = NETLINK_TYPE_U32 },
     184             :         [BOND_ARP_TARGETS_5]        = { .type = NETLINK_TYPE_U32 },
     185             :         [BOND_ARP_TARGETS_6]        = { .type = NETLINK_TYPE_U32 },
     186             :         [BOND_ARP_TARGETS_7]        = { .type = NETLINK_TYPE_U32 },
     187             :         [BOND_ARP_TARGETS_8]        = { .type = NETLINK_TYPE_U32 },
     188             :         [BOND_ARP_TARGETS_9]        = { .type = NETLINK_TYPE_U32 },
     189             :         [BOND_ARP_TARGETS_10]       = { .type = NETLINK_TYPE_U32 },
     190             :         [BOND_ARP_TARGETS_11]       = { .type = NETLINK_TYPE_U32 },
     191             :         [BOND_ARP_TARGETS_12]       = { .type = NETLINK_TYPE_U32 },
     192             :         [BOND_ARP_TARGETS_13]       = { .type = NETLINK_TYPE_U32 },
     193             :         [BOND_ARP_TARGETS_14]       = { .type = NETLINK_TYPE_U32 },
     194             :         [BOND_ARP_TARGETS_MAX]      = { .type = NETLINK_TYPE_U32 },
     195             : };
     196             : 
     197             : static const NLTypeSystem rtnl_bond_arp_type_system = {
     198             :         .count = ELEMENTSOF(rtnl_bond_arp_target_types),
     199             :         .types = rtnl_bond_arp_target_types,
     200             : };
     201             : 
     202             : static const NLType rtnl_link_info_data_bond_types[] = {
     203             :         [IFLA_BOND_MODE]                = { .type = NETLINK_TYPE_U8 },
     204             :         [IFLA_BOND_ACTIVE_SLAVE]        = { .type = NETLINK_TYPE_U32 },
     205             :         [IFLA_BOND_MIIMON]              = { .type = NETLINK_TYPE_U32 },
     206             :         [IFLA_BOND_UPDELAY]             = { .type = NETLINK_TYPE_U32 },
     207             :         [IFLA_BOND_DOWNDELAY]           = { .type = NETLINK_TYPE_U32 },
     208             :         [IFLA_BOND_USE_CARRIER]         = { .type = NETLINK_TYPE_U8 },
     209             :         [IFLA_BOND_ARP_INTERVAL]        = { .type = NETLINK_TYPE_U32 },
     210             :         [IFLA_BOND_ARP_IP_TARGET]       = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bond_arp_type_system },
     211             :         [IFLA_BOND_ARP_VALIDATE]        = { .type = NETLINK_TYPE_U32 },
     212             :         [IFLA_BOND_ARP_ALL_TARGETS]     = { .type = NETLINK_TYPE_U32 },
     213             :         [IFLA_BOND_PRIMARY]             = { .type = NETLINK_TYPE_U32 },
     214             :         [IFLA_BOND_PRIMARY_RESELECT]    = { .type = NETLINK_TYPE_U8 },
     215             :         [IFLA_BOND_FAIL_OVER_MAC]       = { .type = NETLINK_TYPE_U8 },
     216             :         [IFLA_BOND_XMIT_HASH_POLICY]    = { .type = NETLINK_TYPE_U8 },
     217             :         [IFLA_BOND_RESEND_IGMP]         = { .type = NETLINK_TYPE_U32 },
     218             :         [IFLA_BOND_NUM_PEER_NOTIF]      = { .type = NETLINK_TYPE_U8 },
     219             :         [IFLA_BOND_ALL_SLAVES_ACTIVE]   = { .type = NETLINK_TYPE_U8 },
     220             :         [IFLA_BOND_MIN_LINKS]           = { .type = NETLINK_TYPE_U32 },
     221             :         [IFLA_BOND_LP_INTERVAL]         = { .type = NETLINK_TYPE_U32 },
     222             :         [IFLA_BOND_PACKETS_PER_SLAVE]   = { .type = NETLINK_TYPE_U32 },
     223             :         [IFLA_BOND_AD_LACP_RATE]        = { .type = NETLINK_TYPE_U8 },
     224             :         [IFLA_BOND_AD_SELECT]           = { .type = NETLINK_TYPE_U8 },
     225             :         [IFLA_BOND_AD_INFO]             = { .type = NETLINK_TYPE_NESTED },
     226             :         [IFLA_BOND_AD_ACTOR_SYS_PRIO]   = { .type = NETLINK_TYPE_U16 },
     227             :         [IFLA_BOND_AD_USER_PORT_KEY]    = { .type = NETLINK_TYPE_U16 },
     228             :         [IFLA_BOND_AD_ACTOR_SYSTEM]     = { .type = NETLINK_TYPE_ETHER_ADDR },
     229             :         [IFLA_BOND_TLB_DYNAMIC_LB]      = { .type = NETLINK_TYPE_U8 },
     230             : };
     231             : 
     232             : static const NLType rtnl_link_info_data_iptun_types[] = {
     233             :         [IFLA_IPTUN_LINK]                = { .type = NETLINK_TYPE_U32 },
     234             :         [IFLA_IPTUN_LOCAL]               = { .type = NETLINK_TYPE_IN_ADDR },
     235             :         [IFLA_IPTUN_REMOTE]              = { .type = NETLINK_TYPE_IN_ADDR },
     236             :         [IFLA_IPTUN_TTL]                 = { .type = NETLINK_TYPE_U8 },
     237             :         [IFLA_IPTUN_TOS]                 = { .type = NETLINK_TYPE_U8 },
     238             :         [IFLA_IPTUN_PMTUDISC]            = { .type = NETLINK_TYPE_U8 },
     239             :         [IFLA_IPTUN_FLAGS]               = { .type = NETLINK_TYPE_U16 },
     240             :         [IFLA_IPTUN_PROTO]               = { .type = NETLINK_TYPE_U8 },
     241             :         [IFLA_IPTUN_6RD_PREFIX]          = { .type = NETLINK_TYPE_IN_ADDR },
     242             :         [IFLA_IPTUN_6RD_RELAY_PREFIX]    = { .type = NETLINK_TYPE_U32 },
     243             :         [IFLA_IPTUN_6RD_PREFIXLEN]       = { .type = NETLINK_TYPE_U16 },
     244             :         [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NETLINK_TYPE_U16 },
     245             :         [IFLA_IPTUN_ENCAP_TYPE]          = { .type = NETLINK_TYPE_U16 },
     246             :         [IFLA_IPTUN_ENCAP_FLAGS]         = { .type = NETLINK_TYPE_U16 },
     247             :         [IFLA_IPTUN_ENCAP_SPORT]         = { .type = NETLINK_TYPE_U16 },
     248             :         [IFLA_IPTUN_ENCAP_DPORT]         = { .type = NETLINK_TYPE_U16 },
     249             : };
     250             : 
     251             : static  const NLType rtnl_link_info_data_ipgre_types[] = {
     252             :         [IFLA_GRE_LINK]         = { .type = NETLINK_TYPE_U32 },
     253             :         [IFLA_GRE_IFLAGS]       = { .type = NETLINK_TYPE_U16 },
     254             :         [IFLA_GRE_OFLAGS]       = { .type = NETLINK_TYPE_U16 },
     255             :         [IFLA_GRE_IKEY]         = { .type = NETLINK_TYPE_U32 },
     256             :         [IFLA_GRE_OKEY]         = { .type = NETLINK_TYPE_U32 },
     257             :         [IFLA_GRE_LOCAL]        = { .type = NETLINK_TYPE_IN_ADDR },
     258             :         [IFLA_GRE_REMOTE]       = { .type = NETLINK_TYPE_IN_ADDR },
     259             :         [IFLA_GRE_TTL]          = { .type = NETLINK_TYPE_U8 },
     260             :         [IFLA_GRE_TOS]          = { .type = NETLINK_TYPE_U8 },
     261             :         [IFLA_GRE_PMTUDISC]     = { .type = NETLINK_TYPE_U8 },
     262             :         [IFLA_GRE_FLOWINFO]     = { .type = NETLINK_TYPE_U32 },
     263             :         [IFLA_GRE_FLAGS]        = { .type = NETLINK_TYPE_U32 },
     264             :         [IFLA_GRE_ENCAP_TYPE]   = { .type = NETLINK_TYPE_U16 },
     265             :         [IFLA_GRE_ENCAP_FLAGS]  = { .type = NETLINK_TYPE_U16 },
     266             :         [IFLA_GRE_ENCAP_SPORT]  = { .type = NETLINK_TYPE_U16 },
     267             :         [IFLA_GRE_ENCAP_DPORT]  = { .type = NETLINK_TYPE_U16 },
     268             :         [IFLA_GRE_ERSPAN_INDEX] = { .type = NETLINK_TYPE_U32 },
     269             : };
     270             : 
     271             : static const NLType rtnl_link_info_data_ipvti_types[] = {
     272             :         [IFLA_VTI_LINK]         = { .type = NETLINK_TYPE_U32 },
     273             :         [IFLA_VTI_IKEY]         = { .type = NETLINK_TYPE_U32 },
     274             :         [IFLA_VTI_OKEY]         = { .type = NETLINK_TYPE_U32 },
     275             :         [IFLA_VTI_LOCAL]        = { .type = NETLINK_TYPE_IN_ADDR },
     276             :         [IFLA_VTI_REMOTE]       = { .type = NETLINK_TYPE_IN_ADDR },
     277             : };
     278             : 
     279             : static const NLType rtnl_link_info_data_ip6tnl_types[] = {
     280             :         [IFLA_IPTUN_LINK]                = { .type = NETLINK_TYPE_U32 },
     281             :         [IFLA_IPTUN_LOCAL]               = { .type = NETLINK_TYPE_IN_ADDR },
     282             :         [IFLA_IPTUN_REMOTE]              = { .type = NETLINK_TYPE_IN_ADDR },
     283             :         [IFLA_IPTUN_TTL]                 = { .type = NETLINK_TYPE_U8 },
     284             :         [IFLA_IPTUN_FLAGS]               = { .type = NETLINK_TYPE_U32 },
     285             :         [IFLA_IPTUN_PROTO]               = { .type = NETLINK_TYPE_U8 },
     286             :         [IFLA_IPTUN_ENCAP_LIMIT]         = { .type = NETLINK_TYPE_U8 },
     287             :         [IFLA_IPTUN_FLOWINFO]            = { .type = NETLINK_TYPE_U32 },
     288             : };
     289             : 
     290             : static const NLType rtnl_link_info_data_vrf_types[] = {
     291             :         [IFLA_VRF_TABLE]                 = { .type = NETLINK_TYPE_U32 },
     292             : };
     293             : 
     294             : static const NLType rtnl_link_info_data_geneve_types[] = {
     295             :         [IFLA_GENEVE_ID]                = { .type = NETLINK_TYPE_U32 },
     296             :         [IFLA_GENEVE_TTL]               = { .type = NETLINK_TYPE_U8 },
     297             :         [IFLA_GENEVE_TOS]               = { .type = NETLINK_TYPE_U8 },
     298             :         [IFLA_GENEVE_PORT]              = { .type = NETLINK_TYPE_U16 },
     299             :         [IFLA_GENEVE_REMOTE]            = { .type = NETLINK_TYPE_IN_ADDR },
     300             :         [IFLA_GENEVE_REMOTE6]           = { .type = NETLINK_TYPE_IN_ADDR },
     301             :         [IFLA_GENEVE_UDP_CSUM]          = { .type = NETLINK_TYPE_U8 },
     302             :         [IFLA_GENEVE_UDP_ZERO_CSUM6_TX] = { .type = NETLINK_TYPE_U8 },
     303             :         [IFLA_GENEVE_UDP_ZERO_CSUM6_RX] = { .type = NETLINK_TYPE_U8 },
     304             :         [IFLA_GENEVE_LABEL]             = { .type = NETLINK_TYPE_U32 },
     305             :         [IFLA_GENEVE_TTL_INHERIT]       = { .type = NETLINK_TYPE_U8 },
     306             :         [IFLA_GENEVE_DF]                = { .type = NETLINK_TYPE_U8 },
     307             : };
     308             : 
     309             : static const NLType rtnl_link_info_data_can_types[] = {
     310             :         [IFLA_CAN_BITTIMING]            = { .size = sizeof(struct can_bittiming) },
     311             :         [IFLA_CAN_RESTART_MS]           = { .type = NETLINK_TYPE_U32 },
     312             :         [IFLA_CAN_CTRLMODE]             = { .size = sizeof(struct can_ctrlmode) },
     313             : };
     314             : 
     315             : static const NLType rtnl_link_info_data_macsec_types[] = {
     316             :         [IFLA_MACSEC_SCI]            = { .type = NETLINK_TYPE_U64 },
     317             :         [IFLA_MACSEC_PORT]           = { .type = NETLINK_TYPE_U16 },
     318             :         [IFLA_MACSEC_ICV_LEN]        = { .type = NETLINK_TYPE_U8 },
     319             :         [IFLA_MACSEC_CIPHER_SUITE]   = { .type = NETLINK_TYPE_U64 },
     320             :         [IFLA_MACSEC_WINDOW]         = { .type = NETLINK_TYPE_U32 },
     321             :         [IFLA_MACSEC_ENCODING_SA]    = { .type = NETLINK_TYPE_U8 },
     322             :         [IFLA_MACSEC_ENCRYPT]        = { .type = NETLINK_TYPE_U8 },
     323             :         [IFLA_MACSEC_PROTECT]        = { .type = NETLINK_TYPE_U8 },
     324             :         [IFLA_MACSEC_INC_SCI]        = { .type = NETLINK_TYPE_U8 },
     325             :         [IFLA_MACSEC_ES]             = { .type = NETLINK_TYPE_U8 },
     326             :         [IFLA_MACSEC_SCB]            = { .type = NETLINK_TYPE_U8 },
     327             :         [IFLA_MACSEC_REPLAY_PROTECT] = { .type = NETLINK_TYPE_U8 },
     328             :         [IFLA_MACSEC_VALIDATION]     = { .type = NETLINK_TYPE_U8 },
     329             : };
     330             : 
     331             : static const NLType rtnl_link_info_data_xfrm_types[] = {
     332             :         [IFLA_XFRM_LINK]         = { .type = NETLINK_TYPE_U32 },
     333             :         [IFLA_XFRM_IF_ID]        = { .type = NETLINK_TYPE_U32 }
     334             : };
     335             : 
     336             : /* these strings must match the .kind entries in the kernel */
     337             : static const char* const nl_union_link_info_data_table[] = {
     338             :         [NL_UNION_LINK_INFO_DATA_BOND] = "bond",
     339             :         [NL_UNION_LINK_INFO_DATA_BRIDGE] = "bridge",
     340             :         [NL_UNION_LINK_INFO_DATA_VLAN] = "vlan",
     341             :         [NL_UNION_LINK_INFO_DATA_VETH] = "veth",
     342             :         [NL_UNION_LINK_INFO_DATA_DUMMY] = "dummy",
     343             :         [NL_UNION_LINK_INFO_DATA_MACVLAN] = "macvlan",
     344             :         [NL_UNION_LINK_INFO_DATA_MACVTAP] = "macvtap",
     345             :         [NL_UNION_LINK_INFO_DATA_IPVLAN] = "ipvlan",
     346             :         [NL_UNION_LINK_INFO_DATA_IPVTAP] = "ipvtap",
     347             :         [NL_UNION_LINK_INFO_DATA_VXLAN] = "vxlan",
     348             :         [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = "ipip",
     349             :         [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = "gre",
     350             :         [NL_UNION_LINK_INFO_DATA_ERSPAN] = "erspan",
     351             :         [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = "gretap",
     352             :         [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = "ip6gre",
     353             :         [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = "ip6gretap",
     354             :         [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = "sit",
     355             :         [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = "vti",
     356             :         [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = "vti6",
     357             :         [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = "ip6tnl",
     358             :         [NL_UNION_LINK_INFO_DATA_VRF] = "vrf",
     359             :         [NL_UNION_LINK_INFO_DATA_VCAN] = "vcan",
     360             :         [NL_UNION_LINK_INFO_DATA_GENEVE] = "geneve",
     361             :         [NL_UNION_LINK_INFO_DATA_VXCAN] = "vxcan",
     362             :         [NL_UNION_LINK_INFO_DATA_WIREGUARD] = "wireguard",
     363             :         [NL_UNION_LINK_INFO_DATA_NETDEVSIM] = "netdevsim",
     364             :         [NL_UNION_LINK_INFO_DATA_CAN] = "can",
     365             :         [NL_UNION_LINK_INFO_DATA_MACSEC] = "macsec",
     366             :         [NL_UNION_LINK_INFO_DATA_NLMON] = "nlmon",
     367             :         [NL_UNION_LINK_INFO_DATA_XFRM] = "xfrm",
     368             : };
     369             : 
     370          66 : DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData);
     371             : 
     372             : static const NLTypeSystem rtnl_link_info_data_type_systems[] = {
     373             :         [NL_UNION_LINK_INFO_DATA_BOND] =             { .count = ELEMENTSOF(rtnl_link_info_data_bond_types),
     374             :                                                        .types = rtnl_link_info_data_bond_types },
     375             :         [NL_UNION_LINK_INFO_DATA_BRIDGE] =           { .count = ELEMENTSOF(rtnl_link_info_data_bridge_types),
     376             :                                                        .types = rtnl_link_info_data_bridge_types },
     377             :         [NL_UNION_LINK_INFO_DATA_VLAN] =             { .count = ELEMENTSOF(rtnl_link_info_data_vlan_types),
     378             :                                                        .types = rtnl_link_info_data_vlan_types },
     379             :         [NL_UNION_LINK_INFO_DATA_VETH] =             { .count = ELEMENTSOF(rtnl_link_info_data_veth_types),
     380             :                                                        .types = rtnl_link_info_data_veth_types },
     381             :         [NL_UNION_LINK_INFO_DATA_MACVLAN] =          { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types),
     382             :                                                        .types = rtnl_link_info_data_macvlan_types },
     383             :         [NL_UNION_LINK_INFO_DATA_MACVTAP] =          { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types),
     384             :                                                        .types = rtnl_link_info_data_macvlan_types },
     385             :         [NL_UNION_LINK_INFO_DATA_IPVLAN] =           { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types),
     386             :                                                        .types = rtnl_link_info_data_ipvlan_types },
     387             :         [NL_UNION_LINK_INFO_DATA_IPVTAP] =           { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types),
     388             :                                                        .types = rtnl_link_info_data_ipvlan_types },
     389             :         [NL_UNION_LINK_INFO_DATA_VXLAN] =            { .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types),
     390             :                                                        .types = rtnl_link_info_data_vxlan_types },
     391             :         [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] =      { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types),
     392             :                                                        .types = rtnl_link_info_data_iptun_types },
     393             :         [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] =     { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
     394             :                                                        .types = rtnl_link_info_data_ipgre_types },
     395             :         [NL_UNION_LINK_INFO_DATA_ERSPAN] =           { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
     396             :                                                        .types = rtnl_link_info_data_ipgre_types },
     397             :         [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
     398             :                                                        .types = rtnl_link_info_data_ipgre_types },
     399             :         [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] =    { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
     400             :                                                        .types = rtnl_link_info_data_ipgre_types },
     401             :         [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
     402             :                                                        .types = rtnl_link_info_data_ipgre_types },
     403             :         [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] =       { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types),
     404             :                                                        .types = rtnl_link_info_data_iptun_types },
     405             :         [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] =       { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types),
     406             :                                                        .types = rtnl_link_info_data_ipvti_types },
     407             :         [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] =      { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types),
     408             :                                                        .types = rtnl_link_info_data_ipvti_types },
     409             :         [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] =    { .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types),
     410             :                                                        .types = rtnl_link_info_data_ip6tnl_types },
     411             :         [NL_UNION_LINK_INFO_DATA_VRF] =              { .count = ELEMENTSOF(rtnl_link_info_data_vrf_types),
     412             :                                                        .types = rtnl_link_info_data_vrf_types },
     413             :         [NL_UNION_LINK_INFO_DATA_GENEVE] =           { .count = ELEMENTSOF(rtnl_link_info_data_geneve_types),
     414             :                                                        .types = rtnl_link_info_data_geneve_types },
     415             :         [NL_UNION_LINK_INFO_DATA_VXCAN] =            { .count = ELEMENTSOF(rtnl_link_info_data_vxcan_types),
     416             :                                                        .types = rtnl_link_info_data_vxcan_types },
     417             :         [NL_UNION_LINK_INFO_DATA_CAN] =              { .count = ELEMENTSOF(rtnl_link_info_data_can_types),
     418             :                                                        .types = rtnl_link_info_data_can_types },
     419             :         [NL_UNION_LINK_INFO_DATA_MACSEC] =           { .count = ELEMENTSOF(rtnl_link_info_data_macsec_types),
     420             :                                                        .types = rtnl_link_info_data_macsec_types },
     421             :         [NL_UNION_LINK_INFO_DATA_XFRM] =             { .count = ELEMENTSOF(rtnl_link_info_data_xfrm_types),
     422             :                                                        .types = rtnl_link_info_data_xfrm_types },
     423             : };
     424             : 
     425             : static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = {
     426             :         .num = _NL_UNION_LINK_INFO_DATA_MAX,
     427             :         .lookup = nl_union_link_info_data_from_string,
     428             :         .type_systems = rtnl_link_info_data_type_systems,
     429             :         .match_type = NL_MATCH_SIBLING,
     430             :         .match = IFLA_INFO_KIND,
     431             : };
     432             : 
     433             : static const NLType rtnl_link_info_types[] = {
     434             :         [IFLA_INFO_KIND]        = { .type = NETLINK_TYPE_STRING },
     435             :         [IFLA_INFO_DATA]        = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_link_info_data_type_system_union},
     436             : /*
     437             :         [IFLA_INFO_XSTATS],
     438             :         [IFLA_INFO_SLAVE_KIND]  = { .type = NETLINK_TYPE_STRING },
     439             :         [IFLA_INFO_SLAVE_DATA]  = { .type = NETLINK_TYPE_NESTED },
     440             : */
     441             : };
     442             : 
     443             : static const NLTypeSystem rtnl_link_info_type_system = {
     444             :         .count = ELEMENTSOF(rtnl_link_info_types),
     445             :         .types = rtnl_link_info_types,
     446             : };
     447             : 
     448             : static const struct NLType rtnl_prot_info_bridge_port_types[] = {
     449             :         [IFLA_BRPORT_STATE]               = { .type = NETLINK_TYPE_U8 },
     450             :         [IFLA_BRPORT_COST]                = { .type = NETLINK_TYPE_U32 },
     451             :         [IFLA_BRPORT_PRIORITY]            = { .type = NETLINK_TYPE_U16 },
     452             :         [IFLA_BRPORT_MODE]                = { .type = NETLINK_TYPE_U8 },
     453             :         [IFLA_BRPORT_GUARD]               = { .type = NETLINK_TYPE_U8 },
     454             :         [IFLA_BRPORT_PROTECT]             = { .type = NETLINK_TYPE_U8 },
     455             :         [IFLA_BRPORT_FAST_LEAVE]          = { .type = NETLINK_TYPE_U8 },
     456             :         [IFLA_BRPORT_LEARNING]            = { .type = NETLINK_TYPE_U8 },
     457             :         [IFLA_BRPORT_UNICAST_FLOOD]       = { .type = NETLINK_TYPE_U8 },
     458             :         [IFLA_BRPORT_PROXYARP]            = { .type = NETLINK_TYPE_U8 },
     459             :         [IFLA_BRPORT_LEARNING_SYNC]       = { .type = NETLINK_TYPE_U8 },
     460             :         [IFLA_BRPORT_PROXYARP_WIFI]       = { .type = NETLINK_TYPE_U8 },
     461             :         [IFLA_BRPORT_ROOT_ID]             = { .type = NETLINK_TYPE_U8 },
     462             :         [IFLA_BRPORT_BRIDGE_ID]           = { .type = NETLINK_TYPE_U8 },
     463             :         [IFLA_BRPORT_DESIGNATED_PORT]     = { .type = NETLINK_TYPE_U16 },
     464             :         [IFLA_BRPORT_DESIGNATED_COST]     = { .type = NETLINK_TYPE_U16 },
     465             :         [IFLA_BRPORT_ID]                  = { .type = NETLINK_TYPE_U16 },
     466             :         [IFLA_BRPORT_NO]                  = { .type = NETLINK_TYPE_U16 },
     467             :         [IFLA_BRPORT_TOPOLOGY_CHANGE_ACK] = { .type = NETLINK_TYPE_U8 },
     468             :         [IFLA_BRPORT_CONFIG_PENDING]      = { .type = NETLINK_TYPE_U8 },
     469             :         [IFLA_BRPORT_MESSAGE_AGE_TIMER]   = { .type = NETLINK_TYPE_U64 },
     470             :         [IFLA_BRPORT_FORWARD_DELAY_TIMER] = { .type = NETLINK_TYPE_U64 },
     471             :         [IFLA_BRPORT_HOLD_TIMER]          = { .type = NETLINK_TYPE_U64 },
     472             :         [IFLA_BRPORT_FLUSH]               = { .type = NETLINK_TYPE_U8 },
     473             :         [IFLA_BRPORT_MULTICAST_ROUTER]    = { .type = NETLINK_TYPE_U8 },
     474             :         [IFLA_BRPORT_PAD]                 = { .type = NETLINK_TYPE_U8 },
     475             :         [IFLA_BRPORT_MCAST_FLOOD]         = { .type = NETLINK_TYPE_U8 },
     476             :         [IFLA_BRPORT_MCAST_TO_UCAST]      = { .type = NETLINK_TYPE_U8 },
     477             :         [IFLA_BRPORT_VLAN_TUNNEL]         = { .type = NETLINK_TYPE_U8 },
     478             :         [IFLA_BRPORT_BCAST_FLOOD]         = { .type = NETLINK_TYPE_U8 },
     479             :         [IFLA_BRPORT_GROUP_FWD_MASK]      = { .type = NETLINK_TYPE_U16 },
     480             :         [IFLA_BRPORT_NEIGH_SUPPRESS]      = { .type = NETLINK_TYPE_U8 },
     481             :         [IFLA_BRPORT_ISOLATED]            = { .type = NETLINK_TYPE_U8 },
     482             :         [IFLA_BRPORT_BACKUP_PORT]         = { .type = NETLINK_TYPE_U32 },
     483             : };
     484             : 
     485             : static const NLTypeSystem rtnl_prot_info_type_systems[] = {
     486             :         [AF_BRIDGE] =   { .count = ELEMENTSOF(rtnl_prot_info_bridge_port_types),
     487             :                           .types = rtnl_prot_info_bridge_port_types },
     488             : };
     489             : 
     490             : static const NLTypeSystemUnion rtnl_prot_info_type_system_union = {
     491             :         .num = AF_MAX,
     492             :         .type_systems = rtnl_prot_info_type_systems,
     493             :         .match_type = NL_MATCH_PROTOCOL,
     494             : };
     495             : 
     496             : static const struct NLType rtnl_af_spec_inet6_types[] = {
     497             :         [IFLA_INET6_FLAGS]              = { .type = NETLINK_TYPE_U32 },
     498             : /*
     499             :         IFLA_INET6_CONF,
     500             :         IFLA_INET6_STATS,
     501             :         IFLA_INET6_MCAST,
     502             :         IFLA_INET6_CACHEINFO,
     503             :         IFLA_INET6_ICMP6STATS,
     504             : */
     505             :         [IFLA_INET6_TOKEN]              = { .type = NETLINK_TYPE_IN_ADDR },
     506             :         [IFLA_INET6_ADDR_GEN_MODE]      = { .type = NETLINK_TYPE_U8 },
     507             : };
     508             : 
     509             : static const NLTypeSystem rtnl_af_spec_inet6_type_system = {
     510             :         .count = ELEMENTSOF(rtnl_af_spec_inet6_types),
     511             :         .types = rtnl_af_spec_inet6_types,
     512             : };
     513             : 
     514             : static const NLType rtnl_af_spec_types[] = {
     515             :         [AF_INET6] =    { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_af_spec_inet6_type_system },
     516             : };
     517             : 
     518             : static const NLTypeSystem rtnl_af_spec_type_system = {
     519             :         .count = ELEMENTSOF(rtnl_af_spec_types),
     520             :         .types = rtnl_af_spec_types,
     521             : };
     522             : 
     523             : static const NLType rtnl_link_types[] = {
     524             :         [IFLA_ADDRESS]          = { .type = NETLINK_TYPE_ETHER_ADDR },
     525             :         [IFLA_BROADCAST]        = { .type = NETLINK_TYPE_ETHER_ADDR },
     526             :         [IFLA_IFNAME]           = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 },
     527             :         [IFLA_MTU]              = { .type = NETLINK_TYPE_U32 },
     528             :         [IFLA_LINK]             = { .type = NETLINK_TYPE_U32 },
     529             : /*
     530             :         [IFLA_QDISC],
     531             : */
     532             :         [IFLA_STATS]            = { .size = sizeof(struct rtnl_link_stats) },
     533             : /*
     534             :         [IFLA_COST],
     535             :         [IFLA_PRIORITY],
     536             : */
     537             :         [IFLA_MASTER]           = { .type = NETLINK_TYPE_U32 },
     538             : /*
     539             :         [IFLA_WIRELESS],
     540             : */
     541             :         [IFLA_PROTINFO]         = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_prot_info_type_system_union },
     542             :         [IFLA_TXQLEN]           = { .type = NETLINK_TYPE_U32 },
     543             : /*
     544             :         [IFLA_MAP]              = { .len = sizeof(struct rtnl_link_ifmap) },
     545             : */
     546             :         [IFLA_WEIGHT]           = { .type = NETLINK_TYPE_U32 },
     547             :         [IFLA_OPERSTATE]        = { .type = NETLINK_TYPE_U8 },
     548             :         [IFLA_LINKMODE]         = { .type = NETLINK_TYPE_U8 },
     549             :         [IFLA_LINKINFO]         = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_info_type_system },
     550             :         [IFLA_NET_NS_PID]       = { .type = NETLINK_TYPE_U32 },
     551             :         [IFLA_IFALIAS]          = { .type = NETLINK_TYPE_STRING, .size = IFALIASZ - 1 },
     552             : /*
     553             :         [IFLA_NUM_VF],
     554             :         [IFLA_VFINFO_LIST]      = {. type = NETLINK_TYPE_NESTED, },
     555             : */
     556             :         [IFLA_STATS64]          = { .size = sizeof(struct rtnl_link_stats64) },
     557             : /*
     558             :         [IFLA_VF_PORTS]         = { .type = NETLINK_TYPE_NESTED },
     559             :         [IFLA_PORT_SELF]        = { .type = NETLINK_TYPE_NESTED },
     560             : */
     561             :         [IFLA_AF_SPEC]          = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_af_spec_type_system },
     562             : /*
     563             :         [IFLA_VF_PORTS],
     564             :         [IFLA_PORT_SELF],
     565             :         [IFLA_AF_SPEC],
     566             : */
     567             :         [IFLA_GROUP]            = { .type = NETLINK_TYPE_U32 },
     568             :         [IFLA_NET_NS_FD]        = { .type = NETLINK_TYPE_U32 },
     569             :         [IFLA_EXT_MASK]         = { .type = NETLINK_TYPE_U32 },
     570             :         [IFLA_PROMISCUITY]      = { .type = NETLINK_TYPE_U32 },
     571             :         [IFLA_NUM_TX_QUEUES]    = { .type = NETLINK_TYPE_U32 },
     572             :         [IFLA_NUM_RX_QUEUES]    = { .type = NETLINK_TYPE_U32 },
     573             :         [IFLA_CARRIER]          = { .type = NETLINK_TYPE_U8 },
     574             : /*
     575             :         [IFLA_PHYS_PORT_ID]     = { .type = NETLINK_TYPE_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
     576             : */
     577             :         [IFLA_MIN_MTU]              = { .type = NETLINK_TYPE_U32 },
     578             :         [IFLA_MAX_MTU]              = { .type = NETLINK_TYPE_U32 },
     579             : };
     580             : 
     581             : static const NLTypeSystem rtnl_link_type_system = {
     582             :         .count = ELEMENTSOF(rtnl_link_types),
     583             :         .types = rtnl_link_types,
     584             : };
     585             : 
     586             : /* IFA_FLAGS was defined in kernel 3.14, but we still support older
     587             :  * kernels where IFA_MAX is lower. */
     588             : static const NLType rtnl_address_types[] = {
     589             :         [IFA_ADDRESS]           = { .type = NETLINK_TYPE_IN_ADDR },
     590             :         [IFA_LOCAL]             = { .type = NETLINK_TYPE_IN_ADDR },
     591             :         [IFA_LABEL]             = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 },
     592             :         [IFA_BROADCAST]         = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */
     593             :         [IFA_CACHEINFO]         = { .type = NETLINK_TYPE_CACHE_INFO, .size = sizeof(struct ifa_cacheinfo) },
     594             : /*
     595             :         [IFA_ANYCAST],
     596             :         [IFA_MULTICAST],
     597             : */
     598             :         [IFA_FLAGS]             = { .type = NETLINK_TYPE_U32 },
     599             : };
     600             : 
     601             : static const NLTypeSystem rtnl_address_type_system = {
     602             :         .count = ELEMENTSOF(rtnl_address_types),
     603             :         .types = rtnl_address_types,
     604             : };
     605             : 
     606             : /* RTM_METRICS --- array of struct rtattr with types of RTAX_* */
     607             : 
     608             : static const NLType rtnl_route_metrics_types[] = {
     609             :         [RTAX_MTU]                = { .type = NETLINK_TYPE_U32 },
     610             :         [RTAX_WINDOW]             = { .type = NETLINK_TYPE_U32 },
     611             :         [RTAX_RTT]                = { .type = NETLINK_TYPE_U32 },
     612             :         [RTAX_RTTVAR]             = { .type = NETLINK_TYPE_U32 },
     613             :         [RTAX_SSTHRESH]           = { .type = NETLINK_TYPE_U32 },
     614             :         [RTAX_CWND]               = { .type = NETLINK_TYPE_U32 },
     615             :         [RTAX_ADVMSS]             = { .type = NETLINK_TYPE_U32 },
     616             :         [RTAX_REORDERING]         = { .type = NETLINK_TYPE_U32 },
     617             :         [RTAX_HOPLIMIT]           = { .type = NETLINK_TYPE_U32 },
     618             :         [RTAX_INITCWND]           = { .type = NETLINK_TYPE_U32 },
     619             :         [RTAX_FEATURES]           = { .type = NETLINK_TYPE_U32 },
     620             :         [RTAX_RTO_MIN]            = { .type = NETLINK_TYPE_U32 },
     621             :         [RTAX_INITRWND]           = { .type = NETLINK_TYPE_U32 },
     622             :         [RTAX_QUICKACK]           = { .type = NETLINK_TYPE_U32 },
     623             :         [RTAX_CC_ALGO]            = { .type = NETLINK_TYPE_U32 },
     624             :         [RTAX_FASTOPEN_NO_COOKIE] = { .type = NETLINK_TYPE_U32 },
     625             : };
     626             : 
     627             : static const NLTypeSystem rtnl_route_metrics_type_system = {
     628             :         .count = ELEMENTSOF(rtnl_route_metrics_types),
     629             :         .types = rtnl_route_metrics_types,
     630             : };
     631             : 
     632             : static const NLType rtnl_route_types[] = {
     633             :         [RTA_DST]               = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */
     634             :         [RTA_SRC]               = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */
     635             :         [RTA_IIF]               = { .type = NETLINK_TYPE_U32 },
     636             :         [RTA_OIF]               = { .type = NETLINK_TYPE_U32 },
     637             :         [RTA_GATEWAY]           = { .type = NETLINK_TYPE_IN_ADDR },
     638             :         [RTA_PRIORITY]          = { .type = NETLINK_TYPE_U32 },
     639             :         [RTA_PREFSRC]           = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */
     640             :         [RTA_METRICS]           = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_metrics_type_system},
     641             :         [RTA_MULTIPATH]         = { .size = sizeof(struct rtnexthop) },
     642             :         [RTA_FLOW]              = { .type = NETLINK_TYPE_U32 }, /* 6? */
     643             :         [RTA_CACHEINFO]         = { .size = sizeof(struct rta_cacheinfo) },
     644             :         [RTA_TABLE]             = { .type = NETLINK_TYPE_U32 },
     645             :         [RTA_MARK]              = { .type = NETLINK_TYPE_U32 },
     646             :         [RTA_MFC_STATS]         = { .type = NETLINK_TYPE_U64 },
     647             :         [RTA_VIA]               = { .type = NETLINK_TYPE_U32 },
     648             :         [RTA_NEWDST]            = { .type = NETLINK_TYPE_U32 },
     649             :         [RTA_PREF]              = { .type = NETLINK_TYPE_U8 },
     650             :         [RTA_EXPIRES]           = { .type = NETLINK_TYPE_U32 },
     651             :         [RTA_ENCAP_TYPE]        = { .type = NETLINK_TYPE_U16 },
     652             :         [RTA_ENCAP]             = { .type = NETLINK_TYPE_NESTED }, /* Multiple type systems i.e. LWTUNNEL_ENCAP_MPLS/LWTUNNEL_ENCAP_IP/LWTUNNEL_ENCAP_ILA etc... */
     653             :         [RTA_UID]               = { .type = NETLINK_TYPE_U32 },
     654             :         [RTA_TTL_PROPAGATE]     = { .type = NETLINK_TYPE_U8 },
     655             :         [RTA_IP_PROTO]          = { .type = NETLINK_TYPE_U8 },
     656             :         [RTA_SPORT]             = { .type = NETLINK_TYPE_U16 },
     657             :         [RTA_DPORT]             = { .type = NETLINK_TYPE_U16 },
     658             : };
     659             : 
     660             : static const NLTypeSystem rtnl_route_type_system = {
     661             :         .count = ELEMENTSOF(rtnl_route_types),
     662             :         .types = rtnl_route_types,
     663             : };
     664             : 
     665             : static const NLType rtnl_neigh_types[] = {
     666             :         [NDA_DST]               = { .type = NETLINK_TYPE_IN_ADDR },
     667             :         [NDA_LLADDR]            = { /* struct ether_addr, struct in_addr, or struct in6_addr */ },
     668             :         [NDA_CACHEINFO]         = { .type = NETLINK_TYPE_CACHE_INFO, .size = sizeof(struct nda_cacheinfo) },
     669             :         [NDA_PROBES]            = { .type = NETLINK_TYPE_U32 },
     670             :         [NDA_VLAN]              = { .type = NETLINK_TYPE_U16 },
     671             :         [NDA_PORT]              = { .type = NETLINK_TYPE_U16 },
     672             :         [NDA_VNI]               = { .type = NETLINK_TYPE_U32 },
     673             :         [NDA_IFINDEX]           = { .type = NETLINK_TYPE_U32 },
     674             : };
     675             : 
     676             : static const NLTypeSystem rtnl_neigh_type_system = {
     677             :         .count = ELEMENTSOF(rtnl_neigh_types),
     678             :         .types = rtnl_neigh_types,
     679             : };
     680             : 
     681             : static const NLType rtnl_addrlabel_types[] = {
     682             :         [IFAL_ADDRESS]         = { .type = NETLINK_TYPE_IN_ADDR, .size = sizeof(struct in6_addr) },
     683             :         [IFAL_LABEL]           = { .type = NETLINK_TYPE_U32 },
     684             : };
     685             : 
     686             : static const NLTypeSystem rtnl_addrlabel_type_system = {
     687             :         .count = ELEMENTSOF(rtnl_addrlabel_types),
     688             :         .types = rtnl_addrlabel_types,
     689             : };
     690             : 
     691             : static const NLType rtnl_routing_policy_rule_types[] = {
     692             :         [FRA_DST]                 = { .type = NETLINK_TYPE_IN_ADDR },
     693             :         [FRA_SRC]                 = { .type = NETLINK_TYPE_IN_ADDR },
     694             :         [FRA_IIFNAME]             = { .type = NETLINK_TYPE_STRING },
     695             :         [FRA_GOTO]                = { .type = NETLINK_TYPE_U32 },
     696             :         [FRA_PRIORITY]            = { .type = NETLINK_TYPE_U32 },
     697             :         [FRA_FWMARK]              = { .type = NETLINK_TYPE_U32 },
     698             :         [FRA_FLOW]                = { .type = NETLINK_TYPE_U32 },
     699             :         [FRA_TUN_ID]              = { .type = NETLINK_TYPE_U64 },
     700             :         [FRA_SUPPRESS_IFGROUP]    = { .type = NETLINK_TYPE_U32 },
     701             :         [FRA_SUPPRESS_PREFIXLEN]  = { .type = NETLINK_TYPE_U32 },
     702             :         [FRA_TABLE]               = { .type = NETLINK_TYPE_U32 },
     703             :         [FRA_FWMASK]              = { .type = NETLINK_TYPE_U32 },
     704             :         [FRA_OIFNAME]             = { .type = NETLINK_TYPE_STRING },
     705             :         [FRA_PAD]                 = { .type = NETLINK_TYPE_U32 },
     706             :         [FRA_L3MDEV]              = { .type = NETLINK_TYPE_U8 },
     707             :         [FRA_UID_RANGE]           = { .size = sizeof(struct fib_rule_uid_range) },
     708             :         [FRA_PROTOCOL]            = { .type = NETLINK_TYPE_U8 },
     709             :         [FRA_IP_PROTO]            = { .type = NETLINK_TYPE_U8 },
     710             :         [FRA_SPORT_RANGE]         = { .size = sizeof(struct fib_rule_port_range) },
     711             :         [FRA_DPORT_RANGE]         = { .size = sizeof(struct fib_rule_port_range) },
     712             : };
     713             : 
     714             : static const NLTypeSystem rtnl_routing_policy_rule_type_system = {
     715             :         .count = ELEMENTSOF(rtnl_routing_policy_rule_types),
     716             :         .types = rtnl_routing_policy_rule_types,
     717             : };
     718             : 
     719             : static const NLType rtnl_types[] = {
     720             :         [NLMSG_DONE]       = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 },
     721             :         [NLMSG_ERROR]      = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = sizeof(struct nlmsgerr) },
     722             :         [RTM_NEWLINK]      = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
     723             :         [RTM_DELLINK]      = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
     724             :         [RTM_GETLINK]      = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
     725             :         [RTM_SETLINK]      = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
     726             :         [RTM_NEWADDR]      = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
     727             :         [RTM_DELADDR]      = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
     728             :         [RTM_GETADDR]      = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
     729             :         [RTM_NEWROUTE]     = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
     730             :         [RTM_DELROUTE]     = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
     731             :         [RTM_GETROUTE]     = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
     732             :         [RTM_NEWNEIGH]     = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
     733             :         [RTM_DELNEIGH]     = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
     734             :         [RTM_GETNEIGH]     = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
     735             :         [RTM_NEWADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) },
     736             :         [RTM_DELADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) },
     737             :         [RTM_GETADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) },
     738             :         [RTM_NEWRULE]      = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct rtmsg) },
     739             :         [RTM_DELRULE]      = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct rtmsg) },
     740             :         [RTM_GETRULE]      = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct rtmsg) },
     741             : };
     742             : 
     743             : const NLTypeSystem rtnl_type_system_root = {
     744             :         .count = ELEMENTSOF(rtnl_types),
     745             :         .types = rtnl_types,
     746             : };
     747             : 
     748             : static const NLType genl_wireguard_allowedip_types[] = {
     749             :         [WGALLOWEDIP_A_FAMILY] = { .type = NETLINK_TYPE_U16 },
     750             :         [WGALLOWEDIP_A_IPADDR] = { .type = NETLINK_TYPE_IN_ADDR },
     751             :         [WGALLOWEDIP_A_CIDR_MASK] = { .type = NETLINK_TYPE_U8 },
     752             : };
     753             : 
     754             : static const NLTypeSystem genl_wireguard_allowedip_type_system = {
     755             :         .count = ELEMENTSOF(genl_wireguard_allowedip_types),
     756             :         .types = genl_wireguard_allowedip_types,
     757             : };
     758             : 
     759             : static const NLType genl_wireguard_peer_types[] = {
     760             :         [WGPEER_A_PUBLIC_KEY] = { .size = WG_KEY_LEN  },
     761             :         [WGPEER_A_FLAGS] = { .type = NETLINK_TYPE_U32 },
     762             :         [WGPEER_A_PRESHARED_KEY] = { .size = WG_KEY_LEN },
     763             :         [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NETLINK_TYPE_U16 },
     764             :         [WGPEER_A_ENDPOINT] = { .type = NETLINK_TYPE_SOCKADDR },
     765             :         [WGPEER_A_ALLOWEDIPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_allowedip_type_system },
     766             : };
     767             : 
     768             : static const NLTypeSystem genl_wireguard_peer_type_system = {
     769             :         .count = ELEMENTSOF(genl_wireguard_peer_types),
     770             :         .types = genl_wireguard_peer_types,
     771             : };
     772             : 
     773             : static const NLType genl_wireguard_set_device_types[] = {
     774             :         [WGDEVICE_A_IFINDEX] = { .type = NETLINK_TYPE_U32 },
     775             :         [WGDEVICE_A_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ-1 },
     776             :         [WGDEVICE_A_FLAGS] = { .type = NETLINK_TYPE_U32 },
     777             :         [WGDEVICE_A_PRIVATE_KEY] = { .size = WG_KEY_LEN },
     778             :         [WGDEVICE_A_LISTEN_PORT] = { .type = NETLINK_TYPE_U16 },
     779             :         [WGDEVICE_A_FWMARK] = { .type = NETLINK_TYPE_U32 },
     780             :         [WGDEVICE_A_PEERS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_peer_type_system },
     781             : };
     782             : 
     783             : static const NLTypeSystem genl_wireguard_set_device_type_system = {
     784             :         .count = ELEMENTSOF(genl_wireguard_set_device_types),
     785             :         .types = genl_wireguard_set_device_types,
     786             : };
     787             : 
     788             : static const NLType genl_wireguard_cmds[] = {
     789             :         [WG_CMD_SET_DEVICE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_set_device_type_system },
     790             : };
     791             : 
     792             : static const NLTypeSystem genl_wireguard_type_system = {
     793             :         .count = ELEMENTSOF(genl_wireguard_cmds),
     794             :         .types = genl_wireguard_cmds,
     795             : };
     796             : 
     797             : static const NLType genl_mcast_group_types[] = {
     798             :         [CTRL_ATTR_MCAST_GRP_NAME]  = { .type = NETLINK_TYPE_STRING },
     799             :         [CTRL_ATTR_MCAST_GRP_ID]    = { .type = NETLINK_TYPE_U32 },
     800             : };
     801             : 
     802             : static const NLTypeSystem genl_mcast_group_type_system = {
     803             :         .count = ELEMENTSOF(genl_mcast_group_types),
     804             :         .types = genl_mcast_group_types,
     805             : };
     806             : 
     807             : static const NLType genl_get_family_types[] = {
     808             :         [CTRL_ATTR_FAMILY_NAME]  = { .type = NETLINK_TYPE_STRING },
     809             :         [CTRL_ATTR_FAMILY_ID]    = { .type = NETLINK_TYPE_U16 },
     810             :         [CTRL_ATTR_MCAST_GROUPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_mcast_group_type_system },
     811             : };
     812             : 
     813             : static const NLTypeSystem genl_get_family_type_system = {
     814             :         .count = ELEMENTSOF(genl_get_family_types),
     815             :         .types = genl_get_family_types,
     816             : };
     817             : 
     818             : static const NLType genl_ctrl_id_ctrl_cmds[] = {
     819             :         [CTRL_CMD_GETFAMILY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_get_family_type_system },
     820             : };
     821             : 
     822             : static const NLTypeSystem genl_ctrl_id_ctrl_type_system = {
     823             :         .count = ELEMENTSOF(genl_ctrl_id_ctrl_cmds),
     824             :         .types = genl_ctrl_id_ctrl_cmds,
     825             : };
     826             : 
     827             : static const NLType genl_fou_types[] = {
     828             :         [FOU_ATTR_PORT]              = { .type = NETLINK_TYPE_U16 },
     829             :         [FOU_ATTR_AF]                = { .type = NETLINK_TYPE_U8 },
     830             :         [FOU_ATTR_IPPROTO]           = { .type = NETLINK_TYPE_U8 },
     831             :         [FOU_ATTR_TYPE]              = { .type = NETLINK_TYPE_U8 },
     832             :         [FOU_ATTR_REMCSUM_NOPARTIAL] = { .type = NETLINK_TYPE_FLAG },
     833             :         [FOU_ATTR_LOCAL_V4]          = { .type = NETLINK_TYPE_IN_ADDR },
     834             :         [FOU_ATTR_PEER_V4]           = { .type = NETLINK_TYPE_IN_ADDR },
     835             :         [FOU_ATTR_LOCAL_V6]          = { .type = NETLINK_TYPE_IN_ADDR },
     836             :         [FOU_ATTR_PEER_V6]           = { .type = NETLINK_TYPE_IN_ADDR},
     837             :         [FOU_ATTR_PEER_PORT]         = { .type = NETLINK_TYPE_U16},
     838             :         [FOU_ATTR_IFINDEX]           = { .type = NETLINK_TYPE_U32},
     839             : };
     840             : 
     841             : static const NLTypeSystem genl_fou_type_system = {
     842             :         .count = ELEMENTSOF(genl_fou_types),
     843             :         .types = genl_fou_types,
     844             : };
     845             : 
     846             : static const NLType genl_fou_cmds[] = {
     847             :         [FOU_CMD_ADD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system },
     848             :         [FOU_CMD_DEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system },
     849             :         [FOU_CMD_GET] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system },
     850             : };
     851             : 
     852             : static const NLTypeSystem genl_fou_cmds_type_system = {
     853             :         .count = ELEMENTSOF(genl_fou_cmds),
     854             :         .types = genl_fou_cmds,
     855             : };
     856             : 
     857             : static const NLType genl_l2tp_types[] = {
     858             :         [L2TP_ATTR_PW_TYPE]           = { .type = NETLINK_TYPE_U16 },
     859             :         [L2TP_ATTR_ENCAP_TYPE]        = { .type = NETLINK_TYPE_U16 },
     860             :         [L2TP_ATTR_OFFSET]            = { .type = NETLINK_TYPE_U16 },
     861             :         [L2TP_ATTR_DATA_SEQ]          = { .type = NETLINK_TYPE_U16 },
     862             :         [L2TP_ATTR_L2SPEC_TYPE]       = { .type = NETLINK_TYPE_U8 },
     863             :         [L2TP_ATTR_L2SPEC_LEN]        = { .type = NETLINK_TYPE_U8 },
     864             :         [L2TP_ATTR_PROTO_VERSION]     = { .type = NETLINK_TYPE_U8 },
     865             :         [L2TP_ATTR_IFNAME]            = { .type = NETLINK_TYPE_STRING },
     866             :         [L2TP_ATTR_CONN_ID]           = { .type = NETLINK_TYPE_U32 },
     867             :         [L2TP_ATTR_PEER_CONN_ID]      = { .type = NETLINK_TYPE_U32 },
     868             :         [L2TP_ATTR_SESSION_ID]        = { .type = NETLINK_TYPE_U32 },
     869             :         [L2TP_ATTR_PEER_SESSION_ID]   = { .type = NETLINK_TYPE_U32 },
     870             :         [L2TP_ATTR_UDP_CSUM]          = { .type = NETLINK_TYPE_U8 },
     871             :         [L2TP_ATTR_VLAN_ID]           = { .type = NETLINK_TYPE_U16 },
     872             :         [L2TP_ATTR_RECV_SEQ]          = { .type = NETLINK_TYPE_U8 },
     873             :         [L2TP_ATTR_SEND_SEQ]          = { .type = NETLINK_TYPE_U8 },
     874             :         [L2TP_ATTR_LNS_MODE]          = { .type = NETLINK_TYPE_U8 },
     875             :         [L2TP_ATTR_USING_IPSEC]       = { .type = NETLINK_TYPE_U8 },
     876             :         [L2TP_ATTR_FD]                = { .type = NETLINK_TYPE_U32 },
     877             :         [L2TP_ATTR_IP_SADDR]          = { .type = NETLINK_TYPE_IN_ADDR },
     878             :         [L2TP_ATTR_IP_DADDR]          = { .type = NETLINK_TYPE_IN_ADDR },
     879             :         [L2TP_ATTR_UDP_SPORT]         = { .type = NETLINK_TYPE_U16 },
     880             :         [L2TP_ATTR_UDP_DPORT]         = { .type = NETLINK_TYPE_U16 },
     881             :         [L2TP_ATTR_IP6_SADDR]         = { .type = NETLINK_TYPE_IN_ADDR },
     882             :         [L2TP_ATTR_IP6_DADDR]         = { .type = NETLINK_TYPE_IN_ADDR },
     883             :         [L2TP_ATTR_UDP_ZERO_CSUM6_TX] = { .type = NETLINK_TYPE_FLAG },
     884             :         [L2TP_ATTR_UDP_ZERO_CSUM6_RX] = { .type = NETLINK_TYPE_FLAG },
     885             : };
     886             : 
     887             : static const NLTypeSystem genl_l2tp_type_system = {
     888             :         .count = ELEMENTSOF(genl_l2tp_types),
     889             :         .types = genl_l2tp_types,
     890             : };
     891             : 
     892             : static const NLType genl_l2tp[]   = {
     893             :         [L2TP_CMD_TUNNEL_CREATE]  = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system },
     894             :         [L2TP_CMD_TUNNEL_DELETE]  = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system },
     895             :         [L2TP_CMD_TUNNEL_MODIFY]  = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system },
     896             :         [L2TP_CMD_TUNNEL_GET]     = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system },
     897             :         [L2TP_CMD_SESSION_CREATE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system },
     898             :         [L2TP_CMD_SESSION_DELETE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system },
     899             :         [L2TP_CMD_SESSION_MODIFY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system },
     900             :         [L2TP_CMD_SESSION_GET]    = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system },
     901             : };
     902             : 
     903             : static const NLTypeSystem genl_l2tp_tunnel_session_type_system = {
     904             :         .count = ELEMENTSOF(genl_l2tp),
     905             :         .types = genl_l2tp,
     906             : };
     907             : 
     908             : static const NLType genl_rxsc_types[] = {
     909             :         [MACSEC_RXSC_ATTR_SCI] = { .type = NETLINK_TYPE_U64 },
     910             : };
     911             : 
     912             : static const NLTypeSystem genl_rxsc_config_type_system = {
     913             :         .count = ELEMENTSOF(genl_rxsc_types),
     914             :         .types = genl_rxsc_types,
     915             : };
     916             : 
     917             : static const NLType genl_macsec_rxsc_types[] = {
     918             :         [MACSEC_ATTR_IFINDEX]     = { .type = NETLINK_TYPE_U32 },
     919             :         [MACSEC_ATTR_RXSC_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_rxsc_config_type_system },
     920             : };
     921             : 
     922             : static const NLTypeSystem genl_macsec_rxsc_type_system = {
     923             :         .count = ELEMENTSOF(genl_macsec_rxsc_types),
     924             :         .types = genl_macsec_rxsc_types,
     925             : };
     926             : 
     927             : static const NLType genl_macsec_sa_config_types[] = {
     928             :         [MACSEC_SA_ATTR_AN]     = { .type = NETLINK_TYPE_U8 },
     929             :         [MACSEC_SA_ATTR_ACTIVE] = { .type = NETLINK_TYPE_U8 },
     930             :         [MACSEC_SA_ATTR_PN]     = { .type = NETLINK_TYPE_U32 },
     931             :         [MACSEC_SA_ATTR_KEYID]  = { .size = MACSEC_KEYID_LEN },
     932             :         [MACSEC_SA_ATTR_KEY]    = { .size = MACSEC_MAX_KEY_LEN },
     933             : };
     934             : 
     935             : static const NLTypeSystem genl_macsec_sa_config_type_system = {
     936             :         .count = ELEMENTSOF(genl_macsec_sa_config_types),
     937             :         .types = genl_macsec_sa_config_types,
     938             : };
     939             : 
     940             : static const NLType genl_macsec_rxsa_types[] = {
     941             :         [MACSEC_ATTR_IFINDEX]   = { .type = NETLINK_TYPE_U32 },
     942             :         [MACSEC_ATTR_SA_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_config_type_system },
     943             : };
     944             : 
     945             : static const NLTypeSystem genl_macsec_rxsa_type_system = {
     946             :         .count = ELEMENTSOF(genl_macsec_rxsa_types),
     947             :         .types = genl_macsec_rxsa_types,
     948             : };
     949             : 
     950             : static const NLType genl_macsec_sa_types[] = {
     951             :         [MACSEC_ATTR_IFINDEX]     = { .type = NETLINK_TYPE_U32 },
     952             :         [MACSEC_ATTR_RXSC_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_rxsc_config_type_system },
     953             :         [MACSEC_ATTR_SA_CONFIG]   = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_config_type_system },
     954             : };
     955             : 
     956             : static const NLTypeSystem genl_macsec_sa_type_system = {
     957             :         .count = ELEMENTSOF(genl_macsec_sa_types),
     958             :         .types = genl_macsec_sa_types,
     959             : };
     960             : 
     961             : static const NLType genl_macsec[]   = {
     962             :         [MACSEC_CMD_ADD_RXSC]  = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_rxsc_type_system },
     963             :         [MACSEC_CMD_ADD_TXSA]  = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_rxsa_type_system},
     964             :         [MACSEC_CMD_ADD_RXSA]  = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_type_system },
     965             : };
     966             : 
     967             : static const NLTypeSystem genl_macsec_device_type_system = {
     968             :         .count = ELEMENTSOF(genl_macsec),
     969             :         .types = genl_macsec,
     970             : };
     971             : 
     972             : static const NLType genl_families[] = {
     973             :         [SD_GENL_ID_CTRL]   = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_id_ctrl_type_system },
     974             :         [SD_GENL_WIREGUARD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_type_system },
     975             :         [SD_GENL_FOU]       = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_cmds_type_system},
     976             :         [SD_GENL_L2TP]      = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_tunnel_session_type_system },
     977             :         [SD_GENL_MACSEC]    = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_device_type_system },
     978             : };
     979             : 
     980             : const NLTypeSystem genl_family_type_system_root = {
     981             :         .count = ELEMENTSOF(genl_families),
     982             :         .types = genl_families,
     983             : };
     984             : 
     985             : static const NLType genl_types[] = {
     986             :         [NLMSG_ERROR]  = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = sizeof(struct nlmsgerr) },
     987             :         [GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_get_family_type_system, .size = sizeof(struct genlmsghdr) },
     988             : };
     989             : 
     990             : const NLTypeSystem genl_type_system_root = {
     991             :         .count = ELEMENTSOF(genl_types),
     992             :         .types = genl_types,
     993             : };
     994             : 
     995         287 : uint16_t type_get_type(const NLType *type) {
     996         287 :         assert(type);
     997         287 :         return type->type;
     998             : }
     999             : 
    1000         193 : size_t type_get_size(const NLType *type) {
    1001         193 :         assert(type);
    1002         193 :         return type->size;
    1003             : }
    1004             : 
    1005         118 : void type_get_type_system(const NLType *nl_type, const NLTypeSystem **ret) {
    1006         118 :         assert(nl_type);
    1007         118 :         assert(ret);
    1008         118 :         assert(nl_type->type == NETLINK_TYPE_NESTED);
    1009         118 :         assert(nl_type->type_system);
    1010             : 
    1011         118 :         *ret = nl_type->type_system;
    1012         118 : }
    1013             : 
    1014           4 : void type_get_type_system_union(const NLType *nl_type, const NLTypeSystemUnion **ret) {
    1015           4 :         assert(nl_type);
    1016           4 :         assert(ret);
    1017           4 :         assert(nl_type->type == NETLINK_TYPE_UNION);
    1018           4 :         assert(nl_type->type_system_union);
    1019             : 
    1020           4 :         *ret = nl_type->type_system_union;
    1021           4 : }
    1022             : 
    1023           0 : uint16_t type_system_get_count(const NLTypeSystem *type_system) {
    1024           0 :         assert(type_system);
    1025           0 :         return type_system->count;
    1026             : }
    1027             : 
    1028         138 : const NLTypeSystem *type_system_get_root(int protocol) {
    1029         138 :         switch (protocol) {
    1030           1 :                 case NETLINK_GENERIC:
    1031           1 :                         return &genl_type_system_root;
    1032         137 :                 default: /* NETLINK_ROUTE: */
    1033         137 :                         return &rtnl_type_system_root;
    1034             :         }
    1035             : }
    1036             : 
    1037         374 : int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) {
    1038             :         const NLType *nl_type;
    1039             : 
    1040         374 :         assert(ret);
    1041         374 :         assert(type_system);
    1042         374 :         assert(type_system->types);
    1043             : 
    1044         374 :         if (type >= type_system->count)
    1045           0 :                 return -EOPNOTSUPP;
    1046             : 
    1047         374 :         nl_type = &type_system->types[type];
    1048             : 
    1049         374 :         if (nl_type->type == NETLINK_TYPE_UNSPEC)
    1050           0 :                 return -EOPNOTSUPP;
    1051             : 
    1052         374 :         *ret = nl_type;
    1053             : 
    1054         374 :         return 0;
    1055             : }
    1056             : 
    1057          10 : int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSystem **ret, uint16_t type) {
    1058             :         const NLType *nl_type;
    1059             :         int r;
    1060             : 
    1061          10 :         assert(ret);
    1062             : 
    1063          10 :         r = type_system_get_type(type_system, &nl_type, type);
    1064          10 :         if (r < 0)
    1065           0 :                 return r;
    1066             : 
    1067          10 :         type_get_type_system(nl_type, ret);
    1068          10 :         return 0;
    1069             : }
    1070             : 
    1071           4 : int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLTypeSystemUnion **ret, uint16_t type) {
    1072             :         const NLType *nl_type;
    1073             :         int r;
    1074             : 
    1075           4 :         assert(ret);
    1076             : 
    1077           4 :         r = type_system_get_type(type_system, &nl_type, type);
    1078           4 :         if (r < 0)
    1079           0 :                 return r;
    1080             : 
    1081           4 :         type_get_type_system_union(nl_type, ret);
    1082           4 :         return 0;
    1083             : }
    1084             : 
    1085           2 : int type_system_union_get_type_system(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, const char *key) {
    1086             :         int type;
    1087             : 
    1088           2 :         assert(type_system_union);
    1089           2 :         assert(type_system_union->match_type == NL_MATCH_SIBLING);
    1090           2 :         assert(type_system_union->lookup);
    1091           2 :         assert(type_system_union->type_systems);
    1092           2 :         assert(ret);
    1093           2 :         assert(key);
    1094             : 
    1095           2 :         type = type_system_union->lookup(key);
    1096           2 :         if (type < 0)
    1097           0 :                 return -EOPNOTSUPP;
    1098             : 
    1099           2 :         assert(type < type_system_union->num);
    1100             : 
    1101           2 :         *ret = &type_system_union->type_systems[type];
    1102             : 
    1103           2 :         return 0;
    1104             : }
    1105             : 
    1106           2 : int type_system_union_protocol_get_type_system(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, uint16_t protocol) {
    1107             :         const NLTypeSystem *type_system;
    1108             : 
    1109           2 :         assert(type_system_union);
    1110           2 :         assert(type_system_union->type_systems);
    1111           2 :         assert(type_system_union->match_type == NL_MATCH_PROTOCOL);
    1112           2 :         assert(ret);
    1113             : 
    1114           2 :         if (protocol >= type_system_union->num)
    1115           0 :                 return -EOPNOTSUPP;
    1116             : 
    1117           2 :         type_system = &type_system_union->type_systems[protocol];
    1118           2 :         if (!type_system->types)
    1119           0 :                 return -EOPNOTSUPP;
    1120             : 
    1121           2 :         *ret = type_system;
    1122             : 
    1123           2 :         return 0;
    1124             : }

Generated by: LCOV version 1.14