LCOV - code coverage report
Current view: top level - libsystemd/sd-netlink - netlink-types.c (source / functions) Hit Total Coverage
Test: systemd test coverage Lines: 67 74 90.5 %
Date: 2015-07-29 18:47:03 Functions: 12 12 100.0 %

          Line data    Source code
       1             : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
       2             : 
       3             : /***
       4             :   This file is part of systemd.
       5             : 
       6             :   Copyright 2014 Tom Gundersen <teg@jklm.no>
       7             : 
       8             :   systemd is free software; you can redistribute it and/or modify it
       9             :   under the terms of the GNU Lesser General Public License as published by
      10             :   the Free Software Foundation; either version 2.1 of the License, or
      11             :   (at your option) any later version.
      12             : 
      13             :   systemd is distributed in the hope that it will be useful, but
      14             :   WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      16             :   Lesser General Public License for more details.
      17             : 
      18             :   You should have received a copy of the GNU Lesser General Public License
      19             :   along with systemd; If not, see <http://www.gnu.org/licenses/>.
      20             : ***/
      21             : 
      22             : #include <stdint.h>
      23             : #include <sys/socket.h>
      24             : #include <linux/netlink.h>
      25             : #include <linux/rtnetlink.h>
      26             : #include <linux/in6.h>
      27             : #include <linux/veth.h>
      28             : #include <linux/if_bridge.h>
      29             : #include <linux/if_addr.h>
      30             : #include <linux/if.h>
      31             : 
      32             : #include <linux/ip.h>
      33             : #include <linux/if_link.h>
      34             : #include <linux/if_tunnel.h>
      35             : 
      36             : #include "macro.h"
      37             : #include "util.h"
      38             : 
      39             : #include "netlink-types.h"
      40             : #include "missing.h"
      41             : 
      42             : /* Maximum ARP IP target defined in kernel */
      43             : #define BOND_MAX_ARP_TARGETS    16
      44             : 
      45             : typedef enum {
      46             :         BOND_ARP_TARGETS_0,
      47             :         BOND_ARP_TARGETS_1,
      48             :         BOND_ARP_TARGETS_2,
      49             :         BOND_ARP_TARGETS_3,
      50             :         BOND_ARP_TARGETS_4,
      51             :         BOND_ARP_TARGETS_5,
      52             :         BOND_ARP_TARGETS_6,
      53             :         BOND_ARP_TARGETS_7,
      54             :         BOND_ARP_TARGETS_8,
      55             :         BOND_ARP_TARGETS_9,
      56             :         BOND_ARP_TARGETS_10,
      57             :         BOND_ARP_TARGETS_11,
      58             :         BOND_ARP_TARGETS_12,
      59             :         BOND_ARP_TARGETS_13,
      60             :         BOND_ARP_TARGETS_14,
      61             :         BOND_ARP_TARGETS_MAX = BOND_MAX_ARP_TARGETS,
      62             : } BondArpTargets;
      63             : 
      64             : struct NLType {
      65             :         uint16_t type;
      66             :         size_t size;
      67             :         const NLTypeSystem *type_system;
      68             :         const NLTypeSystemUnion *type_system_union;
      69             : };
      70             : 
      71             : struct NLTypeSystem {
      72             :         uint16_t count;
      73             :         const NLType *types;
      74             : };
      75             : 
      76             : static const NLTypeSystem rtnl_link_type_system;
      77             : 
      78             : static const NLType empty_types[1] = {
      79             :         /* fake array to avoid .types==NULL, which denotes invalid type-systems */
      80             : };
      81             : 
      82             : static const NLTypeSystem empty_type_system = {
      83             :         .count = 0,
      84             :         .types = empty_types,
      85             : };
      86             : 
      87             : static const NLType rtnl_link_info_data_veth_types[VETH_INFO_MAX + 1] = {
      88             :         [VETH_INFO_PEER]  = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
      89             : };
      90             : 
      91             : static const NLType rtnl_link_info_data_ipvlan_types[IFLA_IPVLAN_MAX + 1] = {
      92             :         [IFLA_IPVLAN_MODE]  = { .type = NETLINK_TYPE_U16 },
      93             : };
      94             : 
      95             : static const NLType rtnl_link_info_data_macvlan_types[IFLA_MACVLAN_MAX + 1] = {
      96             :         [IFLA_MACVLAN_MODE]  = { .type = NETLINK_TYPE_U32 },
      97             :         [IFLA_MACVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 },
      98             : };
      99             : 
     100             : static const NLType rtnl_link_info_data_bridge_types[IFLA_BRIDGE_MAX + 1] = {
     101             :         [IFLA_BRIDGE_FLAGS]     = { .type = NETLINK_TYPE_U16 },
     102             :         [IFLA_BRIDGE_MODE]      = { .type = NETLINK_TYPE_U16 },
     103             : /*
     104             :         [IFLA_BRIDGE_VLAN_INFO] = { .type = NETLINK_TYPE_BINARY,
     105             :                                     .len = sizeof(struct bridge_vlan_info), },
     106             : */
     107             : };
     108             : 
     109             : static const NLType rtnl_link_info_data_vlan_types[IFLA_VLAN_MAX + 1] = {
     110             :         [IFLA_VLAN_ID]          = { .type = NETLINK_TYPE_U16 },
     111             : /*
     112             :         [IFLA_VLAN_FLAGS]       = { .len = sizeof(struct ifla_vlan_flags) },
     113             :         [IFLA_VLAN_EGRESS_QOS]  = { .type = NETLINK_TYPE_NESTED },
     114             :         [IFLA_VLAN_INGRESS_QOS] = { .type = NETLINK_TYPE_NESTED },
     115             : */
     116             :         [IFLA_VLAN_PROTOCOL]    = { .type = NETLINK_TYPE_U16 },
     117             : };
     118             : 
     119             : static const NLType rtnl_link_info_data_vxlan_types[IFLA_VXLAN_MAX+1] = {
     120             :         [IFLA_VXLAN_ID]         = { .type = NETLINK_TYPE_U32 },
     121             :         [IFLA_VXLAN_GROUP]      = { .type = NETLINK_TYPE_IN_ADDR },
     122             :         [IFLA_VXLAN_LINK]       = { .type = NETLINK_TYPE_U32 },
     123             :         [IFLA_VXLAN_LOCAL]      = { .type = NETLINK_TYPE_U32},
     124             :         [IFLA_VXLAN_TTL]        = { .type = NETLINK_TYPE_U8 },
     125             :         [IFLA_VXLAN_TOS]        = { .type = NETLINK_TYPE_U8 },
     126             :         [IFLA_VXLAN_LEARNING]   = { .type = NETLINK_TYPE_U8 },
     127             :         [IFLA_VXLAN_AGEING]     = { .type = NETLINK_TYPE_U32 },
     128             :         [IFLA_VXLAN_LIMIT]      = { .type = NETLINK_TYPE_U32 },
     129             :         [IFLA_VXLAN_PORT_RANGE] = { .type = NETLINK_TYPE_U32},
     130             :         [IFLA_VXLAN_PROXY]      = { .type = NETLINK_TYPE_U8 },
     131             :         [IFLA_VXLAN_RSC]        = { .type = NETLINK_TYPE_U8 },
     132             :         [IFLA_VXLAN_L2MISS]     = { .type = NETLINK_TYPE_U8 },
     133             :         [IFLA_VXLAN_L3MISS]     = { .type = NETLINK_TYPE_U8 },
     134             : };
     135             : 
     136             : static const NLType rtnl_bond_arp_target_types[BOND_ARP_TARGETS_MAX + 1] = {
     137             :         [BOND_ARP_TARGETS_0]        = { .type = NETLINK_TYPE_U32 },
     138             :         [BOND_ARP_TARGETS_1]        = { .type = NETLINK_TYPE_U32 },
     139             :         [BOND_ARP_TARGETS_2]        = { .type = NETLINK_TYPE_U32 },
     140             :         [BOND_ARP_TARGETS_3]        = { .type = NETLINK_TYPE_U32 },
     141             :         [BOND_ARP_TARGETS_4]        = { .type = NETLINK_TYPE_U32 },
     142             :         [BOND_ARP_TARGETS_5]        = { .type = NETLINK_TYPE_U32 },
     143             :         [BOND_ARP_TARGETS_6]        = { .type = NETLINK_TYPE_U32 },
     144             :         [BOND_ARP_TARGETS_7]        = { .type = NETLINK_TYPE_U32 },
     145             :         [BOND_ARP_TARGETS_8]        = { .type = NETLINK_TYPE_U32 },
     146             :         [BOND_ARP_TARGETS_9]        = { .type = NETLINK_TYPE_U32 },
     147             :         [BOND_ARP_TARGETS_10]       = { .type = NETLINK_TYPE_U32 },
     148             :         [BOND_ARP_TARGETS_11]       = { .type = NETLINK_TYPE_U32 },
     149             :         [BOND_ARP_TARGETS_12]       = { .type = NETLINK_TYPE_U32 },
     150             :         [BOND_ARP_TARGETS_13]       = { .type = NETLINK_TYPE_U32 },
     151             :         [BOND_ARP_TARGETS_14]       = { .type = NETLINK_TYPE_U32 },
     152             :         [BOND_ARP_TARGETS_MAX]      = { .type = NETLINK_TYPE_U32 },
     153             : };
     154             : 
     155             : static const NLTypeSystem rtnl_bond_arp_type_system = {
     156             :         .count = ELEMENTSOF(rtnl_bond_arp_target_types),
     157             :         .types = rtnl_bond_arp_target_types,
     158             : };
     159             : 
     160             : static const NLType rtnl_link_info_data_bond_types[IFLA_BOND_MAX + 1] = {
     161             :         [IFLA_BOND_MODE]                = { .type = NETLINK_TYPE_U8 },
     162             :         [IFLA_BOND_ACTIVE_SLAVE]        = { .type = NETLINK_TYPE_U32 },
     163             :         [IFLA_BOND_MIIMON]              = { .type = NETLINK_TYPE_U32 },
     164             :         [IFLA_BOND_UPDELAY]             = { .type = NETLINK_TYPE_U32 },
     165             :         [IFLA_BOND_DOWNDELAY]           = { .type = NETLINK_TYPE_U32 },
     166             :         [IFLA_BOND_USE_CARRIER]         = { .type = NETLINK_TYPE_U8 },
     167             :         [IFLA_BOND_ARP_INTERVAL]        = { .type = NETLINK_TYPE_U32 },
     168             :         [IFLA_BOND_ARP_IP_TARGET]       = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bond_arp_type_system },
     169             :         [IFLA_BOND_ARP_VALIDATE]        = { .type = NETLINK_TYPE_U32 },
     170             :         [IFLA_BOND_ARP_ALL_TARGETS]     = { .type = NETLINK_TYPE_U32 },
     171             :         [IFLA_BOND_PRIMARY]             = { .type = NETLINK_TYPE_U32 },
     172             :         [IFLA_BOND_PRIMARY_RESELECT]    = { .type = NETLINK_TYPE_U8 },
     173             :         [IFLA_BOND_FAIL_OVER_MAC]       = { .type = NETLINK_TYPE_U8 },
     174             :         [IFLA_BOND_XMIT_HASH_POLICY]    = { .type = NETLINK_TYPE_U8 },
     175             :         [IFLA_BOND_RESEND_IGMP]         = { .type = NETLINK_TYPE_U32 },
     176             :         [IFLA_BOND_NUM_PEER_NOTIF]      = { .type = NETLINK_TYPE_U8 },
     177             :         [IFLA_BOND_ALL_SLAVES_ACTIVE]   = { .type = NETLINK_TYPE_U8 },
     178             :         [IFLA_BOND_MIN_LINKS]           = { .type = NETLINK_TYPE_U32 },
     179             :         [IFLA_BOND_LP_INTERVAL]         = { .type = NETLINK_TYPE_U32 },
     180             :         [IFLA_BOND_PACKETS_PER_SLAVE]   = { .type = NETLINK_TYPE_U32 },
     181             :         [IFLA_BOND_AD_LACP_RATE]        = { .type = NETLINK_TYPE_U8 },
     182             :         [IFLA_BOND_AD_SELECT]           = { .type = NETLINK_TYPE_U8 },
     183             :         [IFLA_BOND_AD_INFO]             = { .type = NETLINK_TYPE_NESTED },
     184             : };
     185             : 
     186             : static const NLType rtnl_link_info_data_iptun_types[IFLA_IPTUN_MAX + 1] = {
     187             :         [IFLA_IPTUN_LINK]                = { .type = NETLINK_TYPE_U32 },
     188             :         [IFLA_IPTUN_LOCAL]               = { .type = NETLINK_TYPE_IN_ADDR },
     189             :         [IFLA_IPTUN_REMOTE]              = { .type = NETLINK_TYPE_IN_ADDR },
     190             :         [IFLA_IPTUN_TTL]                 = { .type = NETLINK_TYPE_U8 },
     191             :         [IFLA_IPTUN_TOS]                 = { .type = NETLINK_TYPE_U8 },
     192             :         [IFLA_IPTUN_PMTUDISC]            = { .type = NETLINK_TYPE_U8 },
     193             :         [IFLA_IPTUN_FLAGS]               = { .type = NETLINK_TYPE_U16 },
     194             :         [IFLA_IPTUN_PROTO]               = { .type = NETLINK_TYPE_U8 },
     195             :         [IFLA_IPTUN_6RD_PREFIX]          = { .type = NETLINK_TYPE_IN_ADDR },
     196             :         [IFLA_IPTUN_6RD_RELAY_PREFIX]    = { .type = NETLINK_TYPE_U32 },
     197             :         [IFLA_IPTUN_6RD_PREFIXLEN]       = { .type = NETLINK_TYPE_U16 },
     198             :         [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NETLINK_TYPE_U16 },
     199             :         [IFLA_IPTUN_ENCAP_TYPE]          = { .type = NETLINK_TYPE_U16 },
     200             :         [IFLA_IPTUN_ENCAP_FLAGS]         = { .type = NETLINK_TYPE_U16 },
     201             :         [IFLA_IPTUN_ENCAP_SPORT]         = { .type = NETLINK_TYPE_U16 },
     202             :         [IFLA_IPTUN_ENCAP_DPORT]         = { .type = NETLINK_TYPE_U16 },
     203             : };
     204             : 
     205             : static  const NLType rtnl_link_info_data_ipgre_types[IFLA_GRE_MAX + 1] = {
     206             :         [IFLA_GRE_LINK]         = { .type = NETLINK_TYPE_U32 },
     207             :         [IFLA_GRE_IFLAGS]       = { .type = NETLINK_TYPE_U16 },
     208             :         [IFLA_GRE_OFLAGS]       = { .type = NETLINK_TYPE_U16 },
     209             :         [IFLA_GRE_IKEY]         = { .type = NETLINK_TYPE_U32 },
     210             :         [IFLA_GRE_OKEY]         = { .type = NETLINK_TYPE_U32 },
     211             :         [IFLA_GRE_LOCAL]        = { .type = NETLINK_TYPE_IN_ADDR },
     212             :         [IFLA_GRE_REMOTE]       = { .type = NETLINK_TYPE_IN_ADDR },
     213             :         [IFLA_GRE_TTL]          = { .type = NETLINK_TYPE_U8 },
     214             :         [IFLA_GRE_TOS]          = { .type = NETLINK_TYPE_U8 },
     215             :         [IFLA_GRE_PMTUDISC]     = { .type = NETLINK_TYPE_U8 },
     216             :         [IFLA_GRE_FLOWINFO]     = { .type = NETLINK_TYPE_U32 },
     217             :         [IFLA_GRE_FLAGS]        = { .type = NETLINK_TYPE_U32 },
     218             :         [IFLA_GRE_ENCAP_TYPE]   = { .type = NETLINK_TYPE_U16 },
     219             :         [IFLA_GRE_ENCAP_FLAGS]  = { .type = NETLINK_TYPE_U16 },
     220             :         [IFLA_GRE_ENCAP_SPORT]  = { .type = NETLINK_TYPE_U16 },
     221             :         [IFLA_GRE_ENCAP_DPORT]  = { .type = NETLINK_TYPE_U16 },
     222             : };
     223             : 
     224             : static const NLType rtnl_link_info_data_ipvti_types[IFLA_VTI_MAX + 1] = {
     225             :         [IFLA_VTI_LINK]         = { .type = NETLINK_TYPE_U32 },
     226             :         [IFLA_VTI_IKEY]         = { .type = NETLINK_TYPE_U32 },
     227             :         [IFLA_VTI_OKEY]         = { .type = NETLINK_TYPE_U32 },
     228             :         [IFLA_VTI_LOCAL]        = { .type = NETLINK_TYPE_IN_ADDR },
     229             :         [IFLA_VTI_REMOTE]       = { .type = NETLINK_TYPE_IN_ADDR },
     230             : };
     231             : 
     232             : static const NLType rtnl_link_info_data_ip6tnl_types[IFLA_IPTUN_MAX + 1] = {
     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_FLAGS]               = { .type = NETLINK_TYPE_U32 },
     238             :         [IFLA_IPTUN_PROTO]               = { .type = NETLINK_TYPE_U8 },
     239             :         [IFLA_IPTUN_ENCAP_LIMIT]         = { .type = NETLINK_TYPE_U8 },
     240             :         [IFLA_IPTUN_FLOWINFO]            = { .type = NETLINK_TYPE_U32 },
     241             : };
     242             : 
     243             : /* these strings must match the .kind entries in the kernel */
     244             : static const char* const nl_union_link_info_data_table[_NL_UNION_LINK_INFO_DATA_MAX] = {
     245             :         [NL_UNION_LINK_INFO_DATA_BOND] = "bond",
     246             :         [NL_UNION_LINK_INFO_DATA_BRIDGE] = "bridge",
     247             :         [NL_UNION_LINK_INFO_DATA_VLAN] = "vlan",
     248             :         [NL_UNION_LINK_INFO_DATA_VETH] = "veth",
     249             :         [NL_UNION_LINK_INFO_DATA_DUMMY] = "dummy",
     250             :         [NL_UNION_LINK_INFO_DATA_MACVLAN] = "macvlan",
     251             :         [NL_UNION_LINK_INFO_DATA_MACVTAP] = "macvtap",
     252             :         [NL_UNION_LINK_INFO_DATA_IPVLAN] = "ipvlan",
     253             :         [NL_UNION_LINK_INFO_DATA_VXLAN] = "vxlan",
     254             :         [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = "ipip",
     255             :         [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = "gre",
     256             :         [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = "gretap",
     257             :         [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = "ip6gre",
     258             :         [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = "ip6gretap",
     259             :         [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = "sit",
     260             :         [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = "vti",
     261             :         [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = "vti6",
     262             :         [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = "ip6tnl",
     263             : };
     264             : 
     265          42 : DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData);
     266             : 
     267             : static const NLTypeSystem rtnl_link_info_data_type_systems[_NL_UNION_LINK_INFO_DATA_MAX] = {
     268             :         [NL_UNION_LINK_INFO_DATA_BOND] =        { .count = ELEMENTSOF(rtnl_link_info_data_bond_types),
     269             :                                                   .types = rtnl_link_info_data_bond_types },
     270             :         [NL_UNION_LINK_INFO_DATA_BRIDGE] =      { .count = ELEMENTSOF(rtnl_link_info_data_bridge_types),
     271             :                                                   .types = rtnl_link_info_data_bridge_types },
     272             :         [NL_UNION_LINK_INFO_DATA_VLAN] =        { .count = ELEMENTSOF(rtnl_link_info_data_vlan_types),
     273             :                                                   .types = rtnl_link_info_data_vlan_types },
     274             :         [NL_UNION_LINK_INFO_DATA_VETH] =        { .count = ELEMENTSOF(rtnl_link_info_data_veth_types),
     275             :                                                   .types = rtnl_link_info_data_veth_types },
     276             :         [NL_UNION_LINK_INFO_DATA_MACVLAN] =     { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types),
     277             :                                                   .types = rtnl_link_info_data_macvlan_types },
     278             :         [NL_UNION_LINK_INFO_DATA_MACVTAP] =     { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types),
     279             :                                                   .types = rtnl_link_info_data_macvlan_types },
     280             :         [NL_UNION_LINK_INFO_DATA_IPVLAN] =      { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types),
     281             :                                                   .types = rtnl_link_info_data_ipvlan_types },
     282             :         [NL_UNION_LINK_INFO_DATA_VXLAN] =       { .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types),
     283             :                                                   .types = rtnl_link_info_data_vxlan_types },
     284             :         [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types),
     285             :                                                   .types = rtnl_link_info_data_iptun_types },
     286             :         [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
     287             :                                                     .types = rtnl_link_info_data_ipgre_types },
     288             :         [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
     289             :                                                     .types = rtnl_link_info_data_ipgre_types },
     290             :         [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
     291             :                                                     .types = rtnl_link_info_data_ipgre_types },
     292             :         [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
     293             :                                                     .types = rtnl_link_info_data_ipgre_types },
     294             :         [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types),
     295             :                                                   .types = rtnl_link_info_data_iptun_types },
     296             :         [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types),
     297             :                                                   .types = rtnl_link_info_data_ipvti_types },
     298             :         [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types),
     299             :                                                   .types = rtnl_link_info_data_ipvti_types },
     300             :         [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types),
     301             :                                                      .types = rtnl_link_info_data_ip6tnl_types },
     302             : 
     303             : };
     304             : 
     305             : static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = {
     306             :         .num = _NL_UNION_LINK_INFO_DATA_MAX,
     307             :         .lookup = nl_union_link_info_data_from_string,
     308             :         .type_systems = rtnl_link_info_data_type_systems,
     309             :         .match_type = NL_MATCH_SIBLING,
     310             :         .match = IFLA_INFO_KIND,
     311             : };
     312             : 
     313             : static const NLType rtnl_link_info_types[IFLA_INFO_MAX + 1] = {
     314             :         [IFLA_INFO_KIND]        = { .type = NETLINK_TYPE_STRING },
     315             :         [IFLA_INFO_DATA]        = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_link_info_data_type_system_union},
     316             : /*
     317             :         [IFLA_INFO_XSTATS],
     318             :         [IFLA_INFO_SLAVE_KIND]  = { .type = NETLINK_TYPE_STRING },
     319             :         [IFLA_INFO_SLAVE_DATA]  = { .type = NETLINK_TYPE_NESTED },
     320             : */
     321             : };
     322             : 
     323             : static const NLTypeSystem rtnl_link_info_type_system = {
     324             :         .count = ELEMENTSOF(rtnl_link_info_types),
     325             :         .types = rtnl_link_info_types,
     326             : };
     327             : 
     328             : static const struct NLType rtnl_prot_info_bridge_port_types[IFLA_BRPORT_MAX + 1] = {
     329             :         [IFLA_BRPORT_STATE]             = { .type = NETLINK_TYPE_U8 },
     330             :         [IFLA_BRPORT_COST]              = { .type = NETLINK_TYPE_U32 },
     331             :         [IFLA_BRPORT_PRIORITY]          = { .type = NETLINK_TYPE_U16 },
     332             :         [IFLA_BRPORT_MODE]              = { .type = NETLINK_TYPE_U8 },
     333             :         [IFLA_BRPORT_GUARD]             = { .type = NETLINK_TYPE_U8 },
     334             :         [IFLA_BRPORT_PROTECT]           = { .type = NETLINK_TYPE_U8 },
     335             :         [IFLA_BRPORT_FAST_LEAVE]        = { .type = NETLINK_TYPE_U8 },
     336             :         [IFLA_BRPORT_LEARNING]          = { .type = NETLINK_TYPE_U8 },
     337             :         [IFLA_BRPORT_UNICAST_FLOOD]     = { .type = NETLINK_TYPE_U8 },
     338             :         [IFLA_BRPORT_PROXYARP]          = { .type = NETLINK_TYPE_U8 },
     339             :         [IFLA_BRPORT_LEARNING_SYNC]     = { .type = NETLINK_TYPE_U8 },
     340             : };
     341             : 
     342             : static const NLTypeSystem rtnl_prot_info_type_systems[AF_MAX] = {
     343             :         [AF_BRIDGE] =   { .count = ELEMENTSOF(rtnl_prot_info_bridge_port_types),
     344             :                           .types = rtnl_prot_info_bridge_port_types },
     345             : };
     346             : 
     347             : static const NLTypeSystemUnion rtnl_prot_info_type_system_union = {
     348             :         .num = AF_MAX,
     349             :         .type_systems = rtnl_prot_info_type_systems,
     350             :         .match_type = NL_MATCH_PROTOCOL,
     351             : };
     352             : 
     353             : static const struct NLType rtnl_af_spec_inet6_types[IFLA_INET6_MAX + 1] = {
     354             :         [IFLA_INET6_FLAGS]              = { .type = NETLINK_TYPE_U32 },
     355             : /*
     356             :         IFLA_INET6_CONF,
     357             :         IFLA_INET6_STATS,
     358             :         IFLA_INET6_MCAST,
     359             :         IFLA_INET6_CACHEINFO,
     360             :         IFLA_INET6_ICMP6STATS,
     361             : */
     362             :         [IFLA_INET6_TOKEN]              = { .type = NETLINK_TYPE_IN_ADDR },
     363             :         [IFLA_INET6_ADDR_GEN_MODE]      = { .type = NETLINK_TYPE_U8 },
     364             : };
     365             : 
     366             : static const NLTypeSystem rtnl_af_spec_inet6_type_system = {
     367             :         .count = ELEMENTSOF(rtnl_af_spec_inet6_types),
     368             :         .types = rtnl_af_spec_inet6_types,
     369             : };
     370             : 
     371             : static const NLType rtnl_af_spec_types[AF_MAX + 1] = {
     372             :         [AF_INET6] =    { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_af_spec_inet6_type_system },
     373             : };
     374             : 
     375             : static const NLTypeSystem rtnl_af_spec_type_system = {
     376             :         .count = ELEMENTSOF(rtnl_af_spec_types),
     377             :         .types = rtnl_af_spec_types,
     378             : };
     379             : 
     380             : static const NLType rtnl_link_types[IFLA_MAX + 1 ] = {
     381             :         [IFLA_ADDRESS]          = { .type = NETLINK_TYPE_ETHER_ADDR },
     382             :         [IFLA_BROADCAST]        = { .type = NETLINK_TYPE_ETHER_ADDR },
     383             :         [IFLA_IFNAME]           = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 },
     384             :         [IFLA_MTU]              = { .type = NETLINK_TYPE_U32 },
     385             :         [IFLA_LINK]             = { .type = NETLINK_TYPE_U32 },
     386             : /*
     387             :         [IFLA_QDISC],
     388             :         [IFLA_STATS],
     389             :         [IFLA_COST],
     390             :         [IFLA_PRIORITY],
     391             : */
     392             :         [IFLA_MASTER]           = { .type = NETLINK_TYPE_U32 },
     393             : /*
     394             :         [IFLA_WIRELESS],
     395             : */
     396             :         [IFLA_PROTINFO]         = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_prot_info_type_system_union },
     397             :         [IFLA_TXQLEN]           = { .type = NETLINK_TYPE_U32 },
     398             : /*
     399             :         [IFLA_MAP]              = { .len = sizeof(struct rtnl_link_ifmap) },
     400             : */
     401             :         [IFLA_WEIGHT]           = { .type = NETLINK_TYPE_U32 },
     402             :         [IFLA_OPERSTATE]        = { .type = NETLINK_TYPE_U8 },
     403             :         [IFLA_LINKMODE]         = { .type = NETLINK_TYPE_U8 },
     404             :         [IFLA_LINKINFO]         = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_info_type_system },
     405             :         [IFLA_NET_NS_PID]       = { .type = NETLINK_TYPE_U32 },
     406             :         [IFLA_IFALIAS]          = { .type = NETLINK_TYPE_STRING, .size = IFALIASZ - 1 },
     407             : /*
     408             :         [IFLA_NUM_VF],
     409             :         [IFLA_VFINFO_LIST]      = {. type = NETLINK_TYPE_NESTED, },
     410             :         [IFLA_STATS64],
     411             :         [IFLA_VF_PORTS]         = { .type = NETLINK_TYPE_NESTED },
     412             :         [IFLA_PORT_SELF]        = { .type = NETLINK_TYPE_NESTED },
     413             : */
     414             :         [IFLA_AF_SPEC]          = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_af_spec_type_system },
     415             : /*
     416             :         [IFLA_VF_PORTS],
     417             :         [IFLA_PORT_SELF],
     418             :         [IFLA_AF_SPEC],
     419             : */
     420             :         [IFLA_GROUP]            = { .type = NETLINK_TYPE_U32 },
     421             :         [IFLA_NET_NS_FD]        = { .type = NETLINK_TYPE_U32 },
     422             :         [IFLA_EXT_MASK]         = { .type = NETLINK_TYPE_U32 },
     423             :         [IFLA_PROMISCUITY]      = { .type = NETLINK_TYPE_U32 },
     424             :         [IFLA_NUM_TX_QUEUES]    = { .type = NETLINK_TYPE_U32 },
     425             :         [IFLA_NUM_RX_QUEUES]    = { .type = NETLINK_TYPE_U32 },
     426             :         [IFLA_CARRIER]          = { .type = NETLINK_TYPE_U8 },
     427             : /*
     428             :         [IFLA_PHYS_PORT_ID]     = { .type = NETLINK_TYPE_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
     429             : */
     430             : };
     431             : 
     432             : static const NLTypeSystem rtnl_link_type_system = {
     433             :         .count = ELEMENTSOF(rtnl_link_types),
     434             :         .types = rtnl_link_types,
     435             : };
     436             : 
     437             : /* IFA_FLAGS was defined in kernel 3.14, but we still support older
     438             :  * kernels where IFA_MAX is lower. */
     439             : static const NLType rtnl_address_types[CONST_MAX(IFA_MAX, IFA_FLAGS) + 1] = {
     440             :         [IFA_ADDRESS]           = { .type = NETLINK_TYPE_IN_ADDR },
     441             :         [IFA_LOCAL]             = { .type = NETLINK_TYPE_IN_ADDR },
     442             :         [IFA_LABEL]             = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 },
     443             :         [IFA_BROADCAST]         = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */
     444             :         [IFA_CACHEINFO]         = { .type = NETLINK_TYPE_CACHE_INFO, .size = sizeof(struct ifa_cacheinfo) },
     445             : /*
     446             :         [IFA_ANYCAST],
     447             :         [IFA_MULTICAST],
     448             : */
     449             :         [IFA_FLAGS]             = { .type = NETLINK_TYPE_U32 },
     450             : };
     451             : 
     452             : static const NLTypeSystem rtnl_address_type_system = {
     453             :         .count = ELEMENTSOF(rtnl_address_types),
     454             :         .types = rtnl_address_types,
     455             : };
     456             : 
     457             : static const NLType rtnl_route_types[RTA_MAX + 1] = {
     458             :         [RTA_DST]               = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */
     459             :         [RTA_SRC]               = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */
     460             :         [RTA_IIF]               = { .type = NETLINK_TYPE_U32 },
     461             :         [RTA_OIF]               = { .type = NETLINK_TYPE_U32 },
     462             :         [RTA_GATEWAY]           = { .type = NETLINK_TYPE_IN_ADDR },
     463             :         [RTA_PRIORITY]          = { .type = NETLINK_TYPE_U32 },
     464             :         [RTA_PREFSRC]           = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */
     465             : /*
     466             :         [RTA_METRICS]           = { .type = NETLINK_TYPE_NESTED },
     467             :         [RTA_MULTIPATH]         = { .len = sizeof(struct rtnexthop) },
     468             : */
     469             :         [RTA_FLOW]              = { .type = NETLINK_TYPE_U32 }, /* 6? */
     470             : /*
     471             :         RTA_CACHEINFO,
     472             :         RTA_TABLE,
     473             :         RTA_MARK,
     474             :         RTA_MFC_STATS,
     475             : */
     476             : };
     477             : 
     478             : static const NLTypeSystem rtnl_route_type_system = {
     479             :         .count = ELEMENTSOF(rtnl_route_types),
     480             :         .types = rtnl_route_types,
     481             : };
     482             : 
     483             : static const NLType rtnl_neigh_types[NDA_MAX + 1] = {
     484             :         [NDA_DST]               = { .type = NETLINK_TYPE_IN_ADDR },
     485             :         [NDA_LLADDR]            = { .type = NETLINK_TYPE_ETHER_ADDR },
     486             :         [NDA_CACHEINFO]         = { .type = NETLINK_TYPE_CACHE_INFO, .size = sizeof(struct nda_cacheinfo) },
     487             :         [NDA_PROBES]            = { .type = NETLINK_TYPE_U32 },
     488             :         [NDA_VLAN]              = { .type = NETLINK_TYPE_U16 },
     489             :         [NDA_PORT]              = { .type = NETLINK_TYPE_U16 },
     490             :         [NDA_VNI]               = { .type = NETLINK_TYPE_U32 },
     491             :         [NDA_IFINDEX]           = { .type = NETLINK_TYPE_U32 },
     492             : };
     493             : 
     494             : static const NLTypeSystem rtnl_neigh_type_system = {
     495             :         .count = ELEMENTSOF(rtnl_neigh_types),
     496             :         .types = rtnl_neigh_types,
     497             : };
     498             : 
     499             : static const NLType rtnl_types[RTM_MAX + 1] = {
     500             :         [NLMSG_DONE]   = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 },
     501             :         [NLMSG_ERROR]  = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = sizeof(struct nlmsgerr) },
     502             :         [RTM_NEWLINK]  = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
     503             :         [RTM_DELLINK]  = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
     504             :         [RTM_GETLINK]  = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
     505             :         [RTM_SETLINK]  = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
     506             :         [RTM_NEWADDR]  = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
     507             :         [RTM_DELADDR]  = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
     508             :         [RTM_GETADDR]  = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
     509             :         [RTM_NEWROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
     510             :         [RTM_DELROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
     511             :         [RTM_GETROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
     512             :         [RTM_NEWNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
     513             :         [RTM_DELNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
     514             :         [RTM_GETNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
     515             : };
     516             : 
     517             : const NLTypeSystem type_system_root = {
     518             :         .count = ELEMENTSOF(rtnl_types),
     519             :         .types = rtnl_types,
     520             : };
     521             : 
     522         172 : uint16_t type_get_type(const NLType *type) {
     523         172 :         assert(type);
     524         172 :         return type->type;
     525             : }
     526             : 
     527         133 : size_t type_get_size(const NLType *type) {
     528         133 :         assert(type);
     529         133 :         return type->size;
     530             : }
     531             : 
     532          78 : void type_get_type_system(const NLType *nl_type, const NLTypeSystem **ret) {
     533          78 :         assert(nl_type);
     534          78 :         assert(ret);
     535          78 :         assert(nl_type->type == NETLINK_TYPE_NESTED);
     536          78 :         assert(nl_type->type_system);
     537             : 
     538          78 :         *ret = nl_type->type_system;
     539          78 : }
     540             : 
     541           4 : void type_get_type_system_union(const NLType *nl_type, const NLTypeSystemUnion **ret) {
     542           4 :         assert(nl_type);
     543           4 :         assert(ret);
     544           4 :         assert(nl_type->type == NETLINK_TYPE_UNION);
     545           4 :         assert(nl_type->type_system_union);
     546             : 
     547           4 :         *ret = nl_type->type_system_union;
     548           4 : }
     549             : 
     550          59 : uint16_t type_system_get_count(const NLTypeSystem *type_system) {
     551          59 :         assert(type_system);
     552          59 :         return type_system->count;
     553             : }
     554             : 
     555         230 : int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) {
     556             :         const NLType *nl_type;
     557             : 
     558         230 :         assert(ret);
     559         230 :         assert(type_system);
     560         230 :         assert(type_system->types);
     561             : 
     562         230 :         if (type >= type_system->count)
     563           0 :                 return -EOPNOTSUPP;
     564             : 
     565         230 :         nl_type = &type_system->types[type];
     566             : 
     567         230 :         if (nl_type->type == NETLINK_TYPE_UNSPEC)
     568           0 :                 return -EOPNOTSUPP;
     569             : 
     570         230 :         *ret = nl_type;
     571             : 
     572         230 :         return 0;
     573             : }
     574             : 
     575           2 : int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSystem **ret, uint16_t type) {
     576             :         const NLType *nl_type;
     577             :         int r;
     578             : 
     579           2 :         assert(ret);
     580             : 
     581           2 :         r = type_system_get_type(type_system, &nl_type, type);
     582           2 :         if (r < 0)
     583           0 :                 return r;
     584             : 
     585           2 :         type_get_type_system(nl_type, ret);
     586           2 :         return 0;
     587             : }
     588             : 
     589           4 : int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLTypeSystemUnion **ret, uint16_t type) {
     590             :         const NLType *nl_type;
     591             :         int r;
     592             : 
     593           4 :         assert(ret);
     594             : 
     595           4 :         r = type_system_get_type(type_system, &nl_type, type);
     596           4 :         if (r < 0)
     597           0 :                 return r;
     598             : 
     599           4 :         type_get_type_system_union(nl_type, ret);
     600           4 :         return 0;
     601             : }
     602             : 
     603           2 : int type_system_union_get_type_system(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, const char *key) {
     604             :         int type;
     605             : 
     606           2 :         assert(type_system_union);
     607           2 :         assert(type_system_union->match_type == NL_MATCH_SIBLING);
     608           2 :         assert(type_system_union->lookup);
     609           2 :         assert(type_system_union->type_systems);
     610           2 :         assert(ret);
     611           2 :         assert(key);
     612             : 
     613           2 :         type = type_system_union->lookup(key);
     614           2 :         if (type < 0)
     615           0 :                 return -EOPNOTSUPP;
     616             : 
     617           2 :         assert(type < type_system_union->num);
     618             : 
     619           2 :         *ret = &type_system_union->type_systems[type];
     620             : 
     621           2 :         return 0;
     622             : }
     623             : 
     624           2 : int type_system_union_protocol_get_type_system(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, uint16_t protocol) {
     625             :         const NLTypeSystem *type_system;
     626             : 
     627           2 :         assert(type_system_union);
     628           2 :         assert(type_system_union->type_systems);
     629           2 :         assert(type_system_union->match_type == NL_MATCH_PROTOCOL);
     630           2 :         assert(ret);
     631             : 
     632           2 :         if (protocol >= type_system_union->num)
     633           0 :                 return -EOPNOTSUPP;
     634             : 
     635           2 :         type_system = &type_system_union->type_systems[protocol];
     636           2 :         if (!type_system->types)
     637           0 :                 return -EOPNOTSUPP;
     638             : 
     639           2 :         *ret = type_system;
     640             : 
     641           2 :         return 0;
     642             : }

Generated by: LCOV version 1.11