summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_route.h
blob: 72923901b837cca1a3ea4f73a9d6b6871c0f9625 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
/* BGP routing information base
 * Copyright (C) 1996, 97, 98, 2000 Kunihiro Ishiguro
 *
 * This file is part of GNU Zebra.
 *
 * GNU Zebra is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * GNU Zebra is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; see the file COPYING; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef _QUAGGA_BGP_ROUTE_H
#define _QUAGGA_BGP_ROUTE_H

#include "queue.h"
#include "nexthop.h"
#include "bgp_table.h"

struct bgp_nexthop_cache;
struct bgp_route_evpn;

enum bgp_show_type {
	bgp_show_type_normal,
	bgp_show_type_regexp,
	bgp_show_type_prefix_list,
	bgp_show_type_filter_list,
	bgp_show_type_route_map,
	bgp_show_type_neighbor,
	bgp_show_type_cidr_only,
	bgp_show_type_prefix_longer,
	bgp_show_type_community_all,
	bgp_show_type_community,
	bgp_show_type_community_exact,
	bgp_show_type_community_list,
	bgp_show_type_community_list_exact,
	bgp_show_type_lcommunity_all,
	bgp_show_type_lcommunity,
	bgp_show_type_lcommunity_list,
	bgp_show_type_flap_statistics,
	bgp_show_type_flap_neighbor,
	bgp_show_type_dampend_paths,
	bgp_show_type_damp_neighbor,
	bgp_show_type_detail,
};

enum bgp_show_adj_route_type {
	bgp_show_adj_route_advertised,
	bgp_show_adj_route_received,
	bgp_show_adj_route_filtered,
};


#define BGP_SHOW_SCODE_HEADER                                                  \
	"Status codes:  s suppressed, d damped, "                              \
	"h history, * valid, > best, = multipath,\n"                           \
	"               i internal, r RIB-failure, S Stale, R Removed\n"
#define BGP_SHOW_OCODE_HEADER "Origin codes:  i - IGP, e - EGP, ? - incomplete\n\n"
#define BGP_SHOW_NCODE_HEADER "Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self\n"
#define BGP_SHOW_HEADER "   Network          Next Hop            Metric LocPrf Weight Path\n"

/* Maximum number of labels we can process or send with a prefix. We
 * really do only 1 for MPLS (BGP-LU) but we can do 2 for EVPN-VxLAN.
 */
#define BGP_MAX_LABELS 2

/* Ancillary information to struct bgp_info,
 * used for uncommonly used data (aggregation, MPLS, etc.)
 * and lazily allocated to save memory.
 */
struct bgp_info_extra {
	/* Pointer to dampening structure.  */
	struct bgp_damp_info *damp_info;

	/* This route is suppressed with aggregation.  */
	int suppress;

	/* Nexthop reachability check.  */
	uint32_t igpmetric;

	/* MPLS label(s) - VNI(s) for EVPN-VxLAN  */
	mpls_label_t label[BGP_MAX_LABELS];
	uint32_t num_labels;

#if ENABLE_BGP_VNC
	union {

		struct {
			void *rfapi_handle; /* export: NVE advertising this
					       route */
			struct list *local_nexthops; /* optional, for static
							routes */
		} export;

		struct {
			struct thread *timer;
			void *hme; /* encap monitor, if this is a VPN route */
			struct prefix_rd
				rd; /* import: route's route-distinguisher */
			uint8_t un_family; /* family of cached un address, 0 if
					     unset */
			union {
				struct in_addr addr4;
				struct in6_addr addr6;
			} un; /* cached un address */
			time_t create_time;
			struct prefix aux_prefix; /* AFI_L2VPN: the IP addr,
						     if family set */
		} import;

	} vnc;
#endif

	/* For imported routes into a VNI (or VRF), this points to the parent.
	 */
	void *parent;

	/*
	 * Some tunnelish parameters follow. Maybe consolidate into an
	 * internal tunnel structure?
	 */

