From 6771b85d9817f12ab859b2ebf1c5e104633d88a4 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 26 Aug 2021 01:05:11 +0900 Subject: [PATCH 01/13] network/netdev: append IFLA_INFO_DATA attribute only when it is necessary --- src/network/netdev/netdev.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index 426be8c7fc7..ce14d521862 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -515,19 +515,23 @@ static int netdev_create(NetDev *netdev, Link *link, link_netlink_message_handle if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m"); - r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, netdev_kind_to_string(netdev->kind)); - if (r < 0) - return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m"); - if (NETDEV_VTABLE(netdev)->fill_message_create) { + r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, netdev_kind_to_string(netdev->kind)); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m"); + r = NETDEV_VTABLE(netdev)->fill_message_create(netdev, link, m); if (r < 0) return r; - } - r = sd_netlink_message_close_container(m); - if (r < 0) - return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m"); + r = sd_netlink_message_close_container(m); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m"); + } else { + r = sd_netlink_message_append_string(m, IFLA_INFO_KIND, netdev_kind_to_string(netdev->kind)); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_KIND attribute: %m"); + } r = sd_netlink_message_close_container(m); if (r < 0) From c46bce8b5ddcbda8dc2d112182f3ae1ce04a7997 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 25 Aug 2021 16:52:32 +0900 Subject: [PATCH 02/13] basic/linux: add more bridge headers --- src/basic/linux/cfm_bridge.h | 64 +++++++++++++++++++++++++++++++ src/basic/linux/mrp_bridge.h | 74 ++++++++++++++++++++++++++++++++++++ src/basic/meson.build | 2 + 3 files changed, 140 insertions(+) create mode 100644 src/basic/linux/cfm_bridge.h create mode 100644 src/basic/linux/mrp_bridge.h diff --git a/src/basic/linux/cfm_bridge.h b/src/basic/linux/cfm_bridge.h new file mode 100644 index 00000000000..3c1cbd1db2f --- /dev/null +++ b/src/basic/linux/cfm_bridge.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ + +#ifndef _UAPI_LINUX_CFM_BRIDGE_H_ +#define _UAPI_LINUX_CFM_BRIDGE_H_ + +#include +#include + +#define ETHER_HEADER_LENGTH (6+6+4+2) +#define CFM_MAID_LENGTH 48 +#define CFM_CCM_PDU_LENGTH 75 +#define CFM_PORT_STATUS_TLV_LENGTH 4 +#define CFM_IF_STATUS_TLV_LENGTH 4 +#define CFM_IF_STATUS_TLV_TYPE 4 +#define CFM_PORT_STATUS_TLV_TYPE 2 +#define CFM_ENDE_TLV_TYPE 0 +#define CFM_CCM_MAX_FRAME_LENGTH (ETHER_HEADER_LENGTH+\ + CFM_CCM_PDU_LENGTH+\ + CFM_PORT_STATUS_TLV_LENGTH+\ + CFM_IF_STATUS_TLV_LENGTH) +#define CFM_FRAME_PRIO 7 +#define CFM_CCM_TLV_OFFSET 70 +#define CFM_CCM_PDU_MAID_OFFSET 10 +#define CFM_CCM_PDU_MEPID_OFFSET 8 +#define CFM_CCM_PDU_SEQNR_OFFSET 4 +#define CFM_CCM_PDU_TLV_OFFSET 74 +#define CFM_CCM_ITU_RESERVED_SIZE 16 + +struct br_cfm_common_hdr { + __u8 mdlevel_version; + __u8 opcode; + __u8 flags; + __u8 tlv_offset; +}; + +enum br_cfm_opcodes { + BR_CFM_OPCODE_CCM = 0x1, +}; + +/* MEP domain */ +enum br_cfm_domain { + BR_CFM_PORT, + BR_CFM_VLAN, +}; + +/* MEP direction */ +enum br_cfm_mep_direction { + BR_CFM_MEP_DIRECTION_DOWN, + BR_CFM_MEP_DIRECTION_UP, +}; + +/* CCM interval supported. */ +enum br_cfm_ccm_interval { + BR_CFM_CCM_INTERVAL_NONE, + BR_CFM_CCM_INTERVAL_3_3_MS, + BR_CFM_CCM_INTERVAL_10_MS, + BR_CFM_CCM_INTERVAL_100_MS, + BR_CFM_CCM_INTERVAL_1_SEC, + BR_CFM_CCM_INTERVAL_10_SEC, + BR_CFM_CCM_INTERVAL_1_MIN, + BR_CFM_CCM_INTERVAL_10_MIN, +}; + +#endif diff --git a/src/basic/linux/mrp_bridge.h b/src/basic/linux/mrp_bridge.h new file mode 100644 index 00000000000..bd4424de56f --- /dev/null +++ b/src/basic/linux/mrp_bridge.h @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ + +#ifndef _UAPI_LINUX_MRP_BRIDGE_H_ +#define _UAPI_LINUX_MRP_BRIDGE_H_ + +#include +#include + +#define MRP_MAX_FRAME_LENGTH 200 +#define MRP_DEFAULT_PRIO 0x8000 +#define MRP_DOMAIN_UUID_LENGTH 16 +#define MRP_VERSION 1 +#define MRP_FRAME_PRIO 7 +#define MRP_OUI_LENGTH 3 +#define MRP_MANUFACTURE_DATA_LENGTH 2 + +enum br_mrp_ring_role_type { + BR_MRP_RING_ROLE_DISABLED, + BR_MRP_RING_ROLE_MRC, + BR_MRP_RING_ROLE_MRM, + BR_MRP_RING_ROLE_MRA, +}; + +enum br_mrp_in_role_type { + BR_MRP_IN_ROLE_DISABLED, + BR_MRP_IN_ROLE_MIC, + BR_MRP_IN_ROLE_MIM, +}; + +enum br_mrp_ring_state_type { + BR_MRP_RING_STATE_OPEN, + BR_MRP_RING_STATE_CLOSED, +}; + +enum br_mrp_in_state_type { + BR_MRP_IN_STATE_OPEN, + BR_MRP_IN_STATE_CLOSED, +}; + +enum br_mrp_port_state_type { + BR_MRP_PORT_STATE_DISABLED, + BR_MRP_PORT_STATE_BLOCKED, + BR_MRP_PORT_STATE_FORWARDING, + BR_MRP_PORT_STATE_NOT_CONNECTED, +}; + +enum br_mrp_port_role_type { + BR_MRP_PORT_ROLE_PRIMARY, + BR_MRP_PORT_ROLE_SECONDARY, + BR_MRP_PORT_ROLE_INTER, +}; + +enum br_mrp_tlv_header_type { + BR_MRP_TLV_HEADER_END = 0x0, + BR_MRP_TLV_HEADER_COMMON = 0x1, + BR_MRP_TLV_HEADER_RING_TEST = 0x2, + BR_MRP_TLV_HEADER_RING_TOPO = 0x3, + BR_MRP_TLV_HEADER_RING_LINK_DOWN = 0x4, + BR_MRP_TLV_HEADER_RING_LINK_UP = 0x5, + BR_MRP_TLV_HEADER_IN_TEST = 0x6, + BR_MRP_TLV_HEADER_IN_TOPO = 0x7, + BR_MRP_TLV_HEADER_IN_LINK_DOWN = 0x8, + BR_MRP_TLV_HEADER_IN_LINK_UP = 0x9, + BR_MRP_TLV_HEADER_IN_LINK_STATUS = 0xa, + BR_MRP_TLV_HEADER_OPTION = 0x7f, +}; + +enum br_mrp_sub_tlv_header_type { + BR_MRP_SUB_TLV_HEADER_TEST_MGR_NACK = 0x1, + BR_MRP_SUB_TLV_HEADER_TEST_PROPAGATE = 0x2, + BR_MRP_SUB_TLV_HEADER_TEST_AUTO_MGR = 0x3, +}; + +#endif diff --git a/src/basic/meson.build b/src/basic/meson.build index 6d755ab6465..b10c4508acb 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -81,6 +81,7 @@ basic_sources = files(''' linux/btrfs_tree.h linux/can/netlink.h linux/can/vxcan.h + linux/cfm_bridge.h linux/fib_rules.h linux/fou.h linux/genetlink.h @@ -101,6 +102,7 @@ basic_sources = files(''' linux/l2tp.h linux/libc-compat.h linux/loadavg.h + linux/mrp_bridge.h linux/netdevice.h linux/netfilter/nf_tables.h linux/netfilter/nfnetlink.h From 38d3bcde5dd0e46412c40b7aeeed21613c70eccd Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 26 Aug 2021 01:20:39 +0900 Subject: [PATCH 03/13] sd-netlink: support more rtnl attributes --- src/basic/missing_network.h | 10 + .../sd-netlink/netlink-types-rtnl.c | 1020 +++++++++++------ 2 files changed, 691 insertions(+), 339 deletions(-) diff --git a/src/basic/missing_network.h b/src/basic/missing_network.h index f9db690d185..24017df8710 100644 --- a/src/basic/missing_network.h +++ b/src/basic/missing_network.h @@ -34,3 +34,13 @@ #ifndef ETHERTYPE_LLDP #define ETHERTYPE_LLDP 0x88cc #endif + +/* Not exposed but defined in linux/netdevice.h */ +#ifndef MAX_PHYS_ITEM_ID_LEN +#define MAX_PHYS_ITEM_ID_LEN 32 +#endif + +/* Not exposed but defined in include/net/bonding.h */ +#ifndef BOND_MAX_ARP_TARGETS +#define BOND_MAX_ARP_TARGETS 16 +#endif diff --git a/src/libsystemd/sd-netlink/netlink-types-rtnl.c b/src/libsystemd/sd-netlink/netlink-types-rtnl.c index 75046e98a98..e2e999711ff 100644 --- a/src/libsystemd/sd-netlink/netlink-types-rtnl.c +++ b/src/libsystemd/sd-netlink/netlink-types-rtnl.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -26,13 +27,11 @@ #include "sd-netlink.h" +#include "missing_network.h" #include "netlink-types-internal.h" #include "string-table.h" -/* Maximum ARP IP target defined in kernel */ -#define BOND_MAX_ARP_TARGETS 16 - -typedef enum { +enum { BOND_ARP_TARGETS_0, BOND_ARP_TARGETS_1, BOND_ARP_TARGETS_2, @@ -48,132 +47,26 @@ typedef enum { BOND_ARP_TARGETS_12, BOND_ARP_TARGETS_13, BOND_ARP_TARGETS_14, - BOND_ARP_TARGETS_MAX = BOND_MAX_ARP_TARGETS, -} BondArpTargets; + BOND_ARP_TARGETS_15, + _BOND_ARP_TARGETS_MAX, +}; + +assert_cc(_BOND_ARP_TARGETS_MAX == BOND_MAX_ARP_TARGETS); static const NLTypeSystem rtnl_link_type_system; +static const NLType rtnl_link_info_data_bareudp_types[] = { + [IFLA_BAREUDP_PORT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BAREUDP_ETHERTYPE] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BAREUDP_SRCPORT_MIN] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BAREUDP_MULTIPROTO_MODE] = { .type = NETLINK_TYPE_FLAG }, +}; + static const NLType rtnl_link_info_data_batadv_types[] = { [IFLA_BATADV_ALGO_NAME] = { .type = NETLINK_TYPE_STRING, .size = 20 }, }; -static const NLType rtnl_link_info_data_veth_types[] = { - [VETH_INFO_PEER] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, -}; - -static const NLType rtnl_link_info_data_vxcan_types[] = { - [VXCAN_INFO_PEER] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, -}; - -static const NLType rtnl_link_info_data_ipvlan_types[] = { - [IFLA_IPVLAN_MODE] = { .type = NETLINK_TYPE_U16 }, - [IFLA_IPVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 }, -}; - -static const NLType rtnl_macvlan_macaddr_types[] = { - [IFLA_MACVLAN_MACADDR] = { .type = NETLINK_TYPE_ETHER_ADDR }, -}; - -DEFINE_TYPE_SYSTEM(rtnl_macvlan_macaddr); - -static const NLType rtnl_link_info_data_macvlan_types[] = { - [IFLA_MACVLAN_MODE] = { .type = NETLINK_TYPE_U32 }, - [IFLA_MACVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 }, - [IFLA_MACVLAN_MACADDR_MODE] = { .type = NETLINK_TYPE_U32 }, - [IFLA_MACVLAN_MACADDR_DATA] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_macvlan_macaddr_type_system }, - [IFLA_MACVLAN_MACADDR_COUNT] = { .type = NETLINK_TYPE_U32 }, - [IFLA_MACVLAN_BC_QUEUE_LEN] = { .type = NETLINK_TYPE_U32 }, - [IFLA_MACVLAN_BC_QUEUE_LEN_USED] = { .type = NETLINK_TYPE_REJECT }, -}; - -static const NLType rtnl_link_info_data_bridge_types[] = { - [IFLA_BR_FORWARD_DELAY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_HELLO_TIME] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_MAX_AGE] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_AGEING_TIME] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_STP_STATE] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_PRIORITY] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_VLAN_FILTERING] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_VLAN_PROTOCOL] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_GROUP_FWD_MASK] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_ROOT_PORT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_ROOT_PATH_COST] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_TOPOLOGY_CHANGE] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_TOPOLOGY_CHANGE_DETECTED] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_HELLO_TIMER] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_TCN_TIMER] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_TOPOLOGY_CHANGE_TIMER] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_GC_TIMER] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BR_GROUP_ADDR] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_FDB_FLUSH] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_MCAST_ROUTER] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_MCAST_SNOOPING] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_MCAST_QUERY_USE_IFADDR] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_MCAST_QUERIER] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_MCAST_HASH_ELASTICITY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_MCAST_HASH_MAX] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_MCAST_LAST_MEMBER_CNT] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_MCAST_STARTUP_QUERY_CNT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_MCAST_LAST_MEMBER_INTVL] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BR_MCAST_MEMBERSHIP_INTVL] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BR_MCAST_QUERIER_INTVL] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BR_MCAST_QUERY_INTVL] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BR_MCAST_QUERY_RESPONSE_INTVL] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BR_MCAST_STARTUP_QUERY_INTVL] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BR_NF_CALL_IPTABLES] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_NF_CALL_IP6TABLES] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_NF_CALL_ARPTABLES] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_VLAN_DEFAULT_PVID] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_MCAST_IGMP_VERSION] = { .type = NETLINK_TYPE_U8 }, -}; - -static const NLType rtnl_vlan_qos_map_types[] = { - [IFLA_VLAN_QOS_MAPPING] = { .size = sizeof(struct ifla_vlan_qos_mapping) }, -}; - -DEFINE_TYPE_SYSTEM(rtnl_vlan_qos_map); - -static const NLType rtnl_link_info_data_vlan_types[] = { - [IFLA_VLAN_ID] = { .type = NETLINK_TYPE_U16 }, - [IFLA_VLAN_FLAGS] = { .size = sizeof(struct ifla_vlan_flags) }, - [IFLA_VLAN_EGRESS_QOS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vlan_qos_map_type_system }, - [IFLA_VLAN_INGRESS_QOS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vlan_qos_map_type_system }, - [IFLA_VLAN_PROTOCOL] = { .type = NETLINK_TYPE_U16 }, -}; - -static const NLType rtnl_link_info_data_vxlan_types[] = { - [IFLA_VXLAN_ID] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VXLAN_GROUP] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_VXLAN_LINK] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VXLAN_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_VXLAN_TTL] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_TOS] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_LEARNING] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_AGEING] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VXLAN_LIMIT] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VXLAN_PORT_RANGE] = { .type = NETLINK_TYPE_U32}, - [IFLA_VXLAN_PROXY] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_RSC] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_L2MISS] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_L3MISS] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_PORT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_VXLAN_GROUP6] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_VXLAN_LOCAL6] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_VXLAN_UDP_CSUM] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_UDP_ZERO_CSUM6_TX] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_UDP_ZERO_CSUM6_RX] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_REMCSUM_TX] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_REMCSUM_RX] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_GBP] = { .type = NETLINK_TYPE_FLAG }, - [IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NETLINK_TYPE_FLAG }, - [IFLA_VXLAN_COLLECT_METADATA] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_LABEL] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VXLAN_GPE] = { .type = NETLINK_TYPE_FLAG }, - [IFLA_VXLAN_TTL_INHERIT] = { .type = NETLINK_TYPE_FLAG }, - [IFLA_VXLAN_DF] = { .type = NETLINK_TYPE_U8 }, -}; - -static const NLType rtnl_bond_arp_target_types[] = { +static const NLType rtnl_bond_arp_ip_target_types[] = { [BOND_ARP_TARGETS_0] = { .type = NETLINK_TYPE_U32 }, [BOND_ARP_TARGETS_1] = { .type = NETLINK_TYPE_U32 }, [BOND_ARP_TARGETS_2] = { .type = NETLINK_TYPE_U32 }, @@ -189,10 +82,20 @@ static const NLType rtnl_bond_arp_target_types[] = { [BOND_ARP_TARGETS_12] = { .type = NETLINK_TYPE_U32 }, [BOND_ARP_TARGETS_13] = { .type = NETLINK_TYPE_U32 }, [BOND_ARP_TARGETS_14] = { .type = NETLINK_TYPE_U32 }, - [BOND_ARP_TARGETS_MAX] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_15] = { .type = NETLINK_TYPE_U32 }, }; -DEFINE_TYPE_SYSTEM(rtnl_bond_arp_target); +DEFINE_TYPE_SYSTEM(rtnl_bond_arp_ip_target); + +static const NLType rtnl_bond_ad_info_types[] = { + [IFLA_BOND_AD_INFO_AGGREGATOR] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BOND_AD_INFO_NUM_PORTS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BOND_AD_INFO_ACTOR_KEY] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BOND_AD_INFO_PARTNER_KEY] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BOND_AD_INFO_PARTNER_MAC] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bond_ad_info); static const NLType rtnl_link_info_data_bond_types[] = { [IFLA_BOND_MODE] = { .type = NETLINK_TYPE_U8 }, @@ -202,7 +105,7 @@ static const NLType rtnl_link_info_data_bond_types[] = { [IFLA_BOND_DOWNDELAY] = { .type = NETLINK_TYPE_U32 }, [IFLA_BOND_USE_CARRIER] = { .type = NETLINK_TYPE_U8 }, [IFLA_BOND_ARP_INTERVAL] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BOND_ARP_IP_TARGET] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bond_arp_target_type_system }, + [IFLA_BOND_ARP_IP_TARGET] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bond_arp_ip_target_type_system }, [IFLA_BOND_ARP_VALIDATE] = { .type = NETLINK_TYPE_U32 }, [IFLA_BOND_ARP_ALL_TARGETS] = { .type = NETLINK_TYPE_U32 }, [IFLA_BOND_PRIMARY] = { .type = NETLINK_TYPE_U32 }, @@ -217,82 +120,88 @@ static const NLType rtnl_link_info_data_bond_types[] = { [IFLA_BOND_PACKETS_PER_SLAVE] = { .type = NETLINK_TYPE_U32 }, [IFLA_BOND_AD_LACP_RATE] = { .type = NETLINK_TYPE_U8 }, [IFLA_BOND_AD_SELECT] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BOND_AD_INFO] = { .type = NETLINK_TYPE_NESTED }, + [IFLA_BOND_AD_INFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bond_ad_info_type_system }, [IFLA_BOND_AD_ACTOR_SYS_PRIO] = { .type = NETLINK_TYPE_U16 }, [IFLA_BOND_AD_USER_PORT_KEY] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BOND_AD_ACTOR_SYSTEM] = { .type = NETLINK_TYPE_ETHER_ADDR }, + [IFLA_BOND_AD_ACTOR_SYSTEM] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN }, [IFLA_BOND_TLB_DYNAMIC_LB] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_PEER_NOTIF_DELAY] = { .type = NETLINK_TYPE_U32 }, }; -static const NLType rtnl_link_info_data_iptun_types[] = { - [IFLA_IPTUN_LINK] = { .type = NETLINK_TYPE_U32 }, - [IFLA_IPTUN_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_IPTUN_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_IPTUN_TTL] = { .type = NETLINK_TYPE_U8 }, - [IFLA_IPTUN_TOS] = { .type = NETLINK_TYPE_U8 }, - [IFLA_IPTUN_PMTUDISC] = { .type = NETLINK_TYPE_U8 }, - [IFLA_IPTUN_FLAGS] = { .type = NETLINK_TYPE_U16 }, - [IFLA_IPTUN_PROTO] = { .type = NETLINK_TYPE_U8 }, - [IFLA_IPTUN_6RD_PREFIX] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_IPTUN_6RD_RELAY_PREFIX] = { .type = NETLINK_TYPE_U32 }, - [IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NETLINK_TYPE_U16 }, - [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NETLINK_TYPE_U16 }, - [IFLA_IPTUN_ENCAP_TYPE] = { .type = NETLINK_TYPE_U16 }, - [IFLA_IPTUN_ENCAP_FLAGS] = { .type = NETLINK_TYPE_U16 }, - [IFLA_IPTUN_ENCAP_SPORT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_IPTUN_ENCAP_DPORT] = { .type = NETLINK_TYPE_U16 }, +static const NLType rtnl_link_info_data_bridge_types[] = { + [IFLA_BR_FORWARD_DELAY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_HELLO_TIME] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_MAX_AGE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_AGEING_TIME] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_STP_STATE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_PRIORITY] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_VLAN_FILTERING] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_VLAN_PROTOCOL] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_GROUP_FWD_MASK] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_ROOT_ID] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct ifla_bridge_id) }, + [IFLA_BR_BRIDGE_ID] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct ifla_bridge_id) }, + [IFLA_BR_ROOT_PORT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_ROOT_PATH_COST] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_TOPOLOGY_CHANGE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_TOPOLOGY_CHANGE_DETECTED] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_HELLO_TIMER] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_TCN_TIMER] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_TOPOLOGY_CHANGE_TIMER] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_GC_TIMER] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_GROUP_ADDR] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN }, + [IFLA_BR_FDB_FLUSH] = { .type = NETLINK_TYPE_FLAG }, + [IFLA_BR_MCAST_ROUTER] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_MCAST_SNOOPING] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_MCAST_QUERY_USE_IFADDR] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_MCAST_QUERIER] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_MCAST_HASH_ELASTICITY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_MCAST_HASH_MAX] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_MCAST_LAST_MEMBER_CNT] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_MCAST_STARTUP_QUERY_CNT] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_MCAST_LAST_MEMBER_INTVL] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_MCAST_MEMBERSHIP_INTVL] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_MCAST_QUERIER_INTVL] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_MCAST_QUERY_INTVL] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_MCAST_QUERY_RESPONSE_INTVL] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_MCAST_STARTUP_QUERY_INTVL] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_NF_CALL_IPTABLES] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_NF_CALL_IP6TABLES] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_NF_CALL_ARPTABLES] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_VLAN_DEFAULT_PVID] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_VLAN_STATS_ENABLED] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_MCAST_STATS_ENABLED] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_MCAST_IGMP_VERSION] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_MCAST_MLD_VERSION] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_VLAN_STATS_PER_PORT] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_MULTI_BOOLOPT] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct br_boolopt_multi) }, }; -static const NLType rtnl_link_info_data_ipgre_types[] = { - [IFLA_GRE_LINK] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GRE_IFLAGS] = { .type = NETLINK_TYPE_U16 }, - [IFLA_GRE_OFLAGS] = { .type = NETLINK_TYPE_U16 }, - [IFLA_GRE_IKEY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GRE_OKEY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GRE_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_GRE_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_GRE_TTL] = { .type = NETLINK_TYPE_U8 }, - [IFLA_GRE_TOS] = { .type = NETLINK_TYPE_U8 }, - [IFLA_GRE_PMTUDISC] = { .type = NETLINK_TYPE_U8 }, - [IFLA_GRE_FLOWINFO] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GRE_FLAGS] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GRE_ENCAP_TYPE] = { .type = NETLINK_TYPE_U16 }, - [IFLA_GRE_ENCAP_FLAGS] = { .type = NETLINK_TYPE_U16 }, - [IFLA_GRE_ENCAP_SPORT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_GRE_ENCAP_DPORT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_GRE_ERSPAN_INDEX] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType rtnl_link_info_data_ipvti_types[] = { - [IFLA_VTI_LINK] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VTI_IKEY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VTI_OKEY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VTI_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_VTI_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, -}; - -static const NLType rtnl_link_info_data_ip6tnl_types[] = { - [IFLA_IPTUN_LINK] = { .type = NETLINK_TYPE_U32 }, - [IFLA_IPTUN_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_IPTUN_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_IPTUN_TTL] = { .type = NETLINK_TYPE_U8 }, - [IFLA_IPTUN_FLAGS] = { .type = NETLINK_TYPE_U32 }, - [IFLA_IPTUN_PROTO] = { .type = NETLINK_TYPE_U8 }, - [IFLA_IPTUN_ENCAP_LIMIT] = { .type = NETLINK_TYPE_U8 }, - [IFLA_IPTUN_FLOWINFO] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType rtnl_link_info_data_vrf_types[] = { - [IFLA_VRF_TABLE] = { .type = NETLINK_TYPE_U32 }, +static const NLType rtnl_link_info_data_can_types[] = { + [IFLA_CAN_BITTIMING] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct can_bittiming) }, + [IFLA_CAN_BITTIMING_CONST] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct can_bittiming_const) }, + [IFLA_CAN_CLOCK] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct can_clock) }, + [IFLA_CAN_STATE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_CAN_CTRLMODE] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct can_ctrlmode) }, + [IFLA_CAN_RESTART_MS] = { .type = NETLINK_TYPE_U32 }, + [IFLA_CAN_RESTART] = { .type = NETLINK_TYPE_U32 }, + [IFLA_CAN_BERR_COUNTER] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct can_berr_counter) }, + [IFLA_CAN_DATA_BITTIMING] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct can_bittiming) }, + [IFLA_CAN_DATA_BITTIMING_CONST] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct can_bittiming_const) }, + [IFLA_CAN_TERMINATION] = { .type = NETLINK_TYPE_U16 }, + [IFLA_CAN_TERMINATION_CONST] = { .type = NETLINK_TYPE_BINARY }, /* size = termination_const_cnt * sizeof(u16) */ + [IFLA_CAN_BITRATE_CONST] = { .type = NETLINK_TYPE_BINARY }, /* size = bitrate_const_cnt * sizeof(u32) */ + [IFLA_CAN_DATA_BITRATE_CONST] = { .type = NETLINK_TYPE_BINARY }, /* size = data_bitrate_const_cnt * sizeof(u32) */ + [IFLA_CAN_BITRATE_MAX] = { .type = NETLINK_TYPE_U32 }, }; static const NLType rtnl_link_info_data_geneve_types[] = { [IFLA_GENEVE_ID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GENEVE_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR, .size = sizeof(struct in_addr) }, [IFLA_GENEVE_TTL] = { .type = NETLINK_TYPE_U8 }, [IFLA_GENEVE_TOS] = { .type = NETLINK_TYPE_U8 }, [IFLA_GENEVE_PORT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_GENEVE_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_GENEVE_REMOTE6] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_GENEVE_COLLECT_METADATA] = { .type = NETLINK_TYPE_FLAG }, + [IFLA_GENEVE_REMOTE6] = { .type = NETLINK_TYPE_IN_ADDR, .size = sizeof(struct in6_addr) }, [IFLA_GENEVE_UDP_CSUM] = { .type = NETLINK_TYPE_U8 }, [IFLA_GENEVE_UDP_ZERO_CSUM6_TX] = { .type = NETLINK_TYPE_U8 }, [IFLA_GENEVE_UDP_ZERO_CSUM6_RX] = { .type = NETLINK_TYPE_U8 }, @@ -301,11 +210,66 @@ static const NLType rtnl_link_info_data_geneve_types[] = { [IFLA_GENEVE_DF] = { .type = NETLINK_TYPE_U8 }, }; -static const NLType rtnl_link_info_data_can_types[] = { - [IFLA_CAN_BITTIMING] = { .size = sizeof(struct can_bittiming) }, - [IFLA_CAN_RESTART_MS] = { .type = NETLINK_TYPE_U32 }, - [IFLA_CAN_CTRLMODE] = { .size = sizeof(struct can_ctrlmode) }, - [IFLA_CAN_TERMINATION] = { .type = NETLINK_TYPE_U16 }, +static const NLType rtnl_link_info_data_gre_types[] = { + [IFLA_GRE_LINK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_IFLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_OFLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_IKEY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_OKEY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_GRE_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_GRE_TTL] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GRE_TOS] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GRE_PMTUDISC] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GRE_ENCAP_LIMIT] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GRE_FLOWINFO] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_ENCAP_TYPE] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_ENCAP_FLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_ENCAP_SPORT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_ENCAP_DPORT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_COLLECT_METADATA] = { .type = NETLINK_TYPE_FLAG }, + [IFLA_GRE_IGNORE_DF] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GRE_FWMARK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_ERSPAN_INDEX] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_ERSPAN_VER] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GRE_ERSPAN_DIR] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GRE_ERSPAN_HWID] = { .type = NETLINK_TYPE_U16 }, +}; + +/* IFLA_IPTUN_ attributes are used in ipv4/ipip.c, ipv6/ip6_tunnel.c, and ipv6/sit.c. And unfortunately, + * IFLA_IPTUN_FLAGS is used with differnt types, ugh... */ +#define DEFINE_IPTUN_TYPES(name, flags_type) \ + static const NLType rtnl_link_info_data_##name##_types[] = { \ + [IFLA_IPTUN_LINK] = { .type = NETLINK_TYPE_U32 }, \ + [IFLA_IPTUN_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, \ + [IFLA_IPTUN_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, \ + [IFLA_IPTUN_TTL] = { .type = NETLINK_TYPE_U8 }, \ + [IFLA_IPTUN_TOS] = { .type = NETLINK_TYPE_U8 }, \ + [IFLA_IPTUN_ENCAP_LIMIT] = { .type = NETLINK_TYPE_U8 }, \ + [IFLA_IPTUN_FLOWINFO] = { .type = NETLINK_TYPE_U32 }, \ + [IFLA_IPTUN_FLAGS] = { .type = flags_type }, \ + [IFLA_IPTUN_PROTO] = { .type = NETLINK_TYPE_U8 }, \ + [IFLA_IPTUN_PMTUDISC] = { .type = NETLINK_TYPE_U8 }, \ + [IFLA_IPTUN_6RD_PREFIX] = { .type = NETLINK_TYPE_IN_ADDR, \ + .size = sizeof(struct in6_addr) }, \ + [IFLA_IPTUN_6RD_RELAY_PREFIX] = { .type = NETLINK_TYPE_U32 }, \ + [IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NETLINK_TYPE_U16 }, \ + [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NETLINK_TYPE_U16 }, \ + [IFLA_IPTUN_ENCAP_TYPE] = { .type = NETLINK_TYPE_U16 }, \ + [IFLA_IPTUN_ENCAP_FLAGS] = { .type = NETLINK_TYPE_U16 }, \ + [IFLA_IPTUN_ENCAP_SPORT] = { .type = NETLINK_TYPE_U16 }, \ + [IFLA_IPTUN_ENCAP_DPORT] = { .type = NETLINK_TYPE_U16 }, \ + [IFLA_IPTUN_COLLECT_METADATA] = { .type = NETLINK_TYPE_FLAG }, \ + [IFLA_IPTUN_FWMARK] = { .type = NETLINK_TYPE_U32 }, \ + } + +DEFINE_IPTUN_TYPES(iptun, NETLINK_TYPE_U32); /* for ipip and ip6tnl */ +DEFINE_IPTUN_TYPES(sit, NETLINK_TYPE_U16); /* for sit */ + +static const NLType rtnl_link_info_data_ipvlan_types[] = { + [IFLA_IPVLAN_MODE] = { .type = NETLINK_TYPE_U16 }, + [IFLA_IPVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 }, }; static const NLType rtnl_link_info_data_macsec_types[] = { @@ -322,6 +286,102 @@ static const NLType rtnl_link_info_data_macsec_types[] = { [IFLA_MACSEC_SCB] = { .type = NETLINK_TYPE_U8 }, [IFLA_MACSEC_REPLAY_PROTECT] = { .type = NETLINK_TYPE_U8 }, [IFLA_MACSEC_VALIDATION] = { .type = NETLINK_TYPE_U8 }, + [IFLA_MACSEC_OFFLOAD] = { .type = NETLINK_TYPE_U8 }, +}; + +static const NLType rtnl_macvlan_macaddr_types[] = { + [IFLA_MACVLAN_MACADDR] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_macvlan_macaddr); + +static const NLType rtnl_link_info_data_macvlan_types[] = { + [IFLA_MACVLAN_MODE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_MACVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_MACVLAN_MACADDR_MODE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_MACVLAN_MACADDR_DATA] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_macvlan_macaddr_type_system }, + [IFLA_MACVLAN_MACADDR_COUNT] = { .type = NETLINK_TYPE_U32 }, + [IFLA_MACVLAN_BC_QUEUE_LEN] = { .type = NETLINK_TYPE_U32 }, + [IFLA_MACVLAN_BC_QUEUE_LEN_USED] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType rtnl_link_info_data_tun_types[] = { + [IFLA_TUN_OWNER] = { .type = NETLINK_TYPE_U32 }, + [IFLA_TUN_GROUP] = { .type = NETLINK_TYPE_U32 }, + [IFLA_TUN_TYPE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_TUN_PI] = { .type = NETLINK_TYPE_U8 }, + [IFLA_TUN_VNET_HDR] = { .type = NETLINK_TYPE_U8 }, + [IFLA_TUN_PERSIST] = { .type = NETLINK_TYPE_U8 }, + [IFLA_TUN_MULTI_QUEUE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_TUN_NUM_QUEUES] = { .type = NETLINK_TYPE_U32 }, + [IFLA_TUN_NUM_DISABLED_QUEUES] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType rtnl_link_info_data_veth_types[] = { + [VETH_INFO_PEER] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, +}; + +static const NLType rtnl_vlan_qos_map_types[] = { + [IFLA_VLAN_QOS_MAPPING] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct ifla_vlan_qos_mapping) }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_vlan_qos_map); + +static const NLType rtnl_link_info_data_vlan_types[] = { + [IFLA_VLAN_ID] = { .type = NETLINK_TYPE_U16 }, + [IFLA_VLAN_FLAGS] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct ifla_vlan_flags) }, + [IFLA_VLAN_EGRESS_QOS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vlan_qos_map_type_system }, + [IFLA_VLAN_INGRESS_QOS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vlan_qos_map_type_system }, + [IFLA_VLAN_PROTOCOL] = { .type = NETLINK_TYPE_U16 }, +}; + +static const NLType rtnl_link_info_data_vrf_types[] = { + [IFLA_VRF_TABLE] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType rtnl_link_info_data_vti_types[] = { + [IFLA_VTI_LINK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VTI_IKEY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VTI_OKEY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VTI_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_VTI_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_VTI_FWMARK] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType rtnl_link_info_data_vxcan_types[] = { + [VXCAN_INFO_PEER] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, +}; + +static const NLType rtnl_link_info_data_vxlan_types[] = { + [IFLA_VXLAN_ID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VXLAN_GROUP] = { .type = NETLINK_TYPE_IN_ADDR, .size = sizeof(struct in_addr) }, + [IFLA_VXLAN_LINK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VXLAN_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR, .size = sizeof(struct in_addr) }, + [IFLA_VXLAN_TTL] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_TOS] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_LEARNING] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_AGEING] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VXLAN_LIMIT] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VXLAN_PORT_RANGE] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct ifla_vxlan_port_range) }, + [IFLA_VXLAN_PROXY] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_RSC] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_L2MISS] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_L3MISS] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_PORT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_VXLAN_GROUP6] = { .type = NETLINK_TYPE_IN_ADDR, .size = sizeof(struct in6_addr) }, + [IFLA_VXLAN_LOCAL6] = { .type = NETLINK_TYPE_IN_ADDR, .size = sizeof(struct in6_addr) }, + [IFLA_VXLAN_UDP_CSUM] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_UDP_ZERO_CSUM6_TX] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_UDP_ZERO_CSUM6_RX] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_REMCSUM_TX] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_REMCSUM_RX] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_GBP] = { .type = NETLINK_TYPE_FLAG }, + [IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NETLINK_TYPE_FLAG }, + [IFLA_VXLAN_COLLECT_METADATA] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_LABEL] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VXLAN_GPE] = { .type = NETLINK_TYPE_FLAG }, + [IFLA_VXLAN_TTL_INHERIT] = { .type = NETLINK_TYPE_FLAG }, + [IFLA_VXLAN_DF] = { .type = NETLINK_TYPE_U8 }, }; static const NLType rtnl_link_info_data_xfrm_types[] = { @@ -329,128 +389,370 @@ static const NLType rtnl_link_info_data_xfrm_types[] = { [IFLA_XFRM_IF_ID] = { .type = NETLINK_TYPE_U32 } }; -static const NLType rtnl_link_info_data_bareudp_types[] = { - [IFLA_BAREUDP_PORT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BAREUDP_ETHERTYPE] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BAREUDP_SRCPORT_MIN] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BAREUDP_MULTIPROTO_MODE] = { .type = NETLINK_TYPE_FLAG }, -}; - static const NLTypeSystemUnionElement rtnl_link_info_data_type_systems[] = { { .name = "bareudp", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_bareudp), }, { .name = "batadv", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_batadv), }, { .name = "bond", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_bond), }, { .name = "bridge", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_bridge), }, +/* + { .name = "caif", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_caif), }, +*/ { .name = "can", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_can), }, - { .name = "dummy", }, - { .name = "erspan", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipgre), }, + { .name = "erspan", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_gre), }, { .name = "geneve", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_geneve), }, - { .name = "gre", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipgre), }, - { .name = "gretap", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipgre), }, - { .name = "ifb", }, - { .name = "ip6gre", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipgre), }, - { .name = "ip6gretap", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipgre), }, - { .name = "ip6tnl", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ip6tnl), }, + { .name = "gre", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_gre), }, + { .name = "gretap", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_gre), }, +/* + { .name = "gtp", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_gtp), }, + { .name = "hsr", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_hsr), }, +*/ + { .name = "ip6erspan", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_gre), }, + { .name = "ip6gre", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_gre), }, + { .name = "ip6gretap", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_gre), }, + { .name = "ip6tnl", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_iptun), }, +/* + { .name = "ipoib", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipoib), }, +*/ { .name = "ipip", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_iptun), }, { .name = "ipvlan", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipvlan), }, { .name = "ipvtap", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipvlan), }, { .name = "macsec", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_macsec), }, { .name = "macvlan", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_macvlan), }, { .name = "macvtap", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_macvlan), }, - { .name = "netdevsim", }, - { .name = "nlmon", }, - { .name = "sit", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_iptun), }, - { .name = "vcan", }, +/* + { .name = "ppp", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ppp), }, + { .name = "rmnet", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_rmnet), }, +*/ + { .name = "sit", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_sit), }, + { .name = "tun", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_tun), }, { .name = "veth", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_veth), }, { .name = "vlan", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_vlan), }, { .name = "vrf", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_vrf), }, - { .name = "vti", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipvti), }, - { .name = "vti6", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipvti), }, + { .name = "vti", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_vti), }, + { .name = "vti6", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_vti), }, { .name = "vxcan", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_vxcan), }, { .name = "vxlan", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_vxlan), }, - { .name = "wireguard", }, +/* + { .name = "wwan", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_wwan), }, +*/ { .name = "xfrm", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_xfrm), }, }; DEFINE_TYPE_SYSTEM_UNION_MATCH_SIBLING(rtnl_link_info_data, IFLA_INFO_KIND); +static const struct NLType rtnl_bridge_port_types[] = { + [IFLA_BRPORT_STATE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_COST] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRPORT_PRIORITY] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRPORT_MODE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_GUARD] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_PROTECT] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_FAST_LEAVE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_LEARNING] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_PROXYARP] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_LEARNING_SYNC] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_PROXYARP_WIFI] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_ROOT_ID] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_BRIDGE_ID] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_DESIGNATED_PORT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRPORT_DESIGNATED_COST] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRPORT_ID] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRPORT_NO] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRPORT_TOPOLOGY_CHANGE_ACK] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_CONFIG_PENDING] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_MESSAGE_AGE_TIMER] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BRPORT_FORWARD_DELAY_TIMER] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BRPORT_HOLD_TIMER] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BRPORT_FLUSH] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_MULTICAST_ROUTER] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_PAD] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_MCAST_FLOOD] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_MCAST_TO_UCAST] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_VLAN_TUNNEL] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_BCAST_FLOOD] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_GROUP_FWD_MASK] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRPORT_NEIGH_SUPPRESS] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_ISOLATED] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_BACKUP_PORT] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRPORT_MRP_RING_OPEN] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_MRP_IN_OPEN] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRPORT_MCAST_EHT_HOSTS_CNT] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystemUnionElement rtnl_link_info_slave_data_type_systems[] = { + { .name = "bridge", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_bridge_port), }, +}; + +DEFINE_TYPE_SYSTEM_UNION_MATCH_SIBLING(rtnl_link_info_slave_data, IFLA_INFO_SLAVE_KIND); + static const NLType rtnl_link_info_types[] = { [IFLA_INFO_KIND] = { .type = NETLINK_TYPE_STRING }, [IFLA_INFO_DATA] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_link_info_data_type_system_union }, -/* - [IFLA_INFO_XSTATS], + /* TODO: Currently IFLA_INFO_XSTATS is used only when IFLA_INFO_KIND is "can". In the future, + * when multiple kinds of netdevs use this attribute, then convert its type to NETLINK_TYPE_UNION. */ + [IFLA_INFO_XSTATS] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct can_device_stats) }, [IFLA_INFO_SLAVE_KIND] = { .type = NETLINK_TYPE_STRING }, - [IFLA_INFO_SLAVE_DATA] = { .type = NETLINK_TYPE_NESTED }, -*/ + [IFLA_INFO_SLAVE_DATA] = { .type = NETLINK_TYPE_NESTED, .type_system_union = &rtnl_link_info_slave_data_type_system_union }, }; DEFINE_TYPE_SYSTEM(rtnl_link_info); -static const struct NLType rtnl_prot_info_bridge_port_types[] = { - [IFLA_BRPORT_STATE] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_COST] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BRPORT_PRIORITY] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BRPORT_MODE] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_GUARD] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_PROTECT] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_FAST_LEAVE] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_LEARNING] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_PROXYARP] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_LEARNING_SYNC] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_PROXYARP_WIFI] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_ROOT_ID] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_BRIDGE_ID] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_DESIGNATED_PORT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BRPORT_DESIGNATED_COST] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BRPORT_ID] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BRPORT_NO] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BRPORT_TOPOLOGY_CHANGE_ACK] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_CONFIG_PENDING] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_MESSAGE_AGE_TIMER] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BRPORT_FORWARD_DELAY_TIMER] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BRPORT_HOLD_TIMER] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BRPORT_FLUSH] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_MULTICAST_ROUTER] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_PAD] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_MCAST_FLOOD] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_MCAST_TO_UCAST] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_VLAN_TUNNEL] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_BCAST_FLOOD] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_GROUP_FWD_MASK] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BRPORT_NEIGH_SUPPRESS] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_ISOLATED] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_BACKUP_PORT] = { .type = NETLINK_TYPE_U32 }, +static const struct NLType rtnl_inet_types[] = { + [IFLA_INET_CONF] = { .type = NETLINK_TYPE_BINARY }, /* size = IPV4_DEVCONF_MAX * 4 */ }; +DEFINE_TYPE_SYSTEM(rtnl_inet); + +static const struct NLType rtnl_inet6_types[] = { + [IFLA_INET6_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [IFLA_INET6_CONF] = { .type = NETLINK_TYPE_BINARY }, /* size = DEVCONF_MAX * sizeof(s32) */ + [IFLA_INET6_STATS] = { .type = NETLINK_TYPE_BINARY }, /* size = IPSTATS_MIB_MAX * sizeof(u64) */ + [IFLA_INET6_MCAST] = {}, /* unused. */ + [IFLA_INET6_CACHEINFO] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct ifla_cacheinfo) }, + [IFLA_INET6_ICMP6STATS] = { .type = NETLINK_TYPE_BINARY }, /* size = ICMP6_MIB_MAX * sizeof(u64) */ + [IFLA_INET6_TOKEN] = { .type = NETLINK_TYPE_IN_ADDR, .size = sizeof(struct in6_addr) }, + [IFLA_INET6_ADDR_GEN_MODE] = { .type = NETLINK_TYPE_U8 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_inet6); + static const NLTypeSystemUnionElement rtnl_prot_info_type_systems[] = { - { .protocol = AF_BRIDGE, .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_prot_info_bridge_port), }, + { .protocol = AF_BRIDGE, .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_bridge_port), }, + { .protocol = AF_INET6, .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_inet6), }, }; DEFINE_TYPE_SYSTEM_UNION_MATCH_PROTOCOL(rtnl_prot_info); -static const struct NLType rtnl_af_spec_inet6_types[] = { - [IFLA_INET6_FLAGS] = { .type = NETLINK_TYPE_U32 }, -/* - IFLA_INET6_CONF, - IFLA_INET6_STATS, - IFLA_INET6_MCAST, - IFLA_INET6_CACHEINFO, - IFLA_INET6_ICMP6STATS, -*/ - [IFLA_INET6_TOKEN] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_INET6_ADDR_GEN_MODE] = { .type = NETLINK_TYPE_U8 }, -}; - -DEFINE_TYPE_SYSTEM(rtnl_af_spec_inet6); - static const NLType rtnl_af_spec_unspec_types[] = { - [AF_INET6] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_af_spec_inet6_type_system }, + [AF_INET] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_inet_type_system }, + [AF_INET6] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_inet6_type_system }, }; +static const NLType rtnl_bridge_vlan_tunnel_info_types[] = { + [IFLA_BRIDGE_VLAN_TUNNEL_ID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_VLAN_TUNNEL_VID] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRIDGE_VLAN_TUNNEL_FLAGS] = { .type = NETLINK_TYPE_U16 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_vlan_tunnel_info); + +static const NLType rtnl_bridge_mrp_instance_types[] = { + [IFLA_BRIDGE_MRP_INSTANCE_RING_ID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_INSTANCE_P_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_INSTANCE_S_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_INSTANCE_PRIO] = { .type = NETLINK_TYPE_U16 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_mrp_instance); + +static const NLType rtnl_bridge_mrp_port_state_types[] = { + [IFLA_BRIDGE_MRP_PORT_STATE_STATE] = { .type = NETLINK_TYPE_U32 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_mrp_port_state); + +static const NLType rtnl_bridge_mrp_port_role_types[] = { + [IFLA_BRIDGE_MRP_PORT_ROLE_ROLE] = { .type = NETLINK_TYPE_U32 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_mrp_port_role); + +static const NLType rtnl_bridge_mrp_ring_state_types[] = { + [IFLA_BRIDGE_MRP_RING_STATE_RING_ID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_RING_STATE_STATE] = { .type = NETLINK_TYPE_U32 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_mrp_ring_state); + +static const NLType rtnl_bridge_mrp_ring_role_types[] = { + [IFLA_BRIDGE_MRP_RING_ROLE_RING_ID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_RING_ROLE_ROLE] = { .type = NETLINK_TYPE_U32 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_mrp_ring_role); + +static const NLType rtnl_bridge_mrp_start_test_types[] = { + [IFLA_BRIDGE_MRP_START_TEST_RING_ID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_START_TEST_INTERVAL] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_START_TEST_MAX_MISS] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_START_TEST_PERIOD] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_START_TEST_MONITOR] = { .type = NETLINK_TYPE_U32 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_mrp_start_test); + +static const NLType rtnl_bridge_mrp_info_types[] = { + [IFLA_BRIDGE_MRP_INFO_RING_ID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_INFO_P_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_INFO_S_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_INFO_PRIO] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRIDGE_MRP_INFO_RING_STATE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_INFO_RING_ROLE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_INFO_TEST_INTERVAL] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_INFO_TEST_MAX_MISS] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_INFO_TEST_MONITOR] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_INFO_I_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_INFO_IN_STATE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_INFO_IN_ROLE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_INFO_IN_TEST_INTERVAL] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_INFO_IN_TEST_MAX_MISS] = { .type = NETLINK_TYPE_U32 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_mrp_info); + +static const NLType rtnl_bridge_mrp_in_role_types[] = { + [IFLA_BRIDGE_MRP_IN_ROLE_RING_ID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_IN_ROLE_IN_ID] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRIDGE_MRP_IN_ROLE_ROLE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_IN_ROLE_I_IFINDEX] = { .type = NETLINK_TYPE_U32 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_mrp_in_role); + +static const NLType rtnl_bridge_mrp_in_state_types[] = { + [IFLA_BRIDGE_MRP_IN_STATE_IN_ID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_IN_STATE_STATE] = { .type = NETLINK_TYPE_U32 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_mrp_in_state); + +static const NLType rtnl_bridge_mrp_start_in_test_types[] = { + [IFLA_BRIDGE_MRP_START_IN_TEST_IN_ID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_START_IN_TEST_INTERVAL] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_START_IN_TEST_MAX_MISS] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_MRP_START_IN_TEST_PERIOD] = { .type = NETLINK_TYPE_U32 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_mrp_start_in_test); + +static const NLType rtnl_bridge_mrp_types[] = { + [IFLA_BRIDGE_MRP_INSTANCE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_mrp_instance_type_system }, + [IFLA_BRIDGE_MRP_PORT_STATE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_mrp_port_state_type_system }, + [IFLA_BRIDGE_MRP_PORT_ROLE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_mrp_port_role_type_system }, + [IFLA_BRIDGE_MRP_RING_STATE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_mrp_ring_state_type_system }, + [IFLA_BRIDGE_MRP_RING_ROLE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_mrp_ring_role_type_system }, + [IFLA_BRIDGE_MRP_START_TEST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_mrp_start_test_type_system }, + [IFLA_BRIDGE_MRP_INFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_mrp_info_type_system }, + [IFLA_BRIDGE_MRP_IN_ROLE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_mrp_in_role_type_system }, + [IFLA_BRIDGE_MRP_IN_STATE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_mrp_in_state_type_system }, + [IFLA_BRIDGE_MRP_START_IN_TEST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_mrp_start_in_test_type_system }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_mrp); + +static const NLType rtnl_bridge_cfm_mep_create_types[] = { + [IFLA_BRIDGE_CFM_MEP_CREATE_INSTANCE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_MEP_CREATE_DOMAIN] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_MEP_CREATE_DIRECTION] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_MEP_CREATE_IFINDEX] = { .type = NETLINK_TYPE_U32 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_cfm_mep_create); + +static const NLType rtnl_bridge_cfm_mep_delete_types[] = { + [IFLA_BRIDGE_CFM_MEP_DELETE_INSTANCE] = { .type = NETLINK_TYPE_U32 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_cfm_mep_delete); + +static const NLType rtnl_bridge_cfm_mep_config_types[] = { + [IFLA_BRIDGE_CFM_MEP_CONFIG_INSTANCE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_MEP_CONFIG_UNICAST_MAC] = { .type = NETLINK_TYPE_ETHER_ADDR }, + [IFLA_BRIDGE_CFM_MEP_CONFIG_MDLEVEL] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_MEP_CONFIG_MEPID] = { .type = NETLINK_TYPE_U32 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_cfm_mep_config); + +static const NLType rtnl_bridge_cfm_cc_config_types[] = { + [IFLA_BRIDGE_CFM_CC_CONFIG_INSTANCE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_CC_CONFIG_ENABLE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_CC_CONFIG_EXP_INTERVAL] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_CC_CONFIG_EXP_MAID] = { .type = NETLINK_TYPE_BINARY, .size = CFM_MAID_LENGTH }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_cfm_cc_config); + +static const NLType rtnl_bridge_cfm_cc_peer_mep_types[] = { + [IFLA_BRIDGE_CFM_CC_PEER_MEP_INSTANCE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_CC_PEER_MEPID] = { .type = NETLINK_TYPE_U32 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_cfm_cc_peer_mep); + +static const NLType rtnl_bridge_cfm_cc_rdi_types[] = { + [IFLA_BRIDGE_CFM_CC_RDI_INSTANCE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_CC_RDI_RDI] = { .type = NETLINK_TYPE_U32 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_cfm_cc_rdi); + +static const NLType rtnl_bridge_cfm_cc_ccm_tx_types[] = { + [IFLA_BRIDGE_CFM_CC_CCM_TX_INSTANCE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_CC_CCM_TX_DMAC] = { .type = NETLINK_TYPE_ETHER_ADDR }, + [IFLA_BRIDGE_CFM_CC_CCM_TX_SEQ_NO_UPDATE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_CC_CCM_TX_PERIOD] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_CC_CCM_TX_IF_TLV] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_CC_CCM_TX_IF_TLV_VALUE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRIDGE_CFM_CC_CCM_TX_PORT_TLV] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_CC_CCM_TX_PORT_TLV_VALUE] = { .type = NETLINK_TYPE_U8 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_cfm_cc_ccm_tx); + +static const NLType rtnl_bridge_cfm_mep_status_types[] = { + [IFLA_BRIDGE_CFM_MEP_STATUS_INSTANCE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_MEP_STATUS_OPCODE_UNEXP_SEEN] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_MEP_STATUS_VERSION_UNEXP_SEEN] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_MEP_STATUS_RX_LEVEL_LOW_SEEN] = { .type = NETLINK_TYPE_U32 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_cfm_mep_status); + +static const NLType rtnl_bridge_cfm_cc_peer_status_types[] = { + [IFLA_BRIDGE_CFM_CC_PEER_STATUS_INSTANCE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_CC_PEER_STATUS_PEER_MEPID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_CC_PEER_STATUS_CCM_DEFECT] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_CC_PEER_STATUS_RDI] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_CC_PEER_STATUS_PORT_TLV_VALUE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRIDGE_CFM_CC_PEER_STATUS_IF_TLV_VALUE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRIDGE_CFM_CC_PEER_STATUS_SEEN] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_CC_PEER_STATUS_TLV_SEEN] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRIDGE_CFM_CC_PEER_STATUS_SEQ_UNEXP_SEEN] = { .type = NETLINK_TYPE_U32 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_cfm_cc_peer_status); + +static const NLType rtnl_bridge_cfm_types[] = { + [IFLA_BRIDGE_CFM_MEP_CREATE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_cfm_mep_create_type_system }, + [IFLA_BRIDGE_CFM_MEP_DELETE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_cfm_mep_delete_type_system }, + [IFLA_BRIDGE_CFM_MEP_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_cfm_mep_config_type_system }, + [IFLA_BRIDGE_CFM_CC_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_cfm_cc_config_type_system }, + [IFLA_BRIDGE_CFM_CC_PEER_MEP_ADD] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_cfm_cc_peer_mep_type_system }, + [IFLA_BRIDGE_CFM_CC_PEER_MEP_REMOVE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_cfm_cc_peer_mep_type_system }, + [IFLA_BRIDGE_CFM_CC_RDI] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_cfm_cc_rdi_type_system }, + [IFLA_BRIDGE_CFM_CC_CCM_TX] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_cfm_cc_ccm_tx_type_system }, + [IFLA_BRIDGE_CFM_MEP_CREATE_INFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_cfm_mep_create_type_system }, + [IFLA_BRIDGE_CFM_MEP_CONFIG_INFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_cfm_mep_config_type_system }, + [IFLA_BRIDGE_CFM_CC_CONFIG_INFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_cfm_cc_config_type_system }, + [IFLA_BRIDGE_CFM_CC_RDI_INFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_cfm_cc_rdi_type_system }, + [IFLA_BRIDGE_CFM_CC_CCM_TX_INFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_cfm_cc_ccm_tx_type_system }, + [IFLA_BRIDGE_CFM_CC_PEER_MEP_INFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_cfm_cc_peer_mep_type_system }, + [IFLA_BRIDGE_CFM_MEP_STATUS_INFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_cfm_mep_status_type_system }, + [IFLA_BRIDGE_CFM_CC_PEER_STATUS_INFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_cfm_cc_peer_status_type_system }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_bridge_cfm); + static const NLType rtnl_af_spec_bridge_types[] = { - [IFLA_BRIDGE_FLAGS] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BRIDGE_VLAN_INFO] = { .size = sizeof(struct bridge_vlan_info) }, + [IFLA_BRIDGE_FLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRIDGE_MODE] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRIDGE_VLAN_INFO] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct bridge_vlan_info) }, + [IFLA_BRIDGE_VLAN_TUNNEL_INFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_vlan_tunnel_info_type_system }, + [IFLA_BRIDGE_MRP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_mrp_type_system }, + [IFLA_BRIDGE_CFM] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bridge_cfm_type_system }, }; static const NLTypeSystemUnionElement rtnl_af_spec_type_systems[] = { @@ -467,23 +769,23 @@ static const NLType rtnl_prop_list_types[] = { DEFINE_TYPE_SYSTEM(rtnl_prop_list); static const NLType rtnl_vf_vlan_list_types[] = { - [IFLA_VF_VLAN_INFO] = { .size = sizeof(struct ifla_vf_vlan_info) }, + [IFLA_VF_VLAN_INFO] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct ifla_vf_vlan_info) }, }; DEFINE_TYPE_SYSTEM(rtnl_vf_vlan_list); static const NLType rtnl_vf_info_types[] = { - [IFLA_VF_MAC] = { .size = sizeof(struct ifla_vf_mac) }, - [IFLA_VF_VLAN] = { .size = sizeof(struct ifla_vf_vlan) }, - [IFLA_VF_VLAN_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vf_vlan_list_type_system}, - [IFLA_VF_TX_RATE] = { .size = sizeof(struct ifla_vf_tx_rate) }, - [IFLA_VF_SPOOFCHK] = { .size = sizeof(struct ifla_vf_spoofchk) }, - [IFLA_VF_RATE] = { .size = sizeof(struct ifla_vf_rate) }, - [IFLA_VF_LINK_STATE] = { .size = sizeof(struct ifla_vf_link_state) }, - [IFLA_VF_RSS_QUERY_EN] = { .size = sizeof(struct ifla_vf_rss_query_en) }, - [IFLA_VF_TRUST] = { .size = sizeof(struct ifla_vf_trust) }, - [IFLA_VF_IB_NODE_GUID] = { .size = sizeof(struct ifla_vf_guid) }, - [IFLA_VF_IB_PORT_GUID] = { .size = sizeof(struct ifla_vf_guid) }, + [IFLA_VF_MAC] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct ifla_vf_mac) }, + [IFLA_VF_VLAN] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct ifla_vf_vlan) }, + [IFLA_VF_VLAN_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vf_vlan_list_type_system }, + [IFLA_VF_TX_RATE] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct ifla_vf_tx_rate) }, + [IFLA_VF_SPOOFCHK] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct ifla_vf_spoofchk) }, + [IFLA_VF_RATE] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct ifla_vf_rate) }, + [IFLA_VF_LINK_STATE] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct ifla_vf_link_state) }, + [IFLA_VF_RSS_QUERY_EN] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct ifla_vf_rss_query_en) }, + [IFLA_VF_TRUST] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct ifla_vf_trust) }, + [IFLA_VF_IB_NODE_GUID] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct ifla_vf_guid) }, + [IFLA_VF_IB_PORT_GUID] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct ifla_vf_guid) }, }; DEFINE_TYPE_SYSTEM(rtnl_vf_info); @@ -494,61 +796,101 @@ static const NLType rtnl_vfinfo_list_types[] = { DEFINE_TYPE_SYSTEM(rtnl_vfinfo_list); +static const NLType rtnl_vf_port_types[] = { + [IFLA_PORT_VF] = { .type = NETLINK_TYPE_U32 }, + [IFLA_PORT_PROFILE] = { .type = NETLINK_TYPE_STRING }, + [IFLA_PORT_VSI_TYPE] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct ifla_port_vsi) }, + [IFLA_PORT_INSTANCE_UUID] = { .type = NETLINK_TYPE_BINARY, .size = PORT_UUID_MAX }, + [IFLA_PORT_HOST_UUID] = { .type = NETLINK_TYPE_BINARY, .size = PORT_UUID_MAX }, + [IFLA_PORT_REQUEST] = { .type = NETLINK_TYPE_U8 }, + [IFLA_PORT_RESPONSE] = { .type = NETLINK_TYPE_U16 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_vf_port); + +static const NLType rtnl_vf_ports_types[] = { + [IFLA_VF_PORT] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vf_port_type_system }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_vf_ports); + +static const NLType rtnl_xdp_types[] = { + [IFLA_XDP_FD] = { .type = NETLINK_TYPE_S32 }, + [IFLA_XDP_ATTACHED] = { .type = NETLINK_TYPE_U8 }, + [IFLA_XDP_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [IFLA_XDP_PROG_ID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_XDP_DRV_PROG_ID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_XDP_SKB_PROG_ID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_XDP_HW_PROG_ID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_XDP_EXPECTED_FD] = { .type = NETLINK_TYPE_S32 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_xdp); + +static const NLType rtnl_proto_down_reason_types[] = { + [IFLA_PROTO_DOWN_REASON_MASK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_PROTO_DOWN_REASON_VALUE] = { .type = NETLINK_TYPE_U32 }, +}; + +DEFINE_TYPE_SYSTEM(rtnl_proto_down_reason); + static const NLType rtnl_link_types[] = { - [IFLA_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR }, - [IFLA_BROADCAST] = { .type = NETLINK_TYPE_ETHER_ADDR }, - [IFLA_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 }, - [IFLA_MTU] = { .type = NETLINK_TYPE_U32 }, - [IFLA_LINK] = { .type = NETLINK_TYPE_U32 }, - [IFLA_QDISC] = { .type = NETLINK_TYPE_STRING }, - [IFLA_STATS] = { .size = sizeof(struct rtnl_link_stats) }, -/* - [IFLA_COST], - [IFLA_PRIORITY], -*/ - [IFLA_MASTER] = { .type = NETLINK_TYPE_U32 }, -/* - [IFLA_WIRELESS], -*/ - [IFLA_PROTINFO] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_prot_info_type_system_union }, - [IFLA_TXQLEN] = { .type = NETLINK_TYPE_U32 }, -/* - [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, -*/ - [IFLA_WEIGHT] = { .type = NETLINK_TYPE_U32 }, - [IFLA_OPERSTATE] = { .type = NETLINK_TYPE_U8 }, - [IFLA_LINKMODE] = { .type = NETLINK_TYPE_U8 }, - [IFLA_LINKINFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_info_type_system }, - [IFLA_NET_NS_PID] = { .type = NETLINK_TYPE_U32 }, - [IFLA_IFALIAS] = { .type = NETLINK_TYPE_STRING, .size = IFALIASZ - 1 }, - [IFLA_NUM_VF] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VFINFO_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vfinfo_list_type_system }, - [IFLA_STATS64] = { .size = sizeof(struct rtnl_link_stats64) }, -/* - [IFLA_VF_PORTS] = { .type = NETLINK_TYPE_NESTED }, - [IFLA_PORT_SELF] = { .type = NETLINK_TYPE_NESTED }, -*/ - [IFLA_AF_SPEC] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_af_spec_type_system_union }, -/* - [IFLA_VF_PORTS], - [IFLA_PORT_SELF], -*/ - [IFLA_GROUP] = { .type = NETLINK_TYPE_U32 }, - [IFLA_NET_NS_FD] = { .type = NETLINK_TYPE_U32 }, - [IFLA_EXT_MASK] = { .type = NETLINK_TYPE_U32 }, - [IFLA_PROMISCUITY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_NUM_TX_QUEUES] = { .type = NETLINK_TYPE_U32 }, - [IFLA_NUM_RX_QUEUES] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GSO_MAX_SEGS] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GSO_MAX_SIZE] = { .type = NETLINK_TYPE_U32 }, - [IFLA_CARRIER] = { .type = NETLINK_TYPE_U8 }, -/* - [IFLA_PHYS_PORT_ID] = { .type = NETLINK_TYPE_BINARY, .len = MAX_PHYS_PORT_ID_LEN }, -*/ - [IFLA_MIN_MTU] = { .type = NETLINK_TYPE_U32 }, - [IFLA_MAX_MTU] = { .type = NETLINK_TYPE_U32 }, - [IFLA_PROP_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_prop_list_type_system }, - [IFLA_ALT_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = ALTIFNAMSIZ - 1 }, + [IFLA_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR }, + [IFLA_BROADCAST] = { .type = NETLINK_TYPE_ETHER_ADDR }, + [IFLA_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 }, + [IFLA_MTU] = { .type = NETLINK_TYPE_U32 }, + [IFLA_LINK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_QDISC] = { .type = NETLINK_TYPE_STRING }, + [IFLA_STATS] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct rtnl_link_stats) }, + [IFLA_COST] = { /* Not used. */ }, + [IFLA_PRIORITY] = { /* Not used. */ }, + [IFLA_MASTER] = { .type = NETLINK_TYPE_U32 }, + [IFLA_WIRELESS] = { /* Used only by wext. */ }, + [IFLA_PROTINFO] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_prot_info_type_system_union }, + [IFLA_TXQLEN] = { .type = NETLINK_TYPE_U32 }, + [IFLA_MAP] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct rtnl_link_ifmap) }, + [IFLA_WEIGHT] = { .type = NETLINK_TYPE_U32 }, + [IFLA_OPERSTATE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_LINKMODE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_LINKINFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_info_type_system }, + [IFLA_NET_NS_PID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_IFALIAS] = { .type = NETLINK_TYPE_STRING, .size = IFALIASZ - 1 }, + [IFLA_NUM_VF] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VFINFO_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vfinfo_list_type_system }, + [IFLA_STATS64] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct rtnl_link_stats64) }, + [IFLA_VF_PORTS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vf_ports_type_system }, + [IFLA_PORT_SELF] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vf_port_type_system }, + [IFLA_AF_SPEC] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_af_spec_type_system_union }, + [IFLA_GROUP] = { .type = NETLINK_TYPE_U32 }, + [IFLA_NET_NS_FD] = { .type = NETLINK_TYPE_U32 }, + [IFLA_EXT_MASK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_PROMISCUITY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_NUM_TX_QUEUES] = { .type = NETLINK_TYPE_U32 }, + [IFLA_NUM_RX_QUEUES] = { .type = NETLINK_TYPE_U32 }, + [IFLA_CARRIER] = { .type = NETLINK_TYPE_U8 }, + [IFLA_PHYS_PORT_ID] = { .type = NETLINK_TYPE_BINARY, .size = MAX_PHYS_ITEM_ID_LEN }, + [IFLA_CARRIER_CHANGES] = { .type = NETLINK_TYPE_U32 }, + [IFLA_PHYS_SWITCH_ID] = { .type = NETLINK_TYPE_BINARY, .size = MAX_PHYS_ITEM_ID_LEN }, + [IFLA_LINK_NETNSID] = { .type = NETLINK_TYPE_S32 }, + [IFLA_PHYS_PORT_NAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 }, + [IFLA_PROTO_DOWN] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GSO_MAX_SEGS] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GSO_MAX_SIZE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_XDP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_xdp_type_system }, + [IFLA_EVENT] = { .type = NETLINK_TYPE_U32 }, + [IFLA_NEW_NETNSID] = { .type = NETLINK_TYPE_S32 }, + [IFLA_TARGET_NETNSID] = { .type = NETLINK_TYPE_S32 }, + [IFLA_CARRIER_UP_COUNT] = { .type = NETLINK_TYPE_U32 }, + [IFLA_CARRIER_DOWN_COUNT] = { .type = NETLINK_TYPE_U32 }, + [IFLA_NEW_IFINDEX] = { .type = NETLINK_TYPE_S32 }, + [IFLA_MIN_MTU] = { .type = NETLINK_TYPE_U32 }, + [IFLA_MAX_MTU] = { .type = NETLINK_TYPE_U32 }, + [IFLA_PROP_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_prop_list_type_system }, + [IFLA_ALT_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = ALTIFNAMSIZ - 1 }, + [IFLA_PERM_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR }, + [IFLA_PROTO_DOWN_REASON] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_proto_down_reason_type_system }, + [IFLA_PARENT_DEV_NAME] = { .type = NETLINK_TYPE_STRING, }, + [IFLA_PARENT_DEV_BUS_NAME] = { .type = NETLINK_TYPE_STRING, }, }; DEFINE_TYPE_SYSTEM(rtnl_link); From e0df8e99935cc87886b4d700b89c53eb4eee1ca5 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 26 Aug 2021 01:29:21 +0900 Subject: [PATCH 04/13] sd-netlink: specify appropriate netlink attribute type --- .../sd-netlink/netlink-types-genl.c | 34 +++++++++---------- .../sd-netlink/netlink-types-rtnl.c | 32 ++++++++--------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-types-genl.c b/src/libsystemd/sd-netlink/netlink-types-genl.c index 0e8783b4983..b2f768181fd 100644 --- a/src/libsystemd/sd-netlink/netlink-types-genl.c +++ b/src/libsystemd/sd-netlink/netlink-types-genl.c @@ -50,18 +50,18 @@ static const NLType genl_batadv_types[] = { [BATADV_ATTR_ALGO_NAME] = { .type = NETLINK_TYPE_STRING }, [BATADV_ATTR_MESH_IFINDEX] = { .type = NETLINK_TYPE_U32 }, [BATADV_ATTR_MESH_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ }, - [BATADV_ATTR_MESH_ADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_MESH_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN }, [BATADV_ATTR_HARD_IFINDEX] = { .type = NETLINK_TYPE_U32 }, [BATADV_ATTR_HARD_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ }, - [BATADV_ATTR_HARD_ADDRESS] = { .size = ETH_ALEN }, - [BATADV_ATTR_ORIG_ADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_HARD_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN }, + [BATADV_ATTR_ORIG_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN }, [BATADV_ATTR_TPMETER_RESULT] = { .type = NETLINK_TYPE_U8 }, [BATADV_ATTR_TPMETER_TEST_TIME] = { .type = NETLINK_TYPE_U32 }, [BATADV_ATTR_TPMETER_BYTES] = { .type = NETLINK_TYPE_U64 }, [BATADV_ATTR_TPMETER_COOKIE] = { .type = NETLINK_TYPE_U32 }, [BATADV_ATTR_PAD] = { .type = NETLINK_TYPE_UNSPEC }, [BATADV_ATTR_ACTIVE] = { .type = NETLINK_TYPE_FLAG }, - [BATADV_ATTR_TT_ADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_TT_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN }, [BATADV_ATTR_TT_TTVN] = { .type = NETLINK_TYPE_U8 }, [BATADV_ATTR_TT_LAST_TTVN] = { .type = NETLINK_TYPE_U8 }, [BATADV_ATTR_TT_CRC32] = { .type = NETLINK_TYPE_U32 }, @@ -69,19 +69,19 @@ static const NLType genl_batadv_types[] = { [BATADV_ATTR_TT_FLAGS] = { .type = NETLINK_TYPE_U32 }, [BATADV_ATTR_FLAG_BEST] = { .type = NETLINK_TYPE_FLAG }, [BATADV_ATTR_LAST_SEEN_MSECS] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_NEIGH_ADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_NEIGH_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN }, [BATADV_ATTR_TQ] = { .type = NETLINK_TYPE_U8 }, [BATADV_ATTR_THROUGHPUT] = { .type = NETLINK_TYPE_U32 }, [BATADV_ATTR_BANDWIDTH_UP] = { .type = NETLINK_TYPE_U32 }, [BATADV_ATTR_BANDWIDTH_DOWN] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_ROUTER] = { .size = ETH_ALEN }, + [BATADV_ATTR_ROUTER] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN }, [BATADV_ATTR_BLA_OWN] = { .type = NETLINK_TYPE_FLAG }, - [BATADV_ATTR_BLA_ADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_BLA_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN }, [BATADV_ATTR_BLA_VID] = { .type = NETLINK_TYPE_U16 }, - [BATADV_ATTR_BLA_BACKBONE] = { .size = ETH_ALEN }, + [BATADV_ATTR_BLA_BACKBONE] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN }, [BATADV_ATTR_BLA_CRC] = { .type = NETLINK_TYPE_U16 }, [BATADV_ATTR_DAT_CACHE_IP4ADDRESS] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_DAT_CACHE_HWADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_DAT_CACHE_HWADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN }, [BATADV_ATTR_DAT_CACHE_VID] = { .type = NETLINK_TYPE_U16 }, [BATADV_ATTR_MCAST_FLAGS] = { .type = NETLINK_TYPE_U32 }, [BATADV_ATTR_MCAST_FLAGS_PRIV] = { .type = NETLINK_TYPE_U32 }, @@ -118,9 +118,9 @@ static const NLType genl_fou_types[] = { [FOU_ATTR_LOCAL_V4] = { .type = NETLINK_TYPE_IN_ADDR }, [FOU_ATTR_PEER_V4] = { .type = NETLINK_TYPE_IN_ADDR }, [FOU_ATTR_LOCAL_V6] = { .type = NETLINK_TYPE_IN_ADDR }, - [FOU_ATTR_PEER_V6] = { .type = NETLINK_TYPE_IN_ADDR}, - [FOU_ATTR_PEER_PORT] = { .type = NETLINK_TYPE_U16}, - [FOU_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32}, + [FOU_ATTR_PEER_V6] = { .type = NETLINK_TYPE_IN_ADDR }, + [FOU_ATTR_PEER_PORT] = { .type = NETLINK_TYPE_U16 }, + [FOU_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, }; /***************** genl l2tp type systems *****************/ @@ -165,8 +165,8 @@ static const NLType genl_macsec_sa_types[] = { [MACSEC_SA_ATTR_AN] = { .type = NETLINK_TYPE_U8 }, [MACSEC_SA_ATTR_ACTIVE] = { .type = NETLINK_TYPE_U8 }, [MACSEC_SA_ATTR_PN] = { .type = NETLINK_TYPE_U32 }, - [MACSEC_SA_ATTR_KEYID] = { .size = MACSEC_KEYID_LEN }, - [MACSEC_SA_ATTR_KEY] = { .size = MACSEC_MAX_KEY_LEN }, + [MACSEC_SA_ATTR_KEYID] = { .type = NETLINK_TYPE_BINARY, .size = MACSEC_KEYID_LEN }, + [MACSEC_SA_ATTR_KEY] = { .type = NETLINK_TYPE_BINARY, .size = MACSEC_MAX_KEY_LEN }, }; DEFINE_TYPE_SYSTEM(genl_macsec_sa); @@ -195,9 +195,9 @@ static const NLType genl_wireguard_allowedip_types[] = { DEFINE_TYPE_SYSTEM(genl_wireguard_allowedip); static const NLType genl_wireguard_peer_types[] = { - [WGPEER_A_PUBLIC_KEY] = { .size = WG_KEY_LEN }, + [WGPEER_A_PUBLIC_KEY] = { .type = NETLINK_TYPE_BINARY, .size = WG_KEY_LEN }, [WGPEER_A_FLAGS] = { .type = NETLINK_TYPE_U32 }, - [WGPEER_A_PRESHARED_KEY] = { .size = WG_KEY_LEN }, + [WGPEER_A_PRESHARED_KEY] = { .type = NETLINK_TYPE_BINARY, .size = WG_KEY_LEN }, [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NETLINK_TYPE_U16 }, [WGPEER_A_ENDPOINT] = { .type = NETLINK_TYPE_SOCKADDR }, [WGPEER_A_ALLOWEDIPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_allowedip_type_system }, @@ -209,7 +209,7 @@ static const NLType genl_wireguard_types[] = { [WGDEVICE_A_IFINDEX] = { .type = NETLINK_TYPE_U32 }, [WGDEVICE_A_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ-1 }, [WGDEVICE_A_FLAGS] = { .type = NETLINK_TYPE_U32 }, - [WGDEVICE_A_PRIVATE_KEY] = { .size = WG_KEY_LEN }, + [WGDEVICE_A_PRIVATE_KEY] = { .type = NETLINK_TYPE_BINARY, .size = WG_KEY_LEN }, [WGDEVICE_A_LISTEN_PORT] = { .type = NETLINK_TYPE_U16 }, [WGDEVICE_A_FWMARK] = { .type = NETLINK_TYPE_U32 }, [WGDEVICE_A_PEERS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_peer_type_system }, diff --git a/src/libsystemd/sd-netlink/netlink-types-rtnl.c b/src/libsystemd/sd-netlink/netlink-types-rtnl.c index e2e999711ff..3424bd625a6 100644 --- a/src/libsystemd/sd-netlink/netlink-types-rtnl.c +++ b/src/libsystemd/sd-netlink/netlink-types-rtnl.c @@ -943,10 +943,10 @@ static const NLType rtnl_route_types[] = { [RTA_GATEWAY] = { .type = NETLINK_TYPE_IN_ADDR }, [RTA_PRIORITY] = { .type = NETLINK_TYPE_U32 }, [RTA_PREFSRC] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */ - [RTA_METRICS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_metrics_type_system}, - [RTA_MULTIPATH] = { .size = sizeof(struct rtnexthop) }, + [RTA_METRICS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_metrics_type_system }, + [RTA_MULTIPATH] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct rtnexthop) }, [RTA_FLOW] = { .type = NETLINK_TYPE_U32 }, /* 6? */ - [RTA_CACHEINFO] = { .size = sizeof(struct rta_cacheinfo) }, + [RTA_CACHEINFO] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct rta_cacheinfo) }, [RTA_TABLE] = { .type = NETLINK_TYPE_U32 }, [RTA_MARK] = { .type = NETLINK_TYPE_U32 }, [RTA_MFC_STATS] = { .type = NETLINK_TYPE_U64 }, @@ -1002,11 +1002,11 @@ static const NLType rtnl_routing_policy_rule_types[] = { [FRA_OIFNAME] = { .type = NETLINK_TYPE_STRING }, [FRA_PAD] = { .type = NETLINK_TYPE_U32 }, [FRA_L3MDEV] = { .type = NETLINK_TYPE_U8 }, - [FRA_UID_RANGE] = { .size = sizeof(struct fib_rule_uid_range) }, + [FRA_UID_RANGE] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct fib_rule_uid_range) }, [FRA_PROTOCOL] = { .type = NETLINK_TYPE_U8 }, [FRA_IP_PROTO] = { .type = NETLINK_TYPE_U8 }, - [FRA_SPORT_RANGE] = { .size = sizeof(struct fib_rule_port_range) }, - [FRA_DPORT_RANGE] = { .size = sizeof(struct fib_rule_port_range) }, + [FRA_SPORT_RANGE] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct fib_rule_port_range) }, + [FRA_DPORT_RANGE] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct fib_rule_port_range) }, }; DEFINE_TYPE_SYSTEM(rtnl_routing_policy_rule); @@ -1097,7 +1097,7 @@ static const NLType rtnl_tca_option_data_fq_pie_types[] = { }; static const NLType rtnl_tca_option_data_gred_types[] = { - [TCA_GRED_DPS] = { .size = sizeof(struct tc_gred_sopt) }, + [TCA_GRED_DPS] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct tc_gred_sopt) }, }; static const NLType rtnl_tca_option_data_hhf_types[] = { @@ -1105,10 +1105,10 @@ static const NLType rtnl_tca_option_data_hhf_types[] = { }; static const NLType rtnl_tca_option_data_htb_types[] = { - [TCA_HTB_PARMS] = { .size = sizeof(struct tc_htb_opt) }, - [TCA_HTB_INIT] = { .size = sizeof(struct tc_htb_glob) }, - [TCA_HTB_CTAB] = { .size = TC_RTAB_SIZE }, - [TCA_HTB_RTAB] = { .size = TC_RTAB_SIZE }, + [TCA_HTB_PARMS] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct tc_htb_opt) }, + [TCA_HTB_INIT] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct tc_htb_glob) }, + [TCA_HTB_CTAB] = { .type = NETLINK_TYPE_BINARY, .size = TC_RTAB_SIZE }, + [TCA_HTB_RTAB] = { .type = NETLINK_TYPE_BINARY, .size = TC_RTAB_SIZE }, [TCA_HTB_RATE64] = { .type = NETLINK_TYPE_U64 }, [TCA_HTB_CEIL64] = { .type = NETLINK_TYPE_U64 }, }; @@ -1123,13 +1123,13 @@ static const NLType rtnl_tca_option_data_qfq_types[] = { }; static const NLType rtnl_tca_option_data_sfb_types[] = { - [TCA_SFB_PARMS] = { .size = sizeof(struct tc_sfb_qopt) }, + [TCA_SFB_PARMS] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct tc_sfb_qopt) }, }; static const NLType rtnl_tca_option_data_tbf_types[] = { - [TCA_TBF_PARMS] = { .size = sizeof(struct tc_tbf_qopt) }, - [TCA_TBF_RTAB] = { .size = TC_RTAB_SIZE }, - [TCA_TBF_PTAB] = { .size = TC_RTAB_SIZE }, + [TCA_TBF_PARMS] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct tc_tbf_qopt) }, + [TCA_TBF_RTAB] = { .type = NETLINK_TYPE_BINARY, .size = TC_RTAB_SIZE }, + [TCA_TBF_PTAB] = { .type = NETLINK_TYPE_BINARY, .size = TC_RTAB_SIZE }, [TCA_TBF_RATE64] = { .type = NETLINK_TYPE_U64 }, [TCA_TBF_PRATE64] = { .type = NETLINK_TYPE_U64 }, [TCA_TBF_BURST] = { .type = NETLINK_TYPE_U32 }, @@ -1165,7 +1165,7 @@ static const NLType rtnl_tca_types[] = { DEFINE_TYPE_SYSTEM(rtnl_tca); static const NLType rtnl_mdb_types[] = { - [MDBA_SET_ENTRY] = { .size = sizeof(struct br_port_msg) }, + [MDBA_SET_ENTRY] = { .type = NETLINK_TYPE_BINARY, .size = sizeof(struct br_port_msg) }, }; DEFINE_TYPE_SYSTEM(rtnl_mdb); From 416e84192a0739de6ada3214fe84183f669aa8a9 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 27 Aug 2021 16:30:19 +0900 Subject: [PATCH 05/13] sd-netlink: introduce sd_netlink_message_get_max_attribute() --- src/libsystemd/sd-netlink/netlink-internal.h | 2 +- src/libsystemd/sd-netlink/netlink-message.c | 44 ++++++++++++-------- src/systemd/sd-netlink.h | 1 + 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h index 050edaec78c..299b7d660bc 100644 --- a/src/libsystemd/sd-netlink/netlink-internal.h +++ b/src/libsystemd/sd-netlink/netlink-internal.h @@ -112,7 +112,7 @@ struct netlink_container { const struct NLTypeSystem *type_system; /* the type system of the container */ size_t offset; /* offset from hdr to the start of the container */ struct netlink_attribute *attributes; - unsigned short n_attributes; /* number of attributes in container */ + uint16_t max_attribute; /* the maximum attribute in container */ }; struct sd_netlink_message { diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index e422d5699c8..2bfaff7ce0e 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -712,7 +712,7 @@ static int netlink_message_read_internal( if (!m->containers[m->n_containers].attributes) return -ENODATA; - if (type >= m->containers[m->n_containers].n_attributes) + if (type > m->containers[m->n_containers].max_attribute) return -ENODATA; attribute = &m->containers[m->n_containers].attributes[type]; @@ -1093,38 +1093,38 @@ int sd_netlink_message_read_strv(sd_netlink_message *m, unsigned short container return 0; } -static int netlink_container_parse(sd_netlink_message *m, - struct netlink_container *container, - struct rtattr *rta, - size_t rt_len) { +static int netlink_container_parse( + sd_netlink_message *m, + struct netlink_container *container, + struct rtattr *rta, + size_t rt_len) { + _cleanup_free_ struct netlink_attribute *attributes = NULL; - size_t n = 0; + uint16_t max_attr = 0; /* RTA_OK() macro compares with rta->rt_len, which is unsigned short, and * LGTM.com analysis does not like the type difference. Hence, here we * introduce an unsigned short variable as a workaround. */ unsigned short len = rt_len; for (; RTA_OK(rta, len); rta = RTA_NEXT(rta, len)) { - unsigned short type; + uint16_t attr; - type = RTA_TYPE(rta); + attr = RTA_TYPE(rta); + max_attr = MAX(max_attr, attr); - if (!GREEDY_REALLOC0(attributes, type + 1)) + if (!GREEDY_REALLOC0(attributes, (size_t) max_attr + 1)) return -ENOMEM; - if (attributes[type].offset != 0) + if (attributes[attr].offset != 0) log_debug("sd-netlink: message parse - overwriting repeated attribute"); - attributes[type].offset = (uint8_t *) rta - (uint8_t *) m->hdr; - attributes[type].nested = RTA_FLAGS(rta) & NLA_F_NESTED; - attributes[type].net_byteorder = RTA_FLAGS(rta) & NLA_F_NET_BYTEORDER; - - if (type + 1U > n) - n = type + 1U; + attributes[attr].offset = (uint8_t *) rta - (uint8_t *) m->hdr; + attributes[attr].nested = RTA_FLAGS(rta) & NLA_F_NESTED; + attributes[attr].net_byteorder = RTA_FLAGS(rta) & NLA_F_NET_BYTEORDER; } container->attributes = TAKE_PTR(attributes); - container->n_attributes = n; + container->max_attribute = max_attr; return 0; } @@ -1259,6 +1259,7 @@ int sd_netlink_message_exit_container(sd_netlink_message *m) { assert_return(m->n_containers > 0, -EINVAL); m->containers[m->n_containers].attributes = mfree(m->containers[m->n_containers].attributes); + m->containers[m->n_containers].max_attribute = 0; m->containers[m->n_containers].type_system = NULL; m->n_containers--; @@ -1266,6 +1267,15 @@ int sd_netlink_message_exit_container(sd_netlink_message *m) { return 0; } +int sd_netlink_message_get_max_attribute(sd_netlink_message *m, uint16_t *ret) { + assert_return(m, -EINVAL); + assert_return(m->sealed, -EINVAL); + assert_return(ret, -EINVAL); + + *ret = m->containers[m->n_containers].max_attribute; + return 0; +} + uint32_t message_get_serial(sd_netlink_message *m) { assert(m); assert(m->hdr); diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h index 5965780fbb7..ee1b32fddb8 100644 --- a/src/systemd/sd-netlink.h +++ b/src/systemd/sd-netlink.h @@ -126,6 +126,7 @@ int sd_netlink_message_get_errno(sd_netlink_message *m); int sd_netlink_message_get_type(sd_netlink_message *m, uint16_t *type); int sd_netlink_message_set_flags(sd_netlink_message *m, uint16_t flags); int sd_netlink_message_is_broadcast(sd_netlink_message *m); +int sd_netlink_message_get_max_attribute(sd_netlink_message *m, uint16_t *ret); /* rtnl */ int sd_rtnl_message_get_family(sd_netlink_message *m, int *family); From 4154524d47d24bcee3ebfed939912a847ebeb1b3 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 27 Aug 2021 17:27:26 +0900 Subject: [PATCH 06/13] udev: fix potential memleak --- src/udev/udev-builtin-net_id.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index 0aede28f7d6..9578fa00c37 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -101,7 +101,6 @@ static int get_virtfn_info(sd_device *dev, struct netnames *names, struct virtfn _cleanup_(sd_device_unrefp) sd_device *physfn_pcidev = NULL; const char *physfn_link_file, *syspath; _cleanup_free_ char *physfn_pci_syspath = NULL; - _cleanup_free_ char *virtfn_pci_syspath = NULL; struct dirent *dent; _cleanup_closedir_ DIR *dir = NULL; char suffix[ALTIFNAMSIZ]; @@ -132,7 +131,7 @@ static int get_virtfn_info(sd_device *dev, struct netnames *names, struct virtfn return -errno; FOREACH_DIRENT_ALL(dent, dir, break) { - _cleanup_free_ char *virtfn_link_file = NULL; + _cleanup_free_ char *virtfn_link_file = NULL, *virtfn_pci_syspath = NULL; if (!startswith(dent->d_name, "virtfn")) continue; From ba86989fcdc974a6c3729ae78041ba3739f44d5e Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 27 Aug 2021 17:36:22 +0900 Subject: [PATCH 07/13] udev: drop redundant chase_symlinks() `sd_device_new_from_syspath()` internally calls chase_symlinks(). --- src/udev/udev-builtin-net_id.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index 9578fa00c37..80c57e287d9 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -99,8 +99,7 @@ static sd_device *skip_virtio(sd_device *dev) { static int get_virtfn_info(sd_device *dev, struct netnames *names, struct virtfn_info *ret) { _cleanup_(sd_device_unrefp) sd_device *physfn_pcidev = NULL; - const char *physfn_link_file, *syspath; - _cleanup_free_ char *physfn_pci_syspath = NULL; + const char *physfn_syspath, *syspath; struct dirent *dent; _cleanup_closedir_ DIR *dir = NULL; char suffix[ALTIFNAMSIZ]; @@ -114,19 +113,18 @@ static int get_virtfn_info(sd_device *dev, struct netnames *names, struct virtfn if (r < 0) return r; - /* Check if this is a virtual function. */ - physfn_link_file = strjoina(syspath, "/physfn"); - r = chase_symlinks(physfn_link_file, NULL, 0, &physfn_pci_syspath, NULL); + /* Get physical function's pci device. */ + physfn_syspath = strjoina(syspath, "/physfn"); + r = sd_device_new_from_syspath(&physfn_pcidev, physfn_syspath); if (r < 0) return r; - /* Get physical function's pci device. */ - r = sd_device_new_from_syspath(&physfn_pcidev, physfn_pci_syspath); + r = sd_device_get_syspath(physfn_pcidev, &physfn_syspath); if (r < 0) return r; /* Find the virtual function number by finding the right virtfn link. */ - dir = opendir(physfn_pci_syspath); + dir = opendir(physfn_syspath); if (!dir) return -errno; @@ -136,7 +134,7 @@ static int get_virtfn_info(sd_device *dev, struct netnames *names, struct virtfn if (!startswith(dent->d_name, "virtfn")) continue; - virtfn_link_file = path_join(physfn_pci_syspath, dent->d_name); + virtfn_link_file = path_join(physfn_syspath, dent->d_name); if (!virtfn_link_file) return -ENOMEM; From 1e6ec639f59ff3e2376506f2c6a419606400559d Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 27 Aug 2021 17:53:27 +0900 Subject: [PATCH 08/13] udev: simplify get_virtfn_info() --- src/udev/udev-builtin-net_id.c | 64 ++++++++++++++++------------------ 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index 80c57e287d9..f8a519af464 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -71,11 +71,6 @@ struct netnames { char netdevsim_path[ALTIFNAMSIZ]; }; -struct virtfn_info { - sd_device *physfn_pcidev; - char suffix[ALTIFNAMSIZ]; -}; - /* skip intermediate virtio devices */ static sd_device *skip_virtio(sd_device *dev) { /* there can only ever be one virtio bus per parent device, so we can @@ -97,19 +92,18 @@ static sd_device *skip_virtio(sd_device *dev) { return dev; } -static int get_virtfn_info(sd_device *dev, struct netnames *names, struct virtfn_info *ret) { +static int get_virtfn_info(sd_device *pcidev, sd_device **ret_physfn_pcidev, char **ret_suffix) { _cleanup_(sd_device_unrefp) sd_device *physfn_pcidev = NULL; const char *physfn_syspath, *syspath; - struct dirent *dent; _cleanup_closedir_ DIR *dir = NULL; - char suffix[ALTIFNAMSIZ]; + struct dirent *dent; int r; - assert(dev); - assert(names); - assert(ret); + assert(pcidev); + assert(ret_physfn_pcidev); + assert(ret_suffix); - r = sd_device_get_syspath(names->pcidev, &syspath); + r = sd_device_get_syspath(pcidev, &syspath); if (r < 0) return r; @@ -130,8 +124,10 @@ static int get_virtfn_info(sd_device *dev, struct netnames *names, struct virtfn FOREACH_DIRENT_ALL(dent, dir, break) { _cleanup_free_ char *virtfn_link_file = NULL, *virtfn_pci_syspath = NULL; + const char *n; - if (!startswith(dent->d_name, "virtfn")) + n = startswith(dent->d_name, "virtfn"); + if (!n) continue; virtfn_link_file = path_join(physfn_syspath, dent->d_name); @@ -142,19 +138,19 @@ static int get_virtfn_info(sd_device *dev, struct netnames *names, struct virtfn continue; if (streq(syspath, virtfn_pci_syspath)) { - if (!snprintf_ok(suffix, sizeof(suffix), "v%s", &dent->d_name[6])) - return -ENOENT; + char *suffix; - break; + suffix = strjoin("v", n); + if (!suffix) + return -ENOMEM; + + *ret_physfn_pcidev = TAKE_PTR(physfn_pcidev); + *ret_suffix = suffix; + return 0; } } - if (isempty(suffix)) - return -ENOENT; - ret->physfn_pcidev = TAKE_PTR(physfn_pcidev); - strncpy(ret->suffix, suffix, sizeof(ret->suffix)); - - return 0; + return -ENOENT; } static bool is_valid_onboard_index(unsigned long idx) { @@ -556,9 +552,9 @@ static int names_platform(sd_device *dev, struct netnames *names, bool test) { } static int names_pci(sd_device *dev, struct netnames *names) { + _cleanup_(sd_device_unrefp) sd_device *physfn_pcidev = NULL; + _cleanup_free_ char *virtfn_suffix = NULL; sd_device *parent; - struct netnames vf_names = {}; - struct virtfn_info vf_info = {}; const char *subsystem; int r; @@ -586,24 +582,26 @@ static int names_pci(sd_device *dev, struct netnames *names) { } if (naming_scheme_has(NAMING_SR_IOV_V) && - get_virtfn_info(dev, names, &vf_info) >= 0) { + get_virtfn_info(names->pcidev, &physfn_pcidev, &virtfn_suffix) >= 0) { + struct netnames vf_names = {}; + /* If this is an SR-IOV virtual device, get base name using physical device and add virtfn suffix. */ - vf_names.pcidev = vf_info.physfn_pcidev; + vf_names.pcidev = physfn_pcidev; dev_pci_onboard(dev, &vf_names); dev_pci_slot(dev, &vf_names); + if (vf_names.pci_onboard[0]) - if (strlen(vf_names.pci_onboard) + strlen(vf_info.suffix) < sizeof(names->pci_onboard)) + if (strlen(vf_names.pci_onboard) + strlen(virtfn_suffix) < sizeof(names->pci_onboard)) strscpyl(names->pci_onboard, sizeof(names->pci_onboard), - vf_names.pci_onboard, vf_info.suffix, NULL); + vf_names.pci_onboard, virtfn_suffix, NULL); if (vf_names.pci_slot[0]) - if (strlen(vf_names.pci_slot) + strlen(vf_info.suffix) < sizeof(names->pci_slot)) + if (strlen(vf_names.pci_slot) + strlen(virtfn_suffix) < sizeof(names->pci_slot)) strscpyl(names->pci_slot, sizeof(names->pci_slot), - vf_names.pci_slot, vf_info.suffix, NULL); + vf_names.pci_slot, virtfn_suffix, NULL); if (vf_names.pci_path[0]) - if (strlen(vf_names.pci_path) + strlen(vf_info.suffix) < sizeof(names->pci_path)) + if (strlen(vf_names.pci_path) + strlen(virtfn_suffix) < sizeof(names->pci_path)) strscpyl(names->pci_path, sizeof(names->pci_path), - vf_names.pci_path, vf_info.suffix, NULL); - sd_device_unref(vf_info.physfn_pcidev); + vf_names.pci_path, virtfn_suffix, NULL); } else { dev_pci_onboard(dev, names); dev_pci_slot(dev, names); From 92232230af6c1b0c76b7586db3c891c0e2860f4f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 30 Aug 2021 08:20:05 +0900 Subject: [PATCH 09/13] udev: pass rtnl to builtin commands --- src/udev/udev-builtin-blkid.c | 2 +- src/udev/udev-builtin-btrfs.c | 2 +- src/udev/udev-builtin-hwdb.c | 2 +- src/udev/udev-builtin-input_id.c | 2 +- src/udev/udev-builtin-keyboard.c | 2 +- src/udev/udev-builtin-kmod.c | 2 +- src/udev/udev-builtin-net_id.c | 2 +- src/udev/udev-builtin-net_setup_link.c | 2 +- src/udev/udev-builtin-path_id.c | 2 +- src/udev/udev-builtin-uaccess.c | 2 +- src/udev/udev-builtin-usb_id.c | 2 +- src/udev/udev-builtin.c | 4 ++-- src/udev/udev-builtin.h | 5 +++-- src/udev/udev-event.c | 2 +- src/udev/udev-rules.c | 2 +- src/udev/udevadm-test-builtin.c | 3 ++- 16 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c index cdb1df7c04d..586f083ffa7 100644 --- a/src/udev/udev-builtin-blkid.c +++ b/src/udev/udev-builtin-blkid.c @@ -233,7 +233,7 @@ static int probe_superblocks(blkid_probe pr) { return blkid_do_safeprobe(pr); } -static int builtin_blkid(sd_device *dev, int argc, char *argv[], bool test) { +static int builtin_blkid(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) { const char *devnode, *root_partition = NULL, *data, *name; _cleanup_(blkid_free_probep) blkid_probe pr = NULL; bool noraid = false, is_gpt = false; diff --git a/src/udev/udev-builtin-btrfs.c b/src/udev/udev-builtin-btrfs.c index 436bf6bd442..a0093cb4234 100644 --- a/src/udev/udev-builtin-btrfs.c +++ b/src/udev/udev-builtin-btrfs.c @@ -12,7 +12,7 @@ #include "udev-builtin.h" #include "util.h" -static int builtin_btrfs(sd_device *dev, int argc, char *argv[], bool test) { +static int builtin_btrfs(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) { struct btrfs_ioctl_vol_args args = {}; _cleanup_close_ int fd = -1; int r; diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c index 87535dbd005..1241c08f2c5 100644 --- a/src/udev/udev-builtin-hwdb.c +++ b/src/udev/udev-builtin-hwdb.c @@ -118,7 +118,7 @@ next: return r; } -static int builtin_hwdb(sd_device *dev, int argc, char *argv[], bool test) { +static int builtin_hwdb(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) { static const struct option options[] = { { "filter", required_argument, NULL, 'f' }, { "device", required_argument, NULL, 'd' }, diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c index 08a9e9c65d5..0e719108ed9 100644 --- a/src/udev/udev-builtin-input_id.c +++ b/src/udev/udev-builtin-input_id.c @@ -322,7 +322,7 @@ static bool test_key(sd_device *dev, return found; } -static int builtin_input_id(sd_device *dev, int argc, char *argv[], bool test) { +static int builtin_input_id(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) { sd_device *pdev; unsigned long bitmask_ev[NBITS(EV_MAX)]; unsigned long bitmask_abs[NBITS(ABS_MAX)]; diff --git a/src/udev/udev-builtin-keyboard.c b/src/udev/udev-builtin-keyboard.c index e6beb190660..cc266cc6634 100644 --- a/src/udev/udev-builtin-keyboard.c +++ b/src/udev/udev-builtin-keyboard.c @@ -159,7 +159,7 @@ static int set_trackpoint_sensitivity(sd_device *dev, const char *value) { return 0; } -static int builtin_keyboard(sd_device *dev, int argc, char *argv[], bool test) { +static int builtin_keyboard(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) { unsigned release[1024]; unsigned release_count = 0; _cleanup_close_ int fd = -1; diff --git a/src/udev/udev-builtin-kmod.c b/src/udev/udev-builtin-kmod.c index 0e31002b42e..bc6a11f2410 100644 --- a/src/udev/udev-builtin-kmod.c +++ b/src/udev/udev-builtin-kmod.c @@ -20,7 +20,7 @@ _printf_(6,0) static void udev_kmod_log(void *data, int priority, const char *fi log_internalv(priority, 0, file, line, fn, format, args); } -static int builtin_kmod(sd_device *dev, int argc, char *argv[], bool test) { +static int builtin_kmod(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) { if (!ctx) return 0; diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index f8a519af464..7b1ffbcfa63 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -863,7 +863,7 @@ static int ieee_oui(sd_device *dev, struct netnames *names, bool test) { return 0; } -static int builtin_net_id(sd_device *dev, int argc, char *argv[], bool test) { +static int builtin_net_id(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) { const char *s, *p, *devtype, *prefix = "en"; struct netnames names = {}; unsigned long i; diff --git a/src/udev/udev-builtin-net_setup_link.c b/src/udev/udev-builtin-net_setup_link.c index 5964e30bf1a..49492349b25 100644 --- a/src/udev/udev-builtin-net_setup_link.c +++ b/src/udev/udev-builtin-net_setup_link.c @@ -10,7 +10,7 @@ static LinkConfigContext *ctx = NULL; -static int builtin_net_setup_link(sd_device *dev, int argc, char **argv, bool test) { +static int builtin_net_setup_link(sd_device *dev, sd_netlink **rtnl, int argc, char **argv, bool test) { _cleanup_free_ char *driver = NULL; const char *name = NULL; LinkConfig *link; diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c index 083ce678036..de1f8dbaa11 100644 --- a/src/udev/udev-builtin-path_id.c +++ b/src/udev/udev-builtin-path_id.c @@ -530,7 +530,7 @@ static sd_device *handle_ap(sd_device *parent, char **path) { return skip_subsystem(parent, "ap"); } -static int builtin_path_id(sd_device *dev, int argc, char *argv[], bool test) { +static int builtin_path_id(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) { sd_device *parent; _cleanup_free_ char *path = NULL; _cleanup_free_ char *compat_path = NULL; diff --git a/src/udev/udev-builtin-uaccess.c b/src/udev/udev-builtin-uaccess.c index 3fdbb88bc4f..6e73d993755 100644 --- a/src/udev/udev-builtin-uaccess.c +++ b/src/udev/udev-builtin-uaccess.c @@ -16,7 +16,7 @@ #include "log.h" #include "udev-builtin.h" -static int builtin_uaccess(sd_device *dev, int argc, char *argv[], bool test) { +static int builtin_uaccess(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) { const char *path = NULL, *seat; bool changed_acl = false; uid_t uid; diff --git a/src/udev/udev-builtin-usb_id.c b/src/udev/udev-builtin-usb_id.c index 746fb40e645..d37469c62b1 100644 --- a/src/udev/udev-builtin-usb_id.c +++ b/src/udev/udev-builtin-usb_id.c @@ -224,7 +224,7 @@ static int dev_if_packed_info(sd_device *dev, char *ifs_str, size_t len) { * 6.) If the device supplies a serial number, this number * is concatenated with the identification with an underscore '_'. */ -static int builtin_usb_id(sd_device *dev, int argc, char *argv[], bool test) { +static int builtin_usb_id(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) { char vendor_str[64] = ""; char vendor_str_enc[256]; const char *vendor_id; diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c index 80d17662b20..a9095969bdc 100644 --- a/src/udev/udev-builtin.c +++ b/src/udev/udev-builtin.c @@ -107,7 +107,7 @@ UdevBuiltinCommand udev_builtin_lookup(const char *command) { return _UDEV_BUILTIN_INVALID; } -int udev_builtin_run(sd_device *dev, UdevBuiltinCommand cmd, const char *command, bool test) { +int udev_builtin_run(sd_device *dev, sd_netlink **rtnl, UdevBuiltinCommand cmd, const char *command, bool test) { _cleanup_strv_free_ char **argv = NULL; int r; @@ -124,7 +124,7 @@ int udev_builtin_run(sd_device *dev, UdevBuiltinCommand cmd, const char *command /* we need '0' here to reset the internal state */ optind = 0; - return builtins[cmd]->cmd(dev, strv_length(argv), argv, test); + return builtins[cmd]->cmd(dev, rtnl, strv_length(argv), argv, test); } int udev_builtin_add_property(sd_device *dev, bool test, const char *key, const char *val) { diff --git a/src/udev/udev-builtin.h b/src/udev/udev-builtin.h index 849e5d9e8d9..abfed2c181d 100644 --- a/src/udev/udev-builtin.h +++ b/src/udev/udev-builtin.h @@ -4,6 +4,7 @@ #include #include "sd-device.h" +#include "sd-netlink.h" typedef enum { #if HAVE_BLKID @@ -29,7 +30,7 @@ typedef enum { typedef struct UdevBuiltin { const char *name; - int (*cmd)(sd_device *dev, int argc, char *argv[], bool test); + int (*cmd)(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test); const char *help; int (*init)(void); void (*exit)(void); @@ -73,7 +74,7 @@ void udev_builtin_exit(void); UdevBuiltinCommand udev_builtin_lookup(const char *command); const char *udev_builtin_name(UdevBuiltinCommand cmd); bool udev_builtin_run_once(UdevBuiltinCommand cmd); -int udev_builtin_run(sd_device *dev, UdevBuiltinCommand cmd, const char *command, bool test); +int udev_builtin_run(sd_device *dev, sd_netlink **rtnl, UdevBuiltinCommand cmd, const char *command, bool test); void udev_builtin_list(void); bool udev_builtin_validate(void); int udev_builtin_add_property(sd_device *dev, bool test, const char *key, const char *val); diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 2179c8d254b..3dfdff71128 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -1073,7 +1073,7 @@ void udev_event_execute_run(UdevEvent *event, usec_t timeout_usec, int timeout_s if (builtin_cmd != _UDEV_BUILTIN_INVALID) { log_device_debug(event->dev, "Running built-in command \"%s\"", command); - r = udev_builtin_run(event->dev, builtin_cmd, command, false); + r = udev_builtin_run(event->dev, &event->rtnl, builtin_cmd, command, false); if (r < 0) log_device_debug_errno(event->dev, r, "Failed to run built-in command \"%s\", ignoring: %m", command); } else { diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index cb7de261d5a..3759ac84007 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -1829,7 +1829,7 @@ static int udev_rule_apply_token_to_event( (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false); log_rule_debug(dev, rules, "Importing properties from results of builtin command '%s'", buf); - r = udev_builtin_run(dev, cmd, buf, false); + r = udev_builtin_run(dev, &event->rtnl, cmd, buf, false); if (r < 0) { /* remember failure */ log_rule_debug_errno(dev, rules, r, "Failed to run builtin '%s': %m", buf); diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c index cae2950c8f5..c266e16849b 100644 --- a/src/udev/udevadm-test-builtin.c +++ b/src/udev/udevadm-test-builtin.c @@ -72,6 +72,7 @@ static int parse_argv(int argc, char *argv[]) { } int builtin_main(int argc, char *argv[], void *userdata) { + _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; _cleanup_(sd_device_unrefp) sd_device *dev = NULL; UdevBuiltinCommand cmd; int r; @@ -97,7 +98,7 @@ int builtin_main(int argc, char *argv[], void *userdata) { goto finish; } - r = udev_builtin_run(dev, cmd, arg_command, true); + r = udev_builtin_run(dev, &rtnl, cmd, arg_command, true); if (r < 0) log_debug_errno(r, "Builtin command '%s' fails: %m", arg_command); From 751dcd8d81144372f8db369c7cb727d1b6ac8f23 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 30 Aug 2021 08:30:12 +0900 Subject: [PATCH 10/13] udev: use passed rtnl in net_setup_link builtin command --- src/udev/net/link-config.c | 14 +++++++------- src/udev/net/link-config.h | 5 +++-- src/udev/udev-builtin-net_setup_link.c | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index 4963ba2fae8..14ca2e032e6 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -37,7 +37,6 @@ struct LinkConfigContext { LIST_HEAD(LinkConfig, links); int ethtool_fd; bool enable_name_policy; - sd_netlink *rtnl; usec_t network_dirs_ts_usec; }; @@ -78,7 +77,6 @@ LinkConfigContext *link_config_ctx_free(LinkConfigContext *ctx) { return NULL; safe_close(ctx->ethtool_fd); - sd_netlink_unref(ctx->rtnl); link_configs_free(ctx); return mfree(ctx); } @@ -239,7 +237,7 @@ bool link_config_should_reload(LinkConfigContext *ctx) { return paths_check_timestamp(NETWORK_DIRS, &ctx->network_dirs_ts_usec, false); } -int link_config_get(LinkConfigContext *ctx, sd_device *device, LinkConfig **ret) { +int link_config_get(LinkConfigContext *ctx, sd_netlink **rtnl, sd_device *device, LinkConfig **ret) { unsigned name_assign_type = NET_NAME_UNKNOWN; struct ether_addr permanent_mac = {}; unsigned short iftype; @@ -249,6 +247,7 @@ int link_config_get(LinkConfigContext *ctx, sd_device *device, LinkConfig **ret) int ifindex, r; assert(ctx); + assert(rtnl); assert(device); assert(ret); @@ -260,7 +259,7 @@ int link_config_get(LinkConfigContext *ctx, sd_device *device, LinkConfig **ret) if (r < 0) return r; - r = rtnl_get_link_info(&ctx->rtnl, ifindex, &iftype, &flags); + r = rtnl_get_link_info(rtnl, ifindex, &iftype, &flags); if (r < 0) return r; @@ -606,13 +605,14 @@ static int link_config_apply_alternative_names(sd_netlink **rtnl, const LinkConf return 0; } -int link_config_apply(LinkConfigContext *ctx, const LinkConfig *config, sd_device *device, const char **ret_name) { +int link_config_apply(LinkConfigContext *ctx, const LinkConfig *config, sd_netlink **rtnl, sd_device *device, const char **ret_name) { const char *new_name; sd_device_action_t a; int r; assert(ctx); assert(config); + assert(rtnl); assert(device); assert(ret_name); @@ -634,7 +634,7 @@ int link_config_apply(LinkConfigContext *ctx, const LinkConfig *config, sd_devic if (r < 0) return r; - r = link_config_apply_rtnl_settings(&ctx->rtnl, config, device); + r = link_config_apply_rtnl_settings(rtnl, config, device); if (r < 0) return r; @@ -650,7 +650,7 @@ int link_config_apply(LinkConfigContext *ctx, const LinkConfig *config, sd_devic return r; } - r = link_config_apply_alternative_names(&ctx->rtnl, config, device, new_name); + r = link_config_apply_alternative_names(rtnl, config, device, new_name); if (r < 0) return r; diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h index 8a29a928228..38a02a75b90 100644 --- a/src/udev/net/link-config.h +++ b/src/udev/net/link-config.h @@ -2,6 +2,7 @@ #pragma once #include "sd-device.h" +#include "sd-netlink.h" #include "condition.h" #include "conf-parser.h" @@ -77,8 +78,8 @@ int link_load_one(LinkConfigContext *ctx, const char *filename); int link_config_load(LinkConfigContext *ctx); bool link_config_should_reload(LinkConfigContext *ctx); -int link_config_get(LinkConfigContext *ctx, sd_device *device, LinkConfig **ret); -int link_config_apply(LinkConfigContext *ctx, const LinkConfig *config, sd_device *device, const char **ret_name); +int link_config_get(LinkConfigContext *ctx, sd_netlink **rtnl, sd_device *device, LinkConfig **ret); +int link_config_apply(LinkConfigContext *ctx, const LinkConfig *config, sd_netlink **rtnl, sd_device *device, const char **ret_name); int link_get_driver(LinkConfigContext *ctx, sd_device *device, char **ret); const char *name_policy_to_string(NamePolicy p) _const_; diff --git a/src/udev/udev-builtin-net_setup_link.c b/src/udev/udev-builtin-net_setup_link.c index 49492349b25..4c7a5b23fdb 100644 --- a/src/udev/udev-builtin-net_setup_link.c +++ b/src/udev/udev-builtin-net_setup_link.c @@ -26,7 +26,7 @@ static int builtin_net_setup_link(sd_device *dev, sd_netlink **rtnl, int argc, c else udev_builtin_add_property(dev, test, "ID_NET_DRIVER", driver); - r = link_config_get(ctx, dev, &link); + r = link_config_get(ctx, rtnl, dev, &link); if (r < 0) { if (r == -ENODEV) return log_device_debug_errno(dev, r, "Link vanished while searching for configuration for it."); @@ -38,7 +38,7 @@ static int builtin_net_setup_link(sd_device *dev, sd_netlink **rtnl, int argc, c return log_device_error_errno(dev, r, "Failed to get link config: %m"); } - r = link_config_apply(ctx, link, dev, &name); + r = link_config_apply(ctx, link, rtnl, dev, &name); if (r == -ENODEV) log_device_debug_errno(dev, r, "Link vanished while applying configuration, ignoring."); else if (r < 0) From d94ab1b27b71fbd7681b30afc788a27ceb4570dc Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 24 Aug 2021 02:22:12 +0900 Subject: [PATCH 11/13] udev: rename struct netnames -> NetNames --- src/udev/udev-builtin-net_id.c | 36 +++++++++++++++++----------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index 7b1ffbcfa63..b897d0e3096 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -39,7 +39,7 @@ #define ONBOARD_14BIT_INDEX_MAX ((1U << 14) - 1) #define ONBOARD_16BIT_INDEX_MAX ((1U << 16) - 1) -enum netname_type{ +typedef enum NetNameType { NET_UNDEF, NET_PCI, NET_USB, @@ -49,10 +49,10 @@ enum netname_type{ NET_VIO, NET_PLATFORM, NET_NETDEVSIM, -}; +} NetNameType; -struct netnames { - enum netname_type type; +typedef struct NetNames { + NetNameType type; uint8_t mac[6]; bool mac_valid; @@ -69,7 +69,7 @@ struct netnames { char vio_slot[ALTIFNAMSIZ]; char platform_path[ALTIFNAMSIZ]; char netdevsim_path[ALTIFNAMSIZ]; -}; +} NetNames; /* skip intermediate virtio devices */ static sd_device *skip_virtio(sd_device *dev) { @@ -164,7 +164,7 @@ static bool is_valid_onboard_index(unsigned long idx) { } /* retrieve on-board index number and label from firmware */ -static int dev_pci_onboard(sd_device *dev, struct netnames *names) { +static int dev_pci_onboard(sd_device *dev, NetNames *names) { unsigned long idx, dev_port = 0; const char *attr, *port_name = NULL; size_t l; @@ -306,7 +306,7 @@ static int parse_hotplug_slot_from_function_id(sd_device *dev, const char *slots return 1; } -static int dev_pci_slot(sd_device *dev, struct netnames *names) { +static int dev_pci_slot(sd_device *dev, NetNames *names) { const char *sysname, *attr, *port_name = NULL, *syspath; _cleanup_(sd_device_unrefp) sd_device *pci = NULL; _cleanup_closedir_ DIR *dir = NULL; @@ -459,7 +459,7 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) { return 0; } -static int names_vio(sd_device *dev, struct netnames *names) { +static int names_vio(sd_device *dev, NetNames *names) { sd_device *parent; unsigned busid, slotid, ethid; const char *syspath, *subsystem; @@ -496,7 +496,7 @@ static int names_vio(sd_device *dev, struct netnames *names) { #define _PLATFORM_PATTERN4 "/sys/devices/platform/%4s%4x:%2x/net/eth%u" #define _PLATFORM_PATTERN3 "/sys/devices/platform/%3s%4x:%2x/net/eth%u" -static int names_platform(sd_device *dev, struct netnames *names, bool test) { +static int names_platform(sd_device *dev, NetNames *names, bool test) { sd_device *parent; char vendor[5]; unsigned model, instance, ethid; @@ -551,7 +551,7 @@ static int names_platform(sd_device *dev, struct netnames *names, bool test) { return 0; } -static int names_pci(sd_device *dev, struct netnames *names) { +static int names_pci(sd_device *dev, NetNames *names) { _cleanup_(sd_device_unrefp) sd_device *physfn_pcidev = NULL; _cleanup_free_ char *virtfn_suffix = NULL; sd_device *parent; @@ -583,7 +583,7 @@ static int names_pci(sd_device *dev, struct netnames *names) { if (naming_scheme_has(NAMING_SR_IOV_V) && get_virtfn_info(names->pcidev, &physfn_pcidev, &virtfn_suffix) >= 0) { - struct netnames vf_names = {}; + NetNames vf_names = {}; /* If this is an SR-IOV virtual device, get base name using physical device and add virtfn suffix. */ vf_names.pcidev = physfn_pcidev; @@ -610,7 +610,7 @@ static int names_pci(sd_device *dev, struct netnames *names) { return 0; } -static int names_usb(sd_device *dev, struct netnames *names) { +static int names_usb(sd_device *dev, NetNames *names) { sd_device *usbdev; char name[256], *ports, *config, *interf, *s; const char *sysname; @@ -668,7 +668,7 @@ static int names_usb(sd_device *dev, struct netnames *names) { return 0; } -static int names_bcma(sd_device *dev, struct netnames *names) { +static int names_bcma(sd_device *dev, NetNames *names) { sd_device *bcmadev; unsigned core; const char *sysname; @@ -696,7 +696,7 @@ static int names_bcma(sd_device *dev, struct netnames *names) { return 0; } -static int names_ccw(sd_device *dev, struct netnames *names) { +static int names_ccw(sd_device *dev, NetNames *names) { sd_device *cdev; const char *bus_id, *subsys; size_t bus_id_len; @@ -754,7 +754,7 @@ static int names_ccw(sd_device *dev, struct netnames *names) { return 0; } -static int names_mac(sd_device *dev, struct netnames *names) { +static int names_mac(sd_device *dev, NetNames *names) { const char *s; unsigned long i; unsigned a1, a2, a3, a4, a5, a6; @@ -810,7 +810,7 @@ static int names_mac(sd_device *dev, struct netnames *names) { return 0; } -static int names_netdevsim(sd_device *dev, struct netnames *names) { +static int names_netdevsim(sd_device *dev, NetNames *names) { sd_device *netdevsimdev; const char *sysname; unsigned addr; @@ -848,7 +848,7 @@ static int names_netdevsim(sd_device *dev, struct netnames *names) { } /* IEEE Organizationally Unique Identifier vendor string */ -static int ieee_oui(sd_device *dev, struct netnames *names, bool test) { +static int ieee_oui(sd_device *dev, NetNames *names, bool test) { char str[32]; if (!names->mac_valid) @@ -865,7 +865,7 @@ static int ieee_oui(sd_device *dev, struct netnames *names, bool test) { static int builtin_net_id(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) { const char *s, *p, *devtype, *prefix = "en"; - struct netnames names = {}; + NetNames names = {}; unsigned long i; int r; From 8327fd1b11c5fb6529d46dfb40e2af981ffa8545 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 27 Aug 2021 17:02:59 +0900 Subject: [PATCH 12/13] udev: introduce link_info_get() --- src/udev/meson.build | 6 ++ src/udev/test-udev-builtin-net_id-netlink.c | 85 ++++++++++++++++++++ src/udev/udev-builtin-net_id-netlink.c | 87 +++++++++++++++++++++ src/udev/udev-builtin-net_id-netlink.h | 23 ++++++ 4 files changed, 201 insertions(+) create mode 100644 src/udev/test-udev-builtin-net_id-netlink.c create mode 100644 src/udev/udev-builtin-net_id-netlink.c create mode 100644 src/udev/udev-builtin-net_id-netlink.h diff --git a/src/udev/meson.build b/src/udev/meson.build index 87bb341a562..7de080348f6 100644 --- a/src/udev/meson.build +++ b/src/udev/meson.build @@ -33,6 +33,8 @@ libudevd_core_sources = ''' udev-builtin-hwdb.c udev-builtin-input_id.c udev-builtin-keyboard.c + udev-builtin-net_id-netlink.c + udev-builtin-net_id-netlink.h udev-builtin-net_id.c udev-builtin-net_setup_link.c udev-builtin-path_id.c @@ -210,6 +212,10 @@ tests += [ [threads, libacl]], + [['src/udev/test-udev-builtin-net_id-netlink.c', + 'src/udev/udev-builtin-net_id-netlink.c', + 'src/udev/udev-builtin-net_id-netlink.h']], + [['src/udev/fido_id/test-fido-id-desc.c', 'src/udev/fido_id/fido_id_desc.c']], ] diff --git a/src/udev/test-udev-builtin-net_id-netlink.c b/src/udev/test-udev-builtin-net_id-netlink.c new file mode 100644 index 00000000000..ee9fd675f1d --- /dev/null +++ b/src/udev/test-udev-builtin-net_id-netlink.c @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "sd-device.h" + +#include "arphrd-list.h" +#include "ether-addr-util.h" +#include "parse-util.h" +#include "tests.h" +#include "udev-builtin-net_id-netlink.h" + +static void test_link_info_one(sd_netlink *rtnl, int ifindex) { + _cleanup_(link_info_clear) LinkInfo info = LINK_INFO_NULL; + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; + unsigned iftype, iflink; + const char *s; + + log_debug("/* %s(ifindex=%i) */", __func__, ifindex); + + assert_se(link_info_get(&rtnl, ifindex, &info) >= 0); + assert_se(sd_device_new_from_ifindex(&dev, ifindex) >= 0); + + /* check iftype */ + log_debug("iftype: %"PRIu16" (%s)", info.iftype, strna(arphrd_to_name(info.iftype))); + assert_se(sd_device_get_sysattr_value(dev, "type", &s) >= 0); + assert_se(safe_atou(s, &iftype) >= 0); + assert_se(iftype == info.iftype); + + /* check hardware address */ + log_debug("hardware address: %s", HW_ADDR_TO_STR(&info.hw_addr)); + assert_se(sd_device_get_sysattr_value(dev, "address", &s) >= 0); + assert_se(streq(s, HW_ADDR_TO_STR(&info.hw_addr))); + + /* check ifname */ + log_debug("ifname: %s", info.ifname); + assert_se(sd_device_get_sysname(dev, &s) >= 0); + assert_se(streq(s, info.ifname)); + + /* check iflink */ + log_debug("iflink: %"PRIu32, info.iflink); + assert_se(sd_device_get_sysattr_value(dev, "iflink", &s) >= 0); + assert_se(safe_atou(s, &iflink) >= 0); + assert_se(iflink == info.iflink); + + /* check phys_port_name */ + log_debug("phys_port_name: %s (%s)", + strna(info.phys_port_name), + info.support_phys_port_name ? "supported" : "unsupported"); + if (info.support_phys_port_name) { + s = NULL; + (void) sd_device_get_sysattr_value(dev, "phys_port_name", &s); + assert_se(streq_ptr(s, info.phys_port_name)); + } +} + +static void test_link_info_get(void) { + _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL; + + log_debug("/* %s */", __func__); + + assert_se(sd_netlink_open(&rtnl) >= 0); + + assert_se(sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0) >= 0); + assert_se(sd_netlink_message_request_dump(req, true) >= 0); + assert_se(sd_netlink_call(rtnl, req, 0, &reply) >= 0); + + for (sd_netlink_message *reply_one = reply; reply_one; reply_one = sd_netlink_message_next(reply_one)) { + uint16_t nlmsg_type; + int ifindex; + + assert_se(sd_netlink_message_get_type(reply_one, &nlmsg_type) >= 0); + assert_se(nlmsg_type == RTM_NEWLINK); + assert_se(sd_rtnl_message_link_get_ifindex(reply_one, &ifindex) >= 0); + + test_link_info_one(rtnl, ifindex); + } +} + +int main(int argc, char *argv[]) { + test_setup_logging(LOG_DEBUG); + + test_link_info_get(); + + return 0; +} diff --git a/src/udev/udev-builtin-net_id-netlink.c b/src/udev/udev-builtin-net_id-netlink.c new file mode 100644 index 00000000000..7fcd2ecd170 --- /dev/null +++ b/src/udev/udev-builtin-net_id-netlink.c @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "netlink-util.h" +#include "udev-builtin-net_id-netlink.h" + +void link_info_clear(LinkInfo *info) { + if (!info) + return; + + info->ifname = mfree(info->ifname); + info->phys_port_name = mfree(info->phys_port_name); +} + +int link_info_get(sd_netlink **rtnl, int ifindex, LinkInfo *ret) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL; + _cleanup_(link_info_clear) LinkInfo info = LINK_INFO_NULL; + uint16_t nlmsg_type; + int r; + + assert(rtnl); + assert(ifindex > 0); + assert(ret); + + if (!*rtnl) { + r = sd_netlink_open(rtnl); + if (r < 0) + return r; + } + + r = sd_rtnl_message_new_link(*rtnl, &message, RTM_GETLINK, ifindex); + if (r < 0) + return r; + + r = sd_netlink_call(*rtnl, message, 0, &reply); + if (r == -EINVAL) + return -ENODEV; /* The device does not exist */ + if (r < 0) + return r; + + r = sd_netlink_message_get_type(reply, &nlmsg_type); + if (r < 0) + return r; + if (nlmsg_type != RTM_NEWLINK) + return -ENXIO; + + r = sd_rtnl_message_link_get_ifindex(reply, &info.ifindex); + if (r < 0) + return r; + if (info.ifindex != ifindex) + return -ENXIO; + + r = sd_rtnl_message_link_get_type(reply, &info.iftype); + if (r < 0) + return r; + + r = netlink_message_read_hw_addr(reply, IFLA_ADDRESS, &info.hw_addr); + if (r < 0 && r != -ENODATA) + return r; + + r = sd_netlink_message_read_string_strdup(reply, IFLA_IFNAME, &info.ifname); + if (r < 0) + return r; + + r = sd_netlink_message_read_u32(reply, IFLA_LINK, &info.iflink); + if (r == -ENODATA) + info.iflink = info.ifindex; + else if (r < 0) + return r; + + r = sd_netlink_message_read_string_strdup(reply, IFLA_PHYS_PORT_NAME, &info.phys_port_name); + if (r == -ENODATA) { + uint16_t max_attr; + + r = sd_netlink_message_get_max_attribute(reply, &max_attr); + if (r < 0) + return r; + + info.support_phys_port_name = max_attr >= IFLA_PHYS_PORT_NAME; + } else if (r >= 0) + info.support_phys_port_name = true; + else + return r; + + *ret = info; + info = LINK_INFO_NULL; + return 0; +} diff --git a/src/udev/udev-builtin-net_id-netlink.h b/src/udev/udev-builtin-net_id-netlink.h new file mode 100644 index 00000000000..286ac198b9f --- /dev/null +++ b/src/udev/udev-builtin-net_id-netlink.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "sd-netlink.h" + +#include "ether-addr-util.h" + +typedef struct LinkInfo { + int ifindex; + uint16_t iftype; /* ARPHRD_* */ + + struct hw_addr_data hw_addr; /* IFLA_ADDRESS */ + char *ifname; /* IFLA_IFNAME */ + uint32_t iflink; /* IFLA_LINK */ + char *phys_port_name; /* IFLA_PHYS_PORT_NAME */ + + bool support_phys_port_name; +} LinkInfo; + +#define LINK_INFO_NULL ((LinkInfo) {}) + +void link_info_clear(LinkInfo *info); +int link_info_get(sd_netlink **rtnl, int ifindex, LinkInfo *ret); From eaba9bb3e69635d2c490c5e1b0d262b763753e1d Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 31 Aug 2021 00:41:36 +0900 Subject: [PATCH 13/13] udev: use link information obtained through netlink --- src/udev/udev-builtin-net_id.c | 209 +++++++++++++++------------------ 1 file changed, 97 insertions(+), 112 deletions(-) diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index b897d0e3096..5a7c94207b6 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -15,10 +15,11 @@ #include #include #include -#include #include #include #include +#include +#include #include #include "alloc-util.h" @@ -34,6 +35,7 @@ #include "string-util.h" #include "strv.h" #include "strxcpyx.h" +#include "udev-builtin-net_id-netlink.h" #include "udev-builtin.h" #define ONBOARD_14BIT_INDEX_MAX ((1U << 14) - 1) @@ -54,9 +56,6 @@ typedef enum NetNameType { typedef struct NetNames { NetNameType type; - uint8_t mac[6]; - bool mac_valid; - sd_device *pcidev; char pci_slot[ALTIFNAMSIZ]; char pci_path[ALTIFNAMSIZ]; @@ -164,13 +163,17 @@ static bool is_valid_onboard_index(unsigned long idx) { } /* retrieve on-board index number and label from firmware */ -static int dev_pci_onboard(sd_device *dev, NetNames *names) { +static int dev_pci_onboard(sd_device *dev, const LinkInfo *info, NetNames *names) { unsigned long idx, dev_port = 0; - const char *attr, *port_name = NULL; + const char *attr; size_t l; char *s; int r; + assert(dev); + assert(info); + assert(names); + /* ACPI _DSM — device specific method for naming a PCI or PCI Express device */ if (sd_device_get_sysattr_value(names->pcidev, "acpi_index", &attr) < 0) { /* SMBIOS type 41 — Onboard Devices Extended Information */ @@ -195,14 +198,12 @@ static int dev_pci_onboard(sd_device *dev, NetNames *names) { log_device_debug_errno(dev, r, "Failed to parse dev_port, ignoring: %m"); } - /* kernel provided front panel port name for multiple port PCI device */ - (void) sd_device_get_sysattr_value(dev, "phys_port_name", &port_name); - s = names->pci_onboard; l = sizeof(names->pci_onboard); l = strpcpyf(&s, l, "o%lu", idx); - if (port_name) - l = strpcpyf(&s, l, "n%s", port_name); + if (!isempty(info->phys_port_name)) + /* kernel provided front panel port name for multiple port PCI device */ + l = strpcpyf(&s, l, "n%s", info->phys_port_name); else if (dev_port > 0) l = strpcpyf(&s, l, "d%lu", dev_port); if (l == 0) @@ -306,8 +307,8 @@ static int parse_hotplug_slot_from_function_id(sd_device *dev, const char *slots return 1; } -static int dev_pci_slot(sd_device *dev, NetNames *names) { - const char *sysname, *attr, *port_name = NULL, *syspath; +static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) { + const char *sysname, *attr, *syspath; _cleanup_(sd_device_unrefp) sd_device *pci = NULL; _cleanup_closedir_ DIR *dir = NULL; unsigned domain, bus, slot, func; @@ -318,6 +319,10 @@ static int dev_pci_slot(sd_device *dev, NetNames *names) { size_t l; int r; + assert(dev); + assert(info); + assert(names); + r = sd_device_get_sysname(names->pcidev, &sysname); if (r < 0) return r; @@ -356,9 +361,6 @@ static int dev_pci_slot(sd_device *dev, NetNames *names) { } } - /* kernel provided front panel port name for multi-port PCI device */ - (void) sd_device_get_sysattr_value(dev, "phys_port_name", &port_name); - /* compose a name based on the raw kernel's PCI bus, slot numbers */ s = names->pci_path; l = sizeof(names->pci_path); @@ -367,8 +369,9 @@ static int dev_pci_slot(sd_device *dev, NetNames *names) { l = strpcpyf(&s, l, "p%us%u", bus, slot); if (func > 0 || is_pci_multifunction(names->pcidev)) l = strpcpyf(&s, l, "f%u", func); - if (port_name) - l = strpcpyf(&s, l, "n%s", port_name); + if (!isempty(info->phys_port_name)) + /* kernel provided front panel port name for multi-port PCI device */ + l = strpcpyf(&s, l, "n%s", info->phys_port_name); else if (dev_port > 0) l = strpcpyf(&s, l, "d%lu", dev_port); if (l == 0) @@ -448,8 +451,8 @@ static int dev_pci_slot(sd_device *dev, NetNames *names) { l = strpcpyf(&s, l, "s%"PRIu32, hotplug_slot); if (func > 0 || is_pci_multifunction(names->pcidev)) l = strpcpyf(&s, l, "f%d", func); - if (port_name) - l = strpcpyf(&s, l, "n%s", port_name); + if (!isempty(info->phys_port_name)) + l = strpcpyf(&s, l, "n%s", info->phys_port_name); else if (dev_port > 0) l = strpcpyf(&s, l, "d%lu", dev_port); if (l == 0) @@ -551,7 +554,7 @@ static int names_platform(sd_device *dev, NetNames *names, bool test) { return 0; } -static int names_pci(sd_device *dev, NetNames *names) { +static int names_pci(sd_device *dev, const LinkInfo *info, NetNames *names) { _cleanup_(sd_device_unrefp) sd_device *physfn_pcidev = NULL; _cleanup_free_ char *virtfn_suffix = NULL; sd_device *parent; @@ -559,6 +562,7 @@ static int names_pci(sd_device *dev, NetNames *names) { int r; assert(dev); + assert(info); assert(names); r = sd_device_get_parent(dev, &parent); @@ -587,8 +591,8 @@ static int names_pci(sd_device *dev, NetNames *names) { /* If this is an SR-IOV virtual device, get base name using physical device and add virtfn suffix. */ vf_names.pcidev = physfn_pcidev; - dev_pci_onboard(dev, &vf_names); - dev_pci_slot(dev, &vf_names); + dev_pci_onboard(dev, info, &vf_names); + dev_pci_slot(dev, info, &vf_names); if (vf_names.pci_onboard[0]) if (strlen(vf_names.pci_onboard) + strlen(virtfn_suffix) < sizeof(names->pci_onboard)) @@ -603,8 +607,8 @@ static int names_pci(sd_device *dev, NetNames *names) { strscpyl(names->pci_path, sizeof(names->pci_path), vf_names.pci_path, virtfn_suffix, NULL); } else { - dev_pci_onboard(dev, names); - dev_pci_slot(dev, names); + dev_pci_onboard(dev, info, names); + dev_pci_slot(dev, info, names); } return 0; @@ -754,76 +758,49 @@ static int names_ccw(sd_device *dev, NetNames *names) { return 0; } -static int names_mac(sd_device *dev, NetNames *names) { +static int names_mac(sd_device *dev, const LinkInfo *info) { const char *s; - unsigned long i; - unsigned a1, a2, a3, a4, a5, a6; + unsigned i; int r; - /* Some kinds of devices tend to have hardware addresses - * that are impossible to use in an iface name. - */ - r = sd_device_get_sysattr_value(dev, "type", &s); - if (r < 0) - return r; + assert(dev); + assert(info); - r = safe_atolu_full(s, 10, &i); - if (r < 0) - return r; - switch (i) { - /* The persistent part of a hardware address of an InfiniBand NIC - * is 8 bytes long. We cannot fit this much in an iface name. - */ - case ARPHRD_INFINIBAND: - return -EINVAL; - default: - break; - } + /* The persistent part of a hardware address of an InfiniBand NIC is 8 bytes long. We cannot + * fit this much in an iface name. + * TODO: but it can be used as alternative names?? */ + if (info->iftype == ARPHRD_INFINIBAND || info->hw_addr.length != 6) + return -EOPNOTSUPP; /* check for NET_ADDR_PERM, skip random MAC addresses */ r = sd_device_get_sysattr_value(dev, "addr_assign_type", &s); if (r < 0) return r; - r = safe_atolu(s, &i); + r = safe_atou(s, &i); if (r < 0) return r; - if (i != 0) - return 0; - - r = sd_device_get_sysattr_value(dev, "address", &s); - if (r < 0) - return r; - if (sscanf(s, "%x:%x:%x:%x:%x:%x", &a1, &a2, &a3, &a4, &a5, &a6) != 6) + if (i != NET_ADDR_PERM) return -EINVAL; - /* skip empty MAC addresses */ - if (a1 + a2 + a3 + a4 + a5 + a6 == 0) - return -EINVAL; - - names->mac[0] = a1; - names->mac[1] = a2; - names->mac[2] = a3; - names->mac[3] = a4; - names->mac[4] = a5; - names->mac[5] = a6; - names->mac_valid = true; return 0; } -static int names_netdevsim(sd_device *dev, NetNames *names) { +static int names_netdevsim(sd_device *dev, const LinkInfo *info, NetNames *names) { sd_device *netdevsimdev; const char *sysname; unsigned addr; - const char *port_name = NULL; int r; - bool ok; if (!naming_scheme_has(NAMING_NETDEVSIM)) return 0; assert(dev); + assert(info); assert(names); + if (isempty(info->phys_port_name)) + return -EINVAL; + r = sd_device_get_parent_with_subsystem_devtype(dev, "netdevsim", NULL, &netdevsimdev); if (r < 0) return r; @@ -834,12 +811,7 @@ static int names_netdevsim(sd_device *dev, NetNames *names) { if (sscanf(sysname, "netdevsim%u", &addr) != 1) return -EINVAL; - r = sd_device_get_sysattr_value(dev, "phys_port_name", &port_name); - if (r < 0) - return r; - - ok = snprintf_ok(names->netdevsim_path, sizeof(names->netdevsim_path), "i%un%s", addr, port_name); - if (!ok) + if (!snprintf_ok(names->netdevsim_path, sizeof(names->netdevsim_path), "i%un%s", addr, info->phys_port_name)) return -ENOBUFS; names->type = NET_NETDEVSIM; @@ -848,36 +820,62 @@ static int names_netdevsim(sd_device *dev, NetNames *names) { } /* IEEE Organizationally Unique Identifier vendor string */ -static int ieee_oui(sd_device *dev, NetNames *names, bool test) { +static int ieee_oui(sd_device *dev, const LinkInfo *info, bool test) { char str[32]; - if (!names->mac_valid) - return -ENOENT; + assert(dev); + assert(info); + + if (info->hw_addr.length != 6) + return -EOPNOTSUPP; + /* skip commonly misused 00:00:00 (Xerox) prefix */ - if (memcmp(names->mac, "\0\0\0", 3) == 0) + if (info->hw_addr.bytes[0] == 0 && + info->hw_addr.bytes[1] == 0 && + info->hw_addr.bytes[2] == 0) return -EINVAL; - xsprintf(str, "OUI:%02X%02X%02X%02X%02X%02X", names->mac[0], - names->mac[1], names->mac[2], names->mac[3], names->mac[4], - names->mac[5]); - udev_builtin_hwdb_lookup(dev, NULL, str, NULL, test); - return 0; + + xsprintf(str, "OUI:%02X%02X%02X%02X%02X%02X", + info->hw_addr.bytes[0], + info->hw_addr.bytes[1], + info->hw_addr.bytes[2], + info->hw_addr.bytes[3], + info->hw_addr.bytes[4], + info->hw_addr.bytes[5]); + return udev_builtin_hwdb_lookup(dev, NULL, str, NULL, test); } static int builtin_net_id(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) { - const char *s, *p, *devtype, *prefix = "en"; + _cleanup_(link_info_clear) LinkInfo info = LINK_INFO_NULL; + const char *devtype, *prefix = "en"; NetNames names = {}; - unsigned long i; - int r; + int ifindex, r; + + r = sd_device_get_ifindex(dev, &ifindex); + if (r < 0) + return r; + + r = link_info_get(rtnl, ifindex, &info); + if (r < 0) + return r; + + if (!info.support_phys_port_name) { + const char *s; + + r = sd_device_get_sysattr_value(dev, "phys_port_name", &s); + if (r >= 0) { + info.phys_port_name = strdup(s); + if (!info.phys_port_name) + return log_oom(); + } + } + + /* skip stacked devices, like VLANs, ... */ + if (info.ifindex != (int) info.iflink) + return 0; /* handle only ARPHRD_ETHER, ARPHRD_SLIP and ARPHRD_INFINIBAND devices */ - r = sd_device_get_sysattr_value(dev, "type", &s); - if (r < 0) - return r; - - r = safe_atolu_full(s, 10, &i); - if (r < 0) - return r; - switch (i) { + switch (info.iftype) { case ARPHRD_ETHER: prefix = "en"; break; @@ -894,16 +892,6 @@ static int builtin_net_id(sd_device *dev, sd_netlink **rtnl, int argc, char *arg return 0; } - /* skip stacked devices, like VLANs, ... */ - r = sd_device_get_sysattr_value(dev, "ifindex", &s); - if (r < 0) - return r; - r = sd_device_get_sysattr_value(dev, "iflink", &p); - if (r < 0) - return r; - if (!streq(s, p)) - return 0; - if (sd_device_get_devtype(dev, &devtype) >= 0) { if (streq("wlan", devtype)) prefix = "wl"; @@ -913,16 +901,13 @@ static int builtin_net_id(sd_device *dev, sd_netlink **rtnl, int argc, char *arg udev_builtin_add_property(dev, test, "ID_NET_NAMING_SCHEME", naming_scheme()->name); - r = names_mac(dev, &names); - if (r >= 0 && names.mac_valid) { + if (names_mac(dev, &info) >= 0) { char str[ALTIFNAMSIZ]; - xsprintf(str, "%sx%02x%02x%02x%02x%02x%02x", prefix, - names.mac[0], names.mac[1], names.mac[2], - names.mac[3], names.mac[4], names.mac[5]); + xsprintf(str, "%s%s", prefix, HW_ADDR_TO_STR(&info.hw_addr)); udev_builtin_add_property(dev, test, "ID_NET_NAME_MAC", str); - ieee_oui(dev, &names, test); + ieee_oui(dev, &info, test); } /* get path names for Linux on System z network devices */ @@ -953,7 +938,7 @@ static int builtin_net_id(sd_device *dev, sd_netlink **rtnl, int argc, char *arg } /* get netdevsim path names */ - if (names_netdevsim(dev, &names) >= 0 && names.type == NET_NETDEVSIM) { + if (names_netdevsim(dev, &info, &names) >= 0 && names.type == NET_NETDEVSIM) { char str[ALTIFNAMSIZ]; if (snprintf_ok(str, sizeof str, "%s%s", prefix, names.netdevsim_path)) @@ -963,7 +948,7 @@ static int builtin_net_id(sd_device *dev, sd_netlink **rtnl, int argc, char *arg } /* get PCI based path names, we compose only PCI based paths */ - if (names_pci(dev, &names) < 0) + if (names_pci(dev, &info, &names) < 0) return 0; /* plain PCI device */