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