	/*
	 * Original bgp instance for imported routes. Needed for:
	 * 1. Find all routes from a specific vrf for deletion
	 * 2. vrf context of original nexthop
	 *
	 * Store pointer to bgp instance rather than bgp->vrf_id because
	 * bgp->vrf_id is not always valid (or may change?).
	 *
	 * Set to NULL if route is not imported from another bgp instance.
	 */
	struct bgp *bgp_orig;

	/*
	 * Nexthop in context of original bgp instance. Needed
	 * for label resolution of core mpls routes exported to a vrf.
	 * Set nexthop_orig.family to 0 if not valid.
	 */
	struct prefix nexthop_orig;
	/* presence of FS pbr entry */
	void *bgp_fs_pbr;
};

struct bgp_info {
	/* For linked list. */
	struct bgp_info *next;
	struct bgp_info *prev;

	/* For nexthop linked list */
	LIST_ENTRY(bgp_info) nh_thread;

	/* Back pointer to the prefix node */
	struct bgp_node *net;

	/* Back pointer to the nexthop structure */
	struct bgp_nexthop_cache *nexthop;

	/* Peer structure.  */
	struct peer *peer;

	/* Attribute structure.  */
	struct attr *attr;

	/* Extra information */
	struct bgp_info_extra *extra;


	/* Multipath information */
	struct bgp_info_mpath *mpath;

	/* Uptime.  */
	time_t uptime;

	/* reference count */
	int lock;

	/* BGP information status.  */
	uint16_t flags;
#define BGP_INFO_IGP_CHANGED    (1 << 0)
#define BGP_INFO_DAMPED         (1 << 1)
#define BGP_INFO_HISTORY        (1 << 2)
#define BGP_INFO_SELECTED       (1 << 3)
#define BGP_INFO_VALID          (1 << 4)
#define BGP_INFO_ATTR_CHANGED   (1 << 5)
#define BGP_INFO_DMED_CHECK     (1 << 6)
#define BGP_INFO_DMED_SELECTED  (1 << 7)
#define BGP_INFO_STALE          (1 << 8)
#define BGP_INFO_REMOVED        (1 << 9)
#define BGP_INFO_COUNTED	(1 << 10)
#define BGP_INFO_MULTIPATH      (1 << 11)
#define BGP_INFO_MULTIPATH_CHG  (1 << 12)
#define BGP_INFO_RIB_ATTR_CHG   (1 << 13)
#define BGP_INFO_ANNC_NH_SELF   (1 << 14)

	/* BGP route type.  This can be static, RIP, OSPF, BGP etc.  */
	uint8_t type;

	/* When above type is BGP.  This sub type specify BGP sub type
	   information.  */
	uint8_t sub_type;
#define BGP_ROUTE_NORMAL       0
#define BGP_ROUTE_STATIC       1
#define BGP_ROUTE_AGGREGATE    2
#define BGP_ROUTE_REDISTRIBUTE 3 
#ifdef ENABLE_BGP_VNC
# define BGP_ROUTE_RFP          4 
#endif
#define BGP_ROUTE_IMPORTED     5        /* from another bgp instance/safi */

	unsigned short instance;

	/* Addpath identifiers */
	uint32_t addpath_rx_id;
	uint32_t addpath_tx_id;
};

/* Structure used in BGP path selection */
struct bgp_info_pair {
	struct bgp_info *old;
	struct bgp_info *new;
};

/* BGP static route configuration. */
struct bgp_static {
	/* Backdoor configuration.  */
	int backdoor;

	/* Label index configuration; applies to LU prefixes. */
	uint32_t label_index;
#define BGP_INVALID_LABEL_INDEX   0xFFFFFFFF

	/* Import check status.  */
	uint8_t valid;

	/* IGP metric. */
	uint32_t igpmetric;

	/* IGP nexthop. */
	struct in_addr igpnexthop;

	/* Atomic set reference count (ie cause of pathlimit) */
	uint32_t atomic;

