1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2022 Alexander V. Chernikov <melifaro@FreeBSD.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28/*
29 * Route-related (RTM_<NEW|DEL|GET>ROUTE) message header and attributes.
30 */
31
32#ifndef _NETLINK_ROUTE_ROUTE_H_
33#define _NETLINK_ROUTE_ROUTE_H_
34
35/* Base header for all of the relevant messages */
36struct rtmsg {
37 unsigned char rtm_family; /* address family */
38 unsigned char rtm_dst_len; /* Prefix length */
39 unsigned char rtm_src_len; /* Source prefix length (not used) */
40 unsigned char rtm_tos; /* Type of service (not used) */
41 unsigned char rtm_table; /* rtable id */
42 unsigned char rtm_protocol; /* Routing protocol id (RTPROT_) */
43 unsigned char rtm_scope; /* Route distance (RT_SCOPE_) */
44 unsigned char rtm_type; /* Route type (RTN_) */
45 unsigned rtm_flags; /* Route flags (RTM_F_) */
46};
47
48/*
49 * RFC 3549, 3.1.1, route type (rtm_type field).
50 */
51enum {
52 RTN_UNSPEC,
53 RTN_UNICAST, /* Unicast route */
54 RTN_LOCAL, /* Accept locally (not supported) */
55 RTN_BROADCAST, /* Accept locally as broadcast, send as broadcast */
56 RTN_ANYCAST, /* Accept locally as broadcast, but send as unicast */
57 RTN_MULTICAST, /* Multicast route */
58 RTN_BLACKHOLE, /* Drop traffic towards destination */
59 RTN_UNREACHABLE, /* Destination is unreachable */
60 RTN_PROHIBIT, /* Administratively prohibited */
61 RTN_THROW, /* Not in this table (not supported) */
62 RTN_NAT, /* Translate this address (not supported) */
63 RTN_XRESOLVE, /* Use external resolver (not supported) */
64 __RTN_MAX,
65};
66#define RTN_MAX (__RTN_MAX - 1)
67
68/*
69 * RFC 3549, 3.1.1, protocol (Identifies what/who added the route).
70 * Values larger than RTPROT_STATIC(4) are not interpreted by the
71 * kernel, they are just for user information.
72 */
73#define RTPROT_UNSPEC 0
74#define RTPROT_REDIRECT 1 /* Route installed by ICMP redirect */
75#define RTPROT_KERNEL 2 /* Route installed by kernel */
76#define RTPROT_BOOT 3 /* Route installed during boot */
77#define RTPROT_STATIC 4 /* Route installed by administrator */
78
79#define RTPROT_GATED 8
80#define RTPROT_RA 9
81#define RTPROT_MRT 1
82#define RTPROT_ZEBRA 11
83#define RTPROT_BIRD 12
84#define RTPROT_DNROUTED 13
85#define RTPROT_XORP 14
86#define RTPROT_NTK 15
87#define RTPROT_DHCP 16
88#define RTPROT_MROUTED 17
89#define RTPROT_KEEPALIVED 18
90#define RTPROT_BABEL 42
91#define RTPROT_OPENR 99
92#define RTPROT_BGP 186
93#define RTPROT_ISIS 187
94#define RTPROT_OSPF 188
95#define RTPROT_RIP 189
96#define RTPROT_EIGRP 192
97
98/*
99 * RFC 3549 3.1.1 Route scope (valid distance to destination).
100 *
101 * The values between RT_SCOPE_UNIVERSE(0) and RT_SCOPE_SITE(200)
102 * are available to the user.
103 */
104enum rt_scope_t {
105 RT_SCOPE_UNIVERSE = 0,
106 /* User defined values */
107 RT_SCOPE_SITE = 200,
108 RT_SCOPE_LINK = 253,
109 RT_SCOPE_HOST = 254,
110 RT_SCOPE_NOWHERE = 255
111};
112
113/*
114 * RFC 3549 3.1.1 Route flags (rtm_flags).
115 * Is a composition of RTNH_F flags (0x1..0x40 range), RTM_F flags (below)
116 * and per-protocol (IPv4/IPv6) flags.
117 */
118#define RTM_F_NOTIFY 0x00000100 /* not supported */
119#define RTM_F_CLONED 0x00000200 /* not supported */
120#define RTM_F_EQUALIZE 0x00000400 /* not supported */
121#define RTM_F_PREFIX 0x00000800 /* not supported */
122#define RTM_F_LOOKUP_TABLE 0x00001000 /* not supported */
123#define RTM_F_FIB_MATCH 0x00002000 /* not supported */
124#define RTM_F_OFFLOAD 0x00004000 /* not supported */
125#define RTM_F_TRAP 0x00008000 /* not supported */
126#define RTM_F_OFFLOAD_FAILED 0x20000000 /* not supported */
127
128/* Compatibility handling helpers */
129#ifndef _KERNEL
130#define NL_RTM_HDRLEN ((int)sizeof(struct rtmsg))
131#define RTM_RTA(_rtm) ((struct rtattr *)((char *)(_rtm) + NL_RTM_HDRLEN))
132#define RTM_PAYLOAD(_hdr) NLMSG_PAYLOAD((_hdr), NL_RTM_HDRLEN)
133#endif
134
135/*
136 * Routing table identifiers.
137 * FreeBSD route table numbering starts from 0, where 0 is a valid default
138 * routing table. Indicating "all tables" via netlink can be done by not
139 * including RTA_TABLE attribute and keeping rtm_table=0 (compatibility) or
140 * setting RTA_TABLE value to RT_TABLE_UNSPEC.
141 */
142#define RT_TABLE_MAIN 0 /* RT_DEFAULT_FIB */
143#define RT_TABLE_UNSPEC 0xFFFFFFFF /* RT_ALL_FIBS */
144
145enum rtattr_type_t {
146 NL_RTA_UNSPEC,
147 NL_RTA_DST = 1, /* binary, IPv4/IPv6 destination */
148 NL_RTA_SRC = 2, /* binary, preferred source address */
149 NL_RTA_IIF = 3, /* not supported */
150 NL_RTA_OIF = 4, /* u32, transmit ifindex */
151 NL_RTA_GATEWAY = 5, /* binary: IPv4/IPv6 gateway */
152 NL_RTA_PRIORITY = 6, /* not supported */
153 NL_RTA_PREFSRC = 7, /* not supported */
154 NL_RTA_METRICS = 8, /* nested, list of NL_RTAX* attrs */
155 NL_RTA_MULTIPATH = 9, /* binary, array of struct rtnexthop */
156 NL_RTA_PROTOINFO = 10, /* not supported / deprecated */
157 NL_RTA_KNH_ID = 10, /* u32, FreeBSD specific, kernel nexthop index */
158 NL_RTA_FLOW = 11, /* not supported */
159 NL_RTA_CACHEINFO = 12, /* not supported */
160 NL_RTA_SESSION = 13, /* not supported / deprecated */
161 NL_RTA_WEIGHT = 13, /* u32, FreeBSD specific, path weight */
162 NL_RTA_MP_ALGO = 14, /* not supported / deprecated */
163 NL_RTA_RTFLAGS = 14, /* u32, FreeBSD specific, path flags (RTF_)*/
164 NL_RTA_TABLE = 15, /* u32, fibnum */
165 NL_RTA_MARK = 16, /* not supported */
166 NL_RTA_MFC_STATS = 17, /* not supported */
167 NL_RTA_VIA = 18, /* binary, struct rtvia */
168 NL_RTA_NEWDST = 19, /* not supported */
169 NL_RTA_PREF = 20, /* not supported */
170 NL_RTA_ENCAP_TYPE = 21, /* not supported */
171 NL_RTA_ENCAP = 22, /* not supported */
172 NL_RTA_EXPIRES = 23, /* u32, seconds till expiration */
173 NL_RTA_PAD = 24, /* not supported */
174 NL_RTA_UID = 25, /* not supported */
175 NL_RTA_TTL_PROPAGATE = 26, /* not supported */
176 NL_RTA_IP_PROTO = 27, /* not supported */
177 NL_RTA_SPORT = 28, /* not supported */
178 NL_RTA_DPORT = 29, /* not supported */
179 NL_RTA_NH_ID = 30, /* u32, nexthop/nexthop group index */
180 __RTA_MAX
181};
182#define NL_RTA_MAX (__RTA_MAX - 1)
183
184/*
185 * Attributes that can be used as filters:
186 *
187 */
188
189#ifndef _KERNEL
190/*
191 * RTA_* space has clashes with rtsock namespace.
192 * Use NL_RTA_ prefix in the kernel and map to
193 * RTA_ for userland.
194 */
195#define RTA_UNSPEC NL_RTA_UNSPEC
196#define RTA_DST NL_RTA_DST
197#define RTA_SRC NL_RTA_SRC
198#define RTA_IIF NL_RTA_IIF
199#define RTA_OIF NL_RTA_OIF
200#define RTA_GATEWAY NL_RTA_GATEWAY
201#define RTA_PRIORITY NL_RTA_PRIORITY
202#define RTA_PREFSRC NL_RTA_PREFSRC
203#define RTA_METRICS NL_RTA_METRICS
204#define RTA_MULTIPATH NL_RTA_MULTIPATH
205#define RTA_PROTOINFO NL_RTA_PROTOINFO
206#define RTA_KNH_ID NL_RTA_KNH_ID
207#define RTA_FLOW NL_RTA_FLOW
208#define RTA_CACHEINFO NL_RTA_CACHEINFO
209#define RTA_SESSION NL_RTA_SESSION
210#define RTA_MP_ALGO NL_RTA_MP_ALGO
211#define RTA_TABLE NL_RTA_TABLE
212#define RTA_MARK NL_RTA_MARK
213#define RTA_MFC_STATS NL_RTA_MFC_STATS
214#define RTA_VIA NL_RTA_VIA
215#define RTA_NEWDST NL_RTA_NEWDST
216#define RTA_PREF NL_RTA_PREF
217#define RTA_ENCAP_TYPE NL_RTA_ENCAP_TYPE
218#define RTA_ENCAP NL_RTA_ENCAP
219#define RTA_EXPIRES NL_RTA_EXPIRES
220#define RTA_PAD NL_RTA_PAD
221#define RTA_UID NL_RTA_UID
222#define RTA_TTL_PROPAGATE NL_RTA_TTL_PROPAGATE
223#define RTA_IP_PROTO NL_RTA_IP_PROTO
224#define RTA_SPORT NL_RTA_SPORT
225#define RTA_DPORT NL_RTA_DPORT
226#define RTA_NH_ID NL_RTA_NH_ID
227#define RTA_MAX NL_RTA_MAX
228#endif
229
230/* route attribute header */
231struct rtattr {
232 unsigned short rta_len;
233 unsigned short rta_type;
234};
235
236#define NL_RTA_ALIGN_SIZE NL_ITEM_ALIGN_SIZE
237#define NL_RTA_ALIGN NL_ITEM_ALIGN
238#define NL_RTA_HDRLEN ((int)sizeof(struct rtattr))
239#define NL_RTA_DATA_LEN(_rta) ((int)((_rta)->rta_len - NL_RTA_HDRLEN))
240#define NL_RTA_DATA(_rta) NL_ITEM_DATA(_rta, NL_RTA_HDRLEN)
241#define NL_RTA_DATA_CONST(_rta) NL_ITEM_DATA_CONST(_rta, NL_RTA_HDRLEN)
242
243/* Compatibility attribute handling helpers */
244#ifndef _KERNEL
245#define RTA_ALIGNTO NL_RTA_ALIGN_SIZE
246#define RTA_ALIGN(_len) NL_RTA_ALIGN(_len)
247#define _RTA_LEN(_rta) ((int)(_rta)->rta_len)
248#define _RTA_ALIGNED_LEN(_rta) RTA_ALIGN(_RTA_LEN(_rta))
249#define RTA_OK(_rta, _len) NL_ITEM_OK(_rta, _len, NL_RTA_HDRLEN, _RTA_LEN)
250#define RTA_NEXT(_rta, _len) NL_ITEM_ITER(_rta, _len, _RTA_ALIGNED_LEN)
251#define RTA_LENGTH(_len) (NL_RTA_HDRLEN + (_len))
252#define RTA_SPACE(_len) RTA_ALIGN(RTA_LENGTH(_len))
253#define RTA_DATA(_rta) NL_RTA_DATA(_rta)
254#define RTA_PAYLOAD(_rta) ((int)(_RTA_LEN(_rta) - NL_RTA_HDRLEN))
255#endif
256
257/* RTA attribute headers */
258
259/* RTA_VIA */
260struct rtvia {
261 sa_family_t rtvia_family;
262 uint8_t rtvia_addr[0];
263};
264
265/*
266 * RTA_METRICS is a nested attribute, consisting of a list of
267 * TLVs with types defined below.
268 */
269 enum {
270 NL_RTAX_UNSPEC,
271 NL_RTAX_LOCK = 1, /* not supported */
272 NL_RTAX_MTU = 2, /* desired path MTU */
273 NL_RTAX_WINDOW = 3, /* not supported */
274 NL_RTAX_RTT = 4, /* not supported */
275 NL_RTAX_RTTVAR = 5, /* not supported */
276 NL_RTAX_SSTHRESH = 6, /* not supported */
277 NL_RTAX_CWND = 7, /* not supported */
278 NL_RTAX_ADVMSS = 8, /* not supported */
279 NL_RTAX_REORDERING = 9, /* not supported */
280 NL_RTAX_HOPLIMIT = 10, /* not supported */
281 NL_RTAX_INITCWND = 11, /* not supporrted */
282 NL_RTAX_FEATURES = 12, /* not supported */
283 NL_RTAX_RTO_MIN = 13, /* not supported */
284 NL_RTAX_INITRWND = 14, /* not supported */
285 NL_RTAX_QUICKACK = 15, /* not supported */
286 NL_RTAX_CC_ALGO = 16, /* not supported */
287 NL_RTAX_FASTOPEN_NO_COOKIE = 17, /* not supported */
288 __NL_RTAX_MAX
289};
290#define NL_RTAX_MAX (__NL_RTAX_MAX - 1)
291
292#define RTAX_FEATURE_ECN (1 << 0)
293#define RTAX_FEATURE_SACK (1 << 1)
294#define RTAX_FEATURE_TIMESTAMP (1 << 2)
295#define RTAX_FEATURE_ALLFRAG (1 << 3)
296
297#define RTAX_FEATURE_MASK \
298 (RTAX_FEATURE_ECN | RTAX_FEATURE_SACK | RTAX_FEATURE_TIMESTAMP | \
299 RTAX_FEATURE_ALLFRAG)
300
301#ifndef _KERNEL
302
303/*
304 * RTAX_* space clashes with rtsock namespace.
305 * Use NL_RTAX_ prefix in the kernel and map to
306 * RTAX_ for userland.
307 */
308#define RTAX_UNSPEC NL_RTAX_UNSPEC
309#define RTAX_LOCK NL_RTAX_LOCK
310#define RTAX_MTU NL_RTAX_MTU
311#define RTAX_WINDOW NL_RTAX_WINDOW
312#define RTAX_RTT NL_RTAX_RTT
313#define RTAX_RTTVAR NL_RTAX_RTTVAR
314#define RTAX_SSTHRESH NL_RTAX_SSTHRESH
315#define RTAX_CWND NL_RTAX_CWND
316#define RTAX_ADVMSS NL_RTAX_ADVMSS
317#define RTAX_REORDERING NL_RTAX_REORDERING
318#define RTAX_HOPLIMIT NL_RTAX_HOPLIMIT
319#define RTAX_INITCWND NL_RTAX_INITCWND
320#define RTAX_FEATURES NL_RTAX_FEATURES
321#define RTAX_RTO_MIN NL_RTAX_RTO_MIN
322#define RTAX_INITRWND NL_RTAX_INITRWND
323#define RTAX_QUICKACK NL_RTAX_QUICKACK
324#define RTAX_CC_ALGO NL_RTAX_CC_ALGO
325#define RTAX_FASTOPEN_NO_COOKIE NL_RTAX_FASTOPEN_NO_COOKIE
326#endif
327
328/*
329 * RTA_MULTIPATH consists of an array of rtnexthop structures.
330 * Each rtnexthop structure contains RTA_GATEWAY or RTA_VIA
331 * attribute following the header.
332 */
333struct rtnexthop {
334 unsigned short rtnh_len;
335 unsigned char rtnh_flags;
336 unsigned char rtnh_hops; /* nexthop weight */
337 int rtnh_ifindex;
338};
339
340/* rtnh_flags */
341#define RTNH_F_DEAD 0x01 /* not supported */
342#define RTNH_F_PERVASIVE 0x02 /* not supported */
343#define RTNH_F_ONLINK 0x04 /* not supported */
344#define RTNH_F_OFFLOAD 0x08 /* not supported */
345#define RTNH_F_LINKDOWN 0x10 /* not supported */
346#define RTNH_F_UNRESOLVED 0x20 /* not supported */
347#define RTNH_F_TRAP 0x40 /* not supported */
348
349#define RTNH_COMPARE_MASK (RTNH_F_DEAD | RTNH_F_LINKDOWN | \
350 RTNH_F_OFFLOAD | RTNH_F_TRAP)
351
352/* Macros to handle hexthops */
353#define RTNH_ALIGNTO NL_ITEM_ALIGN_SIZE
354#define RTNH_ALIGN(_len) NL_ITEM_ALIGN(_len)
355#define RTNH_HDRLEN ((int)sizeof(struct rtnexthop))
356#define _RTNH_LEN(_nh) ((int)(_nh)->rtnh_len)
357#define _RTNH_ALIGNED_LEN(_nh) RTNH_ALIGN(_RTNH_LEN(_nh))
358#define RTNH_OK(_nh, _len) NL_ITEM_OK(_nh, _len, RTNH_HDRLEN, _RTNH_LEN)
359#define RTNH_NEXT(_nh) ((struct rtnexthop *)((char *)(_nh) + _RTNH_ALIGNED_LEN(_nh)))
360#define RTNH_LENGTH(_len) (RTNH_HDRLEN + (_len))
361#define RTNH_SPACE(_len) RTNH_ALIGN(RTNH_LENGTH(_len))
362#define RTNH_DATA(_nh) ((struct rtattr *)NL_ITEM_DATA(_nh, RTNH_HDRLEN))
363
364struct rtgenmsg {
365 unsigned char rtgen_family;
366};
367
368#endif