GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/bgpd/rde.h Lines: 0 1 0.0 %
Date: 2017-11-07 Branches: 0 0 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: rde.h,v 1.162 2017/05/30 18:08:15 benno Exp $ */
2
3
/*
4
 * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
5
 *                          Andre Oppermann <oppermann@networx.ch>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
#ifndef __RDE_H__
20
#define __RDE_H__
21
22
#include <sys/types.h>
23
#include <sys/queue.h>
24
#include <sys/tree.h>
25
#include <stdint.h>
26
27
#include "bgpd.h"
28
29
/* rde internal structures */
30
31
enum peer_state {
32
	PEER_NONE,
33
	PEER_DOWN,
34
	PEER_UP,
35
	PEER_ERR	/* error occurred going to PEER_DOWN state */
36
};
37
38
/*
39
 * How do we identify peers between the session handler and the rde?
40
 * Currently I assume that we can do that with the neighbor_ip...
41
 */
42
LIST_HEAD(rde_peer_head, rde_peer);
43
LIST_HEAD(aspath_head, rde_aspath);
44
RB_HEAD(uptree_prefix, update_prefix);
45
RB_HEAD(uptree_attr, update_attr);
46
struct rib_desc;
47
struct rib;
48
RB_HEAD(rib_tree, rib_entry);
49
TAILQ_HEAD(uplist_prefix, update_prefix);
50
TAILQ_HEAD(uplist_attr, update_attr);
51
52
struct rde_peer {
53
	LIST_ENTRY(rde_peer)		 hash_l; /* hash list over all peers */
54
	LIST_ENTRY(rde_peer)		 peer_l; /* list of all peers */
55
	struct aspath_head		 path_h; /* list of all as paths */
56
	struct peer_config		 conf;
57
	struct bgpd_addr		 remote_addr;
58
	struct bgpd_addr		 local_v4_addr;
59
	struct bgpd_addr		 local_v6_addr;
60
	struct uptree_prefix		 up_prefix;
61
	struct uptree_attr		 up_attrs;
62
	struct uplist_attr		 updates[AID_MAX];
63
	struct uplist_prefix		 withdraws[AID_MAX];
64
	struct capabilities		 capa;
65
	time_t				 staletime[AID_MAX];
66
	u_int64_t			 prefix_rcvd_update;
67
	u_int64_t			 prefix_rcvd_withdraw;
68
	u_int64_t			 prefix_rcvd_eor;
69
	u_int64_t			 prefix_sent_update;
70
	u_int64_t			 prefix_sent_withdraw;
71
	u_int64_t			 prefix_sent_eor;
72
	u_int32_t			 prefix_cnt; /* # of prefixes */
73
	u_int32_t			 remote_bgpid; /* host byte order! */
74
	u_int32_t			 up_pcnt;
75
	u_int32_t			 up_acnt;
76
	u_int32_t			 up_nlricnt;
77
	u_int32_t			 up_wcnt;
78
	enum peer_state			 state;
79
	struct rib			*rib;
80
	u_int16_t			 short_as;
81
	u_int16_t			 mrt_idx;
82
	u_int8_t			 reconf_out;	/* out filter changed */
83
	u_int8_t			 reconf_rib;	/* rib changed */
84
	u_int8_t			 throttled;
85
};
86
87
#define AS_SET			1
88
#define AS_SEQUENCE		2
89
#define AS_CONFED_SEQUENCE	3
90
#define AS_CONFED_SET		4
91
#define ASPATH_HEADER_SIZE	(sizeof(struct aspath) - sizeof(u_char))
92
93
LIST_HEAD(aspath_list, aspath);
94
95
struct aspath {
96
	LIST_ENTRY(aspath)	entry;
97
	int			refcnt;	/* reference count */
98
	u_int16_t		len;	/* total length of aspath in octets */
99
	u_int16_t		ascnt;	/* number of AS hops in data */
100
	u_char			data[1]; /* placeholder for actual data */
101
};
102
103
enum attrtypes {
104
	ATTR_UNDEF,
105
	ATTR_ORIGIN,
106
	ATTR_ASPATH,
107
	ATTR_NEXTHOP,
108
	ATTR_MED,
109
	ATTR_LOCALPREF,
110
	ATTR_ATOMIC_AGGREGATE,
111
	ATTR_AGGREGATOR,
112
	ATTR_COMMUNITIES,
113
	ATTR_ORIGINATOR_ID,
114
	ATTR_CLUSTER_LIST,
115
	ATTR_MP_REACH_NLRI=14,
116
	ATTR_MP_UNREACH_NLRI=15,
117
	ATTR_EXT_COMMUNITIES=16,
118
	ATTR_AS4_PATH=17,
119
	ATTR_AS4_AGGREGATOR=18,
120
	ATTR_LARGE_COMMUNITIES=32,
121
};
122
123
/* attribute flags. 4 low order bits reserved */
124
#define	ATTR_EXTLEN		0x10
125
#define ATTR_PARTIAL		0x20
126
#define ATTR_TRANSITIVE		0x40
127
#define ATTR_OPTIONAL		0x80
128
#define ATTR_RESERVED		0x0f
129
/* by default mask the reserved bits and the ext len bit */
130
#define ATTR_DEFMASK		(ATTR_RESERVED | ATTR_EXTLEN)
131
132
/* default attribute flags for well known attributes */
133
#define ATTR_WELL_KNOWN		ATTR_TRANSITIVE
134
135
struct attr {
136
	LIST_ENTRY(attr)		 entry;
137
	u_char				*data;
138
	int				 refcnt;
139
	u_int32_t			 hash;
140
	u_int16_t			 len;
141
	u_int8_t			 flags;
142
	u_int8_t			 type;
143
};
144
145
struct mpattr {
146
	void		*reach;
147
	void		*unreach;
148
	u_int16_t	 reach_len;
149
	u_int16_t	 unreach_len;
150
};
151
152
LIST_HEAD(attr_list, attr);
153
154
struct path_table {
155
	struct aspath_head	*path_hashtbl;
156
	u_int32_t		 path_hashmask;
157
};
158
159
LIST_HEAD(prefix_head, prefix);
160
161
#define	F_ATTR_ORIGIN		0x00001
162
#define	F_ATTR_ASPATH		0x00002
163
#define	F_ATTR_NEXTHOP		0x00004
164
#define	F_ATTR_LOCALPREF	0x00008
165
#define	F_ATTR_MED		0x00010
166
#define	F_ATTR_MED_ANNOUNCE	0x00020
167
#define	F_ATTR_MP_REACH		0x00040
168
#define	F_ATTR_MP_UNREACH	0x00080
169
#define	F_ATTR_AS4BYTE_NEW	0x00100	/* AS4_PATH or AS4_AGGREGATOR */
170
#define	F_ATTR_LOOP		0x00200 /* path would cause a route loop */
171
#define	F_PREFIX_ANNOUNCED	0x00400
172
#define	F_ANN_DYNAMIC		0x00800
173
#define	F_NEXTHOP_SELF		0x01000
174
#define	F_NEXTHOP_REJECT	0x02000
175
#define	F_NEXTHOP_BLACKHOLE	0x04000
176
#define	F_NEXTHOP_NOMODIFY	0x08000
177
#define	F_NEXTHOP_MASK		0x0f000
178
#define	F_ATTR_PARSE_ERR	0x10000
179
#define	F_ATTR_LINKED		0x20000
180
181
182
#define ORIGIN_IGP		0
183
#define ORIGIN_EGP		1
184
#define ORIGIN_INCOMPLETE	2
185
186
#define DEFAULT_LPREF		100
187
188
struct rde_aspath {
189
	LIST_ENTRY(rde_aspath)		 path_l, peer_l, nexthop_l;
190
	struct prefix_head		 prefix_h;
191
	struct attr			**others;
192
	struct rde_peer			*peer;
193
	struct aspath			*aspath;
194
	struct nexthop			*nexthop;	/* may be NULL */
195
	u_int32_t			 med;		/* multi exit disc */
196
	u_int32_t			 lpref;		/* local pref */
197
	u_int32_t			 weight;	/* low prio lpref */
198
	u_int32_t			 prefix_cnt; /* # of prefixes */
199
	u_int32_t			 active_cnt; /* # of active prefixes */
200
	u_int32_t			 flags;		/* internally used */
201
	u_int16_t			 rtlabelid;	/* route label id */
202
	u_int16_t			 pftableid;	/* pf table id */
203
	u_int8_t			 origin;
204
	u_int8_t			 others_len;
205
};
206
207
enum nexthop_state {
208
	NEXTHOP_LOOKUP,
209
	NEXTHOP_UNREACH,
210
	NEXTHOP_REACH
211
};
212
213
struct nexthop {
214
	LIST_ENTRY(nexthop)	nexthop_l;
215
	struct aspath_head	path_h;
216
	struct bgpd_addr	exit_nexthop;
217
	struct bgpd_addr	true_nexthop;
218
	struct bgpd_addr	nexthop_net;
219
#if 0
220
	/*
221
	 * currently we use the boolean nexthop state, this could be exchanged
222
	 * with a variable cost with a max for unreachable.
223
	 */
224
	u_int32_t		costs;
225
#endif
226
	int			refcnt;	/* filterset reference counter */
227
	enum nexthop_state	state;
228
	u_int8_t		nexthop_netlen;
229
	u_int8_t		flags;
230
#define NEXTHOP_CONNECTED	0x01
231
};
232
233
/* generic entry without address specific part */
234
struct pt_entry {
235
	RB_ENTRY(pt_entry)		 pt_e;
236
	u_int8_t			 aid;
237
	u_int8_t			 prefixlen;
238
	u_int16_t			 refcnt;
239
};
240
241
struct pt_entry4 {
242
	RB_ENTRY(pt_entry)		 pt_e;
243
	u_int8_t			 aid;
244
	u_int8_t			 prefixlen;
245
	u_int16_t			 refcnt;
246
	struct in_addr			 prefix4;
247
};
248
249
struct pt_entry6 {
250
	RB_ENTRY(pt_entry)		 pt_e;
251
	u_int8_t			 aid;
252
	u_int8_t			 prefixlen;
253
	u_int16_t			 refcnt;
254
	struct in6_addr			 prefix6;
255
};
256
257
struct pt_entry_vpn4 {
258
	RB_ENTRY(pt_entry)		 pt_e;
259
	u_int8_t			 aid;
260
	u_int8_t			 prefixlen;
261
	u_int16_t			 refcnt;
262
	struct in_addr			 prefix4;
263
	u_int64_t			 rd;
264
	u_int8_t			 labelstack[21];
265
	u_int8_t			 labellen;
266
	u_int8_t			 pad1;
267
	u_int8_t			 pad2;
268
};
269
270
struct rib_context {
271
	struct rib_entry		*ctx_re;
272
	struct rib			*ctx_rib;
273
	void		(*ctx_upcall)(struct rib_entry *, void *);
274
	void		(*ctx_done)(void *);
275
	void		(*ctx_wait)(void *);
276
	void				*ctx_arg;
277
	unsigned int			 ctx_count;
278
	u_int8_t			 ctx_aid;
279
};
280
281
struct rib_entry {
282
	RB_ENTRY(rib_entry)	 rib_e;
283
	struct prefix_head	 prefix_h;
284
	struct prefix		*active;	/* for fast access */
285
	struct pt_entry		*prefix;
286
	struct rib		*__rib;		/* mangled pointer with flags */
287
};
288
289
struct rib {
290
	struct rib_tree		tree;
291
	u_int			rtableid;
292
	u_int16_t		flags;
293
	u_int16_t		id;
294
};
295
296
struct rib_desc {
297
	char			name[PEER_DESCR_LEN];
298
	struct rib		rib;
299
	struct filter_head	*in_rules;
300
	struct filter_head	*in_rules_tmp;
301
	enum reconf_action 	state;
302
};
303
304
struct prefix {
305
	LIST_ENTRY(prefix)		 rib_l, path_l;
306
	struct rde_aspath		*aspath;
307
	struct pt_entry			*prefix;
308
	struct rib_entry		*re;
309
	time_t				 lastchange;
310
};
311
312
extern struct rde_memstats rdemem;
313
314
/* prototypes */
315
/* mrt.c */
316
int		mrt_dump_v2_hdr(struct mrt *, struct bgpd_config *,
317
		    struct rde_peer_head *);