	/* BGP redistribute route-map.  */
	struct {
		char *name;
		struct route_map *map;
	} rmap;

	/* Route Distinguisher */
	struct prefix_rd prd;

	/* MPLS label.  */
	mpls_label_t label;

	/* EVPN */
	struct eth_segment_id *eth_s_id;
	struct ethaddr *router_mac;
	uint16_t encap_tunneltype;
	struct prefix gatewayIp;
};

#define BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen)                                      \
	((nhlen) < IPV4_MAX_BYTELEN                                            \
		 ? 0                                                           \
		 : ((nhlen) < IPV6_MAX_BYTELEN ? AFI_IP : AFI_IP6))

#define BGP_ATTR_NEXTHOP_AFI_IP6(attr)                                         \
	(!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP))             \
	 && ((attr)->mp_nexthop_len == 16 || (attr)->mp_nexthop_len == 32))
#define BGP_INFO_COUNTABLE(BI)                                                 \
	(!CHECK_FLAG((BI)->flags, BGP_INFO_HISTORY)                            \
	 && !CHECK_FLAG((BI)->flags, BGP_INFO_REMOVED))

/* Flags which indicate a route is unuseable in some form */
#define BGP_INFO_UNUSEABLE                                                     \
	(BGP_INFO_HISTORY | BGP_INFO_DAMPED | BGP_INFO_REMOVED)
/* Macro to check BGP information is alive or not.  Sadly,
 * not equivalent to just checking previous, because of the
 * sense of the additional VALID flag.
 */
#define BGP_INFO_HOLDDOWN(BI)                                                  \
	(!CHECK_FLAG((BI)->flags, BGP_INFO_VALID)                              \
	 || CHECK_FLAG((BI)->flags, BGP_INFO_UNUSEABLE))

#define DISTRIBUTE_IN_NAME(F)   ((F)->dlist[FILTER_IN].name)
#define DISTRIBUTE_IN(F)        ((F)->dlist[FILTER_IN].alist)
#define DISTRIBUTE_OUT_NAME(F)  ((F)->dlist[FILTER_OUT].name)
#define DISTRIBUTE_OUT(F)       ((F)->dlist[FILTER_OUT].alist)

#define PREFIX_LIST_IN_NAME(F)  ((F)->plist[FILTER_IN].name)
#define PREFIX_LIST_IN(F)       ((F)->plist[FILTER_IN].plist)
#define PREFIX_LIST_OUT_NAME(F) ((F)->plist[FILTER_OUT].name)
#define PREFIX_LIST_OUT(F)      ((F)->plist[FILTER_OUT].plist)

#define FILTER_LIST_IN_NAME(F)  ((F)->aslist[FILTER_IN].name)
#define FILTER_LIST_IN(F)       ((F)->aslist[FILTER_IN].aslist)
#define FILTER_LIST_OUT_NAME(F) ((F)->aslist[FILTER_OUT].name)
#define FILTER_LIST_OUT(F)      ((F)->aslist[FILTER_OUT].aslist)

#define ROUTE_MAP_IN_NAME(F)    ((F)->map[RMAP_IN].name)
#define ROUTE_MAP_IN(F)         ((F)->map[RMAP_IN].map)
#define ROUTE_MAP_OUT_NAME(F)   ((F)->map[RMAP_OUT].name)
#define ROUTE_MAP_OUT(F)        ((F)->map[RMAP_OUT].map)

#define UNSUPPRESS_MAP_NAME(F)  ((F)->usmap.name)
#define UNSUPPRESS_MAP(F)       ((F)->usmap.map)

/* path PREFIX (addpath rxid NUMBER) */
#define PATH_ADDPATH_STR_BUFFER PREFIX2STR_BUFFER + 32

enum bgp_path_type { BGP_PATH_ALL, BGP_PATH_BESTPATH, BGP_PATH_MULTIPATH };

