| 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 */ |
| 36 | struct 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 | */ |
| 51 | enum { |
| 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 | */ |
| 104 | enum 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 | |
| 145 | enum 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 */ |
| 231 | struct 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 */ |
| 260 | struct 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 | */ |
| 333 | struct 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 | |
| 364 | struct rtgenmsg { |
| 365 | 	unsigned char rtgen_family; |
| 366 | }; |
| 367 | |
| 368 | #endif |