]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-rtnl/rtnl-types.c
networkd: use valid bus paths
[thirdparty/systemd.git] / src / libsystemd / sd-rtnl / rtnl-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
22#include <stddef.h>
23#include <stdint.h>
24#include <sys/socket.h>
25#include <linux/netlink.h>
26#include <linux/rtnetlink.h>
27#include <linux/in6.h>
28#include <linux/veth.h>
29#include <linux/if_bridge.h>
30#include <linux/if_addr.h>
31#include <linux/if.h>
32
0a827d10 33#include <linux/ip.h>
c4a5ddc9 34#include <linux/if_link.h>
0a827d10
SS
35#include <linux/if_tunnel.h>
36
d8e538ec
TG
37#include "macro.h"
38#include "util.h"
39
40#include "rtnl-types.h"
0830ba61 41#include "missing.h"
d8e538ec
TG
42
43static const NLTypeSystem rtnl_link_type_system;
44
45static const NLType rtnl_link_info_data_veth_types[VETH_INFO_MAX + 1] = {
46 [VETH_INFO_PEER] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
47};
48
c4a5ddc9
TG
49static const NLType rtnl_link_info_data_ipvlan_types[IFLA_IPVLAN_MAX + 1] = {
50 [IFLA_IPVLAN_MODE] = { .type = NLA_U16 },
51};
d8e538ec
TG
52
53static const NLType rtnl_link_info_data_macvlan_types[IFLA_MACVLAN_MAX + 1] = {
54 [IFLA_MACVLAN_MODE] = { .type = NLA_U32 },
55 [IFLA_MACVLAN_FLAGS] = { .type = NLA_U16 },
56};
57
58static const NLType rtnl_link_info_data_bridge_types[IFLA_BRIDGE_MAX + 1] = {
59 [IFLA_BRIDGE_FLAGS] = { .type = NLA_U16 },
60 [IFLA_BRIDGE_MODE] = { .type = NLA_U16 },
61/*
62 [IFLA_BRIDGE_VLAN_INFO] = { .type = NLA_BINARY,
63 .len = sizeof(struct bridge_vlan_info), },
64*/
65};
66
67static const NLType rtnl_link_info_data_vlan_types[IFLA_VLAN_MAX + 1] = {
68 [IFLA_VLAN_ID] = { .type = NLA_U16 },
69/*
70 [IFLA_VLAN_FLAGS] = { .len = sizeof(struct ifla_vlan_flags) },
71 [IFLA_VLAN_EGRESS_QOS] = { .type = NLA_NESTED },
72 [IFLA_VLAN_INGRESS_QOS] = { .type = NLA_NESTED },
73*/
74 [IFLA_VLAN_PROTOCOL] = { .type = NLA_U16 },
75};
76
6ef81477
SS
77static const NLType rtnl_link_info_data_vxlan_types[IFLA_VXLAN_MAX+1] = {
78 [IFLA_VXLAN_ID] = { .type = NLA_U32 },
79 [IFLA_VXLAN_GROUP] = {.type = NLA_IN_ADDR },
80 [IFLA_VXLAN_LINK] = { .type = NLA_U32 },
81 [IFLA_VXLAN_LOCAL] = { .type = NLA_U32},
82 [IFLA_VXLAN_TTL] = { .type = NLA_U8 },
83 [IFLA_VXLAN_TOS] = { .type = NLA_U8 },
84 [IFLA_VXLAN_LEARNING] = { .type = NLA_U8 },
85 [IFLA_VXLAN_AGEING] = { .type = NLA_U32 },
86 [IFLA_VXLAN_LIMIT] = { .type = NLA_U32 },
87 [IFLA_VXLAN_PORT_RANGE] = { .type = NLA_U32},
88 [IFLA_VXLAN_PROXY] = { .type = NLA_U8 },
89 [IFLA_VXLAN_RSC] = { .type = NLA_U8 },
90 [IFLA_VXLAN_L2MISS] = { .type = NLA_U8 },
91 [IFLA_VXLAN_L3MISS] = { .type = NLA_U8 },
92};
93
d8e538ec
TG
94static const NLType rtnl_link_info_data_bond_types[IFLA_BOND_MAX + 1] = {
95 [IFLA_BOND_MODE] = { .type = NLA_U8 },
96 [IFLA_BOND_ACTIVE_SLAVE] = { .type = NLA_U32 },
d8e538ec
TG
97 [IFLA_BOND_MIIMON] = { .type = NLA_U32 },
98 [IFLA_BOND_UPDELAY] = { .type = NLA_U32 },
99 [IFLA_BOND_DOWNDELAY] = { .type = NLA_U32 },
100 [IFLA_BOND_USE_CARRIER] = { .type = NLA_U8 },
101 [IFLA_BOND_ARP_INTERVAL] = { .type = NLA_U32 },
d8e538ec 102 [IFLA_BOND_ARP_IP_TARGET] = { .type = NLA_NESTED },
d8e538ec
TG
103 [IFLA_BOND_ARP_VALIDATE] = { .type = NLA_U32 },
104 [IFLA_BOND_ARP_ALL_TARGETS] = { .type = NLA_U32 },
105 [IFLA_BOND_PRIMARY] = { .type = NLA_U32 },
106 [IFLA_BOND_PRIMARY_RESELECT] = { .type = NLA_U8 },
107 [IFLA_BOND_FAIL_OVER_MAC] = { .type = NLA_U8 },
108 [IFLA_BOND_XMIT_HASH_POLICY] = { .type = NLA_U8 },
109 [IFLA_BOND_RESEND_IGMP] = { .type = NLA_U32 },
110 [IFLA_BOND_NUM_PEER_NOTIF] = { .type = NLA_U8 },
111 [IFLA_BOND_ALL_SLAVES_ACTIVE] = { .type = NLA_U8 },
112 [IFLA_BOND_MIN_LINKS] = { .type = NLA_U32 },
113 [IFLA_BOND_LP_INTERVAL] = { .type = NLA_U32 },
114 [IFLA_BOND_PACKETS_PER_SLAVE] = { .type = NLA_U32 },
115 [IFLA_BOND_AD_LACP_RATE] = { .type = NLA_U8 },
116 [IFLA_BOND_AD_SELECT] = { .type = NLA_U8 },
d8e538ec 117 [IFLA_BOND_AD_INFO] = { .type = NLA_NESTED },
d8e538ec
TG
118};
119
0a827d10
SS
120static const NLType rtnl_link_info_data_iptun_types[IFLA_IPTUN_MAX + 1] = {
121 [IFLA_IPTUN_LINK] = { .type = NLA_U32 },
7951dea2
SS
122 [IFLA_IPTUN_LOCAL] = { .type = NLA_IN_ADDR },
123 [IFLA_IPTUN_REMOTE] = { .type = NLA_IN_ADDR },
0a827d10
SS
124 [IFLA_IPTUN_TTL] = { .type = NLA_U8 },
125 [IFLA_IPTUN_TOS] = { .type = NLA_U8 },
126 [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 },
127 [IFLA_IPTUN_FLAGS] = { .type = NLA_U16 },
128 [IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
129 [IFLA_IPTUN_6RD_PREFIX] = { .type = NLA_IN_ADDR },
130 [IFLA_IPTUN_6RD_RELAY_PREFIX] = { .type = NLA_U32 },
131 [IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NLA_U16 },
132 [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NLA_U16 },
133};
134
8bb088c5
SS
135static const NLType rtnl_link_info_data_ipgre_types[IFLA_GRE_MAX + 1] = {
136 [IFLA_GRE_LINK] = { .type = NLA_U32 },
137 [IFLA_GRE_IFLAGS] = { .type = NLA_U16 },
138 [IFLA_GRE_OFLAGS] = { .type = NLA_U16 },
139 [IFLA_GRE_IKEY] = { .type = NLA_U32 },
140 [IFLA_GRE_OKEY] = { .type = NLA_U32 },
141 [IFLA_GRE_LOCAL] = { .type = NLA_IN_ADDR },
142 [IFLA_GRE_REMOTE] = { .type = NLA_IN_ADDR },
143 [IFLA_GRE_TTL] = { .type = NLA_U8 },
144 [IFLA_GRE_TOS] = { .type = NLA_U8 },
145 [IFLA_GRE_PMTUDISC] = { .type = NLA_U8 },
146};
147
a613382b
SS
148static const NLType rtnl_link_info_data_ipvti_types[IFLA_VTI_MAX + 1] = {
149 [IFLA_VTI_LINK] = { .type = NLA_U32 },
150 [IFLA_VTI_IKEY] = { .type = NLA_U32 },
151 [IFLA_VTI_OKEY] = { .type = NLA_U32 },
152 [IFLA_VTI_LOCAL] = { .type = NLA_IN_ADDR },
153 [IFLA_VTI_REMOTE] = { .type = NLA_IN_ADDR },
154};
155
855ee1a1
SS
156static const NLType rtnl_link_info_data_ip6tnl_types[IFLA_IPTUN_MAX + 1] = {
157 [IFLA_IPTUN_LINK] = { .type = NLA_U32 },
158 [IFLA_IPTUN_LOCAL] = { .type = NLA_IN_ADDR },
159 [IFLA_IPTUN_REMOTE] = { .type = NLA_IN_ADDR },
160 [IFLA_IPTUN_TTL] = { .type = NLA_U8 },
161 [IFLA_IPTUN_FLAGS] = { .type = NLA_U32 },
162 [IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
163 [IFLA_IPTUN_ENCAP_LIMIT] = { .type = NLA_U8 },
164 [IFLA_IPTUN_FLOWINFO] = { .type = NLA_U32},
165};
166
0a827d10 167/* these strings must match the .kind entries in the kernel */
d8e538ec
TG
168static const char* const nl_union_link_info_data_table[_NL_UNION_LINK_INFO_DATA_MAX] = {
169 [NL_UNION_LINK_INFO_DATA_BOND] = "bond",
170 [NL_UNION_LINK_INFO_DATA_BRIDGE] = "bridge",
171 [NL_UNION_LINK_INFO_DATA_VLAN] = "vlan",
172 [NL_UNION_LINK_INFO_DATA_VETH] = "veth",
9e358851 173 [NL_UNION_LINK_INFO_DATA_DUMMY] = "dummy",
d8e538ec 174 [NL_UNION_LINK_INFO_DATA_MACVLAN] = "macvlan",
c4a5ddc9 175 [NL_UNION_LINK_INFO_DATA_IPVLAN] = "ipvlan",
6ef81477 176 [NL_UNION_LINK_INFO_DATA_VXLAN] = "vxlan",
0a827d10 177 [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = "ipip",
8bb088c5 178 [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = "gre",
1af2536a 179 [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = "gretap",
b16492f8
SS
180 [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = "ip6gre",
181 [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = "ip6gretap",
0a827d10 182 [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = "sit",
a613382b 183 [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = "vti",
855ee1a1 184 [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = "ip6tnl",
d8e538ec
TG
185};
186
187DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData);
188
189static const NLTypeSystem rtnl_link_info_data_type_systems[_NL_UNION_LINK_INFO_DATA_MAX] = {
0a827d10
SS
190 [NL_UNION_LINK_INFO_DATA_BOND] = { .max = ELEMENTSOF(rtnl_link_info_data_bond_types) - 1,
191 .types = rtnl_link_info_data_bond_types },
192 [NL_UNION_LINK_INFO_DATA_BRIDGE] = { .max = ELEMENTSOF(rtnl_link_info_data_bridge_types) - 1,
193 .types = rtnl_link_info_data_bridge_types },
194 [NL_UNION_LINK_INFO_DATA_VLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_vlan_types) - 1,
195 .types = rtnl_link_info_data_vlan_types },
196 [NL_UNION_LINK_INFO_DATA_VETH] = { .max = ELEMENTSOF(rtnl_link_info_data_veth_types) - 1,
197 .types = rtnl_link_info_data_veth_types },
198 [NL_UNION_LINK_INFO_DATA_MACVLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_macvlan_types) - 1,
199 .types = rtnl_link_info_data_macvlan_types },
c4a5ddc9
TG
200 [NL_UNION_LINK_INFO_DATA_IPVLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvlan_types) - 1,
201 .types = rtnl_link_info_data_ipvlan_types },
6ef81477
SS
202 [NL_UNION_LINK_INFO_DATA_VXLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_vxlan_types) - 1,
203 .types = rtnl_link_info_data_vxlan_types },
0a827d10
SS
204 [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1,
205 .types = rtnl_link_info_data_iptun_types },
8bb088c5
SS
206 [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
207 .types = rtnl_link_info_data_ipgre_types },
1af2536a
SS
208 [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
209 .types = rtnl_link_info_data_ipgre_types },
b16492f8
SS
210 [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
211 .types = rtnl_link_info_data_ipgre_types },
212 [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
213 .types = rtnl_link_info_data_ipgre_types },
0a827d10
SS
214 [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1,
215 .types = rtnl_link_info_data_iptun_types },
a613382b
SS
216 [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvti_types) - 1,
217 .types = rtnl_link_info_data_ipvti_types },
855ee1a1
SS
218 [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types) - 1,
219 .types = rtnl_link_info_data_ip6tnl_types },
220
d8e538ec
TG
221};
222
223static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = {
224 .num = _NL_UNION_LINK_INFO_DATA_MAX,
225 .lookup = nl_union_link_info_data_from_string,
226 .type_systems = rtnl_link_info_data_type_systems,
227 .match = IFLA_INFO_KIND,
228};
229
230static const NLType rtnl_link_info_types[IFLA_INFO_MAX + 1] = {
231 [IFLA_INFO_KIND] = { .type = NLA_STRING },
232 [IFLA_INFO_DATA] = { .type = NLA_UNION, .type_system_union = &rtnl_link_info_data_type_system_union},
233/*
234 [IFLA_INFO_XSTATS],
235 [IFLA_INFO_SLAVE_KIND] = { .type = NLA_STRING },
236 [IFLA_INFO_SLAVE_DATA] = { .type = NLA_NESTED },
237*/
238};
239
240static const NLTypeSystem rtnl_link_info_type_system = {
241 .max = ELEMENTSOF(rtnl_link_info_types) - 1,
242 .types = rtnl_link_info_types,
243};
244
d0159fdc
SS
245static const struct NLType rtnl_bridge_port_types[IFLA_BRPORT_MAX + 1] = {
246 [IFLA_BRPORT_STATE] = { .type = NLA_U8 },
247 [IFLA_BRPORT_COST] = { .type = NLA_U32 },
248 [IFLA_BRPORT_PRIORITY] = { .type = NLA_U16 },
249 [IFLA_BRPORT_MODE] = { .type = NLA_U8 },
250 [IFLA_BRPORT_GUARD] = { .type = NLA_U8 },
251 [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 },
252 [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 },
253 [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 },
254};
255
256static const NLTypeSystem rtnl_bridge_port_type_system = {
257 .max = ELEMENTSOF(rtnl_bridge_port_types) - 1,
258 .types = rtnl_bridge_port_types,
259};
260
261static const NLType rtnl_link_types[IFLA_MAX + 1 ] = {
d8e538ec
TG
262 [IFLA_ADDRESS] = { .type = NLA_ETHER_ADDR, },
263 [IFLA_BROADCAST] = { .type = NLA_ETHER_ADDR, },
264 [IFLA_IFNAME] = { .type = NLA_STRING, .size = IFNAMSIZ - 1, },
265 [IFLA_MTU] = { .type = NLA_U32 },
266 [IFLA_LINK] = { .type = NLA_U32 },
267/*
268 [IFLA_QDISC],
269 [IFLA_STATS],
270 [IFLA_COST],
271 [IFLA_PRIORITY],
272*/
273 [IFLA_MASTER] = { .type = NLA_U32 },
274/*
275 [IFLA_WIRELESS],
276 [IFLA_PROTINFO],
277*/
d0159fdc 278 [IFLA_PROTINFO] = { .type = NLA_NESTED, .type_system = &rtnl_bridge_port_type_system },
d8e538ec
TG
279 [IFLA_TXQLEN] = { .type = NLA_U32 },
280/*
281 [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) },
282*/
283 [IFLA_WEIGHT] = { .type = NLA_U32 },
284 [IFLA_OPERSTATE] = { .type = NLA_U8 },
285 [IFLA_LINKMODE] = { .type = NLA_U8 },
286 [IFLA_LINKINFO] = { .type = NLA_NESTED, .type_system = &rtnl_link_info_type_system },
287 [IFLA_NET_NS_PID] = { .type = NLA_U32 },
288 [IFLA_IFALIAS] = { .type = NLA_STRING, .size = IFALIASZ - 1 },
289/*
290 [IFLA_NUM_VF],
291 [IFLA_VFINFO_LIST] = {. type = NLA_NESTED, },
292 [IFLA_STATS64],
293 [IFLA_VF_PORTS] = { .type = NLA_NESTED },
294 [IFLA_PORT_SELF] = { .type = NLA_NESTED },
295 [IFLA_AF_SPEC] = { .type = NLA_NESTED },
296 [IFLA_VF_PORTS],
297 [IFLA_PORT_SELF],
298 [IFLA_AF_SPEC],
299*/
300 [IFLA_GROUP] = { .type = NLA_U32 },
301 [IFLA_NET_NS_FD] = { .type = NLA_U32 },
302 [IFLA_EXT_MASK] = { .type = NLA_U32 },
303 [IFLA_PROMISCUITY] = { .type = NLA_U32 },
304 [IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 },
305 [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
306 [IFLA_CARRIER] = { .type = NLA_U8 },
307/*
308 [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
309*/
310};
311
312static const NLTypeSystem rtnl_link_type_system = {
313 .max = ELEMENTSOF(rtnl_link_types) - 1,
314 .types = rtnl_link_types,
315};
316
317static const NLType rtnl_address_types[IFA_MAX + 1] = {
318 [IFA_ADDRESS] = { .type = NLA_IN_ADDR },
319 [IFA_LOCAL] = { .type = NLA_IN_ADDR },
320 [IFA_LABEL] = { .type = NLA_STRING, .size = IFNAMSIZ - 1 },
321 [IFA_BROADCAST] = { .type = NLA_IN_ADDR }, /* 6? */
aba496a5 322 [IFA_CACHEINFO] = { .type = NLA_CACHE_INFO, .size = sizeof(struct ifa_cacheinfo) },
d8e538ec
TG
323/*
324 [IFA_ANYCAST],
d8e538ec
TG
325 [IFA_MULTICAST],
326*/
327#ifdef IFA_FLAGS
328 [IFA_FLAGS] = { .type = NLA_U32 },
329#endif
330};
331
332static const NLTypeSystem rtnl_address_type_system = {
333 .max = ELEMENTSOF(rtnl_address_types) - 1,
334 .types = rtnl_address_types,
335};
336
337static const NLType rtnl_route_types[RTA_MAX + 1] = {
338 [RTA_DST] = { .type = NLA_IN_ADDR }, /* 6? */
339 [RTA_SRC] = { .type = NLA_IN_ADDR }, /* 6? */
340 [RTA_IIF] = { .type = NLA_U32 },
341 [RTA_OIF] = { .type = NLA_U32 },
342 [RTA_GATEWAY] = { .type = NLA_IN_ADDR },
343 [RTA_PRIORITY] = { .type = NLA_U32 },
344 [RTA_PREFSRC] = { .type = NLA_IN_ADDR }, /* 6? */
345/*
346 [RTA_METRICS] = { .type = NLA_NESTED },
347 [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) },
348*/
349 [RTA_FLOW] = { .type = NLA_U32 }, /* 6? */
350/*
351 RTA_CACHEINFO,
352 RTA_TABLE,
353 RTA_MARK,
354 RTA_MFC_STATS,
355*/
356};
357
358static const NLTypeSystem rtnl_route_type_system = {
359 .max = ELEMENTSOF(rtnl_route_types) - 1,
360 .types = rtnl_route_types,
361};
362
e559b384
TG
363static const NLType rtnl_neigh_types[NDA_MAX + 1] = {
364 [NDA_DST] = { .type = NLA_IN_ADDR },
365 [NDA_LLADDR] = { .type = NLA_ETHER_ADDR },
b98b483b
AR
366 [NDA_CACHEINFO] = { .type = NLA_CACHE_INFO, .size = sizeof(struct nda_cacheinfo) },
367 [NDA_PROBES] = { .type = NLA_U32 },
368 [NDA_VLAN] = { .type = NLA_U16 },
369 [NDA_PORT] = { .type = NLA_U16 },
370 [NDA_VNI] = { .type = NLA_U32 },
371 [NDA_IFINDEX] = { .type = NLA_U32 },
e559b384
TG
372};
373
374static const NLTypeSystem rtnl_neigh_type_system = {
375 .max = ELEMENTSOF(rtnl_neigh_types) - 1,
376 .types = rtnl_neigh_types,
377};
378
d8e538ec
TG
379static const NLType rtnl_types[RTM_MAX + 1] = {
380 [NLMSG_ERROR] = { .type = NLA_META, .size = sizeof(struct nlmsgerr) },
381 [RTM_NEWLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
382 [RTM_DELLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
383 [RTM_GETLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
384 [RTM_SETLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
385 [RTM_NEWADDR] = { .type = NLA_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
386 [RTM_DELADDR] = { .type = NLA_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
387 [RTM_GETADDR] = { .type = NLA_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
388 [RTM_NEWROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
389 [RTM_DELROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
390 [RTM_GETROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
e559b384
TG
391 [RTM_NEWNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
392 [RTM_DELNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
393 [RTM_GETNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
d8e538ec
TG
394};
395
396const NLTypeSystem rtnl_type_system = {
397 .max = ELEMENTSOF(rtnl_types) - 1,
398 .types = rtnl_types,
399};
400
401int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) {
402 const NLType *nl_type;
403
404 assert(ret);
405
406 if (!type_system)
407 type_system = &rtnl_type_system;
408
409 assert(type_system->types);
410
411 if (type > type_system->max)
412 return -ENOTSUP;
413
414 nl_type = &type_system->types[type];
415
416 if (nl_type->type == NLA_UNSPEC)
417 return -ENOTSUP;
418
419 *ret = nl_type;
420
421 return 0;
422}
423
424int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSystem **ret, uint16_t type) {
425 const NLType *nl_type;
426 int r;
427
428 assert(ret);
429
430 r = type_system_get_type(type_system, &nl_type, type);
431 if (r < 0)
432 return r;
433
434 assert_return(nl_type->type == NLA_NESTED, -EINVAL);
435
436 assert(nl_type->type_system);
437
438 *ret = nl_type->type_system;
439
440 return 0;
441}
442
443int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLTypeSystemUnion **ret, uint16_t type) {
444 const NLType *nl_type;
445 int r;
446
447 assert(ret);
448
449 r = type_system_get_type(type_system, &nl_type, type);
450 if (r < 0)
451 return r;
452
453 assert_return(nl_type->type == NLA_UNION, -EINVAL);
454
455 assert(nl_type->type_system_union);
456
457 *ret = nl_type->type_system_union;
458
459 return 0;
460}
461
462int type_system_union_get_type_system(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, const char *key) {
463 int type;
464
465 assert(type_system_union);
466 assert(type_system_union->lookup);
467 assert(type_system_union->type_systems);
468 assert(ret);
469 assert(key);
470
471 type = type_system_union->lookup(key);
472 if (type < 0)
473 return -ENOTSUP;
474
475 assert(type < type_system_union->num);
476
477 *ret = &type_system_union->type_systems[type];
478
479 return 0;
480}