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 routing table.
138 * Indicating "all tables" via netlink can be done by not including RTA_TABLE attribute
139 * and keeping rtm_table=0 (compatibility) or setting RTA_TABLE value to RT_TABLE_UNSPEC.
140 */
141#define	RT_TABLE_MAIN	0		/* RT_DEFAULT_FIB */
142#define	RT_TABLE_UNSPEC	0xFFFFFFFF	/* RT_ALL_FIBS */
143
144enum rtattr_type_t {
145	NL_RTA_UNSPEC,
146	NL_RTA_DST		= 1, /* binary, IPv4/IPv6 destination */
147	NL_RTA_SRC		= 2, /* binary, preferred source address */
148	NL_RTA_IIF		= 3, /* not supported */
149	NL_RTA_OIF		= 4, /* u32, transmit ifindex */
150	NL_RTA_GATEWAY		= 5, /* binary: IPv4/IPv6 gateway */
151	NL_RTA_PRIORITY		= 6, /* not supported */
152	NL_RTA_PREFSRC		= 7, /* not supported */
153	NL_RTA_METRICS		= 8, /* nested, list of NL_RTAX* attrs */
154	NL_RTA_MULTIPATH	= 9, /* binary, array of struct rtnexthop */
155	NL_RTA_PROTOINFO	= 10, /* not supported / deprecated */
156	NL_RTA_KNH_ID		= 10, /* u32, FreeBSD specific, kernel nexthop index */
157	NL_RTA_FLOW		= 11, /* not supported */
158	NL_RTA_CACHEINFO	= 12, /* not supported */
159	NL_RTA_SESSION		= 13, /* not supported / deprecated */
160	NL_RTA_WEIGHT		= 13, /* u32, FreeBSD specific, path weight */
161	NL_RTA_MP_ALGO		= 14, /* not supported / deprecated */
162	NL_RTA_RTFLAGS		= 14, /* u32, FreeBSD specific, path flags (RTF_)*/
163	NL_RTA_TABLE		= 15, /* u32, fibnum */
164	NL_RTA_MARK		= 16, /* not supported */
165	NL_RTA_MFC_STATS	= 17, /* not supported */
166	NL_RTA_VIA		= 18, /* binary, struct rtvia */
167	NL_RTA_NEWDST		= 19, /* not supported */
168	NL_RTA_PREF		= 20, /* not supported */
169	NL_RTA_ENCAP_TYPE	= 21, /* not supported */
170	NL_RTA_ENCAP		= 22, /* not supported */
171	NL_RTA_EXPIRES		= 23, /* u32, seconds till expiration */
172	NL_RTA_PAD		= 24, /* not supported */
173	NL_RTA_UID		= 25, /* not supported */
174	NL_RTA_TTL_PROPAGATE	= 26, /* not supported */
175	NL_RTA_IP_PROTO		= 27, /* not supported */
176	NL_RTA_SPORT		= 28, /* not supported */
177	NL_RTA_DPORT		= 29, /* not supported */
178	NL_RTA_NH_ID		= 30, /* u32, nexthop/nexthop group index */
179	__RTA_MAX
180};
181#define NL_RTA_MAX (__RTA_MAX - 1)
182
183/*
184 * Attributes that can be used as filters:
185 *
186 */
187
188#ifndef _KERNEL
189/*
190 * RTA_* space has clashes with rtsock namespace.
191 * Use NL_RTA_ prefix in the kernel and map to
192 * RTA_ for userland.
193 */
194#define RTA_UNSPEC		NL_RTA_UNSPEC
195#define RTA_DST			NL_RTA_DST
196#define RTA_SRC			NL_RTA_SRC
197#define RTA_IIF			NL_RTA_IIF
198#define RTA_OIF			NL_RTA_OIF
199#define RTA_GATEWAY		NL_RTA_GATEWAY
200#define RTA_PRIORITY		NL_RTA_PRIORITY
201#define RTA_PREFSRC		NL_RTA_PREFSRC
202#define RTA_METRICS		NL_RTA_METRICS
203#define RTA_MULTIPATH		NL_RTA_MULTIPATH
204#define	RTA_PROTOINFO		NL_RTA_PROTOINFO
205#define	RTA_KNH_ID		NL_RTA_KNH_ID
206#define RTA_FLOW		NL_RTA_FLOW
207#define RTA_CACHEINFO		NL_RTA_CACHEINFO
208#define	RTA_SESSION		NL_RTA_SESSION
209#define	RTA_MP_ALGO		NL_RTA_MP_ALGO
210#define RTA_TABLE		NL_RTA_TABLE
211#define RTA_MARK		NL_RTA_MARK
212#define RTA_MFC_STATS		NL_RTA_MFC_STATS
213#define RTA_VIA			NL_RTA_VIA
214#define RTA_NEWDST		NL_RTA_NEWDST
215#define RTA_PREF		NL_RTA_PREF
216#define RTA_ENCAP_TYPE		NL_RTA_ENCAP_TYPE
217#define RTA_ENCAP		NL_RTA_ENCAP
218#define RTA_EXPIRES		NL_RTA_EXPIRES
219#define RTA_PAD			NL_RTA_PAD
220#define RTA_UID			NL_RTA_UID
221#define RTA_TTL_PROPAGATE	NL_RTA_TTL_PROPAGATE
222#define RTA_IP_PROTO		NL_RTA_IP_PROTO
223#define RTA_SPORT		NL_RTA_SPORT
224#define RTA_DPORT		NL_RTA_DPORT
225#define RTA_NH_ID		NL_RTA_NH_ID
226#define	RTA_MAX			NL_RTA_MAX
227#endif
228
229/* route attribute header */
230struct rtattr {
231	unsigned short rta_len;
232	unsigned short rta_type;
233};
234
235#define	NL_RTA_ALIGN_SIZE	NL_ITEM_ALIGN_SIZE
236#define	NL_RTA_ALIGN		NL_ITEM_ALIGN
237#define	NL_RTA_HDRLEN		((int)sizeof(struct rtattr))
238#define	NL_RTA_DATA_LEN(_rta)	((int)((_rta)->rta_len - NL_RTA_HDRLEN))
239#define	NL_RTA_DATA(_rta)	NL_ITEM_DATA(_rta, NL_RTA_HDRLEN)
240#define	NL_RTA_DATA_CONST(_rta)	NL_ITEM_DATA_CONST(_rta, NL_RTA_HDRLEN)
241
242/* Compatibility attribute handling helpers */
243#ifndef _KERNEL
244#define	RTA_ALIGNTO		NL_RTA_ALIGN_SIZE
245#define	RTA_ALIGN(_len)		NL_RTA_ALIGN(_len)
246#define	_RTA_LEN(_rta)		((int)(_rta)->rta_len)
247#define	_RTA_ALIGNED_LEN(_rta)	RTA_ALIGN(_RTA_LEN(_rta))
248#define	RTA_OK(_rta, _len)	NL_ITEM_OK(_rta, _len, NL_RTA_HDRLEN, _RTA_LEN)
249#define	RTA_NEXT(_rta, _len)	NL_ITEM_ITER(_rta, _len, _RTA_ALIGNED_LEN)
250#define	RTA_LENGTH(_len)	(NL_RTA_HDRLEN + (_len))
251#define	RTA_SPACE(_len)		RTA_ALIGN(RTA_LENGTH(_len))
252#define	RTA_DATA(_rta)		NL_RTA_DATA(_rta)
253#define	RTA_PAYLOAD(_rta)	((int)(_RTA_LEN(_rta) - NL_RTA_HDRLEN))
254#endif
255
256/* RTA attribute headers */
257
258/* RTA_VIA */
259struct rtvia {
260	sa_family_t	rtvia_family;
261	uint8_t		rtvia_addr[0];
262};
263
264/*
265 * RTA_METRICS is a nested attribute, consisting of a list of
266 * TLVs with types defined below.
267 */
268 enum {
269	NL_RTAX_UNSPEC,
270	NL_RTAX_LOCK			= 1, /* not supported */
271	NL_RTAX_MTU			= 2, /* desired path MTU */
272	NL_RTAX_WINDOW			= 3, /* not supported */
273	NL_RTAX_RTT			= 4, /* not supported */
274	NL_RTAX_RTTVAR			= 5, /* not supported */
275	NL_RTAX_SSTHRESH		= 6, /* not supported */
276	NL_RTAX_CWND			= 7, /* not supported */
277	NL_RTAX_ADVMSS			= 8, /* not supported  */
278	NL_RTAX_REORDERING		= 9, /* not supported */
279	NL_RTAX_HOPLIMIT		= 10, /* not supported */
280	NL_RTAX_INITCWND		= 11, /* not supporrted */
281	NL_RTAX_FEATURES		= 12, /* not supported */
282	NL_RTAX_RTO_MIN			= 13, /* not supported */
283	NL_RTAX_INITRWND		= 14, /* not supported */
284	NL_RTAX_QUICKACK		= 15, /* not supported */
285	NL_RTAX_CC_ALGO			= 16, /* not supported */
286	NL_RTAX_FASTOPEN_NO_COOKIE	= 17, /* not supported */
287	__NL_RTAX_MAX
288};
289#define NL_RTAX_MAX (__NL_RTAX_MAX - 1)
290
291#define RTAX_FEATURE_ECN (1 << 0)
292#define RTAX_FEATURE_SACK (1 << 1)
293#define RTAX_FEATURE_TIMESTAMP (1 << 2)
294#define RTAX_FEATURE_ALLFRAG (1 << 3)
295
296#define RTAX_FEATURE_MASK                                                \
297	(RTAX_FEATURE_ECN | RTAX_FEATURE_SACK | RTAX_FEATURE_TIMESTAMP | \
298	    RTAX_FEATURE_ALLFRAG)
299
300#ifndef _KERNEL
301
302/*
303 * RTAX_* space clashes with rtsock namespace.
304 * Use NL_RTAX_ prefix in the kernel and map to
305 * RTAX_ for userland.
306 */
307#define RTAX_UNSPEC		NL_RTAX_UNSPEC
308#define RTAX_LOCK		NL_RTAX_LOCK
309#define RTAX_MTU		NL_RTAX_MTU
310#define RTAX_WINDOW		NL_RTAX_WINDOW
311#define RTAX_RTT		NL_RTAX_RTT
312#define RTAX_RTTVAR		NL_RTAX_RTTVAR
313#define RTAX_SSTHRESH		NL_RTAX_SSTHRESH
314#define RTAX_CWND		NL_RTAX_CWND
315#define RTAX_ADVMSS		NL_RTAX_ADVMSS
316#define RTAX_REORDERING		NL_RTAX_REORDERING
317#define RTAX_HOPLIMIT		NL_RTAX_HOPLIMIT
318#define RTAX_INITCWND		NL_RTAX_INITCWND
319#define RTAX_FEATURES		NL_RTAX_FEATURES
320#define RTAX_RTO_MIN		NL_RTAX_RTO_MIN
321#define RTAX_INITRWND		NL_RTAX_INITRWND
322#define RTAX_QUICKACK		NL_RTAX_QUICKACK
323#define RTAX_CC_ALGO		NL_RTAX_CC_ALGO
324#define RTAX_FASTOPEN_NO_COOKIE	NL_RTAX_FASTOPEN_NO_COOKIE
325#endif
326
327/*
328 * RTA_MULTIPATH consists of an array of rtnexthop structures.
329 * Each rtnexthop structure contains RTA_GATEWAY or RTA_VIA
330 * attribute following the header.
331 */
332struct rtnexthop {
333	unsigned short		rtnh_len;
334	unsigned char		rtnh_flags;
335	unsigned char		rtnh_hops;	/* nexthop weight */
336	int			rtnh_ifindex;
337};
338
339/* rtnh_flags */
340#define RTNH_F_DEAD		0x01	/* not supported */
341#define RTNH_F_PERVASIVE	0x02	/* not supported */
342#define RTNH_F_ONLINK		0x04	/* not supported */
343#define RTNH_F_OFFLOAD		0x08	/* not supported */
344#define RTNH_F_LINKDOWN		0x10	/* not supported */
345#define RTNH_F_UNRESOLVED	0x20	/* not supported */
346#define RTNH_F_TRAP		0x40	/* not supported */
347
348#define RTNH_COMPARE_MASK	(RTNH_F_DEAD | RTNH_F_LINKDOWN | \
349				 RTNH_F_OFFLOAD | RTNH_F_TRAP)
350
351/* Macros to handle hexthops */
352#define	RTNH_ALIGNTO		NL_ITEM_ALIGN_SIZE
353#define	RTNH_ALIGN(_len)	NL_ITEM_ALIGN(_len)
354#define	RTNH_HDRLEN		((int)sizeof(struct rtnexthop))
355#define	_RTNH_LEN(_nh)		((int)(_nh)->rtnh_len)
356#define	_RTNH_ALIGNED_LEN(_nh)	RTNH_ALIGN(_RTNH_LEN(_nh))
357#define	RTNH_OK(_nh, _len)	NL_ITEM_OK(_nh, _len, RTNH_HDRLEN, _RTNH_LEN)
358#define	RTNH_NEXT(_nh)		((struct rtnexthop *)((char *)(_nh) + _RTNH_ALIGNED_LEN(_nh)))
359#define	RTNH_LENGTH(_len)	(RTNH_HDRLEN + (_len))
360#define	RTNH_SPACE(_len)	RTNH_ALIGN(RTNH_LENGTH(_len))
361#define	RTNH_DATA(_nh)		((struct rtattr *)NL_ITEM_DATA(_nh, RTNH_HDRLEN))
362
363struct rtgenmsg {
364	unsigned char rtgen_family;
365};
366
367#endif