]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_route.h
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / ospf6d / ospf6_route.h
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2003 Yasuhiro Ohara
4 */
5
6 #ifndef OSPF6_ROUTE_H
7 #define OSPF6_ROUTE_H
8
9 #include "command.h"
10 #include "zclient.h"
11 #include "lib/json.h"
12 #include "lib/nexthop.h"
13
14 #define OSPF6_MULTI_PATH_LIMIT 4
15
16 /* Debug option */
17 extern unsigned char conf_debug_ospf6_route;
18 #define OSPF6_DEBUG_ROUTE_TABLE 0x01
19 #define OSPF6_DEBUG_ROUTE_INTRA 0x02
20 #define OSPF6_DEBUG_ROUTE_INTER 0x04
21 #define OSPF6_DEBUG_ROUTE_MEMORY 0x08
22 #define OSPF6_DEBUG_ROUTE_ALL \
23 (OSPF6_DEBUG_ROUTE_TABLE | OSPF6_DEBUG_ROUTE_INTRA \
24 | OSPF6_DEBUG_ROUTE_INTER | OSPF6_DEBUG_ROUTE_MEMORY)
25 #define OSPF6_DEBUG_ROUTE_ON(level) (conf_debug_ospf6_route |= (level))
26 #define OSPF6_DEBUG_ROUTE_OFF(level) (conf_debug_ospf6_route &= ~(level))
27 #define IS_OSPF6_DEBUG_ROUTE(e) (conf_debug_ospf6_route & OSPF6_DEBUG_ROUTE_##e)
28
29 /* Nexthop */
30 struct ospf6_nexthop {
31 /* Interface index */
32 ifindex_t ifindex;
33
34 /* IP address, if any */
35 struct in6_addr address;
36
37 /** Next-hop type information. */
38 enum nexthop_types_t type;
39 };
40
41 static inline bool ospf6_nexthop_is_set(const struct ospf6_nexthop *nh)
42 {
43 return nh->type != 0;
44 }
45
46 static inline bool ospf6_nexthop_is_same(const struct ospf6_nexthop *nha,
47 const struct ospf6_nexthop *nhb)
48 {
49 if (nha->type != nhb->type)
50 return false;
51
52 switch (nha->type) {
53 case NEXTHOP_TYPE_BLACKHOLE:
54 /* NOTHING */
55 break;
56
57 case NEXTHOP_TYPE_IFINDEX:
58 if (nha->ifindex != nhb->ifindex)
59 return false;
60 break;
61
62 case NEXTHOP_TYPE_IPV4_IFINDEX:
63 case NEXTHOP_TYPE_IPV4:
64 /* OSPFv3 does not support IPv4 next hops. */
65 return false;
66
67 case NEXTHOP_TYPE_IPV6_IFINDEX:
68 if (nha->ifindex != nhb->ifindex)
69 return false;
70 /* FALLTHROUGH */
71 case NEXTHOP_TYPE_IPV6:
72 if (!IN6_ARE_ADDR_EQUAL(&nha->address, &nhb->address))
73 return false;
74 break;
75 }
76
77 return true;
78 }
79
80 static inline void ospf6_nexthop_clear(struct ospf6_nexthop *nh)
81 {
82 memset(nh, 0, sizeof(*nh));
83 }
84
85 static inline void ospf6_nexthop_copy(struct ospf6_nexthop *nha,
86 const struct ospf6_nexthop *nhb)
87 {
88 memcpy(nha, nhb, sizeof(*nha));
89 }
90
91 /* Path */
92 struct ospf6_ls_origin {
93 uint16_t type;
94 in_addr_t id;
95 in_addr_t adv_router;
96 };
97
98 struct ospf6_path {
99 /* Link State Origin */
100 struct ospf6_ls_origin origin;
101
102 /* Router bits */
103 uint8_t router_bits;
104
105 /* Optional Capabilities */
106 uint8_t options[3];
107
108 /* Associated Area */
109 in_addr_t area_id;
110
111 /* Path-type */
112 uint8_t type;
113 uint8_t subtype; /* only used for redistribute i.e ZEBRA_ROUTE_XXX */
114
115 /* Cost */
116 uint8_t metric_type;
117 uint32_t cost;
118
119 struct prefix ls_prefix;
120
121 union {
122 uint32_t cost_e2;
123 uint32_t cost_config;
124 } u;
125 uint32_t tag;
126
127 /* nh list for this path */
128 struct list *nh_list;
129 };
130
131 #define OSPF6_PATH_TYPE_NONE 0
132 #define OSPF6_PATH_TYPE_INTRA 1
133 #define OSPF6_PATH_TYPE_INTER 2
134 #define OSPF6_PATH_TYPE_EXTERNAL1 3
135 #define OSPF6_PATH_TYPE_EXTERNAL2 4
136 #define OSPF6_PATH_TYPE_MAX 5
137
138 #define OSPF6_PATH_SUBTYPE_DEFAULT_RT 1
139
140 #define OSPF6_PATH_COST_IS_CONFIGURED(path) (path.u.cost_config != OSPF_AREA_RANGE_COST_UNSPEC)
141
142 #include "prefix.h"
143 #include "table.h"
144 #include "bitfield.h"
145
146 struct ospf6_route {
147 struct route_node *rnode;
148 struct ospf6_route_table *table;
149 struct ospf6_route *prev;
150 struct ospf6_route *next;
151
152 /* Back pointer to ospf6 */
153 struct ospf6 *ospf6;
154
155 unsigned int lock;
156
157 /* Destination Type */
158 uint8_t type;
159
160 /* XXX: It would likely be better to use separate struct in_addr's
161 * for the advertising router-ID and prefix IDs, instead of stuffing
162 * them
163 * into one. See also XXX below.
164 */
165 /* Destination ID */
166 struct prefix prefix;
167
168 /* Time */
169 struct timeval installed;
170 struct timeval changed;
171
172 /* flag */
173 uint16_t flag;
174
175 /* Prefix Options */
176 uint8_t prefix_options;
177
178 /* route option */
179 void *route_option;
180
181 /* link state id for advertising */
182 uint32_t linkstate_id;
183
184 /* path */
185 struct ospf6_path path;
186
187 /* List of Paths. */
188 struct list *paths;
189
190 /* nexthop */
191 struct list *nh_list;
192
193 /* points to the summarised route */
194 struct ospf6_external_aggr_rt *aggr_route;
195
196 /* For Aggr routes */
197 bool to_be_processed;
198 };
199
200 #define OSPF6_DEST_TYPE_NONE 0
201 #define OSPF6_DEST_TYPE_ROUTER 1
202 #define OSPF6_DEST_TYPE_NETWORK 2
203 #define OSPF6_DEST_TYPE_DISCARD 3
204 #define OSPF6_DEST_TYPE_LINKSTATE 4
205 #define OSPF6_DEST_TYPE_RANGE 5
206 #define OSPF6_DEST_TYPE_MAX 6
207
208 #define OSPF6_ROUTE_CHANGE 0x0001
209 #define OSPF6_ROUTE_ADD 0x0002
210 #define OSPF6_ROUTE_REMOVE 0x0004
211 #define OSPF6_ROUTE_BEST 0x0008
212 #define OSPF6_ROUTE_ACTIVE_SUMMARY 0x0010
213 #define OSPF6_ROUTE_DO_NOT_ADVERTISE 0x0020
214 #define OSPF6_ROUTE_WAS_REMOVED 0x0040
215 #define OSPF6_ROUTE_BLACKHOLE_ADDED 0x0080
216 #define OSPF6_ROUTE_NSSA_RANGE 0x0100
217 struct ospf6;
218
219 struct ospf6_route_table {
220 int scope_type;
221 int table_type;
222 void *scope;
223
224 /* patricia tree */
225 struct route_table *table;
226
227 uint32_t count;
228
229 /* hooks */
230 void (*hook_add)(struct ospf6_route *);
231 void (*hook_change)(struct ospf6_route *);
232 void (*hook_remove)(struct ospf6_route *);
233 };
234
235 #define OSPF6_SCOPE_TYPE_NONE 0
236 #define OSPF6_SCOPE_TYPE_GLOBAL 1
237 #define OSPF6_SCOPE_TYPE_AREA 2
238 #define OSPF6_SCOPE_TYPE_INTERFACE 3
239
240 #define OSPF6_TABLE_TYPE_NONE 0
241 #define OSPF6_TABLE_TYPE_ROUTES 1
242 #define OSPF6_TABLE_TYPE_BORDER_ROUTERS 2
243 #define OSPF6_TABLE_TYPE_CONNECTED_ROUTES 3
244 #define OSPF6_TABLE_TYPE_EXTERNAL_ROUTES 4
245 #define OSPF6_TABLE_TYPE_SPF_RESULTS 5
246 #define OSPF6_TABLE_TYPE_PREFIX_RANGES 6
247 #define OSPF6_TABLE_TYPE_SUMMARY_PREFIXES 7
248 #define OSPF6_TABLE_TYPE_SUMMARY_ROUTERS 8
249
250 #define OSPF6_ROUTE_TABLE_CREATE(s, t) \
251 ospf6_route_table_create(OSPF6_SCOPE_TYPE_##s, OSPF6_TABLE_TYPE_##t)
252
253 extern const char *const ospf6_dest_type_str[OSPF6_DEST_TYPE_MAX];
254 extern const char *const ospf6_dest_type_substr[OSPF6_DEST_TYPE_MAX];
255 #define OSPF6_DEST_TYPE_NAME(x) \
256 (0 < (x) && (x) < OSPF6_DEST_TYPE_MAX ? ospf6_dest_type_str[(x)] \
257 : ospf6_dest_type_str[0])
258 #define OSPF6_DEST_TYPE_SUBSTR(x) \
259 (0 < (x) && (x) < OSPF6_DEST_TYPE_MAX ? ospf6_dest_type_substr[(x)] \
260 : ospf6_dest_type_substr[0])
261
262 extern const char *const ospf6_path_type_str[OSPF6_PATH_TYPE_MAX];
263 extern const char *const ospf6_path_type_substr[OSPF6_PATH_TYPE_MAX];
264 #define OSPF6_PATH_TYPE_NAME(x) \
265 (0 < (x) && (x) < OSPF6_PATH_TYPE_MAX ? ospf6_path_type_str[(x)] \
266 : ospf6_path_type_str[0])
267 #define OSPF6_PATH_TYPE_SUBSTR(x) \
268 (0 < (x) && (x) < OSPF6_PATH_TYPE_MAX ? ospf6_path_type_substr[(x)] \
269 : ospf6_path_type_substr[0])
270 #define OSPF6_PATH_TYPE_JSON(x) \
271 (0 < (x) && (x) < OSPF6_PATH_TYPE_MAX ? ospf6_path_type_json[(x)] \
272 : ospf6_path_type_json[0])
273
274 #define OSPF6_ROUTE_ADDRESS_STR "Display the route bestmatches the address\n"
275 #define OSPF6_ROUTE_PREFIX_STR "Display the route\n"
276 #define OSPF6_ROUTE_MATCH_STR "Display the route matches the prefix\n"
277
278 #define ospf6_route_is_prefix(p, r) (prefix_same(p, &(r)->prefix))
279 #define ospf6_route_is_same(ra, rb) (prefix_same(&(ra)->prefix, &(rb)->prefix))
280 #define ospf6_route_is_same_origin(ra, rb) \
281 ((ra)->path.area_id == (rb)->path.area_id \
282 && (ra)->path.origin.type == (rb)->path.origin.type \
283 && (ra)->path.origin.id == (rb)->path.origin.id \
284 && (ra)->path.origin.adv_router == (rb)->path.origin.adv_router)
285 #define ospf6_route_is_identical(ra, rb) \
286 ((ra)->type == (rb)->type && \
287 prefix_same(&(ra)->prefix, &(rb)->prefix) && \
288 (ra)->path.type == (rb)->path.type && \
289 (ra)->path.cost == (rb)->path.cost && \
290 (ra)->path.u.cost_e2 == (rb)->path.u.cost_e2 && \
291 listcount(ra->paths) == listcount(rb->paths) && \
292 ospf6_route_cmp_nexthops(ra, rb))
293
294 #define ospf6_route_is_best(r) (CHECK_FLAG ((r)->flag, OSPF6_ROUTE_BEST))
295
296 #define ospf6_linkstate_prefix_adv_router(x) ((x)->u.lp.id.s_addr)
297 #define ospf6_linkstate_prefix_id(x) ((x)->u.lp.adv_router.s_addr)
298
299 #define ADV_ROUTER_IN_PREFIX(x) ((x)->u.lp.id.s_addr)
300
301 /* Function prototype */
302 extern void ospf6_linkstate_prefix(uint32_t adv_router, uint32_t id,
303 struct prefix *prefix);
304 extern void ospf6_linkstate_prefix2str(struct prefix *prefix, char *buf,
305 int size);
306
307 extern struct ospf6_nexthop *ospf6_nexthop_create(void);
308 extern int ospf6_nexthop_cmp(struct ospf6_nexthop *a, struct ospf6_nexthop *b);
309 extern void ospf6_nexthop_delete(struct ospf6_nexthop *nh);
310 extern void ospf6_clear_nexthops(struct list *nh_list);
311 extern int ospf6_num_nexthops(struct list *nh_list);
312 extern void ospf6_copy_nexthops(struct list *dst, struct list *src);
313 extern void ospf6_merge_nexthops(struct list *dst, struct list *src);
314 extern void ospf6_add_nexthop(struct list *nh_list, int ifindex,
315 struct in6_addr *addr);
316 extern void ospf6_add_route_nexthop_blackhole(struct ospf6_route *route);
317 extern int ospf6_num_nexthops(struct list *nh_list);
318 extern bool ospf6_route_cmp_nexthops(struct ospf6_route *a,
319 struct ospf6_route *b);
320 extern void ospf6_route_zebra_copy_nexthops(struct ospf6_route *route,
321 struct zapi_nexthop nexthops[],
322 int entries, vrf_id_t vrf_id);
323 extern int ospf6_route_get_first_nh_index(struct ospf6_route *route);
324
325 /* Hide abstraction of nexthop implementation in route from outsiders */
326 #define ospf6_route_copy_nexthops(dst, src) ospf6_copy_nexthops(dst->nh_list, src->nh_list)
327 #define ospf6_route_merge_nexthops(dst, src) ospf6_merge_nexthops(dst->nh_list, src->nh_list)
328 #define ospf6_route_num_nexthops(route) ospf6_num_nexthops(route->nh_list)
329 #define ospf6_route_add_nexthop(route, ifindex, addr) \
330 ospf6_add_nexthop(route->nh_list, ifindex, addr)
331
332 extern struct ospf6_route *ospf6_route_create(struct ospf6 *ospf6);
333 extern void ospf6_route_delete(struct ospf6_route *route);
334 extern struct ospf6_route *ospf6_route_copy(struct ospf6_route *route);
335 extern int ospf6_route_cmp(struct ospf6_route *ra, struct ospf6_route *rb);
336
337 extern void ospf6_route_lock(struct ospf6_route *route);
338 extern void ospf6_route_unlock(struct ospf6_route *route);
339 extern struct ospf6_route *ospf6_route_lookup(struct prefix *prefix,
340 struct ospf6_route_table *table);
341 extern struct ospf6_route *
342 ospf6_route_lookup_identical(struct ospf6_route *route,
343 struct ospf6_route_table *table);
344 extern struct ospf6_route *
345 ospf6_route_lookup_bestmatch(struct prefix *prefix,
346 struct ospf6_route_table *table);
347
348 extern struct ospf6_route *ospf6_route_add(struct ospf6_route *route,
349 struct ospf6_route_table *table);
350 extern void ospf6_route_remove(struct ospf6_route *route,
351 struct ospf6_route_table *table);
352
353 extern struct ospf6_route *ospf6_route_head(struct ospf6_route_table *table);
354 extern struct ospf6_route *ospf6_route_next(struct ospf6_route *route);
355 extern struct ospf6_route *ospf6_route_best_next(struct ospf6_route *route);
356
357 extern struct ospf6_route *
358 ospf6_route_match_head(struct prefix *prefix, struct ospf6_route_table *table);
359 extern struct ospf6_route *ospf6_route_match_next(struct prefix *prefix,
360 struct ospf6_route *route);
361
362 extern void ospf6_route_remove_all(struct ospf6_route_table *table);
363 extern struct ospf6_route_table *ospf6_route_table_create(int s, int t);
364 extern void ospf6_route_table_delete(struct ospf6_route_table *table);
365 extern void ospf6_route_dump(struct ospf6_route_table *table);
366
367
368 extern void ospf6_route_show(struct vty *vty, struct ospf6_route *route,
369 json_object *json, bool use_json);
370 extern void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route,
371 json_object *json, bool use_json);
372
373
374 extern int ospf6_route_table_show(struct vty *vty, int argc_start, int argc,
375 struct cmd_token **argv,
376 struct ospf6_route_table *table,
377 bool use_json);
378 extern int ospf6_linkstate_table_show(struct vty *vty, int idx_ipv4, int argc,
379 struct cmd_token **argv,
380 struct ospf6_route_table *table);
381
382 extern void ospf6_brouter_show_header(struct vty *vty);
383 extern void ospf6_brouter_show(struct vty *vty, struct ospf6_route *route);
384
385 extern int config_write_ospf6_debug_route(struct vty *vty);
386 extern void install_element_ospf6_debug_route(void);
387 extern void ospf6_route_init(void);
388 extern void ospf6_path_free(struct ospf6_path *op);
389 extern struct ospf6_path *ospf6_path_dup(struct ospf6_path *path);
390 extern void ospf6_copy_paths(struct list *dst, struct list *src);
391
392 #endif /* OSPF6_ROUTE_H */