1 /*
2  * Nexthop structure definition.
3  * Copyright (C) 1997, 98, 99, 2001 Kunihiro Ishiguro
4  * Copyright (C) 2013 Cumulus Networks, Inc.
5  *
6  * This file is part of Quagga.
7  *
8  * Quagga is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2, or (at your option) any
11  * later version.
12  *
13  * Quagga 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  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; see the file COPYING; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #ifndef _LIB_NEXTHOP_H
24 #define _LIB_NEXTHOP_H
25 
26 #include "prefix.h"
27 #include "mpls.h"
28 #include "vxlan.h"
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 /* Maximum next hop string length - gateway + ifindex */
35 #define NEXTHOP_STRLEN (INET6_ADDRSTRLEN + 30)
36 
37 union g_addr {
38 	struct in_addr ipv4;
39 	struct in6_addr ipv6;
40 };
41 
42 enum nexthop_types_t {
43 	NEXTHOP_TYPE_IFINDEX = 1,  /* Directly connected.  */
44 	NEXTHOP_TYPE_IPV4,	 /* IPv4 nexthop.  */
45 	NEXTHOP_TYPE_IPV4_IFINDEX, /* IPv4 nexthop with ifindex.  */
46 	NEXTHOP_TYPE_IPV6,	 /* IPv6 nexthop.  */
47 	NEXTHOP_TYPE_IPV6_IFINDEX, /* IPv6 nexthop with ifindex.  */
48 	NEXTHOP_TYPE_BLACKHOLE,    /* Null0 nexthop.  */
49 };
50 
51 enum blackhole_type {
52 	BLACKHOLE_UNSPEC = 0,
53 	BLACKHOLE_NULL,
54 	BLACKHOLE_REJECT,
55 	BLACKHOLE_ADMINPROHIB,
56 };
57 
58 /* IPV[46] -> IPV[46]_IFINDEX */
59 #define NEXTHOP_FIRSTHOPTYPE(type)                                             \
60 	((type) == NEXTHOP_TYPE_IFINDEX || (type) == NEXTHOP_TYPE_BLACKHOLE)   \
61 		? (type)                                                       \
62 		: ((type) | 1)
63 
64 enum nh_encap_type {
65 	NET_VXLAN = 100, /* value copied from FPM_NH_ENCAP_VXLAN. */
66 };
67 
68 /* Fixed limit on the number of backup nexthops per primary nexthop */
69 #define NEXTHOP_MAX_BACKUPS  8
70 
71 /* Backup index value is limited */
72 #define NEXTHOP_BACKUP_IDX_MAX 255
73 
74 /* Nexthop structure. */
75 struct nexthop {
76 	struct nexthop *next;
77 	struct nexthop *prev;
78 
79 	/*
80 	 * What vrf is this nexthop associated with?
81 	 */
82 	vrf_id_t vrf_id;
83 
84 	/* Interface index. */
85 	ifindex_t ifindex;
86 
87 	enum nexthop_types_t type;
88 
89 	uint8_t flags;
90 #define NEXTHOP_FLAG_ACTIVE     (1 << 0) /* This nexthop is alive. */
91 #define NEXTHOP_FLAG_FIB        (1 << 1) /* FIB nexthop. */
92 #define NEXTHOP_FLAG_RECURSIVE  (1 << 2) /* Recursive nexthop. */
93 #define NEXTHOP_FLAG_ONLINK     (1 << 3) /* Nexthop should be installed
94 					  * onlink.
95 					  */
96 #define NEXTHOP_FLAG_DUPLICATE  (1 << 4) /* nexthop duplicates another
97 					  * active one
98 					  */
99 #define NEXTHOP_FLAG_RNH_FILTERED  (1 << 5) /* rmap filtered, used by rnh */
100 #define NEXTHOP_FLAG_HAS_BACKUP (1 << 6)    /* Backup nexthop index is set */
101 #define NEXTHOP_FLAG_SRTE       (1 << 7) /* SR-TE color used for BGP traffic */
102 
103 #define NEXTHOP_IS_ACTIVE(flags)                                               \
104 	(CHECK_FLAG(flags, NEXTHOP_FLAG_ACTIVE)                                \
105 	 && !CHECK_FLAG(flags, NEXTHOP_FLAG_DUPLICATE))
106 
107 	/* Nexthop address */
108 	union {
109 		union g_addr gate;
110 		enum blackhole_type bh_type;
111 	};
112 	union g_addr src;
113 	union g_addr rmap_src; /* Src is set via routemap */
114 
115 	/* Nexthops obtained by recursive resolution.
116 	 *
117 	 * If the nexthop struct needs to be resolved recursively,
118 	 * NEXTHOP_FLAG_RECURSIVE will be set in flags and the nexthops
119 	 * obtained by recursive resolution will be added to `resolved'.
120 	 */
121 	struct nexthop *resolved;
122 	/* Recursive parent */
123 	struct nexthop *rparent;
124 
125 	/* Type of label(s), if any */
126 	enum lsp_types_t nh_label_type;
127 
128 	/* Label(s) associated with this nexthop. */
129 	struct mpls_label_stack *nh_label;
130 
131 	/* Weight of the nexthop ( for unequal cost ECMP ) */
132 	uint8_t weight;
133 
134 	/* Count and index of corresponding backup nexthop(s) in a backup list;
135 	 * only meaningful if the HAS_BACKUP flag is set.
136 	 */
137 	uint8_t backup_num;
138 	uint8_t backup_idx[NEXTHOP_MAX_BACKUPS];
139 
140 	/* Encapsulation information. */
141 	enum nh_encap_type nh_encap_type;
142 	union {
143 		vni_t vni;
144 	} nh_encap;
145 
146 	/* SR-TE color used for matching SR-TE policies */
147 	uint32_t srte_color;
148 };
149 
150 /* Utility to append one nexthop to another. */
151 #define NEXTHOP_APPEND(to, new)           \
152 	do {                              \
153 		(to)->next = (new);       \
154 		(new)->prev = (to);       \
155 		(new)->next = NULL;       \
156 	} while (0)
157 
158 struct nexthop *nexthop_new(void);
159 
160 void nexthop_free(struct nexthop *nexthop);
161 void nexthops_free(struct nexthop *nexthop);
162 
163 void nexthop_add_labels(struct nexthop *nexthop, enum lsp_types_t ltype,
164 			uint8_t num_labels, const mpls_label_t *labels);
165 void nexthop_del_labels(struct nexthop *);
166 
167 /*
168  * Allocate a new nexthop object and initialize it from various args.
169  */
170 struct nexthop *nexthop_from_ifindex(ifindex_t ifindex, vrf_id_t vrf_id);
171 struct nexthop *nexthop_from_ipv4(const struct in_addr *ipv4,
172 				  const struct in_addr *src,
173 				  vrf_id_t vrf_id);
174 struct nexthop *nexthop_from_ipv4_ifindex(const struct in_addr *ipv4,
175 					  const struct in_addr *src,
176 					  ifindex_t ifindex, vrf_id_t vrf_id);
177 struct nexthop *nexthop_from_ipv6(const struct in6_addr *ipv6,
178 				  vrf_id_t vrf_id);
179 struct nexthop *nexthop_from_ipv6_ifindex(const struct in6_addr *ipv6,
180 					  ifindex_t ifindex, vrf_id_t vrf_id);
181 struct nexthop *nexthop_from_blackhole(enum blackhole_type bh_type);
182 
183 /*
184  * Hash a nexthop. Suitable for use with hash tables.
185  *
186  * This function uses the following values when computing the hash:
187  * - vrf_id
188  * - ifindex
189  * - type
190  * - gate
191  *
192  * nexthop
193  *    The nexthop to hash
194  *
195  * Returns:
196  *    32-bit hash of nexthop
197  */
198 uint32_t nexthop_hash(const struct nexthop *nexthop);
199 /*
200  * Hash a nexthop only on word-sized attributes:
201  * - vrf_id
202  * - ifindex
203  * - type
204  * - (some) flags
205  */
206 uint32_t nexthop_hash_quick(const struct nexthop *nexthop);
207 
208 extern bool nexthop_same(const struct nexthop *nh1, const struct nexthop *nh2);
209 extern bool nexthop_same_no_labels(const struct nexthop *nh1,
210 				   const struct nexthop *nh2);
211 extern int nexthop_cmp(const struct nexthop *nh1, const struct nexthop *nh2);
212 extern int nexthop_g_addr_cmp(enum nexthop_types_t type,
213 			      const union g_addr *addr1,
214 			      const union g_addr *addr2);
215 
216 extern const char *nexthop_type_to_str(enum nexthop_types_t nh_type);
217 extern bool nexthop_labels_match(const struct nexthop *nh1,
218 				 const struct nexthop *nh2);
219 extern bool nexthop_same_firsthop(const struct nexthop *next1,
220 				  const struct nexthop *next2);
221 
222 extern const char *nexthop2str(const struct nexthop *nexthop,
223 			       char *str, int size);
224 extern struct nexthop *nexthop_next(const struct nexthop *nexthop);
225 extern struct nexthop *
226 nexthop_next_active_resolved(const struct nexthop *nexthop);
227 extern unsigned int nexthop_level(const struct nexthop *nexthop);
228 /* Copies to an already allocated nexthop struct */
229 extern void nexthop_copy(struct nexthop *copy, const struct nexthop *nexthop,
230 			 struct nexthop *rparent);
231 /* Copies to an already allocated nexthop struct, not including recurse info */
232 extern void nexthop_copy_no_recurse(struct nexthop *copy,
233 				    const struct nexthop *nexthop,
234 				    struct nexthop *rparent);
235 /* Duplicates a nexthop and returns the newly allocated nexthop */
236 extern struct nexthop *nexthop_dup(const struct nexthop *nexthop,
237 				   struct nexthop *rparent);
238 /* Duplicates a nexthop and returns the newly allocated nexthop */
239 extern struct nexthop *nexthop_dup_no_recurse(const struct nexthop *nexthop,
240 					      struct nexthop *rparent);
241 
242 /*
243  * Parse one or more backup index values, as comma-separated numbers,
244  * into caller's array of uint8_ts. The array must be NEXTHOP_MAX_BACKUPS
245  * in size. Mails back the number of values converted, and returns 0 on
246  * success, <0 if an error in parsing.
247  */
248 int nexthop_str2backups(const char *str, int *num_backups,
249 			uint8_t *backups);
250 
251 #ifdef _FRR_ATTRIBUTE_PRINTFRR
252 #pragma FRR printfrr_ext "%pNH"  (struct nexthop *)
253 #endif
254 
255 #ifdef __cplusplus
256 }
257 #endif
258 
259 #endif /*_LIB_NEXTHOP_H */
260