318
void		mrt_dump_upcall(struct rib_entry *, void *);
319
void		mrt_done(void *);
320
321
/* rde.c */
322
void		rde_send_kroute(struct rib *, struct prefix *, struct prefix *);
323
void		rde_send_nexthop(struct bgpd_addr *, int);
324
void		rde_send_pftable(u_int16_t, struct bgpd_addr *,
325
		    u_int8_t, int);
326
void		rde_send_pftable_commit(void);
327
328
void		rde_generate_updates(struct rib *, struct prefix *,
329
		    struct prefix *);
330
u_int32_t	rde_local_as(void);
331
int		rde_noevaluate(void);
332
int		rde_decisionflags(void);
333
int		rde_as4byte(struct rde_peer *);
334
335
/* rde_attr.c */
336
int		 attr_write(void *, u_int16_t, u_int8_t, u_int8_t, void *,
337
		     u_int16_t);
338
int		 attr_writebuf(struct ibuf *, u_int8_t, u_int8_t, void *,
339
		     u_int16_t);
340
void		 attr_init(u_int32_t);
341
void		 attr_shutdown(void);
342
int		 attr_optadd(struct rde_aspath *, u_int8_t, u_int8_t,
343
		     void *, u_int16_t);
344
struct attr	*attr_optget(const struct rde_aspath *, u_int8_t);
345
void		 attr_copy(struct rde_aspath *, struct rde_aspath *);
346
int		 attr_compare(struct rde_aspath *, struct rde_aspath *);
347
void		 attr_freeall(struct rde_aspath *);
348
void		 attr_free(struct rde_aspath *, struct attr *);
349
#define		 attr_optlen(x)	\
350
    ((x)->len > 255 ? (x)->len + 4 : (x)->len + 3)
