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
489
490
491
|
/* RIP related values and structures.
* Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
*
* 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 _ZEBRA_RIP_H
#define _ZEBRA_RIP_H
#include "hook.h"
#include "nexthop.h"
#include "distribute.h"
#include "rip_memory.h"
/* RIP version number. */
#define RIPv1 1
#define RIPv2 2
/* N.B. stuff will break if
(RIPv1 != RI_RIP_VERSION_1) || (RIPv2 != RI_RIP_VERSION_2) */
/* RIP command list. */
#define RIP_REQUEST 1
#define RIP_RESPONSE 2
#define RIP_TRACEON 3 /* Obsolete */
#define RIP_TRACEOFF 4 /* Obsolete */
#define RIP_POLL 5
#define RIP_POLL_ENTRY 6
#define RIP_COMMAND_MAX 7
/* RIP metric infinity value.*/
#define RIP_METRIC_INFINITY 16
/* Normal RIP packet min and max size. */
#define RIP_PACKET_MINSIZ 4
#define RIP_PACKET_MAXSIZ 512
#define RIP_HEADER_SIZE 4
#define RIP_RTE_SIZE 20
/* Max count of routing table entry in one rip packet. */
#define RIP_MAX_RTE ((RIP_PACKET_MAXSIZ - RIP_HEADER_SIZE) / RIP_RTE_SIZE)
/* RIP version 2 multicast address. */
#ifndef INADDR_RIP_GROUP
#define INADDR_RIP_GROUP 0xe0000009 /* 224.0.0.9 */
#endif
/* RIP peer timeout value. */
#define RIP_PEER_TIMER_DEFAULT 180
/* RIP port number. */
#define RIP_PORT_DEFAULT 520
#define RIP_VTY_PORT 2602
/* Default configuration file name. */
#define RIPD_DEFAULT_CONFIG "ripd.conf"
/* RIP route types. */
#define RIP_ROUTE_RTE 0
#define RIP_ROUTE_STATIC 1
#define RIP_ROUTE_DEFAULT 2
#define RIP_ROUTE_REDISTRIBUTE 3
#define RIP_ROUTE_INTERFACE 4
/* RIPv2 special RTE family types */
#define RIP_FAMILY_AUTH 0xffff
/* RIPv2 authentication types, for RIP_FAMILY_AUTH RTE's */
#define RIP_NO_AUTH 0
#define RIP_AUTH_DATA 1
#define RIP_AUTH_SIMPLE_PASSWORD 2
#define RIP_AUTH_MD5 3
/* RIPv2 Simple authentication */
#define RIP_AUTH_SIMPLE_SIZE 16
/* RIPv2 MD5 authentication. */
#define RIP_AUTH_MD5_SIZE 16
#define RIP_AUTH_MD5_COMPAT_SIZE RIP_RTE_SIZE
/* YANG paths */
#define RIP_INSTANCE "/frr-ripd:ripd/instance"
#define RIP_IFACE "/frr-interface:lib/interface/frr-ripd:rip"
/* RIP structure. */
struct rip {
/* RIP socket. */
int sock;
/* Default version of rip instance. */
int version_send; /* version 1 or 2 (but not both) */
int version_recv; /* version 1 or 2 or both */
/* Output buffer of RIP. */
struct stream *obuf;
/* RIP routing information base. */
struct route_table *table;
/* RIP neighbor. */
struct route_table *neighbor;
/* RIP threads. */
struct thread *t_read;
/* Update and garbage timer. */
struct thread *t_update;
/* Triggered update hack. */
int trigger;
struct thread *t_triggered_update;
struct thread *t_triggered_interval;
/* RIP timer values. */
uint32_t update_time;
uint32_t timeout_time;
uint32_t garbage_time;
/* RIP default metric. */
uint8_t default_metric;
/* RIP default distance. */
uint8_t distance;
struct route_table *distance_table;
/* RIP ECMP flag */
bool ecmp;
/* Are we in passive-interface default mode? */
bool passive_default;
/* RIP enabled interfaces. */
vector enable_interface;
/* RIP enabled networks. */
struct route_table *enable_network;
/* Vector to store passive-interface name. */
vector passive_nondefault;
/* For redistribute route map. */
struct {
char *name;
struct route_map *map;
bool metric_config;
uint8_t metric;
} route_map[ZEBRA_ROUTE_MAX];
/* For distribute-list container */
struct distribute_ctx *distribute_ctx;
};
/* RIP routing table entry which belong to rip_packet. */
struct rte {
uint16_t family; /* Address family of this route. */
uint16_t tag; /* Route Tag which included in RIP2 packet. */
struct in_addr prefix; /* Prefix of rip route. */
struct in_addr mask; /* Netmask of rip route. */
struct in_addr nexthop; /* Next hop of rip route. */
uint32_t metric; /* Metric value of rip route. */
};
/* RIP packet structure. */
struct rip_packet {
unsigned char command; /* Command type of RIP packet. */
unsigned char version; /* RIP version which coming from peer. */
unsigned char pad1; /* Padding of RIP packet header. */
unsigned char pad2; /* Same as above. */
struct rte rte[1]; /* Address structure. */
};
/* Buffer to read RIP packet. */
union rip_buf {
struct rip_packet rip_packet;
char buf[RIP_PACKET_MAXSIZ];
};
/* RIP route information. */
struct rip_info {
/* This route's type. */
int type;
/* Sub type. */
int sub_type;
/* RIP nexthop. */
struct nexthop nh;
struct in_addr from;
/* Metric of this route. */
uint32_t metric;
/* External metric of this route.
if learnt from an externalm proto */
uint32_t external_metric;
/* Tag information of this route. */
uint16_t tag;
/* Flags of RIP route. */
#define RIP_RTF_FIB 1
#define RIP_RTF_CHANGED 2
uint8_t flags;
/* Garbage collect timer. */
struct thread *t_timeout;
struct thread *t_garbage_collect;
/* Route-map futures - this variables can be changed. */
struct in_addr nexthop_out;
uint8_t metric_set;
uint32_t metric_out;
uint16_t tag_out;
ifindex_t ifindex_out;
struct route_node *rp;
uint8_t distance;
#ifdef NEW_RIP_TABLE
struct rip_info *next;
struct rip_info *prev;
#endif /* NEW_RIP_TABLE */
};
typedef enum {
RIP_NO_SPLIT_HORIZON = 0,
RIP_SPLIT_HORIZON,
RIP_SPLIT_HORIZON_POISONED_REVERSE
} split_horizon_policy_t;
/* RIP specific interface configuration. */
struct rip_interface {
/* RIP is enabled on this interface. */
int enable_network;
int enable_interface;
/* RIP is running on this interface. */
int running;
/* RIP version control. */
int ri_send;
int ri_receive;
/* RIPv2 broadcast mode */
bool v2_broadcast;
/* RIPv2 authentication type. */
int auth_type;
/* RIPv2 authentication string. */
char *auth_str;
/* RIPv2 authentication key chain. */
char *key_chain;
/* value to use for md5->auth_len */
int md5_auth_len;
/* Split horizon flag. */
split_horizon_policy_t split_horizon;
/* For filter type slot. */
#define RIP_FILTER_IN 0
#define RIP_FILTER_OUT 1
#define RIP_FILTER_MAX 2
/* Access-list. */
struct access_list *list[RIP_FILTER_MAX];
/* Prefix-list. */
struct prefix_list *prefix[RIP_FILTER_MAX];
/* Route-map. */
struct route_map *routemap[RIP_FILTER_MAX];
/* Wake up thread. */
struct thread *t_wakeup;
/* Interface statistics. */
int recv_badpackets;
int recv_badroutes;
int sent_updates;
/* Passive interface. */
int passive;
};
/* RIP peer information. */
struct rip_peer {
/* Peer address. */
struct in_addr addr;
/* Peer RIP 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 thread *t_timeout;
};
struct rip_distance {
/* Distance value for the IP source prefix. */
uint8_t distance;
/* Name of the access-list to be matched. */
char *access_list;
};
struct rip_md5_info {
uint16_t family;
uint16_t type;
uint16_t packet_len;
uint8_t keyid;
uint8_t auth_len;
uint32_t sequence;
uint32_t reserv1;
uint32_t reserv2;
};
struct rip_md5_data {
uint16_t family;
uint16_t type;
uint8_t digest[16];
};
/* RIP accepet/announce methods. */
#define RI_RIP_UNSPEC 0
#define RI_RIP_VERSION_1 1
#define RI_RIP_VERSION_2 2
#define RI_RIP_VERSION_1_AND_2 3
#define RI_RIP_VERSION_NONE 4
/* N.B. stuff will break if
(RIPv1 != RI_RIP_VERSION_1) || (RIPv2 != RI_RIP_VERSION_2) */
/* RIP event. */
enum rip_event {
RIP_READ,
RIP_UPDATE_EVENT,
RIP_TRIGGERED_UPDATE,
};
/* Macro for timer turn on. */
#define RIP_TIMER_ON(T,F,V) thread_add_timer (master, (F), rinfo, (V), &(T))
/* Macro for timer turn off. */
#define RIP_TIMER_OFF(X) THREAD_TIMER_OFF(X)
#define RIP_OFFSET_LIST_IN 0
#define RIP_OFFSET_LIST_OUT 1
#define RIP_OFFSET_LIST_MAX 2
struct rip_offset_list {
char *ifname;
struct {
char *alist_name;
/* struct access_list *alist; */
uint8_t metric;
} direct[RIP_OFFSET_LIST_MAX];
};
/* Prototypes. */
extern void rip_init(void);
extern void rip_clean(void);
extern void rip_clean_network(void);
extern void rip_interfaces_clean(void);
extern int rip_passive_nondefault_set(const char *ifname);
extern int rip_passive_nondefault_unset(const char *ifname);
extern void rip_passive_nondefault_clean(void);
extern void rip_if_init(void);
extern void rip_if_down_all(void);
extern void rip_route_map_init(void);
extern void rip_zclient_init(struct thread_master *);
extern void rip_zclient_stop(void);
extern int if_check_address(struct in_addr addr);
extern int rip_create(int socket);
extern int rip_request_send(struct sockaddr_in *, struct interface *, uint8_t,
struct connected *);
extern int rip_neighbor_lookup(struct sockaddr_in *);
extern int rip_neighbor_add(struct prefix_ipv4 *p);
extern int rip_neighbor_delete(struct prefix_ipv4 *p);
extern int rip_enable_network_add(struct prefix *p);
extern int rip_enable_network_delete(struct prefix *p);
extern int rip_enable_if_add(const char *ifname);
extern int rip_enable_if_delete(const char *ifname);
extern void rip_event(enum rip_event, int);
extern void rip_ecmp_disable(void);
extern int rip_create_socket(void);
extern int rip_redistribute_check(int);
extern void rip_redistribute_conf_update(int type);
extern void rip_redistribute_conf_delete(int type);
extern void rip_redistribute_add(int type, int sub_type, struct prefix_ipv4 *p,
struct nexthop *nh, unsigned int metric,
unsigned char distance, route_tag_t tag);
extern void rip_redistribute_delete(int, int, struct prefix_ipv4 *, ifindex_t);
extern void rip_redistribute_withdraw(int);
extern void rip_zebra_ipv4_add(struct route_node *);
extern void rip_zebra_ipv4_delete(struct route_node *);
extern void rip_interface_multicast_set(int, struct connected *);
extern void rip_distribute_update_interface(struct interface *);
extern void rip_if_rmap_update_interface(struct interface *);
extern int rip_show_network_config(struct vty *);
extern void rip_show_redistribute_config(struct vty *);
extern void rip_peer_init(void);
extern void rip_peer_update(struct sockaddr_in *, uint8_t);
extern void rip_peer_bad_route(struct sockaddr_in *);
extern void rip_peer_bad_packet(struct sockaddr_in *);
extern void rip_peer_display(struct vty *);
extern struct rip_peer *rip_peer_lookup(struct in_addr *);
extern struct rip_peer *rip_peer_lookup_next(struct in_addr *);
extern void rip_info_free(struct rip_info *);
extern struct rip_distance *rip_distance_new(void);
extern void rip_distance_free(struct rip_distance *rdistance);
extern uint8_t rip_distance_apply(struct rip_info *);
extern void rip_redistribute_clean(void);
extern int rip_route_rte(struct rip_info *rinfo);
extern struct rip_info *rip_ecmp_add(struct rip_info *);
extern struct rip_info *rip_ecmp_replace(struct rip_info *);
extern struct rip_info *rip_ecmp_delete(struct rip_info *);
extern struct rip_offset_list *rip_offset_list_new(const char *ifname);
extern void offset_list_del(struct rip_offset_list *offset);
extern struct rip_offset_list *rip_offset_list_lookup(const char *ifname);
extern int rip_offset_list_apply_in(struct prefix_ipv4 *, struct interface *,
uint32_t *);
extern int rip_offset_list_apply_out(struct prefix_ipv4 *, struct interface *,
uint32_t *);
extern void rip_offset_init(void);
extern void rip_offset_clean(void);
/* YANG notifications */
extern void ripd_notif_send_auth_type_failure(const char *ifname);
extern void ripd_notif_send_auth_failure(const char *ifname);
/* There is only one rip strucutre. */
extern struct rip *rip;
extern struct zebra_privs_t ripd_privs;
/* Master thread strucutre. */
extern struct thread_master *master;
/* RIP statistics for SNMP. */
extern long rip_global_route_changes;
extern long rip_global_queries;
DECLARE_HOOK(rip_ifaddr_add, (struct connected * ifc), (ifc))
DECLARE_HOOK(rip_ifaddr_del, (struct connected * ifc), (ifc))
extern struct list *peer_list;
extern struct route_table *rip_distance_table;
/* Northbound. */
extern void rip_cli_init(void);
extern const struct frr_yang_module_info frr_ripd_info;
#endif /* _ZEBRA_RIP_H */
|