blob: 8b1c64d6e4396611498c52ca9c466822ebc17270 [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)
95 zlog_debug ("%s: %s/%d nexthops %d",
96 (cmd == ZEBRA_IPV4_ROUTE_ADD) ? \
97 "Install into zebra" : "Delete from zebra",
98 inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen, count);
paul718e3742002-12-13 20:15:29 +000099
100 rip_global_route_changes++;
101 }
102}
103
Lu Fengb397cf42014-07-18 06:13:18 +0000104/* Add/update ECMP routes to zebra. */
paul718e3742002-12-13 20:15:29 +0000105void
Lu Fengb397cf42014-07-18 06:13:18 +0000106rip_zebra_ipv4_add (struct route_node *rp)
paul718e3742002-12-13 20:15:29 +0000107{
Lu Fengb397cf42014-07-18 06:13:18 +0000108 rip_zebra_ipv4_send (rp, ZEBRA_IPV4_ROUTE_ADD);
109}
paul718e3742002-12-13 20:15:29 +0000110
Lu Fengb397cf42014-07-18 06:13:18 +0000111/* Delete ECMP routes from zebra. */
112void
113rip_zebra_ipv4_delete (struct route_node *rp)
114{
115 rip_zebra_ipv4_send (rp, ZEBRA_IPV4_ROUTE_DELETE);
paul718e3742002-12-13 20:15:29 +0000116}
117
118/* Zebra route add and delete treatment. */
pauldc63bfd2005-10-25 23:31:05 +0000119static int
paul718e3742002-12-13 20:15:29 +0000120rip_zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
121{
122 struct stream *s;
123 struct zapi_ipv4 api;
124 unsigned long ifindex;
125 struct in_addr nexthop;
126 struct prefix_ipv4 p;
127
128 s = zclient->ibuf;
129 ifindex = 0;
130 nexthop.s_addr = 0;
131
132 /* Type, flags, message. */
133 api.type = stream_getc (s);
134 api.flags = stream_getc (s);
135 api.message = stream_getc (s);
136
137 /* IPv4 prefix. */
138 memset (&p, 0, sizeof (struct prefix_ipv4));
139 p.family = AF_INET;
140 p.prefixlen = stream_getc (s);
141 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
142
143 /* Nexthop, ifindex, distance, metric. */
144 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
145 {
146 api.nexthop_num = stream_getc (s);
147 nexthop.s_addr = stream_get_ipv4 (s);
148 }
149 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
150 {
151 api.ifindex_num = stream_getc (s);
152 ifindex = stream_getl (s);
153 }
154 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
155 api.distance = stream_getc (s);
vincentfbf5d032005-09-29 11:25:50 +0000156 else
157 api.distance = 255;
paul718e3742002-12-13 20:15:29 +0000158 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
159 api.metric = stream_getl (s);
vincentfbf5d032005-09-29 11:25:50 +0000160 else
161 api.metric = 0;
paul718e3742002-12-13 20:15:29 +0000162
163 /* Then fetch IPv4 prefixes. */
164 if (command == ZEBRA_IPV4_ROUTE_ADD)
vincentfbf5d032005-09-29 11:25:50 +0000165 rip_redistribute_add (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex,
166 &nexthop, api.metric, api.distance);
paul718e3742002-12-13 20:15:29 +0000167 else
168 rip_redistribute_delete (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex);
169
170 return 0;
171}
172
173void
pauldc63bfd2005-10-25 23:31:05 +0000174rip_zclient_reset (void)
paul718e3742002-12-13 20:15:29 +0000175{
176 zclient_reset (zclient);
177}
178
179/* RIP route-map set for redistribution */
pauldc63bfd2005-10-25 23:31:05 +0000180static void
hasso98b718a2004-10-11 12:57:57 +0000181rip_routemap_set (int type, const char *name)
paul718e3742002-12-13 20:15:29 +0000182{
183 if (rip->route_map[type].name)
184 free(rip->route_map[type].name);
185
186 rip->route_map[type].name = strdup (name);
187 rip->route_map[type].map = route_map_lookup_by_name (name);
188}
189
pauldc63bfd2005-10-25 23:31:05 +0000190static void
hasso8a676be2004-10-08 06:36:38 +0000191rip_redistribute_metric_set (int type, unsigned int metric)
paul718e3742002-12-13 20:15:29 +0000192{
193 rip->route_map[type].metric_config = 1;
194 rip->route_map[type].metric = metric;
195}
196
pauldc63bfd2005-10-25 23:31:05 +0000197static int
hasso8a676be2004-10-08 06:36:38 +0000198rip_metric_unset (int type, unsigned int metric)
paul718e3742002-12-13 20:15:29 +0000199{
200#define DONT_CARE_METRIC_RIP 17
201 if (metric != DONT_CARE_METRIC_RIP &&
202 rip->route_map[type].metric != metric)
203 return 1;
204 rip->route_map[type].metric_config = 0;
205 rip->route_map[type].metric = 0;
206 return 0;
207}
208
209/* RIP route-map unset for redistribution */
pauldc63bfd2005-10-25 23:31:05 +0000210static int
hasso98b718a2004-10-11 12:57:57 +0000211rip_routemap_unset (int type, const char *name)
paul718e3742002-12-13 20:15:29 +0000212{
213 if (! rip->route_map[type].name ||
214 (name != NULL && strcmp(rip->route_map[type].name,name)))
215 return 1;
216
217 free (rip->route_map[type].name);
218 rip->route_map[type].name = NULL;
219 rip->route_map[type].map = NULL;
220
221 return 0;
222}
David Lamparter6b0655a2014-06-04 06:53:35 +0200223
paul718e3742002-12-13 20:15:29 +0000224/* Redistribution types */
225static struct {
226 int type;
227 int str_min_len;
hasso8a676be2004-10-08 06:36:38 +0000228 const char *str;
paul718e3742002-12-13 20:15:29 +0000229} redist_type[] = {
230 {ZEBRA_ROUTE_KERNEL, 1, "kernel"},
231 {ZEBRA_ROUTE_CONNECT, 1, "connected"},
232 {ZEBRA_ROUTE_STATIC, 1, "static"},
233 {ZEBRA_ROUTE_OSPF, 1, "ospf"},
Matthieu Boutier9c58fbd2012-02-09 21:51:17 +0100234 {ZEBRA_ROUTE_BGP, 2, "bgp"},
235 {ZEBRA_ROUTE_BABEL, 2, "babel"},
paul718e3742002-12-13 20:15:29 +0000236 {0, 0, NULL}
237};
238
239DEFUN (router_zebra,
240 router_zebra_cmd,
241 "router zebra",
242 "Enable a routing process\n"
243 "Make connection to zebra daemon\n")
244{
245 vty->node = ZEBRA_NODE;
246 zclient->enable = 1;
247 zclient_start (zclient);
248 return CMD_SUCCESS;
249}
250
251DEFUN (no_router_zebra,
252 no_router_zebra_cmd,
253 "no router zebra",
254 NO_STR
255 "Enable a routing process\n"
256 "Make connection to zebra daemon\n")
257{
258 zclient->enable = 0;
259 zclient_stop (zclient);
260 return CMD_SUCCESS;
261}
262
Stephen Hemminger2c239702009-12-10 19:16:05 +0300263#if 0
pauldc63bfd2005-10-25 23:31:05 +0000264static int
paul718e3742002-12-13 20:15:29 +0000265rip_redistribute_set (int type)
266{
267 if (zclient->redist[type])
268 return CMD_SUCCESS;
269
270 zclient->redist[type] = 1;
271
272 if (zclient->sock > 0)
ajs634f9ea2005-04-11 15:51:40 +0000273 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
paul718e3742002-12-13 20:15:29 +0000274
275 return CMD_SUCCESS;
276}
Stephen Hemminger2c239702009-12-10 19:16:05 +0300277#endif
paul718e3742002-12-13 20:15:29 +0000278
pauldc63bfd2005-10-25 23:31:05 +0000279static int
paul718e3742002-12-13 20:15:29 +0000280rip_redistribute_unset (int type)
281{
282 if (! zclient->redist[type])
283 return CMD_SUCCESS;
284
285 zclient->redist[type] = 0;
286
287 if (zclient->sock > 0)
ajs634f9ea2005-04-11 15:51:40 +0000288 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
paul718e3742002-12-13 20:15:29 +0000289
290 /* Remove the routes from RIP table. */
291 rip_redistribute_withdraw (type);
292
293 return CMD_SUCCESS;
294}
295
296int
297rip_redistribute_check (int type)
298{
299 return (zclient->redist[type]);
300}
301
302void
pauldc63bfd2005-10-25 23:31:05 +0000303rip_redistribute_clean (void)
paul718e3742002-12-13 20:15:29 +0000304{
305 int i;
306
307 for (i = 0; redist_type[i].str; i++)
308 {
309 if (zclient->redist[redist_type[i].type])
310 {
311 if (zclient->sock > 0)
312 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
ajs634f9ea2005-04-11 15:51:40 +0000313 zclient, redist_type[i].type);
paul718e3742002-12-13 20:15:29 +0000314
315 zclient->redist[redist_type[i].type] = 0;
316
317 /* Remove the routes from RIP table. */
318 rip_redistribute_withdraw (redist_type[i].type);
319 }
320 }
321}
322
323DEFUN (rip_redistribute_rip,
324 rip_redistribute_rip_cmd,
325 "redistribute rip",
326 "Redistribute information from another routing protocol\n"
327 "Routing Information Protocol (RIP)\n")
328{
329 zclient->redist[ZEBRA_ROUTE_RIP] = 1;
330 return CMD_SUCCESS;
331}
332
333DEFUN (no_rip_redistribute_rip,
334 no_rip_redistribute_rip_cmd,
335 "no redistribute rip",
336 NO_STR
337 "Redistribute information from another routing protocol\n"
338 "Routing Information Protocol (RIP)\n")
339{
340 zclient->redist[ZEBRA_ROUTE_RIP] = 0;
341 return CMD_SUCCESS;
342}
343
344DEFUN (rip_redistribute_type,
345 rip_redistribute_type_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000346 "redistribute " QUAGGA_REDIST_STR_RIPD,
347 REDIST_STR
348 QUAGGA_REDIST_HELP_STR_RIPD)
paul718e3742002-12-13 20:15:29 +0000349{
350 int i;
351
352 for(i = 0; redist_type[i].str; i++)
353 {
354 if (strncmp (redist_type[i].str, argv[0],
355 redist_type[i].str_min_len) == 0)
356 {
paul0a589352004-05-08 11:48:26 +0000357 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient,
358 redist_type[i].type);
paul718e3742002-12-13 20:15:29 +0000359 return CMD_SUCCESS;
360 }
361 }
362
363 vty_out(vty, "Invalid type %s%s", argv[0],
364 VTY_NEWLINE);
365
366 return CMD_WARNING;
367}
368
369DEFUN (no_rip_redistribute_type,
370 no_rip_redistribute_type_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000371 "no redistribute " QUAGGA_REDIST_STR_RIPD,
paul718e3742002-12-13 20:15:29 +0000372 NO_STR
Paul Jakma9a57dc62006-06-30 16:58:53 +0000373 REDIST_STR
374 QUAGGA_REDIST_HELP_STR_RIPD)
paul718e3742002-12-13 20:15:29 +0000375{
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 rip_metric_unset (redist_type[i].type, DONT_CARE_METRIC_RIP);
384 rip_routemap_unset (redist_type[i].type,NULL);
385 rip_redistribute_unset (redist_type[i].type);
386 return CMD_SUCCESS;
387 }
388 }
389
390 vty_out(vty, "Invalid type %s%s", argv[0],
391 VTY_NEWLINE);
392
393 return CMD_WARNING;
394}
395
396DEFUN (rip_redistribute_type_routemap,
397 rip_redistribute_type_routemap_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000398 "redistribute " QUAGGA_REDIST_STR_RIPD " route-map WORD",
399 REDIST_STR
400 QUAGGA_REDIST_HELP_STR_RIPD
paul718e3742002-12-13 20:15:29 +0000401 "Route map reference\n"
402 "Pointer to route-map entries\n")
403{
404 int i;
405
406 for (i = 0; redist_type[i].str; i++) {
407 if (strncmp(redist_type[i].str, argv[0],
408 redist_type[i].str_min_len) == 0)
409 {
410 rip_routemap_set (redist_type[i].type, argv[1]);
paul0a589352004-05-08 11:48:26 +0000411 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
paul718e3742002-12-13 20:15:29 +0000412 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
422DEFUN (no_rip_redistribute_type_routemap,
423 no_rip_redistribute_type_routemap_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000424 "no redistribute " QUAGGA_REDIST_STR_RIPD " route-map WORD",
paul718e3742002-12-13 20:15:29 +0000425 NO_STR
Paul Jakma9a57dc62006-06-30 16:58:53 +0000426 REDIST_STR
427 QUAGGA_REDIST_HELP_STR_RIPD
paul718e3742002-12-13 20:15:29 +0000428 "Route map reference\n"
429 "Pointer to route-map entries\n")
430{
431 int i;
432
433 for (i = 0; redist_type[i].str; i++)
434 {
435 if (strncmp(redist_type[i].str, argv[0],
436 redist_type[i].str_min_len) == 0)
437 {
438 if (rip_routemap_unset (redist_type[i].type,argv[1]))
439 return CMD_WARNING;
440 rip_redistribute_unset (redist_type[i].type);
441 return CMD_SUCCESS;
442 }
443 }
444
445 vty_out(vty, "Invalid type %s%s", argv[0],
446 VTY_NEWLINE);
447
448 return CMD_WARNING;
449}
450
451DEFUN (rip_redistribute_type_metric,
452 rip_redistribute_type_metric_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000453 "redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16>",
454 REDIST_STR
455 QUAGGA_REDIST_HELP_STR_RIPD
paul718e3742002-12-13 20:15:29 +0000456 "Metric\n"
457 "Metric value\n")
458{
459 int i;
460 int metric;
461
462 metric = atoi (argv[1]);
463
464 for (i = 0; redist_type[i].str; i++) {
465 if (strncmp(redist_type[i].str, argv[0],
466 redist_type[i].str_min_len) == 0)
467 {
468 rip_redistribute_metric_set (redist_type[i].type, metric);
paul0a589352004-05-08 11:48:26 +0000469 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
paul718e3742002-12-13 20:15:29 +0000470 return CMD_SUCCESS;
471 }
472 }
473
474 vty_out(vty, "Invalid type %s%s", argv[0],
475 VTY_NEWLINE);
476
477 return CMD_WARNING;
478}
479
480DEFUN (no_rip_redistribute_type_metric,
481 no_rip_redistribute_type_metric_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000482 "no redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16>",
paul718e3742002-12-13 20:15:29 +0000483 NO_STR
Paul Jakma9a57dc62006-06-30 16:58:53 +0000484 REDIST_STR
485 QUAGGA_REDIST_HELP_STR_RIPD
paul718e3742002-12-13 20:15:29 +0000486 "Metric\n"
487 "Metric value\n")
488{
489 int i;
490
491 for (i = 0; redist_type[i].str; i++)
492 {
493 if (strncmp(redist_type[i].str, argv[0],
494 redist_type[i].str_min_len) == 0)
495 {
496 if (rip_metric_unset (redist_type[i].type, atoi(argv[1])))
497 return CMD_WARNING;
498 rip_redistribute_unset (redist_type[i].type);
499 return CMD_SUCCESS;
500 }
501 }
502
503 vty_out(vty, "Invalid type %s%s", argv[0],
504 VTY_NEWLINE);
505
506 return CMD_WARNING;
507}
508
hasso16705132003-05-25 14:49:19 +0000509DEFUN (rip_redistribute_type_metric_routemap,
510 rip_redistribute_type_metric_routemap_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000511 "redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16> route-map WORD",
512 REDIST_STR
513 QUAGGA_REDIST_HELP_STR_RIPD
hasso16705132003-05-25 14:49:19 +0000514 "Metric\n"
515 "Metric value\n"
516 "Route map reference\n"
517 "Pointer to route-map entries\n")
518{
519 int i;
520 int metric;
521
522 metric = atoi (argv[1]);
523
524 for (i = 0; redist_type[i].str; i++) {
525 if (strncmp(redist_type[i].str, argv[0],
526 redist_type[i].str_min_len) == 0)
527 {
528 rip_redistribute_metric_set (redist_type[i].type, metric);
529 rip_routemap_set (redist_type[i].type, argv[2]);
paul0a589352004-05-08 11:48:26 +0000530 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
hasso16705132003-05-25 14:49:19 +0000531 return CMD_SUCCESS;
532 }
533 }
534
535 vty_out(vty, "Invalid type %s%s", argv[0],
536 VTY_NEWLINE);
537
538 return CMD_WARNING;
539}
540
541
paul718e3742002-12-13 20:15:29 +0000542DEFUN (no_rip_redistribute_type_metric_routemap,
543 no_rip_redistribute_type_metric_routemap_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000544 "no redistribute " QUAGGA_REDIST_STR_RIPD
545 " metric <0-16> route-map WORD",
paul718e3742002-12-13 20:15:29 +0000546 NO_STR
Paul Jakma9a57dc62006-06-30 16:58:53 +0000547 REDIST_STR
548 QUAGGA_REDIST_HELP_STR_RIPD
paul718e3742002-12-13 20:15:29 +0000549 "Metric\n"
550 "Metric value\n"
551 "Route map reference\n"
552 "Pointer to route-map entries\n")
553{
554 int i;
555
556 for (i = 0; redist_type[i].str; i++)
557 {
558 if (strncmp(redist_type[i].str, argv[0],
559 redist_type[i].str_min_len) == 0)
560 {
561 if (rip_metric_unset (redist_type[i].type, atoi(argv[1])))
562 return CMD_WARNING;
563 if (rip_routemap_unset (redist_type[i].type, argv[2]))
564 {
565 rip_redistribute_metric_set(redist_type[i].type, atoi(argv[1]));
566 return CMD_WARNING;
567 }
568 rip_redistribute_unset (redist_type[i].type);
569 return CMD_SUCCESS;
570 }
571 }
572
573 vty_out(vty, "Invalid type %s%s", argv[0],
574 VTY_NEWLINE);
575
576 return CMD_WARNING;
577}
David Lamparter6b0655a2014-06-04 06:53:35 +0200578
paul718e3742002-12-13 20:15:29 +0000579/* Default information originate. */
580
581DEFUN (rip_default_information_originate,
582 rip_default_information_originate_cmd,
583 "default-information originate",
584 "Control distribution of default route\n"
585 "Distribute a default route\n")
586{
587 struct prefix_ipv4 p;
588
589 if (! rip->default_information)
590 {
591 memset (&p, 0, sizeof (struct prefix_ipv4));
592 p.family = AF_INET;
593
594 rip->default_information = 1;
595
vincentfbf5d032005-09-29 11:25:50 +0000596 rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0,
597 NULL, 0, 0);
paul718e3742002-12-13 20:15:29 +0000598 }
599
600 return CMD_SUCCESS;
601}
602
603DEFUN (no_rip_default_information_originate,
604 no_rip_default_information_originate_cmd,
605 "no default-information originate",
606 NO_STR
607 "Control distribution of default route\n"
608 "Distribute a default route\n")
609{
610 struct prefix_ipv4 p;
611
612 if (rip->default_information)
613 {
614 memset (&p, 0, sizeof (struct prefix_ipv4));
615 p.family = AF_INET;
616
617 rip->default_information = 0;
618
hasso16705132003-05-25 14:49:19 +0000619 rip_redistribute_delete (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0);
paul718e3742002-12-13 20:15:29 +0000620 }
621
622 return CMD_SUCCESS;
623}
David Lamparter6b0655a2014-06-04 06:53:35 +0200624
paul718e3742002-12-13 20:15:29 +0000625/* RIP configuration write function. */
pauldc63bfd2005-10-25 23:31:05 +0000626static int
paul718e3742002-12-13 20:15:29 +0000627config_write_zebra (struct vty *vty)
628{
629 if (! zclient->enable)
630 {
631 vty_out (vty, "no router zebra%s", VTY_NEWLINE);
632 return 1;
633 }
634 else if (! zclient->redist[ZEBRA_ROUTE_RIP])
635 {
636 vty_out (vty, "router zebra%s", VTY_NEWLINE);
637 vty_out (vty, " no redistribute rip%s", VTY_NEWLINE);
638 return 1;
639 }
640 return 0;
641}
642
643int
644config_write_rip_redistribute (struct vty *vty, int config_mode)
645{
646 int i;
paul718e3742002-12-13 20:15:29 +0000647
648 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
649 if (i != zclient->redist_default && zclient->redist[i])
650 {
651 if (config_mode)
652 {
653 if (rip->route_map[i].metric_config)
654 {
655 if (rip->route_map[i].name)
656 vty_out (vty, " redistribute %s metric %d route-map %s%s",
ajsf52d13c2005-10-01 17:38:06 +0000657 zebra_route_string(i), rip->route_map[i].metric,
paul718e3742002-12-13 20:15:29 +0000658 rip->route_map[i].name,
659 VTY_NEWLINE);
660 else
661 vty_out (vty, " redistribute %s metric %d%s",
ajsf52d13c2005-10-01 17:38:06 +0000662 zebra_route_string(i), rip->route_map[i].metric,
paul718e3742002-12-13 20:15:29 +0000663 VTY_NEWLINE);
664 }
665 else
666 {
667 if (rip->route_map[i].name)
668 vty_out (vty, " redistribute %s route-map %s%s",
ajsf52d13c2005-10-01 17:38:06 +0000669 zebra_route_string(i), rip->route_map[i].name,
paul718e3742002-12-13 20:15:29 +0000670 VTY_NEWLINE);
671 else
ajsf52d13c2005-10-01 17:38:06 +0000672 vty_out (vty, " redistribute %s%s", zebra_route_string(i),
paul718e3742002-12-13 20:15:29 +0000673 VTY_NEWLINE);
674 }
675 }
676 else
ajsf52d13c2005-10-01 17:38:06 +0000677 vty_out (vty, " %s", zebra_route_string(i));
paul718e3742002-12-13 20:15:29 +0000678 }
679 return 0;
680}
681
682/* Zebra node structure. */
Stephen Hemminger7fc626d2008-12-01 11:10:34 -0800683static struct cmd_node zebra_node =
paul718e3742002-12-13 20:15:29 +0000684{
685 ZEBRA_NODE,
686 "%s(config-router)# ",
687};
688
689void
690rip_zclient_init ()
691{
692 /* Set default value to the zebra client structure. */
693 zclient = zclient_new ();
694 zclient_init (zclient, ZEBRA_ROUTE_RIP);
695 zclient->interface_add = rip_interface_add;
696 zclient->interface_delete = rip_interface_delete;
697 zclient->interface_address_add = rip_interface_address_add;
698 zclient->interface_address_delete = rip_interface_address_delete;
699 zclient->ipv4_route_add = rip_zebra_read_ipv4;
700 zclient->ipv4_route_delete = rip_zebra_read_ipv4;
701 zclient->interface_up = rip_interface_up;
702 zclient->interface_down = rip_interface_down;
703
704 /* Install zebra node. */
705 install_node (&zebra_node, config_write_zebra);
706
707 /* Install command elements to zebra node. */
708 install_element (CONFIG_NODE, &router_zebra_cmd);
709 install_element (CONFIG_NODE, &no_router_zebra_cmd);
710 install_default (ZEBRA_NODE);
711 install_element (ZEBRA_NODE, &rip_redistribute_rip_cmd);
712 install_element (ZEBRA_NODE, &no_rip_redistribute_rip_cmd);
713
714 /* Install command elements to rip node. */
715 install_element (RIP_NODE, &rip_redistribute_type_cmd);
716 install_element (RIP_NODE, &rip_redistribute_type_routemap_cmd);
717 install_element (RIP_NODE, &rip_redistribute_type_metric_cmd);
hasso16705132003-05-25 14:49:19 +0000718 install_element (RIP_NODE, &rip_redistribute_type_metric_routemap_cmd);
paul718e3742002-12-13 20:15:29 +0000719 install_element (RIP_NODE, &no_rip_redistribute_type_cmd);
720 install_element (RIP_NODE, &no_rip_redistribute_type_routemap_cmd);
721 install_element (RIP_NODE, &no_rip_redistribute_type_metric_cmd);
722 install_element (RIP_NODE, &no_rip_redistribute_type_metric_routemap_cmd);
723 install_element (RIP_NODE, &rip_default_information_originate_cmd);
724 install_element (RIP_NODE, &no_rip_default_information_originate_cmd);
725}