351
352
int		 aspath_verify(void *, u_int16_t, int);
353
#define		 AS_ERR_LEN	-1
354
#define		 AS_ERR_TYPE	-2
355
#define		 AS_ERR_BAD	-3
356
#define		 AS_ERR_SOFT	-4
357
void		 aspath_init(u_int32_t);
358
void		 aspath_shutdown(void);
359
struct aspath	*aspath_get(void *, u_int16_t);
360
void		 aspath_put(struct aspath *);
361
u_char		*aspath_inflate(void *, u_int16_t, u_int16_t *);
362
u_char		*aspath_deflate(u_char *, u_int16_t *, int *);
363
void		 aspath_merge(struct rde_aspath *, struct attr *);
364
u_char		*aspath_dump(struct aspath *);
365
u_int16_t	 aspath_length(struct aspath *);
366
u_int16_t	 aspath_count(const void *, u_int16_t);
367
u_int32_t	 aspath_neighbor(struct aspath *);
368
int		 aspath_loopfree(struct aspath *, u_int32_t);
369
int		 aspath_compare(struct aspath *, struct aspath *);
370
u_char		*aspath_prepend(struct aspath *, u_int32_t, int, u_int16_t *);
371
int		 aspath_lenmatch(struct aspath *, enum aslen_spec, u_int);
372
int		 community_match(struct rde_aspath *, int, int);
373
int		 community_set(struct rde_aspath *, int, int);
374
void		 community_delete(struct rde_aspath *, int, int);
375
int		 community_large_match(struct rde_aspath *, int64_t, int64_t,
376
		    int64_t);
