summaryrefslogtreecommitdiffstats
path: root/ripngd/ripngd.h
blob: c7468b6317c57ef4afcd7d36ea7093fc25248677 (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
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * RIPng related value and structure.
 * Copyright (C) 1998 Kunihiro Ishiguro
 */

#ifndef _ZEBRA_RIPNG_RIPNGD_H
#define _ZEBRA_RIPNG_RIPNGD_H

#include <zclient.h>
#include <vty.h>
#include <distribute.h>
#include <vector.h>
#include <memory.h>

/* RIPng version and port number. */
#define RIPNG_V1                         1
#define RIPNG_PORT_DEFAULT             521
#define RIPNG_VTY_PORT                2603
#define RIPNG_MAX_PACKET_SIZE         1500
#define RIPNG_PRIORITY_DEFAULT           0

/* RIPng commands. */
#define RIPNG_REQUEST                    1
#define RIPNG_RESPONSE                   2

/* RIPng metric and multicast group address. */
#define RIPNG_METRIC_INFINITY           16
#define RIPNG_METRIC_NEXTHOP          0xff
#define RIPNG_GROUP              "ff02::9"

/* RIPng peer timeout value. */
#define RIPNG_PEER_TIMER_DEFAULT       180

/* Default config file name. */
#define RIPNG_DEFAULT_CONFIG "ripngd.conf"

/* RIPng route types. */
#define RIPNG_ROUTE_RTE                  0
#define RIPNG_ROUTE_STATIC               1
#define RIPNG_ROUTE_DEFAULT              2
#define RIPNG_ROUTE_REDISTRIBUTE         3
#define RIPNG_ROUTE_INTERFACE            4
#define RIPNG_ROUTE_AGGREGATE            5

/* Interface send/receive configuration. */
#define RIPNG_SEND_UNSPEC                0
#define RIPNG_SEND_OFF                   1
#define RIPNG_RECEIVE_UNSPEC             0
#define RIPNG_RECEIVE_OFF                1

/* RIP default route's accept/announce methods. */
#define RIPNG_DEFAULT_ADVERTISE_UNSPEC   0
#define RIPNG_DEFAULT_ADVERTISE_NONE     1
#define RIPNG_DEFAULT_ADVERTISE          2

#define RIPNG_DEFAULT_ACCEPT_UNSPEC      0
#define RIPNG_DEFAULT_ACCEPT_NONE        1
#define RIPNG_DEFAULT_ACCEPT             2

/* For max RTE calculation. */
#ifndef IPV6_HDRLEN
#define IPV6_HDRLEN 40
#endif /* IPV6_HDRLEN */

#ifndef IFMINMTU
#define IFMINMTU    576
#endif /* IFMINMTU */

/* YANG paths */
#define RIPNG_INSTANCE	"/frr-ripngd:ripngd/instance"
#define RIPNG_IFACE	"/frr-interface:lib/interface/frr-ripngd:ripng"

DECLARE_MGROUP(RIPNGD);

/* RIPng structure. */
struct ripng {
	RB_ENTRY(ripng) entry;

	/* VRF this routing instance is associated with. */
	char *vrf_name;

	/* VRF backpointer (might be NULL if the VRF doesn't exist). */
	struct vrf *vrf;

	/* Status of the routing instance. */
	bool enabled;

	/* RIPng socket. */
	int sock;

	/* RIPng Parameters.*/
	uint8_t command;
	uint8_t version;
	uint16_t update_time;
	uint16_t timeout_time;
	uint16_t garbage_time;
	int max_mtu;
	uint8_t default_metric;

	/* Input/output buffer of RIPng. */
	struct stream *ibuf;
	struct stream *obuf;

	/* RIPng routing information base. */
	struct agg_table *table;

	/* Linked list of RIPng peers. */
	struct list *peer_list;

	/* RIPng enabled interfaces. */
	vector enable_if;

	/* RIPng enabled networks. */
	struct agg_table *enable_network;

	/* Vector to store passive-interface name. */
	vector passive_interface;

	/* RIPng offset-lists. */
	struct list *offset_list_master;

	/* RIPng threads. */
	struct event *t_read;
	struct event *t_update;

	/* Triggered update hack. */
	int trigger;
	struct event *t_triggered_update;
	struct event *t_triggered_interval;

	/* RIPng ECMP flag */
	uint8_t ecmp;

	/* RIPng redistribute configuration. */
	struct {
		bool enabled;
		struct {
			char *name;
			struct route_map *map;
		} route_map;
		bool metric_config;
		uint8_t metric;
	} redist[ZEBRA_ROUTE_MAX];

	/* For distribute-list container */
	struct distribute_ctx *distribute_ctx;

	/* For if_rmap container */
	struct if_rmap_ctx *if_rmap_ctx;
};
RB_HEAD(ripng_instance_head, ripng);
RB_PROTOTYPE(ripng_instance_head, ripng, entry, ripng_instance_compare)

/* Routing table entry. */
struct rte {
	struct in6_addr addr; /* RIPng destination prefix */
	uint16_t tag;	 /* RIPng tag */
	uint8_t prefixlen;    /* Length of the RIPng prefix */
	uint8_t metric;       /* Metric of the RIPng route */
			      /* The nexthop is stored by the structure
			       * ripng_nexthop within ripngd.c */
};

/* RIPNG send packet. */
struct ripng_packet {
	uint8_t command;
	uint8_t version;
	uint16_t zero;
	struct rte rte[1];
};

/* Each route's information. */
struct ripng_info {
	/* This route's type.  Static, ripng or aggregate. */
	uint8_t type;

	/* Sub type for static route. */
	uint8_t sub_type;

	/* RIPng specific information */
	struct in6_addr nexthop;
	struct in6_addr from;

	/* Which interface does this route come from. */
	ifindex_t ifindex;

	/* Metric of this route.  */
	uint8_t metric;

	/* Tag field of RIPng packet.*/
	uint16_t tag;

	/* For aggregation. */
	unsigned int suppress;

/* Flags of RIPng route. */
#define RIPNG_RTF_FIB      1
#define RIPNG_RTF_CHANGED  2
	uint8_t flags;

	/* Garbage collect timer. */
	struct event *t_timeout;
	struct event *t_garbage_collect;

	/* Route-map features - this variables can be changed. */
	struct in6_addr nexthop_out;
	uint8_t metric_set;
	uint8_t metric_out;
	uint16_t tag_out;

	struct agg_node *rp;
};

typedef enum {
	RIPNG_NO_SPLIT_HORIZON = 0,
	RIPNG_SPLIT_HORIZON,
	RIPNG_SPLIT_HORIZON_POISONED_REVERSE
} split_horizon_policy_t;

/* RIPng specific interface configuration. */
struct ripng_interface {
	/* Parent routing instance. */
	struct ripng *ripng;

	/* RIPng is enabled on this interface. */
	int enable_network;
	int enable_interface;

	/* RIPng is running on this interface. */
	int running;

	/* Split horizon flag. */
	split_horizon_policy_t split_horizon;

/* For filter type slot. */
#define RIPNG_FILTER_IN  0
#define RIPNG_FILTER_OUT 1
#define RIPNG_FILTER_MAX 2

	/* Access-list. */
	struct access_list *list[RIPNG_FILTER_MAX];

	/* Prefix-list. */
	struct prefix_list *prefix[RIPNG_FILTER_MAX];

	/* Route-map. */
	struct route_map *routemap[RIPNG_FILTER_MAX];

	/* Default information originate. */
	uint8_t default_originate;

	/* Default information only. */
	uint8_t default_only;

	/* Wake up thread. */
	struct event *t_wakeup;

	/* Passive interface. */
	int passive;
};

/* RIPng peer information. */
struct ripng_peer {
	/* Parent routing instance. */
	struct ripng *ripng;

	/* Peer address. */
	struct in6_addr addr;

	/* Peer RIPng tag value. */
	int domain;

	/* Last update time. */
	time_t uptime;

	/* Peer RIP version. */
	uint8_t version;

	/* Statistics. */
	int recv_badpackets;
	int recv_badroutes;

	/* Timeout thread. */
	struct event *t_timeout;
};

/* All RIPng events. */
enum ripng_event {
	RIPNG_READ,
	RIPNG_ZEBRA,
	RIPNG_REQUEST_EVENT,
	RIPNG_UPDATE_EVENT,
	RIPNG_TRIGGERED_UPDATE,
};

/* RIPng timer on/off macro. */
#define RIPNG_TIMER_ON(T, F, V) event_add_timer(master, (F), rinfo, (V), &(T))

#define RIPNG_OFFSET_LIST_IN  0
#define RIPNG_OFFSET_LIST_OUT 1
#define RIPNG_OFFSET_LIST_MAX 2

struct ripng_offset_list {
	/* Parent routing instance. */
	struct ripng *ripng;

	char *ifname;

	struct {
		char *alist_name;
		/* struct access_list *alist; */
		uint8_t metric;
	} direct[RIPNG_OFFSET_LIST_MAX];
};

/* Extern variables. */
extern struct zebra_privs_t ripngd_privs;
extern struct event_loop *master;
extern struct ripng_instance_head ripng_instances;

/* Prototypes. */
extern void ripng_init(void);
extern void ripng_clean(struct ripng *ripng);
extern void ripng_clean_network(struct ripng *ripng);
extern void ripng_interface_clean(struct ripng *ripng);
extern int ripng_enable_network_add(struct ripng *ripng, struct prefix *p);
extern int ripng_enable_network_delete(struct ripng *ripng, struct prefix *p);
extern int ripng_enable_if_add(struct ripng *ripng, const char *ifname);
extern int ripng_enable_if_delete(struct ripng *ripng, const char *ifname);
extern int ripng_passive_interface_set(struct ripng *ripng, const char *ifname);
extern int ripng_passive_interface_unset(struct ripng *ripng,
					 const char *ifname);
extern void ripng_passive_interface_clean(struct ripng *ripng);
extern void ripng_if_init(void);
extern void ripng_route_map_init(void);
extern void ripng_zebra_vrf_register(struct vrf *vrf);
extern void ripng_zebra_vrf_deregister(struct vrf *vrf);
extern void ripng_terminate(void);
/* zclient_init() is done by ripng_zebra.c:zebra_init() */
extern void zebra_init(struct event_loop *master);
extern void ripng_zebra_stop(void);
extern void ripng_redistribute_conf_update(struct ripng *ripng, int type);
extern void ripng_redistribute_conf_delete(struct ripng *ripng, int type);

extern void ripng_peer_update(struct ripng *ripng, struct sockaddr_in6 *from,
			      uint8_t version);
extern void ripng_peer_bad_route(struct ripng *ripng,
				 struct sockaddr_in6 *from);
extern void ripng_peer_bad_packet(struct ripng *ripng,
				  struct sockaddr_in6 *from);
extern void ripng_peer_display(struct vty *vty, struct ripng *ripng);
extern struct ripng_peer *ripng_peer_lookup(struct ripng *ripng,
					    struct in6_addr *addr);
extern struct ripng_peer *ripng_peer_lookup_next(struct ripng *ripng,
						 struct in6_addr *addr);
extern int ripng_peer_list_cmp(struct ripng_peer *p1, struct ripng_peer *p2);
extern void ripng_peer_list_del(void *arg);

extern struct ripng_offset_list *ripng_offset_list_new(struct ripng *ripng,
						       const char *ifname);
extern void ripng_offset_list_del(struct ripng_offset_list *offset);
extern void ripng_offset_list_free(struct ripng_offset_list *offset);
extern struct ripng_offset_list *ripng_offset_list_lookup(struct ripng *ripng,
							  const char *ifname);
extern int ripng_offset_list_apply_in(struct ripng *ripng,
				      struct prefix_ipv6 *p,
				      struct interface *ifp, uint8_t *metric);
extern int ripng_offset_list_apply_out(struct ripng *ripng,
				       struct prefix_ipv6 *p,
				       struct interface *ifp, uint8_t *metric);
extern int offset_list_cmp(struct ripng_offset_list *o1,
			   struct ripng_offset_list *o2);

extern int ripng_route_rte(struct ripng_info *rinfo);
extern struct ripng_info *ripng_info_new(void);
extern void ripng_info_free(struct ripng_info *rinfo);
extern struct ripng *ripng_info_get_instance(const struct ripng_info *rinfo);
extern void ripng_event(struct ripng *ripng, enum ripng_event event, int sock);
extern int ripng_request(struct interface *ifp);
extern void ripng_redistribute_add(struct ripng *ripng, int type, int sub_type,
				   struct prefix_ipv6 *p, ifindex_t ifindex,
				   struct in6_addr *nexthop, route_tag_t tag);
extern void ripng_redistribute_delete(struct ripng *ripng, int type,
				      int sub_type, struct prefix_ipv6 *p,
				      ifindex_t ifindex);
extern void ripng_redistribute_withdraw(struct ripng *ripng, int type);

extern void ripng_ecmp_disable(struct ripng *ripng);
extern void ripng_distribute_update_interface(struct interface *);
extern void ripng_if_rmap_update_interface(struct interface *);

extern void ripng_zebra_ipv6_add(struct ripng *ripng, struct agg_node *node);
extern void ripng_zebra_ipv6_delete(struct ripng *ripng, struct agg_node *node);

extern void ripng_redistribute_enable(struct ripng *ripng);
extern void ripng_redistribute_disable(struct ripng *ripng);
extern int ripng_redistribute_check(struct ripng *ripng, int type);
extern void ripng_redistribute_write(struct vty *vty, struct ripng *ripng);

extern int ripng_write_rte(int num, struct stream *s, struct prefix_ipv6 *p,
			   struct in6_addr *nexthop, uint16_t tag,
			   uint8_t metric);
extern int ripng_send_packet(caddr_t buf, int bufsize, struct sockaddr_in6 *to,
			     struct interface *ifp);

extern void ripng_packet_dump(struct ripng_packet *packet, int size,
			      const char *sndrcv);

extern int ripng_interface_up(ZAPI_CALLBACK_ARGS);
extern int ripng_interface_down(ZAPI_CALLBACK_ARGS);
extern int ripng_interface_add(ZAPI_CALLBACK_ARGS);
extern int ripng_interface_delete(ZAPI_CALLBACK_ARGS);
extern int ripng_interface_address_add(ZAPI_CALLBACK_ARGS);
extern int ripng_interface_address_delete(ZAPI_CALLBACK_ARGS);
extern int ripng_interface_vrf_update(ZAPI_CALLBACK_ARGS);
extern void ripng_interface_sync(struct interface *ifp);

extern struct ripng *ripng_lookup_by_vrf_id(vrf_id_t vrf_id);
extern struct ripng *ripng_lookup_by_vrf_name(const char *vrf_name);
extern struct ripng *ripng_create(const char *vrf_name, struct vrf *vrf,
				  int socket);
extern int ripng_make_socket(struct vrf *vrf);
extern int ripng_network_write(struct vty *vty, struct ripng *ripng);

extern struct ripng_info *ripng_ecmp_add(struct ripng *ripng,
					 struct ripng_info *rinfo);
extern struct ripng_info *ripng_ecmp_replace(struct ripng *ripng,
					     struct ripng_info *rinfo);
extern struct ripng_info *ripng_ecmp_delete(struct ripng *ripng,
					    struct ripng_info *rinfo);
extern void ripng_ecmp_change(struct ripng *ripng);

extern void ripng_vrf_init(void);
extern void ripng_vrf_terminate(void);
extern void ripng_cli_init(void);

extern uint32_t zebra_ecmp_count;

#endif /* _ZEBRA_RIPNG_RIPNGD_H */