]> git.proxmox.com Git - mirror_frr.git/blob - ripd/rip_zebra.c
release: FRR 3.0-rc1
[mirror_frr.git] / ripd / rip_zebra.c
1 /* RIPd and zebra interface.
2 * Copyright (C) 1997, 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22 #include <zebra.h>
23
24 #include "command.h"
25 #include "prefix.h"
26 #include "table.h"
27 #include "stream.h"
28 #include "memory.h"
29 #include "routemap.h"
30 #include "zclient.h"
31 #include "log.h"
32 #include "vrf.h"
33 #include "ripd/ripd.h"
34 #include "ripd/rip_debug.h"
35 #include "ripd/rip_interface.h"
36
37 /* All information about zebra. */
38 struct zclient *zclient = NULL;
39
40 /* Send ECMP routes to zebra. */
41 static void rip_zebra_ipv4_send(struct route_node *rp, u_char cmd)
42 {
43 static struct in_addr **nexthops = NULL;
44 static unsigned int nexthops_len = 0;
45
46 struct list *list = (struct list *)rp->info;
47 struct zapi_ipv4 api;
48 struct listnode *listnode = NULL;
49 struct rip_info *rinfo = NULL;
50 int count = 0;
51
52 if (vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_RIP],
53 VRF_DEFAULT)) {
54 api.vrf_id = VRF_DEFAULT;
55 api.type = ZEBRA_ROUTE_RIP;
56 api.instance = 0;
57 api.flags = 0;
58 api.message = 0;
59 api.safi = SAFI_UNICAST;
60
61 if (nexthops_len < listcount(list)) {
62 nexthops_len = listcount(list);
63 nexthops = XREALLOC(MTYPE_TMP, nexthops,
64 nexthops_len
65 * sizeof(struct in_addr *));
66 }
67
68 SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
69 for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
70 nexthops[count++] = &rinfo->nexthop;
71 if (cmd == ZEBRA_IPV4_ROUTE_ADD)
72 SET_FLAG(rinfo->flags, RIP_RTF_FIB);
73 else
74 UNSET_FLAG(rinfo->flags, RIP_RTF_FIB);
75 }
76
77 api.nexthop = nexthops;
78 api.nexthop_num = count;
79 api.ifindex_num = 0;
80
81 rinfo = listgetdata(listhead(list));
82
83 SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
84 api.metric = rinfo->metric;
85
86 if (rinfo->distance
87 && rinfo->distance != ZEBRA_RIP_DISTANCE_DEFAULT) {
88 SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
89 api.distance = rinfo->distance;
90 }
91
92 if (rinfo->tag) {
93 SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
94 api.tag = rinfo->tag;
95 }
96
97 zapi_ipv4_route(cmd, zclient, (struct prefix_ipv4 *)&rp->p,
98 &api);
99
100 if (IS_RIP_DEBUG_ZEBRA) {
101 if (rip->ecmp)
102 zlog_debug("%s: %s/%d nexthops %d",
103 (cmd == ZEBRA_IPV4_ROUTE_ADD)
104 ? "Install into zebra"
105 : "Delete from zebra",
106 inet_ntoa(rp->p.u.prefix4),
107 rp->p.prefixlen, count);
108 else
109 zlog_debug("%s: %s/%d",
110 (cmd == ZEBRA_IPV4_ROUTE_ADD)
111 ? "Install into zebra"
112 : "Delete from zebra",
113 inet_ntoa(rp->p.u.prefix4),
114 rp->p.prefixlen);
115 }
116
117 rip_global_route_changes++;
118 }
119 }
120
121 /* Add/update ECMP routes to zebra. */
122 void rip_zebra_ipv4_add(struct route_node *rp)
123 {
124 rip_zebra_ipv4_send(rp, ZEBRA_IPV4_ROUTE_ADD);
125 }
126
127 /* Delete ECMP routes from zebra. */
128 void rip_zebra_ipv4_delete(struct route_node *rp)
129 {
130 rip_zebra_ipv4_send(rp, ZEBRA_IPV4_ROUTE_DELETE);
131 }
132
133 /* Zebra route add and delete treatment. */
134 static int rip_zebra_read_ipv4(int command, struct zclient *zclient,
135 zebra_size_t length, vrf_id_t vrf_id)
136 {
137 struct stream *s;
138 struct zapi_ipv4 api;
139 unsigned long ifindex;
140 struct in_addr nexthop;
141 struct prefix_ipv4 p;
142
143 if (!rip)
144 return 0;
145
146 s = zclient->ibuf;
147 ifindex = 0;
148 nexthop.s_addr = 0;
149
150 /* Type, flags, message. */
151 api.type = stream_getc(s);
152 api.instance = stream_getw(s);
153 api.flags = stream_getl(s);
154 api.message = stream_getc(s);
155
156 /* IPv4 prefix. */
157 memset(&p, 0, sizeof(struct prefix_ipv4));
158 p.family = AF_INET;
159 p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc(s));
160 stream_get(&p.prefix, s, PSIZE(p.prefixlen));
161
162 /* Nexthop, ifindex, distance, metric. */
163 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) {
164 api.nexthop_num = stream_getc(s);
165 nexthop.s_addr = stream_get_ipv4(s);
166 }
167 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) {
168 api.ifindex_num = stream_getc(s);
169 ifindex = stream_getl(s);
170 }
171 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE))
172 api.distance = stream_getc(s);
173 else
174 api.distance = 255;
175 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC))
176 api.metric = stream_getl(s);
177 else
178 api.metric = 0;
179
180 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG))
181 api.tag = stream_getl(s);
182 else
183 api.tag = 0;
184
185 /* Then fetch IPv4 prefixes. */
186 if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD)
187 rip_redistribute_add(api.type, RIP_ROUTE_REDISTRIBUTE, &p,
188 ifindex, &nexthop, api.metric,
189 api.distance, api.tag);
190 else if (command == ZEBRA_REDISTRIBUTE_IPV4_DEL)
191 rip_redistribute_delete(api.type, RIP_ROUTE_REDISTRIBUTE, &p,
192 ifindex);
193
194 return 0;
195 }
196
197 void rip_zclient_reset(void)
198 {
199 zclient_reset(zclient);
200 }
201
202 /* RIP route-map set for redistribution */
203 static void rip_routemap_set(int type, const char *name)
204 {
205 if (rip->route_map[type].name)
206 free(rip->route_map[type].name);
207
208 rip->route_map[type].name = strdup(name);
209 rip->route_map[type].map = route_map_lookup_by_name(name);
210 }
211
212 static void rip_redistribute_metric_set(int type, unsigned int metric)
213 {
214 rip->route_map[type].metric_config = 1;
215 rip->route_map[type].metric = metric;
216 }
217
218 static int rip_metric_unset(int type, unsigned int metric)
219 {
220 #define DONT_CARE_METRIC_RIP 17
221 if (metric != DONT_CARE_METRIC_RIP
222 && rip->route_map[type].metric != metric)
223 return 1;
224 rip->route_map[type].metric_config = 0;
225 rip->route_map[type].metric = 0;
226 return 0;
227 }
228
229 /* RIP route-map unset for redistribution */
230 static int rip_routemap_unset(int type, const char *name)
231 {
232 if (!rip->route_map[type].name
233 || (name != NULL && strcmp(rip->route_map[type].name, name)))
234 return 1;
235
236 free(rip->route_map[type].name);
237 rip->route_map[type].name = NULL;
238 rip->route_map[type].map = NULL;
239
240 return 0;
241 }
242
243 /* Redistribution types */
244 static struct {
245 int type;
246 int str_min_len;
247 const char *str;
248 } redist_type[] = {{ZEBRA_ROUTE_KERNEL, 1, "kernel"},
249 {ZEBRA_ROUTE_CONNECT, 1, "connected"},
250 {ZEBRA_ROUTE_STATIC, 1, "static"},
251 {ZEBRA_ROUTE_OSPF, 1, "ospf"},
252 {ZEBRA_ROUTE_BGP, 2, "bgp"},
253 {ZEBRA_ROUTE_VNC, 1, "vnc"},
254 {0, 0, NULL}};
255
256 static int rip_redistribute_unset(int type)
257 {
258 if (!vrf_bitmap_check(zclient->redist[AFI_IP][type], VRF_DEFAULT))
259 return CMD_SUCCESS;
260
261 vrf_bitmap_unset(zclient->redist[AFI_IP][type], VRF_DEFAULT);
262
263 if (zclient->sock > 0)
264 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
265 AFI_IP, type, 0, VRF_DEFAULT);
266
267 /* Remove the routes from RIP table. */
268 rip_redistribute_withdraw(type);
269
270 return CMD_SUCCESS;
271 }
272
273 int rip_redistribute_check(int type)
274 {
275 return vrf_bitmap_check(zclient->redist[AFI_IP][type], VRF_DEFAULT);
276 }
277
278 void rip_redistribute_clean(void)
279 {
280 int i;
281
282 for (i = 0; redist_type[i].str; i++) {
283 if (vrf_bitmap_check(
284 zclient->redist[AFI_IP][redist_type[i].type],
285 VRF_DEFAULT)) {
286 if (zclient->sock > 0)
287 zebra_redistribute_send(
288 ZEBRA_REDISTRIBUTE_DELETE, zclient,
289 AFI_IP, redist_type[i].type, 0,
290 VRF_DEFAULT);
291
292 vrf_bitmap_unset(
293 zclient->redist[AFI_IP][redist_type[i].type],
294 VRF_DEFAULT);
295
296 /* Remove the routes from RIP table. */
297 rip_redistribute_withdraw(redist_type[i].type);
298 }
299 }
300 }
301
302 DEFUN (rip_redistribute_rip,
303 rip_redistribute_rip_cmd,
304 "redistribute rip",
305 "Redistribute information from another routing protocol\n"
306 "Routing Information Protocol (RIP)\n")
307 {
308 vrf_bitmap_set(zclient->redist[AFI_IP][ZEBRA_ROUTE_RIP], VRF_DEFAULT);
309 return CMD_SUCCESS;
310 }
311
312 DEFUN (no_rip_redistribute_rip,
313 no_rip_redistribute_rip_cmd,
314 "no redistribute rip",
315 NO_STR
316 "Redistribute information from another routing protocol\n"
317 "Routing Information Protocol (RIP)\n")
318 {
319 vrf_bitmap_unset(zclient->redist[AFI_IP][ZEBRA_ROUTE_RIP], VRF_DEFAULT);
320 return CMD_SUCCESS;
321 }
322
323 DEFUN (rip_redistribute_type,
324 rip_redistribute_type_cmd,
325 "redistribute " FRR_REDIST_STR_RIPD,
326 REDIST_STR
327 FRR_REDIST_HELP_STR_RIPD)
328 {
329 int i;
330
331 for (i = 0; redist_type[i].str; i++) {
332 if (strncmp(redist_type[i].str, argv[1]->arg,
333 redist_type[i].str_min_len)
334 == 0) {
335 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient,
336 AFI_IP, redist_type[i].type, 0,
337 VRF_DEFAULT);
338 return CMD_SUCCESS;
339 }
340 }
341
342 vty_out(vty, "Invalid type %s%s", argv[1]->arg, VTY_NEWLINE);
343
344 return CMD_WARNING;
345 }
346
347 DEFUN (no_rip_redistribute_type,
348 no_rip_redistribute_type_cmd,
349 "no redistribute " FRR_REDIST_STR_RIPD,
350 NO_STR
351 REDIST_STR
352 FRR_REDIST_HELP_STR_RIPD)
353 {
354 int i;
355
356 for (i = 0; redist_type[i].str; i++) {
357 if (strncmp(redist_type[i].str, argv[2]->arg,
358 redist_type[i].str_min_len)
359 == 0) {
360 rip_metric_unset(redist_type[i].type,
361 DONT_CARE_METRIC_RIP);
362 rip_routemap_unset(redist_type[i].type, NULL);
363 rip_redistribute_unset(redist_type[i].type);
364 return CMD_SUCCESS;
365 }
366 }
367
368 vty_out(vty, "Invalid type %s%s", argv[2]->arg, VTY_NEWLINE);
369
370 return CMD_WARNING;
371 }
372
373 DEFUN (rip_redistribute_type_routemap,
374 rip_redistribute_type_routemap_cmd,
375 "redistribute " FRR_REDIST_STR_RIPD " route-map WORD",
376 REDIST_STR
377 FRR_REDIST_HELP_STR_RIPD
378 "Route map reference\n"
379 "Pointer to route-map entries\n")
380 {
381 int idx_protocol = 1;
382 int idx_word = 3;
383 int i;
384
385 for (i = 0; redist_type[i].str; i++) {
386 if (strmatch(redist_type[i].str, argv[idx_protocol]->text)) {
387 rip_routemap_set(redist_type[i].type,
388 argv[idx_word]->arg);
389 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient,
390 AFI_IP, redist_type[i].type, 0,
391 VRF_DEFAULT);
392 return CMD_SUCCESS;
393 }
394 }
395
396 vty_out(vty, "Invalid type %s%s", argv[idx_protocol]->text,
397 VTY_NEWLINE);
398
399 return CMD_WARNING;
400 }
401
402 DEFUN (no_rip_redistribute_type_routemap,
403 no_rip_redistribute_type_routemap_cmd,
404 "no redistribute " FRR_REDIST_STR_RIPD " route-map WORD",
405 NO_STR
406 REDIST_STR
407 FRR_REDIST_HELP_STR_RIPD
408 "Route map reference\n"
409 "Pointer to route-map entries\n")
410 {
411 int idx_protocol = 2;
412 int idx_word = 4;
413 int i;
414
415 for (i = 0; redist_type[i].str; i++) {
416 if (strmatch(redist_type[i].str, argv[idx_protocol]->text)) {
417 if (rip_routemap_unset(redist_type[i].type,
418 argv[idx_word]->arg))
419 return CMD_WARNING;
420 rip_redistribute_unset(redist_type[i].type);
421 return CMD_SUCCESS;
422 }
423 }
424
425 vty_out(vty, "Invalid type %s%s", argv[idx_protocol]->text,
426 VTY_NEWLINE);
427
428 return CMD_WARNING;
429 }
430
431 DEFUN (rip_redistribute_type_metric,
432 rip_redistribute_type_metric_cmd,
433 "redistribute " FRR_REDIST_STR_RIPD " metric (0-16)",
434 REDIST_STR
435 FRR_REDIST_HELP_STR_RIPD
436 "Metric\n"
437 "Metric value\n")
438 {
439 int idx_protocol = 1;
440 int idx_number = 3;
441 int i;
442 int metric;
443
444 metric = atoi(argv[idx_number]->arg);
445
446 for (i = 0; redist_type[i].str; i++) {
447 if (strmatch(redist_type[i].str, argv[idx_protocol]->text)) {
448 rip_redistribute_metric_set(redist_type[i].type,
449 metric);
450 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient,
451 AFI_IP, redist_type[i].type, 0,
452 VRF_DEFAULT);
453 return CMD_SUCCESS;
454 }
455 }
456
457 vty_out(vty, "Invalid type %s%s", argv[idx_protocol]->text,
458 VTY_NEWLINE);
459
460 return CMD_WARNING;
461 }
462
463 DEFUN (no_rip_redistribute_type_metric,
464 no_rip_redistribute_type_metric_cmd,
465 "no redistribute " FRR_REDIST_STR_RIPD " metric (0-16)",
466 NO_STR
467 REDIST_STR
468 FRR_REDIST_HELP_STR_RIPD
469 "Metric\n"
470 "Metric value\n")
471 {
472 int idx_protocol = 2;
473 int idx_number = 4;
474 int i;
475
476 for (i = 0; redist_type[i].str; i++) {
477 if (strmatch(redist_type[i].str, argv[idx_protocol]->text)) {
478 if (rip_metric_unset(redist_type[i].type,
479 atoi(argv[idx_number]->arg)))
480 return CMD_WARNING;
481 rip_redistribute_unset(redist_type[i].type);
482 return CMD_SUCCESS;
483 }
484 }
485
486 vty_out(vty, "Invalid type %s%s", argv[idx_protocol]->text,
487 VTY_NEWLINE);
488
489 return CMD_WARNING;
490 }
491
492 DEFUN (rip_redistribute_type_metric_routemap,
493 rip_redistribute_type_metric_routemap_cmd,
494 "redistribute " FRR_REDIST_STR_RIPD " metric (0-16) route-map WORD",
495 REDIST_STR
496 FRR_REDIST_HELP_STR_RIPD
497 "Metric\n"
498 "Metric value\n"
499 "Route map reference\n"
500 "Pointer to route-map entries\n")
501 {
502 int idx_protocol = 1;
503 int idx_number = 3;
504 int idx_word = 5;
505 int i;
506 int metric;
507
508 metric = atoi(argv[idx_number]->arg);
509
510 for (i = 0; redist_type[i].str; i++) {
511 if (strmatch(redist_type[i].str, argv[idx_protocol]->text)) {
512 rip_redistribute_metric_set(redist_type[i].type,
513 metric);
514 rip_routemap_set(redist_type[i].type,
515 argv[idx_word]->arg);
516 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient,
517 AFI_IP, redist_type[i].type, 0,
518 VRF_DEFAULT);
519 return CMD_SUCCESS;
520 }
521 }
522
523 vty_out(vty, "Invalid type %s%s", argv[idx_protocol]->text,
524 VTY_NEWLINE);
525
526 return CMD_WARNING;
527 }
528
529
530 DEFUN (no_rip_redistribute_type_metric_routemap,
531 no_rip_redistribute_type_metric_routemap_cmd,
532 "no redistribute " FRR_REDIST_STR_RIPD " metric (0-16) route-map WORD",
533 NO_STR
534 REDIST_STR
535 FRR_REDIST_HELP_STR_RIPD
536 "Metric\n"
537 "Metric value\n"
538 "Route map reference\n"
539 "Pointer to route-map entries\n")
540 {
541 int idx_protocol = 2;
542 int idx_number = 4;
543 int idx_word = 6;
544 int i;
545
546 for (i = 0; redist_type[i].str; i++) {
547 if (strmatch(redist_type[i].str, argv[idx_protocol]->text)) {
548 if (rip_metric_unset(redist_type[i].type,
549 atoi(argv[idx_number]->arg)))
550 return CMD_WARNING;
551 if (rip_routemap_unset(redist_type[i].type,
552 argv[idx_word]->arg)) {
553 rip_redistribute_metric_set(
554 redist_type[i].type,
555 atoi(argv[idx_number]->arg));
556 return CMD_WARNING;
557 }
558 rip_redistribute_unset(redist_type[i].type);
559 return CMD_SUCCESS;
560 }
561 }
562
563 vty_out(vty, "Invalid type %s%s", argv[idx_protocol]->text,
564 VTY_NEWLINE);
565
566 return CMD_WARNING;
567 }
568
569 /* Default information originate. */
570
571 DEFUN (rip_default_information_originate,
572 rip_default_information_originate_cmd,
573 "default-information originate",
574 "Control distribution of default route\n"
575 "Distribute a default route\n")
576 {
577 struct prefix_ipv4 p;
578
579 if (!rip->default_information) {
580 memset(&p, 0, sizeof(struct prefix_ipv4));
581 p.family = AF_INET;
582
583 rip->default_information = 1;
584
585 rip_redistribute_add(ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0,
586 NULL, 0, 0, 0);
587 }
588
589 return CMD_SUCCESS;
590 }
591
592 DEFUN (no_rip_default_information_originate,
593 no_rip_default_information_originate_cmd,
594 "no default-information originate",
595 NO_STR
596 "Control distribution of default route\n"
597 "Distribute a default route\n")
598 {
599 struct prefix_ipv4 p;
600
601 if (rip->default_information) {
602 memset(&p, 0, sizeof(struct prefix_ipv4));
603 p.family = AF_INET;
604
605 rip->default_information = 0;
606
607 rip_redistribute_delete(ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p,
608 0);
609 }
610
611 return CMD_SUCCESS;
612 }
613
614 /* RIP configuration write function. */
615 static int config_write_zebra(struct vty *vty)
616 {
617 if (!zclient->enable) {
618 vty_out(vty, "no router zebra%s", VTY_NEWLINE);
619 return 1;
620 } else if (!vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_RIP],
621 VRF_DEFAULT)) {
622 vty_out(vty, "router zebra%s", VTY_NEWLINE);
623 vty_out(vty, " no redistribute rip%s", VTY_NEWLINE);
624 return 1;
625 }
626 return 0;
627 }
628
629 int config_write_rip_redistribute(struct vty *vty, int config_mode)
630 {
631 int i;
632
633 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
634 if (i != zclient->redist_default
635 && vrf_bitmap_check(zclient->redist[AFI_IP][i],
636 VRF_DEFAULT)) {
637 if (config_mode) {
638 if (rip->route_map[i].metric_config) {
639 if (rip->route_map[i].name)
640 vty_out(vty,
641 " redistribute %s metric %d route-map %s%s",
642 zebra_route_string(i),
643 rip->route_map[i]
644 .metric,
645 rip->route_map[i].name,
646 VTY_NEWLINE);
647 else
648 vty_out(vty,
649 " redistribute %s metric %d%s",
650 zebra_route_string(i),
651 rip->route_map[i]
652 .metric,
653 VTY_NEWLINE);
654 } else {
655 if (rip->route_map[i].name)
656 vty_out(vty,
657 " redistribute %s route-map %s%s",
658 zebra_route_string(i),
659 rip->route_map[i].name,
660 VTY_NEWLINE);
661 else
662 vty_out(vty,
663 " redistribute %s%s",
664 zebra_route_string(i),
665 VTY_NEWLINE);
666 }
667 } else
668 vty_out(vty, " %s", zebra_route_string(i));
669 }
670 return 0;
671 }
672
673 /* Zebra node structure. */
674 static struct cmd_node zebra_node = {
675 ZEBRA_NODE, "%s(config-router)# ",
676 };
677
678 static void rip_zebra_connected(struct zclient *zclient)
679 {
680 zclient_send_reg_requests(zclient, VRF_DEFAULT);
681 }
682
683 void rip_zclient_init(struct thread_master *master)
684 {
685 /* Set default value to the zebra client structure. */
686 zclient = zclient_new(master);
687 zclient_init(zclient, ZEBRA_ROUTE_RIP, 0);
688 zclient->zebra_connected = rip_zebra_connected;
689 zclient->interface_add = rip_interface_add;
690 zclient->interface_delete = rip_interface_delete;
691 zclient->interface_address_add = rip_interface_address_add;
692 zclient->interface_address_delete = rip_interface_address_delete;
693 zclient->interface_up = rip_interface_up;
694 zclient->interface_down = rip_interface_down;
695 zclient->redistribute_route_ipv4_add = rip_zebra_read_ipv4;
696 zclient->redistribute_route_ipv4_del = rip_zebra_read_ipv4;
697
698 /* Install zebra node. */
699 install_node(&zebra_node, config_write_zebra);
700
701 /* Install command elements to zebra node. */
702 install_default(ZEBRA_NODE);
703 install_element(ZEBRA_NODE, &rip_redistribute_rip_cmd);
704 install_element(ZEBRA_NODE, &no_rip_redistribute_rip_cmd);
705
706 /* Install command elements to rip node. */
707 install_element(RIP_NODE, &rip_redistribute_type_cmd);
708 install_element(RIP_NODE, &rip_redistribute_type_routemap_cmd);
709 install_element(RIP_NODE, &rip_redistribute_type_metric_cmd);
710 install_element(RIP_NODE, &rip_redistribute_type_metric_routemap_cmd);
711 install_element(RIP_NODE, &no_rip_redistribute_type_cmd);
712 install_element(RIP_NODE, &no_rip_redistribute_type_routemap_cmd);
713 install_element(RIP_NODE, &no_rip_redistribute_type_metric_cmd);
714 install_element(RIP_NODE,
715 &no_rip_redistribute_type_metric_routemap_cmd);
716 install_element(RIP_NODE, &rip_default_information_originate_cmd);
717 install_element(RIP_NODE, &no_rip_default_information_originate_cmd);
718 }