377
int		 community_large_set(struct rde_aspath *, int64_t, int64_t,
378
		    int64_t);
379
void		 community_large_delete(struct rde_aspath *, int64_t,
380
		    int64_t, int64_t);
381
int		 community_ext_match(struct rde_aspath *,
382
		    struct filter_extcommunity *, u_int16_t);
383
int		 community_ext_set(struct rde_aspath *,
384
		    struct filter_extcommunity *, u_int16_t);
385
void		 community_ext_delete(struct rde_aspath *,
386
		    struct filter_extcommunity *, u_int16_t);
387
int		 community_ext_conv(struct filter_extcommunity *, u_int16_t,
388
		    u_int64_t *);
389
u_char		*community_ext_delete_non_trans(u_char *, u_int16_t,
390
		    u_int16_t *);
391
392
/* rde_decide.c */
393
void		 prefix_evaluate(struct prefix *, struct rib_entry *);
394
395
/* rde_filter.c */
396
enum filter_actions rde_filter(struct filter_head *, struct rde_aspath **,
397
		     struct rde_peer *, struct rde_aspath *,
398
		     struct bgpd_addr *, u_int8_t, struct rde_peer *);
399
void		 rde_apply_set(struct rde_aspath *, struct filter_set_head *,
400
		     u_int8_t, struct rde_peer *, struct rde_peer *);