static inline void bgp_bump_version(struct bgp_node *node)
{
	node->version = bgp_table_next_version(bgp_node_table(node));
}

static inline int bgp_fibupd_safi(safi_t safi)
{
	if (safi == SAFI_UNICAST || safi == SAFI_MULTICAST
	    || safi == SAFI_LABELED_UNICAST
	    || safi == SAFI_FLOWSPEC)
		return 1;
	return 0;
}

/* Prototypes. */
extern void bgp_rib_remove(struct bgp_node *rn, struct bgp_info *ri,
			   struct peer *peer, afi_t afi, safi_t safi);
extern void bgp_process_queue_init(void);
extern void bgp_route_init(void);
extern void bgp_route_finish(void);
extern void bgp_cleanup_routes(struct bgp *);
extern void bgp_announce_route(struct peer *, afi_t, safi_t);
extern void bgp_stop_announce_route_timer(struct peer_af *paf);
extern void bgp_announce_route_all(struct peer *);
extern void bgp_default_originate(struct peer *, afi_t, safi_t, int);
extern void bgp_soft_reconfig_in(struct peer *, afi_t, safi_t);
extern void bgp_clear_route(struct peer *, afi_t, safi_t);
extern void bgp_clear_route_all(struct peer *);
extern void bgp_clear_adj_in(struct peer *, afi_t, safi_t);
extern void bgp_clear_stale_route(struct peer *, afi_t, safi_t);

extern struct bgp_node *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
					 safi_t safi, struct prefix *p,
					 struct prefix_rd *prd);
extern struct bgp_info *bgp_info_lock(struct bgp_info *);
extern struct bgp_info *bgp_info_unlock(struct bgp_info *);
extern void bgp_info_add(struct bgp_node *rn, struct bgp_info *ri);
extern void bgp_info_reap(struct bgp_node *rn, struct bgp_info *ri);
extern void bgp_info_delete(struct bgp_node *rn, struct bgp_info *ri);
extern struct bgp_info_extra *bgp_info_extra_get(struct bgp_info *);
extern void bgp_info_set_flag(struct bgp_node *, struct bgp_info *, uint32_t);
extern void bgp_info_unset_flag(struct bgp_node *, struct bgp_info *, uint32_t);
extern void bgp_info_path_with_addpath_rx_str(struct bgp_info *ri, char *buf);

extern int bgp_nlri_parse_ip(struct peer *, struct attr *, struct bgp_nlri *);

extern int bgp_maximum_prefix_overflow(struct peer *, afi_t, safi_t, int);

extern void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
				 const union g_addr *nexthop, ifindex_t ifindex,
				 enum nexthop_types_t nhtype, uint32_t metric,
				 uint8_t type, unsigned short instance,
				 route_tag_t tag);
extern void bgp_redistribute_delete(struct bgp *, struct prefix *, uint8_t,
				    unsigned short);
extern void bgp_redistribute_withdraw(struct bgp *, afi_t, int, unsigned short);

extern void bgp_static_add(struct bgp *);
extern void bgp_static_delete(struct bgp *);
extern void bgp_static_redo_import_check(struct bgp *);
extern void bgp_purge_static_redist_routes(struct bgp *bgp);
extern void bgp_static_update(struct bgp *, struct prefix *,
			      struct bgp_static *, afi_t, safi_t);
extern void bgp_static_withdraw(struct bgp *, struct prefix *, afi_t, safi_t);

extern int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
			       const char *, const char *, const char *,
			       const char *, int, const char *, const char *,
			       const char *, const char *);

extern int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *,
				 const char *, const char *, const char *, int,
				 const char *, const char *, const char *);

/* this is primarily for MPLS-VPN */
extern int bgp_update(struct peer *, struct prefix *, uint32_t, struct attr *,
		      afi_t, safi_t, int, int, struct prefix_rd *,
		      mpls_label_t *, uint32_t, int, struct bgp_route_evpn *);
