Import Upstream version 1.2.2
[quagga-debian.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
42 rip_zebra_ipv4_send (struct route_node *rp, u_char cmd)
43 {
44   static struct in_addr **nexthops = NULL;
45   static unsigned int nexthops_len = 0;
46
47   struct list *list = (struct list *)rp->info;
48   struct zapi_ipv4 api;
49   struct listnode *listnode = NULL;
50   struct rip_info *rinfo = NULL;
51   int count = 0;
52
53   if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_RIP], VRF_DEFAULT))
54     {
55       api.vrf_id = VRF_DEFAULT;
56       api.type = ZEBRA_ROUTE_RIP;
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   unsigned char plength = 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.flags = stream_getc (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   plength = stream_getc (s);
159   p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength);
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     {
165       api.nexthop_num = stream_getc (s);
166       nexthop.s_addr = stream_get_ipv4 (s);
167     }
168   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
169     {
170       api.ifindex_num = stream_getc (s);
171       ifindex = stream_getl (s);
172     }
173   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
174     api.distance = stream_getc (s);
175   else
176     api.distance = 255;
177   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
178     api.metric = stream_getl (s);
179   else
180     api.metric = 0;
181
182   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
183     api.tag = stream_getl (s);
184   else
185     api.tag = 0;
186
187   /* Then fetch IPv4 prefixes. */
188   if (command == ZEBRA_IPV4_ROUTE_ADD)
189     rip_redistribute_add (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex, 
190                           &nexthop, api.metric, api.distance, api.tag);
191   else
192     rip_redistribute_delete (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex);
193
194   return 0;
195 }
196
197 void
198 rip_zclient_reset (void)
199 {
200   zclient_reset (zclient);
201 }
202
203 /* RIP route-map set for redistribution */
204 static void
205 rip_routemap_set (int type, const char *name)
206 {
207   if (rip->route_map[type].name)
208     free(rip->route_map[type].name);
209
210   rip->route_map[type].name = strdup (name);
211   rip->route_map[type].map = route_map_lookup_by_name (name);
212 }
213
214 static void
215 rip_redistribute_metric_set (int type, unsigned int metric)
216 {
217   rip->route_map[type].metric_config = 1;
218   rip->route_map[type].metric = metric;
219 }
220
221 static int
222 rip_metric_unset (int type, unsigned int metric)
223 {
224 #define DONT_CARE_METRIC_RIP 17  
225   if (metric != DONT_CARE_METRIC_RIP &&
226       rip->route_map[type].metric != metric)
227     return 1;
228   rip->route_map[type].metric_config = 0;
229   rip->route_map[type].metric = 0;
230   return 0;
231 }
232
233 /* RIP route-map unset for redistribution */
234 static int
235 rip_routemap_unset (int type, const char *name)
236 {
237   if (! rip->route_map[type].name ||
238       (name != NULL && strcmp(rip->route_map[type].name,name)))
239     return 1;
240
241   free (rip->route_map[type].name);
242   rip->route_map[type].name = NULL;
243   rip->route_map[type].map = NULL;
244
245   return 0;
246 }
247
248 /* Redistribution types */
249 static struct {
250   int type;
251   int str_min_len;
252   const char *str;
253 } redist_type[] = {
254   {ZEBRA_ROUTE_KERNEL,  1, "kernel"},
255   {ZEBRA_ROUTE_CONNECT, 1, "connected"},
256   {ZEBRA_ROUTE_STATIC,  1, "static"},
257   {ZEBRA_ROUTE_OSPF,    1, "ospf"},
258   {ZEBRA_ROUTE_BGP,     2, "bgp"},
259   {ZEBRA_ROUTE_BABEL,   2, "babel"},
260   {0, 0, NULL}
261 };
262
263 DEFUN (router_zebra,
264        router_zebra_cmd,
265        "router zebra",
266        "Enable a routing process\n"
267        "Make connection to zebra daemon\n")
268 {
269   vty->node = ZEBRA_NODE;
270   zclient->enable = 1;
271   zclient_start (zclient);
272   return CMD_SUCCESS;
273 }
274
275 DEFUN (no_router_zebra,
276        no_router_zebra_cmd,
277        "no router zebra",
278        NO_STR
279        "Enable a routing process\n"
280        "Make connection to zebra daemon\n")
281 {
282   zclient->enable = 0;
283   zclient_stop (zclient);
284   return CMD_SUCCESS;
285 }
286
287 #if 0
288 static int
289 rip_redistribute_set (int type)
290 {
291   if (vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
292     return CMD_SUCCESS;
293
294   vrf_bitmap_set (zclient->redist[type], VRF_DEFAULT);
295
296   if (zclient->sock > 0)
297     zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
298
299   return CMD_SUCCESS;
300 }
301 #endif
302
303 static int
304 rip_redistribute_unset (int type)
305 {
306   if (! vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
307     return CMD_SUCCESS;
308
309   vrf_bitmap_unset (zclient->redist[type], VRF_DEFAULT);
310
311   if (zclient->sock > 0)
312     zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type,
313                              VRF_DEFAULT);
314
315   /* Remove the routes from RIP table. */
316   rip_redistribute_withdraw (type);
317
318   return CMD_SUCCESS;
319 }
320
321 int
322 rip_redistribute_check (int type)
323 {
324   return vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT);
325 }
326
327 void
328 rip_redistribute_clean (void)
329 {
330   int i;
331
332   for (i = 0; redist_type[i].str; i++)
333     {
334       if (vrf_bitmap_check (zclient->redist[redist_type[i].type], VRF_DEFAULT))
335         {
336           if (zclient->sock > 0)
337             zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
338                                      zclient, redist_type[i].type,
339                                      VRF_DEFAULT);
340
341           vrf_bitmap_unset (zclient->redist[redist_type[i].type], VRF_DEFAULT);
342
343           /* Remove the routes from RIP table. */
344           rip_redistribute_withdraw (redist_type[i].type);
345         }
346     }
347 }
348
349 DEFUN (rip_redistribute_rip,
350        rip_redistribute_rip_cmd,
351        "redistribute rip",
352        "Redistribute information from another routing protocol\n"
353        "Routing Information Protocol (RIP)\n")
354 {
355   vrf_bitmap_set (zclient->redist[ZEBRA_ROUTE_RIP], VRF_DEFAULT);
356   return CMD_SUCCESS;
357 }
358
359 DEFUN (no_rip_redistribute_rip,
360        no_rip_redistribute_rip_cmd,
361        "no redistribute rip",
362        NO_STR
363        "Redistribute information from another routing protocol\n"
364        "Routing Information Protocol (RIP)\n")
365 {
366   vrf_bitmap_unset (zclient->redist[ZEBRA_ROUTE_RIP], VRF_DEFAULT);
367   return CMD_SUCCESS;
368 }
369
370 DEFUN (rip_redistribute_type,
371        rip_redistribute_type_cmd,
372        "redistribute " QUAGGA_REDIST_STR_RIPD,
373        REDIST_STR
374        QUAGGA_REDIST_HELP_STR_RIPD)
375 {
376   int i;
377
378   for(i = 0; redist_type[i].str; i++) 
379     {
380       if (strncmp (redist_type[i].str, argv[0], 
381                    redist_type[i].str_min_len) == 0) 
382         {
383           zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, 
384                                 redist_type[i].type, VRF_DEFAULT);
385           return CMD_SUCCESS;
386         }
387     }
388
389   vty_out(vty, "Invalid type %s%s", argv[0],
390           VTY_NEWLINE);
391
392   return CMD_WARNING;
393 }
394
395 DEFUN (no_rip_redistribute_type,
396        no_rip_redistribute_type_cmd,
397        "no redistribute " QUAGGA_REDIST_STR_RIPD,
398        NO_STR
399        REDIST_STR
400        QUAGGA_REDIST_HELP_STR_RIPD)
401 {
402   int i;
403
404   for (i = 0; redist_type[i].str; i++) 
405     {
406       if (strncmp(redist_type[i].str, argv[0], 
407                   redist_type[i].str_min_len) == 0) 
408         {
409           rip_metric_unset (redist_type[i].type, DONT_CARE_METRIC_RIP);
410           rip_routemap_unset (redist_type[i].type,NULL);
411           rip_redistribute_unset (redist_type[i].type);
412           return CMD_SUCCESS;
413         }
414     }
415
416   vty_out(vty, "Invalid type %s%s", argv[0],
417           VTY_NEWLINE);
418
419   return CMD_WARNING;
420 }
421
422 DEFUN (rip_redistribute_type_routemap,
423        rip_redistribute_type_routemap_cmd,
424        "redistribute " QUAGGA_REDIST_STR_RIPD " route-map WORD",
425        REDIST_STR
426        QUAGGA_REDIST_HELP_STR_RIPD
427        "Route map reference\n"
428        "Pointer to route-map entries\n")
429 {
430   int i;
431
432   for (i = 0; redist_type[i].str; i++) {
433     if (strncmp(redist_type[i].str, argv[0],
434                 redist_type[i].str_min_len) == 0) 
435       {
436         rip_routemap_set (redist_type[i].type, argv[1]);
437         zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type,
438                               VRF_DEFAULT);
439         return CMD_SUCCESS;
440       }
441   }
442
443   vty_out(vty, "Invalid type %s%s", argv[0],
444           VTY_NEWLINE);
445
446   return CMD_WARNING;
447 }
448
449 DEFUN (no_rip_redistribute_type_routemap,
450        no_rip_redistribute_type_routemap_cmd,
451        "no redistribute " QUAGGA_REDIST_STR_RIPD " route-map WORD",
452        NO_STR
453        REDIST_STR
454        QUAGGA_REDIST_HELP_STR_RIPD
455        "Route map reference\n"
456        "Pointer to route-map entries\n")
457 {
458   int i;
459
460   for (i = 0; redist_type[i].str; i++) 
461     {
462       if (strncmp(redist_type[i].str, argv[0], 
463                   redist_type[i].str_min_len) == 0) 
464         {
465           if (rip_routemap_unset (redist_type[i].type,argv[1]))
466             return CMD_WARNING;
467           rip_redistribute_unset (redist_type[i].type);
468           return CMD_SUCCESS;
469         }
470     }
471
472   vty_out(vty, "Invalid type %s%s", argv[0],
473           VTY_NEWLINE);
474
475   return CMD_WARNING;
476 }
477
478 DEFUN (rip_redistribute_type_metric,
479        rip_redistribute_type_metric_cmd,
480        "redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16>",
481        REDIST_STR
482        QUAGGA_REDIST_HELP_STR_RIPD
483        "Metric\n"
484        "Metric value\n")
485 {
486   int i;
487   int metric;
488
489   metric = atoi (argv[1]);
490
491   for (i = 0; redist_type[i].str; i++) {
492     if (strncmp(redist_type[i].str, argv[0],
493                 redist_type[i].str_min_len) == 0) 
494       {
495         rip_redistribute_metric_set (redist_type[i].type, metric);
496         zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type,
497                               VRF_DEFAULT);
498         return CMD_SUCCESS;
499       }
500   }
501
502   vty_out(vty, "Invalid type %s%s", argv[0],
503           VTY_NEWLINE);
504
505   return CMD_WARNING;
506 }
507
508 DEFUN (no_rip_redistribute_type_metric,
509        no_rip_redistribute_type_metric_cmd,
510        "no redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16>",
511        NO_STR
512        REDIST_STR
513        QUAGGA_REDIST_HELP_STR_RIPD
514        "Metric\n"
515        "Metric value\n")
516 {
517   int i;
518
519   for (i = 0; redist_type[i].str; i++) 
520     {
521       if (strncmp(redist_type[i].str, argv[0], 
522                   redist_type[i].str_min_len) == 0) 
523         {
524           if (rip_metric_unset (redist_type[i].type, atoi(argv[1])))
525             return CMD_WARNING;
526           rip_redistribute_unset (redist_type[i].type);
527           return CMD_SUCCESS;
528         }
529     }
530
531   vty_out(vty, "Invalid type %s%s", argv[0],
532           VTY_NEWLINE);
533
534   return CMD_WARNING;
535 }
536
537 DEFUN (rip_redistribute_type_metric_routemap,
538        rip_redistribute_type_metric_routemap_cmd,
539        "redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16> route-map WORD",
540        REDIST_STR
541        QUAGGA_REDIST_HELP_STR_RIPD
542        "Metric\n"
543        "Metric value\n"
544        "Route map reference\n"
545        "Pointer to route-map entries\n")
546 {
547   int i;
548   int metric;
549
550   metric = atoi (argv[1]);
551
552   for (i = 0; redist_type[i].str; i++) {
553     if (strncmp(redist_type[i].str, argv[0],
554                 redist_type[i].str_min_len) == 0) 
555       {
556         rip_redistribute_metric_set (redist_type[i].type, metric);
557         rip_routemap_set (redist_type[i].type, argv[2]);
558         zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type,
559                               VRF_DEFAULT);
560         return CMD_SUCCESS;
561       }
562   }
563
564   vty_out(vty, "Invalid type %s%s", argv[0],
565           VTY_NEWLINE);
566
567   return CMD_WARNING;
568 }
569
570
571 DEFUN (no_rip_redistribute_type_metric_routemap,
572        no_rip_redistribute_type_metric_routemap_cmd,
573        "no redistribute " QUAGGA_REDIST_STR_RIPD
574        " metric <0-16> route-map WORD",
575        NO_STR
576        REDIST_STR
577        QUAGGA_REDIST_HELP_STR_RIPD
578        "Metric\n"
579        "Metric value\n"
580        "Route map reference\n"
581        "Pointer to route-map entries\n")
582 {
583   int i;
584
585   for (i = 0; redist_type[i].str; i++) 
586     {
587       if (strncmp(redist_type[i].str, argv[0], 
588                   redist_type[i].str_min_len) == 0) 
589         {
590           if (rip_metric_unset (redist_type[i].type, atoi(argv[1])))
591             return CMD_WARNING;
592           if (rip_routemap_unset (redist_type[i].type, argv[2]))
593             {
594               rip_redistribute_metric_set(redist_type[i].type, atoi(argv[1]));   
595               return CMD_WARNING;
596             }
597           rip_redistribute_unset (redist_type[i].type);
598           return CMD_SUCCESS;
599         }
600     }
601
602   vty_out(vty, "Invalid type %s%s", argv[0],
603           VTY_NEWLINE);
604
605   return CMD_WARNING;
606 }
607
608 /* Default information originate. */
609
610 DEFUN (rip_default_information_originate,
611        rip_default_information_originate_cmd,
612        "default-information originate",
613        "Control distribution of default route\n"
614        "Distribute a default route\n")
615 {
616   struct prefix_ipv4 p;
617
618   if (! rip->default_information)
619     {
620       memset (&p, 0, sizeof (struct prefix_ipv4));
621       p.family = AF_INET;
622
623       rip->default_information = 1;
624   
625       rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0, 
626                             NULL, 0, 0, 0);
627     }
628
629   return CMD_SUCCESS;
630 }
631
632 DEFUN (no_rip_default_information_originate,
633        no_rip_default_information_originate_cmd,
634        "no default-information originate",
635        NO_STR
636        "Control distribution of default route\n"
637        "Distribute a default route\n")
638 {
639   struct prefix_ipv4 p;
640
641   if (rip->default_information)
642     {
643       memset (&p, 0, sizeof (struct prefix_ipv4));
644       p.family = AF_INET;
645
646       rip->default_information = 0;
647   
648       rip_redistribute_delete (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0);
649     }
650
651   return CMD_SUCCESS;
652 }
653
654 /* RIP configuration write function. */
655 static int
656 config_write_zebra (struct vty *vty)
657 {
658   if (! zclient->enable)
659     {
660       vty_out (vty, "no router zebra%s", VTY_NEWLINE);
661       return 1;
662     }
663   else if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_RIP], VRF_DEFAULT))
664     {
665       vty_out (vty, "router zebra%s", VTY_NEWLINE);
666       vty_out (vty, " no redistribute rip%s", VTY_NEWLINE);
667       return 1;
668     }
669   return 0;
670 }
671
672 int
673 config_write_rip_redistribute (struct vty *vty, int config_mode)
674 {
675   int i;
676
677   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
678     if (i != zclient->redist_default &&
679         vrf_bitmap_check (zclient->redist[i], VRF_DEFAULT))
680       {
681         if (config_mode)
682           {
683             if (rip->route_map[i].metric_config)
684               {
685                 if (rip->route_map[i].name)
686                   vty_out (vty, " redistribute %s metric %d route-map %s%s",
687                            zebra_route_string(i), rip->route_map[i].metric,
688                            rip->route_map[i].name,
689                            VTY_NEWLINE);
690                 else
691                   vty_out (vty, " redistribute %s metric %d%s",
692                            zebra_route_string(i), rip->route_map[i].metric,
693                            VTY_NEWLINE);
694               }
695             else
696               {
697                 if (rip->route_map[i].name)
698                   vty_out (vty, " redistribute %s route-map %s%s",
699                            zebra_route_string(i), rip->route_map[i].name,
700                            VTY_NEWLINE);
701                 else
702                   vty_out (vty, " redistribute %s%s", zebra_route_string(i),
703                            VTY_NEWLINE);
704               }
705           }
706         else
707           vty_out (vty, " %s", zebra_route_string(i));
708       }
709   return 0;
710 }
711
712 /* Zebra node structure. */
713 static struct cmd_node zebra_node =
714 {
715   ZEBRA_NODE,
716   "%s(config-router)# ",
717 };
718
719 static void
720 rip_zebra_connected (struct zclient *zclient)
721 {
722   zclient_send_requests (zclient, VRF_DEFAULT);
723 }
724
725 void
726 rip_zclient_init (struct thread_master *master)
727 {
728   /* Set default value to the zebra client structure. */
729   zclient = zclient_new (master);
730   zclient_init (zclient, ZEBRA_ROUTE_RIP);
731   zclient->zebra_connected = rip_zebra_connected;
732   zclient->interface_add = rip_interface_add;
733   zclient->interface_delete = rip_interface_delete;
734   zclient->interface_address_add = rip_interface_address_add;
735   zclient->interface_address_delete = rip_interface_address_delete;
736   zclient->ipv4_route_add = rip_zebra_read_ipv4;
737   zclient->ipv4_route_delete = rip_zebra_read_ipv4;
738   zclient->interface_up = rip_interface_up;
739   zclient->interface_down = rip_interface_down;
740   
741   /* Install zebra node. */
742   install_node (&zebra_node, config_write_zebra);
743
744   /* Install command elements to zebra node. */ 
745   install_element (CONFIG_NODE, &router_zebra_cmd);
746   install_element (CONFIG_NODE, &no_router_zebra_cmd);
747   install_default (ZEBRA_NODE);
748   install_element (ZEBRA_NODE, &rip_redistribute_rip_cmd);
749   install_element (ZEBRA_NODE, &no_rip_redistribute_rip_cmd);
750
751   /* Install command elements to rip node. */
752   install_element (RIP_NODE, &rip_redistribute_type_cmd);
753   install_element (RIP_NODE, &rip_redistribute_type_routemap_cmd);
754   install_element (RIP_NODE, &rip_redistribute_type_metric_cmd);
755   install_element (RIP_NODE, &rip_redistribute_type_metric_routemap_cmd);
756   install_element (RIP_NODE, &no_rip_redistribute_type_cmd);
757   install_element (RIP_NODE, &no_rip_redistribute_type_routemap_cmd);
758   install_element (RIP_NODE, &no_rip_redistribute_type_metric_cmd);
759   install_element (RIP_NODE, &no_rip_redistribute_type_metric_routemap_cmd);
760   install_element (RIP_NODE, &rip_default_information_originate_cmd);
761   install_element (RIP_NODE, &no_rip_default_information_originate_cmd);
762 }