401
int		 rde_filter_equal(struct filter_head *, struct filter_head *,
402
		     struct rde_peer *);
403
void		 rde_filter_calc_skip_steps(struct filter_head *);
404
405
/* rde_prefix.c */
406
#define pt_empty(pt)	((pt)->refcnt == 0)
407
#define pt_ref(pt)	do {				\
408
	++(pt)->refcnt;					\
409
	if ((pt)->refcnt == 0)				\
410
		fatalx("pt_ref: overflow");		\
411
} while(0)
412
#define pt_unref(pt)	do {				\
413
	if ((pt)->refcnt == 0)				\
414
		fatalx("pt_unref: underflow");		\
415
	--(pt)->refcnt;					\
416
} while(0)
417
418
void	 pt_init(void);
419
void	 pt_shutdown(void);
420
void	 pt_getaddr(struct pt_entry *, struct bgpd_addr *);
421
struct pt_entry	*pt_fill(struct bgpd_addr *, int);
422
struct pt_entry	*pt_get(struct bgpd_addr *, int);
423
struct pt_entry *pt_add(struct bgpd_addr *, int);
424
void	 pt_remove(struct pt_entry *);
425
struct pt_entry	*pt_lookup(struct bgpd_addr *);
426
int	 pt_prefix_cmp(const struct pt_entry *, const struct pt_entry *);
427
428
/* rde_rib.c */
429
extern u_int16_t	 rib_size;
430
extern struct rib_desc	*ribs;
431
432
struct rib	*rib_new(char *, u_int, u_int16_t);
433
struct rib	*rib_find(char *);
434
struct rib_desc	*rib_desc(struct rib *);
435
void		 rib_free(struct rib *);
436
struct rib_entry *rib_get(struct rib *, struct bgpd_addr *, int);
437
struct rib_entry *rib_lookup(struct rib *, struct bgpd_addr *);
438
void		 rib_dump(struct rib *, void (*)(struct rib_entry *, void *),
439
		     void *, u_int8_t);
