blob: b005ece9671924946480c0b33220373ad8147f8b [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* 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"
Lu Fengb397cf42014-07-18 06:13:18 +000026#include "table.h"
paul718e3742002-12-13 20:15:29 +000027#include "stream.h"
Lu Fengb397cf42014-07-18 06:13:18 +000028#include "memory.h"
paul718e3742002-12-13 20:15:29 +000029#include "routemap.h"
30#include "zclient.h"
31#include "log.h"
32#include "ripd/ripd.h"
33#include "ripd/rip_debug.h"
pauldc63bfd2005-10-25 23:31:05 +000034#include "ripd/rip_interface.h"
paul718e3742002-12-13 20:15:29 +000035
36/* All information about zebra. */
37struct zclient *zclient = NULL;
David Lamparter6b0655a2014-06-04 06:53:35 +020038
Lu Fengb397cf42014-07-18 06:13:18 +000039/* Send ECMP routes to zebra. */
40static void
41rip_zebra_ipv4_send (struct route_node *rp, u_char cmd)
paul718e3742002-12-13 20:15:29 +000042{
Lu Fengb397cf42014-07-18 06:13:18 +000043 static struct in_addr **nexthops = NULL;
44 static unsigned int nexthops_len = 0;
45
46 struct list *list = (struct list *)rp->info;
paul718e3742002-12-13 20:15:29 +000047 struct zapi_ipv4 api;
Lu Fengb397cf42014-07-18 06:13:18 +000048 struct listnode *listnode = NULL;
49 struct rip_info *rinfo = NULL;
50 int count = 0;
paul718e3742002-12-13 20:15:29 +000051
52 if (zclient->redist[ZEBRA_ROUTE_RIP])
53 {
54 api.type = ZEBRA_ROUTE_RIP;
55 api.flags = 0;
56 api.message = 0;
Denis Ovsienkob4e45f62011-12-05 16:35:14 +040057 api.safi = SAFI_UNICAST;
Lu Fengb397cf42014-07-18 06:13:18 +000058
59 if (nexthops_len < listcount (list))
60 {
61 nexthops_len = listcount (list);
62 nexthops = XREALLOC (MTYPE_TMP, nexthops,
63 nexthops_len * sizeof (struct in_addr *));
64 }
65
paul718e3742002-12-13 20:15:29 +000066 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
Lu Fengb397cf42014-07-18 06:13:18 +000067 for (ALL_LIST_ELEMENTS_RO (list, listnode, rinfo))
68 {
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;
paul718e3742002-12-13 20:15:29 +000078 api.ifindex_num = 0;
Lu Fengb397cf42014-07-18 06:13:18 +000079
80 rinfo = listgetdata (listhead (list));
81
paul718e3742002-12-13 20:15:29 +000082 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
Lu Fengb397cf42014-07-18 06:13:18 +000083 api.metric = rinfo->metric;
paul718e3742002-12-13 20:15:29 +000084
Lu Fengb397cf42014-07-18 06:13:18 +000085 if (rinfo->distance && rinfo->distance != ZEBRA_RIP_DISTANCE_DEFAULT)
86 {
87 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
88 api.distance = rinfo->distance;
89 }
paul718e3742002-12-13 20:15:29 +000090
Lu Fengb397cf42014-07-18 06:13:18 +000091 zapi_ipv4_route (cmd, zclient,
92 (struct prefix_ipv4 *)&rp->p, &api);
93
94 if (IS_RIP_DEBUG_ZEBRA)
Lu Feng0b74a0a2014-07-18 06:13:19 +000095 {
96 if (rip->ecmp)
97 zlog_debug ("%s: %s/%d nexthops %d",
98 (cmd == ZEBRA_IPV4_ROUTE_ADD) ? \
99 "Install into zebra" : "Delete from zebra",
100 inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen, count);
101 else
102 zlog_debug ("%s: %s/%d",
103 (cmd == ZEBRA_IPV4_ROUTE_ADD) ? \
104 "Install into zebra" : "Delete from zebra",
105 inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen);
106 }
paul718e3742002-12-13 20:15:29 +0000107
108 rip_global_route_changes++;
109 }
110}
111
Lu Fengb397cf42014-07-18 06:13:18 +0000112/* Add/update ECMP routes to zebra. */
paul718e3742002-12-13 20:15:29 +0000113void
Lu Fengb397cf42014-07-18 06:13:18 +0000114rip_zebra_ipv4_add (struct route_node *rp)
paul718e3742002-12-13 20:15:29 +0000115{
Lu Fengb397cf42014-07-18 06:13:18 +0000116 rip_zebra_ipv4_send (rp, ZEBRA_IPV4_ROUTE_ADD);
117}
paul718e3742002-12-13 20:15:29 +0000118
Lu Fengb397cf42014-07-18 06:13:18 +0000119/* Delete ECMP routes from zebra. */
120void
121rip_zebra_ipv4_delete (struct route_node *rp)
122{
123 rip_zebra_ipv4_send (rp, ZEBRA_IPV4_ROUTE_DELETE);
paul718e3742002-12-13 20:15:29 +0000124}
125
126/* Zebra route add and delete treatment. */
pauldc63bfd2005-10-25 23:31:05 +0000127static int
paul718e3742002-12-13 20:15:29 +0000128rip_zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
129{
130 struct stream *s;
131 struct zapi_ipv4 api;
132 unsigned long ifindex;
133 struct in_addr nexthop;
134 struct prefix_ipv4 p;
135
136 s = zclient->ibuf;
137 ifindex = 0;
138 nexthop.s_addr = 0;
139
140 /* Type, flags, message. */
141 api.type = stream_getc (s);
142 api.flags = stream_getc (s);
143 api.message = stream_getc (s);
144
145 /* IPv4 prefix. */
146 memset (&p, 0, sizeof (struct prefix_ipv4));
147 p.family = AF_INET;
148 p.prefixlen = stream_getc (s);
149 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
150
151 /* Nexthop, ifindex, distance, metric. */
152 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
153 {
154 api.nexthop_num = stream_getc (s);
155 nexthop.s_addr = stream_get_ipv4 (s);
156 }
157 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
158 {
159 api.ifindex_num = stream_getc (s);
160 ifindex = stream_getl (s);
161 }
162 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
163 api.distance = stream_getc (s);
vincentfbf5d032005-09-29 11:25:50 +0000164 else
165 api.distance = 255;
paul718e3742002-12-13 20:15:29 +0000166 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
167 api.metric = stream_getl (s);
vincentfbf5d032005-09-29 11:25:50 +0000168 else
169 api.metric = 0;
paul718e3742002-12-13 20:15:29 +0000170
171 /* Then fetch IPv4 prefixes. */
172 if (command == ZEBRA_IPV4_ROUTE_ADD)
vincentfbf5d032005-09-29 11:25:50 +0000173 rip_redistribute_add (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex,
174 &nexthop, api.metric, api.distance);
paul718e3742002-12-13 20:15:29 +0000175 else
176 rip_redistribute_delete (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex);
177
178 return 0;
179}
180
181void
pauldc63bfd2005-10-25 23:31:05 +0000182rip_zclient_reset (void)
paul718e3742002-12-13 20:15:29 +0000183{
184 zclient_reset (zclient);
185}
186
187/* RIP route-map set for redistribution */
pauldc63bfd2005-10-25 23:31:05 +0000188static void
hasso98b718a2004-10-11 12:57:57 +0000189rip_routemap_set (int type, const char *name)
paul718e3742002-12-13 20:15:29 +0000190{
191 if (rip->route_map[type].name)
192 free(rip->route_map[type].name);
193
194 rip->route_map[type].name = strdup (name);
195 rip->route_map[type].map = route_map_lookup_by_name (name);
196}
197
pauldc63bfd2005-10-25 23:31:05 +0000198static void
hasso8a676be2004-10-08 06:36:38 +0000199rip_redistribute_metric_set (int type, unsigned int metric)
paul718e3742002-12-13 20:15:29 +0000200{
201 rip->route_map[type].metric_config = 1;
202 rip->route_map[type].metric = metric;
203}
204
pauldc63bfd2005-10-25 23:31:05 +0000205static int
hasso8a676be2004-10-08 06:36:38 +0000206rip_metric_unset (int type, unsigned int metric)
paul718e3742002-12-13 20:15:29 +0000207{
208#define DONT_CARE_METRIC_RIP 17
209 if (metric != DONT_CARE_METRIC_RIP &&
210 rip->route_map[type].metric != metric)
211 return 1;
212 rip->route_map[type].metric_config = 0;
213 rip->route_map[type].metric = 0;
214 return 0;
215}
216
217/* RIP route-map unset for redistribution */
pauldc63bfd2005-10-25 23:31:05 +0000218static int
hasso98b718a2004-10-11 12:57:57 +0000219rip_routemap_unset (int type, const char *name)
paul718e3742002-12-13 20:15:29 +0000220{
221 if (! rip->route_map[type].name ||
222 (name != NULL && strcmp(rip->route_map[type].name,name)))
223 return 1;
224
225 free (rip->route_map[type].name);
226 rip->route_map[type].name = NULL;
227 rip->route_map[type].map = NULL;
228
229 return 0;
230}
David Lamparter6b0655a2014-06-04 06:53:35 +0200231
paul718e3742002-12-13 20:15:29 +0000232/* Redistribution types */
233static struct {
234 int type;
235 int str_min_len;
hasso8a676be2004-10-08 06:36:38 +0000236 const char *str;
paul718e3742002-12-13 20:15:29 +0000237} redist_type[] = {
238 {ZEBRA_ROUTE_KERNEL, 1, "kernel"},
239 {ZEBRA_ROUTE_CONNECT, 1, "connected"},
240 {ZEBRA_ROUTE_STATIC, 1, "static"},
241 {ZEBRA_ROUTE_OSPF, 1, "ospf"},
Matthieu Boutier9c58fbd2012-02-09 21:51:17 +0100242 {ZEBRA_ROUTE_BGP, 2, "bgp"},
243 {ZEBRA_ROUTE_BABEL, 2, "babel"},
paul718e3742002-12-13 20:15:29 +0000244 {0, 0, NULL}
245};
246
247DEFUN (router_zebra,
248 router_zebra_cmd,
249 "router zebra",
250 "Enable a routing process\n"
251 "Make connection to zebra daemon\n")
252{
253 vty->node = ZEBRA_NODE;
254 zclient->enable = 1;
255 zclient_start (zclient);
256 return CMD_SUCCESS;
257}
258
259DEFUN (no_router_zebra,
260 no_router_zebra_cmd,
261 "no router zebra",
262 NO_STR
263 "Enable a routing process\n"
264 "Make connection to zebra daemon\n")
265{
266 zclient->enable = 0;
267 zclient_stop (zclient);
268 return CMD_SUCCESS;
269}
270
Stephen Hemminger2c239702009-12-10 19:16:05 +0300271#if 0
pauldc63bfd2005-10-25 23:31:05 +0000272static int
paul718e3742002-12-13 20:15:29 +0000273rip_redistribute_set (int type)
274{
275 if (zclient->redist[type])
276 return CMD_SUCCESS;
277
278 zclient->redist[type] = 1;
279
280 if (zclient->sock > 0)
ajs634f9ea2005-04-11 15:51:40 +0000281 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
paul718e3742002-12-13 20:15:29 +0000282
283 return CMD_SUCCESS;
284}
Stephen Hemminger2c239702009-12-10 19:16:05 +0300285#endif
paul718e3742002-12-13 20:15:29 +0000286
pauldc63bfd2005-10-25 23:31:05 +0000287static int
paul718e3742002-12-13 20:15:29 +0000288rip_redistribute_unset (int type)
289{
290 if (! zclient->redist[type])
291 return CMD_SUCCESS;
292
293 zclient->redist[type] = 0;
294
295 if (zclient->sock > 0)
ajs634f9ea2005-04-11 15:51:40 +0000296 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
paul718e3742002-12-13 20:15:29 +0000297
298 /* Remove the routes from RIP table. */
299 rip_redistribute_withdraw (type);
300
301 return CMD_SUCCESS;
302}
303
304int
305rip_redistribute_check (int type)
306{
307 return (zclient->redist[type]);
308}
309
310void
pauldc63bfd2005-10-25 23:31:05 +0000311rip_redistribute_clean (void)
paul718e3742002-12-13 20:15:29 +0000312{
313 int i;
314
315 for (i = 0; redist_type[i].str; i++)
316 {
317 if (zclient->redist[redist_type[i].type])
318 {
319 if (zclient->sock > 0)
320 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
ajs634f9ea2005-04-11 15:51:40 +0000321 zclient, redist_type[i].type);
paul718e3742002-12-13 20:15:29 +0000322
323 zclient->redist[redist_type[i].type] = 0;
324
325 /* Remove the routes from RIP table. */
326 rip_redistribute_withdraw (redist_type[i].type);
327 }
328 }
329}
330
331DEFUN (rip_redistribute_rip,
332 rip_redistribute_rip_cmd,
333 "redistribute rip",
334 "Redistribute information from another routing protocol\n"
335 "Routing Information Protocol (RIP)\n")
336{
337 zclient->redist[ZEBRA_ROUTE_RIP] = 1;
338 return CMD_SUCCESS;
339}
340
341DEFUN (no_rip_redistribute_rip,
342 no_rip_redistribute_rip_cmd,
343 "no redistribute rip",
344 NO_STR
345 "Redistribute information from another routing protocol\n"
346 "Routing Information Protocol (RIP)\n")
347{
348 zclient->redist[ZEBRA_ROUTE_RIP] = 0;
349 return CMD_SUCCESS;
350}
351
352DEFUN (rip_redistribute_type,
353 rip_redistribute_type_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000354 "redistribute " QUAGGA_REDIST_STR_RIPD,
355 REDIST_STR
356 QUAGGA_REDIST_HELP_STR_RIPD)
paul718e3742002-12-13 20:15:29 +0000357{
358 int i;
359
360 for(i = 0; redist_type[i].str; i++)
361 {
362 if (strncmp (redist_type[i].str, argv[0],
363 redist_type[i].str_min_len) == 0)
364 {
paul0a589352004-05-08 11:48:26 +0000365 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient,
366 redist_type[i].type);
paul718e3742002-12-13 20:15:29 +0000367 return CMD_SUCCESS;
368 }
369 }
370
371 vty_out(vty, "Invalid type %s%s", argv[0],
372 VTY_NEWLINE);
373
374 return CMD_WARNING;
375}
376
377DEFUN (no_rip_redistribute_type,
378 no_rip_redistribute_type_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000379 "no redistribute " QUAGGA_REDIST_STR_RIPD,
paul718e3742002-12-13 20:15:29 +0000380 NO_STR
Paul Jakma9a57dc62006-06-30 16:58:53 +0000381 REDIST_STR
382 QUAGGA_REDIST_HELP_STR_RIPD)
paul718e3742002-12-13 20:15:29 +0000383{
384 int i;
385
386 for (i = 0; redist_type[i].str; i++)
387 {
388 if (strncmp(redist_type[i].str, argv[0],
389 redist_type[i].str_min_len) == 0)
390 {
391 rip_metric_unset (redist_type[i].type, DONT_CARE_METRIC_RIP);
392 rip_routemap_unset (redist_type[i].type,NULL);
393 rip_redistribute_unset (redist_type[i].type);
394 return CMD_SUCCESS;
395 }
396 }
397
398 vty_out(vty, "Invalid type %s%s", argv[0],
399 VTY_NEWLINE);
400
401 return CMD_WARNING;
402}
403
404DEFUN (rip_redistribute_type_routemap,
405 rip_redistribute_type_routemap_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000406 "redistribute " QUAGGA_REDIST_STR_RIPD " route-map WORD",
407 REDIST_STR
408 QUAGGA_REDIST_HELP_STR_RIPD
paul718e3742002-12-13 20:15:29 +0000409 "Route map reference\n"
410 "Pointer to route-map entries\n")
411{
412 int i;
413
414 for (i = 0; redist_type[i].str; i++) {
415 if (strncmp(redist_type[i].str, argv[0],
416 redist_type[i].str_min_len) == 0)
417 {
418 rip_routemap_set (redist_type[i].type, argv[1]);
paul0a589352004-05-08 11:48:26 +0000419 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
paul718e3742002-12-13 20:15:29 +0000420 return CMD_SUCCESS;
421 }
422 }
423
424 vty_out(vty, "Invalid type %s%s", argv[0],
425 VTY_NEWLINE);
426
427 return CMD_WARNING;
428}
429
430DEFUN (no_rip_redistribute_type_routemap,
431 no_rip_redistribute_type_routemap_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000432 "no redistribute " QUAGGA_REDIST_STR_RIPD " route-map WORD",
paul718e3742002-12-13 20:15:29 +0000433 NO_STR
Paul Jakma9a57dc62006-06-30 16:58:53 +0000434 REDIST_STR
435 QUAGGA_REDIST_HELP_STR_RIPD
paul718e3742002-12-13 20:15:29 +0000436 "Route map reference\n"
437 "Pointer to route-map entries\n")
438{
439 int i;
440
441 for (i = 0; redist_type[i].str; i++)
442 {
443 if (strncmp(redist_type[i].str, argv[0],
444 redist_type[i].str_min_len) == 0)
445 {
446 if (rip_routemap_unset (redist_type[i].type,argv[1]))
447 return CMD_WARNING;
448 rip_redistribute_unset (redist_type[i].type);
449 return CMD_SUCCESS;
450 }
451 }
452
453 vty_out(vty, "Invalid type %s%s", argv[0],
454 VTY_NEWLINE);
455
456 return CMD_WARNING;
457}
458
459DEFUN (rip_redistribute_type_metric,
460 rip_redistribute_type_metric_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000461 "redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16>",
462 REDIST_STR
463 QUAGGA_REDIST_HELP_STR_RIPD
paul718e3742002-12-13 20:15:29 +0000464 "Metric\n"
465 "Metric value\n")
466{
467 int i;
468 int metric;
469
470 metric = atoi (argv[1]);
471
472 for (i = 0; redist_type[i].str; i++) {
473 if (strncmp(redist_type[i].str, argv[0],
474 redist_type[i].str_min_len) == 0)
475 {
476 rip_redistribute_metric_set (redist_type[i].type, metric);
paul0a589352004-05-08 11:48:26 +0000477 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
paul718e3742002-12-13 20:15:29 +0000478 return CMD_SUCCESS;
479 }
480 }
481
482 vty_out(vty, "Invalid type %s%s", argv[0],
483 VTY_NEWLINE);
484
485 return CMD_WARNING;
486}
487
488DEFUN (no_rip_redistribute_type_metric,
489 no_rip_redistribute_type_metric_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000490 "no redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16>",
paul718e3742002-12-13 20:15:29 +0000491 NO_STR
Paul Jakma9a57dc62006-06-30 16:58:53 +0000492 REDIST_STR
493 QUAGGA_REDIST_HELP_STR_RIPD
paul718e3742002-12-13 20:15:29 +0000494 "Metric\n"
495 "Metric value\n")
496{
497 int i;
498
499 for (i = 0; redist_type[i].str; i++)
500 {
501 if (strncmp(redist_type[i].str, argv[0],
502 redist_type[i].str_min_len) == 0)
503 {
504 if (rip_metric_unset (redist_type[i].type, atoi(argv[1])))
505 return CMD_WARNING;
506 rip_redistribute_unset (redist_type[i].type);
507 return CMD_SUCCESS;
508 }
509 }
510
511 vty_out(vty, "Invalid type %s%s", argv[0],
512 VTY_NEWLINE);
513
514 return CMD_WARNING;
515}
516
hasso16705132003-05-25 14:49:19 +0000517DEFUN (rip_redistribute_type_metric_routemap,
518 rip_redistribute_type_metric_routemap_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000519 "redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16> route-map WORD",
520 REDIST_STR
521 QUAGGA_REDIST_HELP_STR_RIPD
hasso16705132003-05-25 14:49:19 +0000522 "Metric\n"
523 "Metric value\n"
524 "Route map reference\n"
525 "Pointer to route-map entries\n")
526{
527 int i;
528 int metric;
529
530 metric = atoi (argv[1]);
531
532 for (i = 0; redist_type[i].str; i++) {
533 if (strncmp(redist_type[i].str, argv[0],
534 redist_type[i].str_min_len) == 0)
535 {
536 rip_redistribute_metric_set (redist_type[i].type, metric);
537 rip_routemap_set (redist_type[i].type, argv[2]);
paul0a589352004-05-08 11:48:26 +0000538 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
hasso16705132003-05-25 14:49:19 +0000539 return CMD_SUCCESS;
540 }
541 }
542
543 vty_out(vty, "Invalid type %s%s", argv[0],
544 VTY_NEWLINE);
545
546 return CMD_WARNING;
547}
548
549
paul718e3742002-12-13 20:15:29 +0000550DEFUN (no_rip_redistribute_type_metric_routemap,
551 no_rip_redistribute_type_metric_routemap_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000552 "no redistribute " QUAGGA_REDIST_STR_RIPD
553 " metric <0-16> route-map WORD",
paul718e3742002-12-13 20:15:29 +0000554 NO_STR
Paul Jakma9a57dc62006-06-30 16:58:53 +0000555 REDIST_STR
556 QUAGGA_REDIST_HELP_STR_RIPD
paul718e3742002-12-13 20:15:29 +0000557 "Metric\n"
558 "Metric value\n"
559 "Route map reference\n"
560 "Pointer to route-map entries\n")
561{
562 int i;
563
564 for (i = 0; redist_type[i].str; i++)
565 {
566 if (strncmp(redist_type[i].str, argv[0],
567 redist_type[i].str_min_len) == 0)
568 {
569 if (rip_metric_unset (redist_type[i].type, atoi(argv[1])))
570 return CMD_WARNING;
571 if (rip_routemap_unset (redist_type[i].type, argv[2]))
572 {
573 rip_redistribute_metric_set(redist_type[i].type, atoi(argv[1]));
574 return CMD_WARNING;
575 }
576 rip_redistribute_unset (redist_type[i].type);
577 return CMD_SUCCESS;
578 }
579 }
580
581 vty_out(vty, "Invalid type %s%s", argv[0],
582 VTY_NEWLINE);
583
584 return CMD_WARNING;
585}
David Lamparter6b0655a2014-06-04 06:53:35 +0200586
paul718e3742002-12-13 20:15:29 +0000587/* Default information originate. */
588
589DEFUN (rip_default_information_originate,
590 rip_default_information_originate_cmd,
591 "default-information originate",
592 "Control distribution of default route\n"
593 "Distribute a default route\n")
594{
595 struct prefix_ipv4 p;
596
597 if (! rip->default_information)
598 {
599 memset (&p, 0, sizeof (struct prefix_ipv4));
600 p.family = AF_INET;
601
602 rip->default_information = 1;
603
vincentfbf5d032005-09-29 11:25:50 +0000604 rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0,
605 NULL, 0, 0);
paul718e3742002-12-13 20:15:29 +0000606 }
607
608 return CMD_SUCCESS;
609}
610
611DEFUN (no_rip_default_information_originate,
612 no_rip_default_information_originate_cmd,
613 "no default-information originate",
614 NO_STR
615 "Control distribution of default route\n"
616 "Distribute a default route\n")
617{
618 struct prefix_ipv4 p;
619
620 if (rip->default_information)
621 {
622 memset (&p, 0, sizeof (struct prefix_ipv4));
623 p.family = AF_INET;
624
625 rip->default_information = 0;
626
hasso16705132003-05-25 14:49:19 +0000627 rip_redistribute_delete (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0);
paul718e3742002-12-13 20:15:29 +0000628 }
629
630 return CMD_SUCCESS;
631}
David Lamparter6b0655a2014-06-04 06:53:35 +0200632
paul718e3742002-12-13 20:15:29 +0000633/* RIP configuration write function. */
pauldc63bfd2005-10-25 23:31:05 +0000634static int
paul718e3742002-12-13 20:15:29 +0000635config_write_zebra (struct vty *vty)
636{
637 if (! zclient->enable)
638 {
639 vty_out (vty, "no router zebra%s", VTY_NEWLINE);
640 return 1;
641 }
642 else if (! zclient->redist[ZEBRA_ROUTE_RIP])
643 {
644 vty_out (vty, "router zebra%s", VTY_NEWLINE);
645 vty_out (vty, " no redistribute rip%s", VTY_NEWLINE);
646 return 1;
647 }
648 return 0;
649}
650
651int
652config_write_rip_redistribute (struct vty *vty, int config_mode)
653{
654 int i;
paul718e3742002-12-13 20:15:29 +0000655
656 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
657 if (i != zclient->redist_default && zclient->redist[i])
658 {
659 if (config_mode)
660 {
661 if (rip->route_map[i].metric_config)
662 {
663 if (rip->route_map[i].name)
664 vty_out (vty, " redistribute %s metric %d route-map %s%s",
ajsf52d13c2005-10-01 17:38:06 +0000665 zebra_route_string(i), rip->route_map[i].metric,
paul718e3742002-12-13 20:15:29 +0000666 rip->route_map[i].name,
667 VTY_NEWLINE);
668 else
669 vty_out (vty, " redistribute %s metric %d%s",
ajsf52d13c2005-10-01 17:38:06 +0000670 zebra_route_string(i), rip->route_map[i].metric,
paul718e3742002-12-13 20:15:29 +0000671 VTY_NEWLINE);
672 }
673 else
674 {
675 if (rip->route_map[i].name)
676 vty_out (vty, " redistribute %s route-map %s%s",
ajsf52d13c2005-10-01 17:38:06 +0000677 zebra_route_string(i), rip->route_map[i].name,
paul718e3742002-12-13 20:15:29 +0000678 VTY_NEWLINE);
679 else
ajsf52d13c2005-10-01 17:38:06 +0000680 vty_out (vty, " redistribute %s%s", zebra_route_string(i),
paul718e3742002-12-13 20:15:29 +0000681 VTY_NEWLINE);
682 }
683 }
684 else
ajsf52d13c2005-10-01 17:38:06 +0000685 vty_out (vty, " %s", zebra_route_string(i));
paul718e3742002-12-13 20:15:29 +0000686 }
687 return 0;
688}
689
690/* Zebra node structure. */
Stephen Hemminger7fc626d2008-12-01 11:10:34 -0800691static struct cmd_node zebra_node =
paul718e3742002-12-13 20:15:29 +0000692{
693 ZEBRA_NODE,
694 "%s(config-router)# ",
695};
696
697void
698rip_zclient_init ()
699{
700 /* Set default value to the zebra client structure. */
701 zclient = zclient_new ();
702 zclient_init (zclient, ZEBRA_ROUTE_RIP);
703 zclient->interface_add = rip_interface_add;
704 zclient->interface_delete = rip_interface_delete;
705 zclient->interface_address_add = rip_interface_address_add;
706 zclient->interface_address_delete = rip_interface_address_delete;
707 zclient->ipv4_route_add = rip_zebra_read_ipv4;
708 zclient->ipv4_route_delete = rip_zebra_read_ipv4;
709 zclient->interface_up = rip_interface_up;
710 zclient->interface_down = rip_interface_down;
711
712 /* Install zebra node. */
713 install_node (&zebra_node, config_write_zebra);
714
715 /* Install command elements to zebra node. */
716 install_element (CONFIG_NODE, &router_zebra_cmd);
717 install_element (CONFIG_NODE, &no_router_zebra_cmd);
718 install_default (ZEBRA_NODE);
719 install_element (ZEBRA_NODE, &rip_redistribute_rip_cmd);
720 install_element (ZEBRA_NODE, &no_rip_redistribute_rip_cmd);
721
722 /* Install command elements to rip node. */
723 install_element (RIP_NODE, &rip_redistribute_type_cmd);
724 install_element (RIP_NODE, &rip_redistribute_type_routemap_cmd);
725 install_element (RIP_NODE, &rip_redistribute_type_metric_cmd);
hasso16705132003-05-25 14:49:19 +0000726 install_element (RIP_NODE, &rip_redistribute_type_metric_routemap_cmd);
paul718e3742002-12-13 20:15:29 +0000727 install_element (RIP_NODE, &no_rip_redistribute_type_cmd);
728 install_element (RIP_NODE, &no_rip_redistribute_type_routemap_cmd);
729 install_element (RIP_NODE, &no_rip_redistribute_type_metric_cmd);
730 install_element (RIP_NODE, &no_rip_redistribute_type_metric_routemap_cmd);
731 install_element (RIP_NODE, &rip_default_information_originate_cmd);
732 install_element (RIP_NODE, &no_rip_default_information_originate_cmd);
733}