extern int bgp_withdraw(struct peer *, struct prefix *, uint32_t, struct attr *,
			afi_t, safi_t, int, int, struct prefix_rd *,
			mpls_label_t *, uint32_t, struct bgp_route_evpn *);

/* for bgp_nexthop and bgp_damp */
extern void bgp_process(struct bgp *, struct bgp_node *, afi_t, safi_t);

/*
 * Add an end-of-initial-update marker to the process queue. This is just a
 * queue element with NULL bgp node.
 */
extern void bgp_add_eoiu_mark(struct bgp *);
extern void bgp_config_write_table_map(struct vty *, struct bgp *, afi_t,
				       safi_t);
extern void bgp_config_write_network(struct vty *, struct bgp *, afi_t, safi_t);
extern void bgp_config_write_distance(struct vty *, struct bgp *, afi_t,
				      safi_t);

extern void bgp_aggregate_increment(struct bgp *, struct prefix *,
				    struct bgp_info *, afi_t, safi_t);
extern void bgp_aggregate_decrement(struct bgp *, struct prefix *,
				    struct bgp_info *, afi_t, safi_t);

extern uint8_t bgp_distance_apply(struct prefix *, struct bgp_info *, afi_t,
				  safi_t, struct bgp *);

extern afi_t bgp_node_afi(struct vty *);
extern safi_t bgp_node_safi(struct vty *);

extern struct bgp_info *info_make(int type, int sub_type,
				  unsigned short instance, struct peer *peer,
				  struct attr *attr, struct bgp_node *rn);

extern void route_vty_out(struct vty *, struct prefix *, struct bgp_info *, int,
			  safi_t, json_object *);
extern void route_vty_out_tag(struct vty *, struct prefix *, struct bgp_info *,
			      int, safi_t, json_object *);
extern void route_vty_out_tmp(struct vty *, struct prefix *, struct attr *,
			      safi_t, uint8_t, json_object *);
extern void route_vty_out_overlay(struct vty *vty, struct prefix *p,
				  struct bgp_info *binfo, int display,
				  json_object *json);

extern int subgroup_process_announce_selected(struct update_subgroup *subgrp,
					      struct bgp_info *selected,
					      struct bgp_node *rn,
					      uint32_t addpath_tx_id);

extern int subgroup_announce_check(struct bgp_node *rn, struct bgp_info *ri,
				   struct update_subgroup *subgrp,
				   struct prefix *p, struct attr *attr);

extern void bgp_peer_clear_node_queue_drain_immediate(struct peer *peer);
extern void bgp_process_queues_drain_immediate(void);

/* for encap/vpn */
extern struct bgp_node *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
					    safi_t safi, struct prefix *p,
					    struct prefix_rd *prd);
extern struct bgp_info *bgp_info_new(void);
extern void bgp_info_restore(struct bgp_node *, struct bgp_info *);

extern int bgp_info_cmp_compatible(struct bgp *, struct bgp_info *,
				   struct bgp_info *, char *pfx_buf, afi_t afi,
				   safi_t safi);
extern void bgp_attr_add_gshut_community(struct attr *attr);

extern void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
			       struct bgp_maxpaths_cfg *mpath_cfg,
			       struct bgp_info_pair *result, afi_t afi,
			       safi_t safi);
extern void bgp_zebra_clear_route_change_flags(struct bgp_node *rn);
extern int bgp_zebra_has_route_changed(struct bgp_node *rn,
				       struct bgp_info *selected);

extern void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
					struct bgp_node *rn,
					struct prefix_rd *prd, afi_t afi,
					safi_t safi, json_object *json);
extern void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
				 struct prefix *p, struct bgp_info *binfo,
				 afi_t afi, safi_t safi,
				 json_object *json_paths);
extern int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
			     struct bgp_table *table, struct prefix_rd *prd,
			     enum bgp_show_type type, void *output_arg,
			     uint8_t use_json);
#endif /* _QUAGGA_BGP_ROUTE_H */