440
void		 rib_dump_r(struct rib_context *);
441
442
static inline struct rib *
443
re_rib(struct rib_entry *re)
444
{
445
	return (struct rib *)((intptr_t)re->__rib & ~1);
446
}
447
448
void		 path_init(u_int32_t);
449
void		 path_init(u_int32_t);
450
void		 path_shutdown(void);
451
int		 path_update(struct rib *, struct rde_peer *,
452
		     struct rde_aspath *, struct bgpd_addr *, int);
453
int		 path_compare(struct rde_aspath *, struct rde_aspath *);
454
struct rde_aspath *path_lookup(struct rde_aspath *, struct rde_peer *);
455
void		 path_remove(struct rde_aspath *);
456
u_int32_t	 path_remove_stale(struct rde_aspath *, u_int8_t);
457
void		 path_destroy(struct rde_aspath *);
458
int		 path_empty(struct rde_aspath *);
459
struct rde_aspath *path_copy(struct rde_aspath *);
460
struct rde_aspath *path_get(void);
461
void		 path_put(struct rde_aspath *);
462
463
#define	PREFIX_SIZE(x)	(((x) + 7) / 8 + 1)
464
struct prefix	*prefix_get(struct rib *, struct rde_peer *,
465
		    struct bgpd_addr *, int, u_int32_t);
466
int		 prefix_add(struct rib *, struct rde_aspath *,
467
		    struct bgpd_addr *, int);
468
void		 prefix_move(struct rde_aspath *, struct prefix *);
469
int		 prefix_remove(struct rib *, struct rde_peer *,
470
		    struct bgpd_addr *, int, u_int32_t);
471
int		 prefix_write(u_char *, int, struct bgpd_addr *, u_int8_t);
472
int		 prefix_writebuf(struct ibuf *, struct bgpd_addr *, u_int8_t);
473
struct prefix	*prefix_bypeer(struct rib_entry *, struct rde_peer *,
474
		     u_int32_t);
475
void		 prefix_updateall(struct rde_aspath *, enum nexthop_state,
476
		     enum nexthop_state);
477
void		 prefix_destroy(struct prefix *);
478
void		 prefix_network_clean(struct rde_peer *, time_t, u_int32_t);
479
480
void		 nexthop_init(u_int32_t);
481
void		 nexthop_shutdown(void);
482
void		 nexthop_modify(struct rde_aspath *, struct bgpd_addr *,
483
		     enum action_types, u_int8_t);
484
void		 nexthop_link(struct rde_aspath *);
485
void		 nexthop_unlink(struct rde_aspath *);
486
int		 nexthop_delete(struct nexthop *);
487
void		 nexthop_update(struct kroute_nexthop *);
488
struct nexthop	*nexthop_get(struct bgpd_addr *);
489
int		 nexthop_compare(struct nexthop *, struct nexthop *);
490
491
/* rde_update.c */
492
void		 up_init(struct rde_peer *);
493
void		 up_down(struct rde_peer *);
494
int		 up_test_update(struct rde_peer *, struct prefix *);
495
int		 up_generate(struct rde_peer *, struct rde_aspath *,
496
		     struct bgpd_addr *, u_int8_t);
497
void		 up_generate_updates(struct filter_head *, struct rde_peer *,
498
		     struct prefix *, struct prefix *);
499
void		 up_generate_default(struct filter_head *, struct rde_peer *,
500
		     u_int8_t);
501
int		 up_generate_marker(struct rde_peer *, u_int8_t);
502
int		 up_dump_prefix(u_char *, int, struct uplist_prefix *,
503
		     struct rde_peer *);
504
int		 up_dump_attrnlri(u_char *, int, struct rde_peer *);
505
u_char		*up_dump_mp_unreach(u_char *, u_int16_t *, struct rde_peer *,
506
		     u_int8_t);
507
int		 up_dump_mp_reach(u_char *, u_int16_t *, struct rde_peer *,
508
		     u_int8_t);
509
510
#endif /* __RDE_H__ */