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