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