]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-rtnl/rtnl-types.c
networkd: introduce gretap
[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
0a827d10 156/* these strings must match the .kind entries in the kernel */
d8e538ec
TG
157static const char* const nl_union_link_info_data_table[_NL_UNION_LINK_INFO_DATA_MAX] = {
158 [NL_UNION_LINK_INFO_DATA_BOND] = "bond",
159 [NL_UNION_LINK_INFO_DATA_BRIDGE] = "bridge",
160 [NL_UNION_LINK_INFO_DATA_VLAN] = "vlan",
161 [NL_UNION_LINK_INFO_DATA_VETH] = "veth",
9e358851 162 [NL_UNION_LINK_INFO_DATA_DUMMY] = "dummy",
d8e538ec 163 [NL_UNION_LINK_INFO_DATA_MACVLAN] = "macvlan",
c4a5ddc9 164 [NL_UNION_LINK_INFO_DATA_IPVLAN] = "ipvlan",
6ef81477 165 [NL_UNION_LINK_INFO_DATA_VXLAN] = "vxlan",
0a827d10 166 [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = "ipip",
8bb088c5 167 [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = "gre",
1af2536a 168 [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = "gretap",
0a827d10 169 [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = "sit",
a613382b 170 [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = "vti",
d8e538ec
TG
171};
172
173DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData);
174
175static const NLTypeSystem rtnl_link_info_data_type_systems[_NL_UNION_LINK_INFO_DATA_MAX] = {
0a827d10
SS
176 [NL_UNION_LINK_INFO_DATA_BOND] = { .max = ELEMENTSOF(rtnl_link_info_data_bond_types) - 1,
177 .types = rtnl_link_info_data_bond_types },
178 [NL_UNION_LINK_INFO_DATA_BRIDGE] = { .max = ELEMENTSOF(rtnl_link_info_data_bridge_types) - 1,
179 .types = rtnl_link_info_data_bridge_types },
180 [NL_UNION_LINK_INFO_DATA_VLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_vlan_types) - 1,
181 .types = rtnl_link_info_data_vlan_types },
182 [NL_UNION_LINK_INFO_DATA_VETH] = { .max = ELEMENTSOF(rtnl_link_info_data_veth_types) - 1,
183 .types = rtnl_link_info_data_veth_types },
184 [NL_UNION_LINK_INFO_DATA_MACVLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_macvlan_types) - 1,
185 .types = rtnl_link_info_data_macvlan_types },
c4a5ddc9
TG
186 [NL_UNION_LINK_INFO_DATA_IPVLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvlan_types) - 1,
187 .types = rtnl_link_info_data_ipvlan_types },
6ef81477
SS
188 [NL_UNION_LINK_INFO_DATA_VXLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_vxlan_types) - 1,
189 .types = rtnl_link_info_data_vxlan_types },
0a827d10
SS
190 [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1,
191 .types = rtnl_link_info_data_iptun_types },
8bb088c5
SS
192 [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
193 .types = rtnl_link_info_data_ipgre_types },
1af2536a
SS
194 [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
195 .types = rtnl_link_info_data_ipgre_types },
0a827d10
SS
196 [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1,
197 .types = rtnl_link_info_data_iptun_types },
a613382b
SS
198 [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvti_types) - 1,
199 .types = rtnl_link_info_data_ipvti_types },
d8e538ec
TG
200};
201
202static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = {
203 .num = _NL_UNION_LINK_INFO_DATA_MAX,
204 .lookup = nl_union_link_info_data_from_string,
205 .type_systems = rtnl_link_info_data_type_systems,
206 .match = IFLA_INFO_KIND,
207};
208
209static const NLType rtnl_link_info_types[IFLA_INFO_MAX + 1] = {
210 [IFLA_INFO_KIND] = { .type = NLA_STRING },
211 [IFLA_INFO_DATA] = { .type = NLA_UNION, .type_system_union = &rtnl_link_info_data_type_system_union},
212/*
213 [IFLA_INFO_XSTATS],
214 [IFLA_INFO_SLAVE_KIND] = { .type = NLA_STRING },
215 [IFLA_INFO_SLAVE_DATA] = { .type = NLA_NESTED },
216*/
217};
218
219static const NLTypeSystem rtnl_link_info_type_system = {
220 .max = ELEMENTSOF(rtnl_link_info_types) - 1,
221 .types = rtnl_link_info_types,
222};
223
d0159fdc
SS
224static const struct NLType rtnl_bridge_port_types[IFLA_BRPORT_MAX + 1] = {
225 [IFLA_BRPORT_STATE] = { .type = NLA_U8 },
226 [IFLA_BRPORT_COST] = { .type = NLA_U32 },
227 [IFLA_BRPORT_PRIORITY] = { .type = NLA_U16 },
228 [IFLA_BRPORT_MODE] = { .type = NLA_U8 },
229 [IFLA_BRPORT_GUARD] = { .type = NLA_U8 },
230 [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 },
231 [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 },
232 [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 },
233};
234
235static const NLTypeSystem rtnl_bridge_port_type_system = {
236 .max = ELEMENTSOF(rtnl_bridge_port_types) - 1,
237 .types = rtnl_bridge_port_types,
238};
239
240static const NLType rtnl_link_types[IFLA_MAX + 1 ] = {
d8e538ec
TG
241 [IFLA_ADDRESS] = { .type = NLA_ETHER_ADDR, },
242 [IFLA_BROADCAST] = { .type = NLA_ETHER_ADDR, },
243 [IFLA_IFNAME] = { .type = NLA_STRING, .size = IFNAMSIZ - 1, },
244 [IFLA_MTU] = { .type = NLA_U32 },
245 [IFLA_LINK] = { .type = NLA_U32 },
246/*
247 [IFLA_QDISC],
248 [IFLA_STATS],
249 [IFLA_COST],
250 [IFLA_PRIORITY],
251*/
252 [IFLA_MASTER] = { .type = NLA_U32 },
253/*
254 [IFLA_WIRELESS],
255 [IFLA_PROTINFO],
256*/
d0159fdc 257 [IFLA_PROTINFO] = { .type = NLA_NESTED, .type_system = &rtnl_bridge_port_type_system },
d8e538ec
TG
258 [IFLA_TXQLEN] = { .type = NLA_U32 },
259/*
260 [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) },
261*/
262 [IFLA_WEIGHT] = { .type = NLA_U32 },
263 [IFLA_OPERSTATE] = { .type = NLA_U8 },
264 [IFLA_LINKMODE] = { .type = NLA_U8 },
265 [IFLA_LINKINFO] = { .type = NLA_NESTED, .type_system = &rtnl_link_info_type_system },
266 [IFLA_NET_NS_PID] = { .type = NLA_U32 },
267 [IFLA_IFALIAS] = { .type = NLA_STRING, .size = IFALIASZ - 1 },
268/*
269 [IFLA_NUM_VF],
270 [IFLA_VFINFO_LIST] = {. type = NLA_NESTED, },
271 [IFLA_STATS64],
272 [IFLA_VF_PORTS] = { .type = NLA_NESTED },
273 [IFLA_PORT_SELF] = { .type = NLA_NESTED },
274 [IFLA_AF_SPEC] = { .type = NLA_NESTED },
275 [IFLA_VF_PORTS],
276 [IFLA_PORT_SELF],
277 [IFLA_AF_SPEC],
278*/
279 [IFLA_GROUP] = { .type = NLA_U32 },
280 [IFLA_NET_NS_FD] = { .type = NLA_U32 },
281 [IFLA_EXT_MASK] = { .type = NLA_U32 },
282 [IFLA_PROMISCUITY] = { .type = NLA_U32 },
283 [IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 },
284 [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
285 [IFLA_CARRIER] = { .type = NLA_U8 },
286/*
287 [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
288*/
289};
290
291static const NLTypeSystem rtnl_link_type_system = {
292 .max = ELEMENTSOF(rtnl_link_types) - 1,
293 .types = rtnl_link_types,
294};
295
296static const NLType rtnl_address_types[IFA_MAX + 1] = {
297 [IFA_ADDRESS] = { .type = NLA_IN_ADDR },
298 [IFA_LOCAL] = { .type = NLA_IN_ADDR },
299 [IFA_LABEL] = { .type = NLA_STRING, .size = IFNAMSIZ - 1 },
300 [IFA_BROADCAST] = { .type = NLA_IN_ADDR }, /* 6? */
aba496a5 301 [IFA_CACHEINFO] = { .type = NLA_CACHE_INFO, .size = sizeof(struct ifa_cacheinfo) },
d8e538ec
TG
302/*
303 [IFA_ANYCAST],
d8e538ec
TG
304 [IFA_MULTICAST],
305*/
306#ifdef IFA_FLAGS
307 [IFA_FLAGS] = { .type = NLA_U32 },
308#endif
309};
310
311static const NLTypeSystem rtnl_address_type_system = {
312 .max = ELEMENTSOF(rtnl_address_types) - 1,
313 .types = rtnl_address_types,
314};
315
316static const NLType rtnl_route_types[RTA_MAX + 1] = {
317 [RTA_DST] = { .type = NLA_IN_ADDR }, /* 6? */
318 [RTA_SRC] = { .type = NLA_IN_ADDR }, /* 6? */
319 [RTA_IIF] = { .type = NLA_U32 },
320 [RTA_OIF] = { .type = NLA_U32 },
321 [RTA_GATEWAY] = { .type = NLA_IN_ADDR },
322 [RTA_PRIORITY] = { .type = NLA_U32 },
323 [RTA_PREFSRC] = { .type = NLA_IN_ADDR }, /* 6? */
324/*
325 [RTA_METRICS] = { .type = NLA_NESTED },
326 [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) },
327*/
328 [RTA_FLOW] = { .type = NLA_U32 }, /* 6? */
329/*
330 RTA_CACHEINFO,
331 RTA_TABLE,
332 RTA_MARK,
333 RTA_MFC_STATS,
334*/
335};
336
337static const NLTypeSystem rtnl_route_type_system = {
338 .max = ELEMENTSOF(rtnl_route_types) - 1,
339 .types = rtnl_route_types,
340};
341
e559b384
TG
342static const NLType rtnl_neigh_types[NDA_MAX + 1] = {
343 [NDA_DST] = { .type = NLA_IN_ADDR },
344 [NDA_LLADDR] = { .type = NLA_ETHER_ADDR },
b98b483b
AR
345 [NDA_CACHEINFO] = { .type = NLA_CACHE_INFO, .size = sizeof(struct nda_cacheinfo) },
346 [NDA_PROBES] = { .type = NLA_U32 },
347 [NDA_VLAN] = { .type = NLA_U16 },
348 [NDA_PORT] = { .type = NLA_U16 },
349 [NDA_VNI] = { .type = NLA_U32 },
350 [NDA_IFINDEX] = { .type = NLA_U32 },
e559b384
TG
351};
352
353static const NLTypeSystem rtnl_neigh_type_system = {
354 .max = ELEMENTSOF(rtnl_neigh_types) - 1,
355 .types = rtnl_neigh_types,
356};
357
d8e538ec
TG
358static const NLType rtnl_types[RTM_MAX + 1] = {
359 [NLMSG_ERROR] = { .type = NLA_META, .size = sizeof(struct nlmsgerr) },
360 [RTM_NEWLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
361 [RTM_DELLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
362 [RTM_GETLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
363 [RTM_SETLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
364 [RTM_NEWADDR] = { .type = NLA_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
365 [RTM_DELADDR] = { .type = NLA_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
366 [RTM_GETADDR] = { .type = NLA_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
367 [RTM_NEWROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
368 [RTM_DELROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
369 [RTM_GETROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
e559b384
TG
370 [RTM_NEWNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
371 [RTM_DELNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
372 [RTM_GETNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
d8e538ec
TG
373};
374
375const NLTypeSystem rtnl_type_system = {
376 .max = ELEMENTSOF(rtnl_types) - 1,
377 .types = rtnl_types,
378};
379
380int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) {
381 const NLType *nl_type;
382
383 assert(ret);
384
385 if (!type_system)
386 type_system = &rtnl_type_system;
387
388 assert(type_system->types);
389
390 if (type > type_system->max)
391 return -ENOTSUP;
392
393 nl_type = &type_system->types[type];
394
395 if (nl_type->type == NLA_UNSPEC)
396 return -ENOTSUP;
397
398 *ret = nl_type;
399
400 return 0;
401}
402
403int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSystem **ret, uint16_t type) {
404 const NLType *nl_type;
405 int r;
406
407 assert(ret);
408
409 r = type_system_get_type(type_system, &nl_type, type);
410 if (r < 0)
411 return r;
412
413 assert_return(nl_type->type == NLA_NESTED, -EINVAL);
414
415 assert(nl_type->type_system);
416
417 *ret = nl_type->type_system;
418
419 return 0;
420}
421
422int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLTypeSystemUnion **ret, uint16_t type) {
423 const NLType *nl_type;
424 int r;
425
426 assert(ret);
427
428 r = type_system_get_type(type_system, &nl_type, type);
429 if (r < 0)
430 return r;
431
432 assert_return(nl_type->type == NLA_UNION, -EINVAL);
433
434 assert(nl_type->type_system_union);
435
436 *ret = nl_type->type_system_union;
437
438 return 0;
439}
440
441int type_system_union_get_type_system(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, const char *key) {
442 int type;
443
444 assert(type_system_union);
445 assert(type_system_union->lookup);
446 assert(type_system_union->type_systems);
447 assert(ret);
448 assert(key);
449
450 type = type_system_union->lookup(key);
451 if (type < 0)
452 return -ENOTSUP;
453
454 assert(type < type_system_union->num);
455
456 *ret = &type_system_union->type_systems[type];
457
458 return 0;
459}