blob: de981623aa9e7f1089eaedb256bc389be4f2a725 [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"
Feng Luc99f3482014-10-16 09:52:36 +080032#include "vrf.h"
paul718e3742002-12-13 20:15:29 +000033#include "ripd/ripd.h"
34#include "ripd/rip_debug.h"
pauldc63bfd2005-10-25 23:31:05 +000035#include "ripd/rip_interface.h"
paul718e3742002-12-13 20:15:29 +000036
37/* All information about zebra. */
38struct zclient *zclient = NULL;
David Lamparter6b0655a2014-06-04 06:53:35 +020039
Lu Fengb397cf42014-07-18 06:13:18 +000040/* Send ECMP routes to zebra. */
41static void
42rip_zebra_ipv4_send (struct route_node *rp, u_char cmd)
paul718e3742002-12-13 20:15:29 +000043{
Lu Fengb397cf42014-07-18 06:13:18 +000044 static struct in_addr **nexthops = NULL;
45 static unsigned int nexthops_len = 0;
46
47 struct list *list = (struct list *)rp->info;
paul718e3742002-12-13 20:15:29 +000048 struct zapi_ipv4 api;
Lu Fengb397cf42014-07-18 06:13:18 +000049 struct listnode *listnode = NULL;
50 struct rip_info *rinfo = NULL;
51 int count = 0;
paul718e3742002-12-13 20:15:29 +000052
Feng Luc99f3482014-10-16 09:52:36 +080053 if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_RIP], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +000054 {
Feng Luc99f3482014-10-16 09:52:36 +080055 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +000056 api.type = ZEBRA_ROUTE_RIP;
57 api.flags = 0;
58 api.message = 0;
Denis Ovsienkob4e45f62011-12-05 16:35:14 +040059 api.safi = SAFI_UNICAST;
Lu Fengb397cf42014-07-18 06:13:18 +000060
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
paul718e3742002-12-13 20:15:29 +000068 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
Lu Fengb397cf42014-07-18 06:13:18 +000069 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;
paul718e3742002-12-13 20:15:29 +000080 api.ifindex_num = 0;
Lu Fengb397cf42014-07-18 06:13:18 +000081
82 rinfo = listgetdata (listhead (list));
83
paul718e3742002-12-13 20:15:29 +000084 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
Lu Fengb397cf42014-07-18 06:13:18 +000085 api.metric = rinfo->metric;
paul718e3742002-12-13 20:15:29 +000086
Lu Fengb397cf42014-07-18 06:13:18 +000087 if (rinfo->distance && rinfo->distance != ZEBRA_RIP_DISTANCE_DEFAULT)
88 {
89 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
90 api.distance = rinfo->distance;
91 }
paul718e3742002-12-13 20:15:29 +000092
Lu Fengb397cf42014-07-18 06:13:18 +000093 zapi_ipv4_route (cmd, zclient,
94 (struct prefix_ipv4 *)&rp->p, &api);
95
96 if (IS_RIP_DEBUG_ZEBRA)
Lu Feng0b74a0a2014-07-18 06:13:19 +000097 {
98 if (rip->ecmp)
99 zlog_debug ("%s: %s/%d nexthops %d",
100 (cmd == ZEBRA_IPV4_ROUTE_ADD) ? \
101 "Install into zebra" : "Delete from zebra",
102 inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen, count);
103 else
104 zlog_debug ("%s: %s/%d",
105 (cmd == ZEBRA_IPV4_ROUTE_ADD) ? \
106 "Install into zebra" : "Delete from zebra",
107 inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen);
108 }
paul718e3742002-12-13 20:15:29 +0000109
110 rip_global_route_changes++;
111 }
112}
113
Lu Fengb397cf42014-07-18 06:13:18 +0000114/* Add/update ECMP routes to zebra. */
paul718e3742002-12-13 20:15:29 +0000115void
Lu Fengb397cf42014-07-18 06:13:18 +0000116rip_zebra_ipv4_add (struct route_node *rp)
paul718e3742002-12-13 20:15:29 +0000117{
Lu Fengb397cf42014-07-18 06:13:18 +0000118 rip_zebra_ipv4_send (rp, ZEBRA_IPV4_ROUTE_ADD);
119}
paul718e3742002-12-13 20:15:29 +0000120
Lu Fengb397cf42014-07-18 06:13:18 +0000121/* Delete ECMP routes from zebra. */
122void
123rip_zebra_ipv4_delete (struct route_node *rp)
124{
125 rip_zebra_ipv4_send (rp, ZEBRA_IPV4_ROUTE_DELETE);
paul718e3742002-12-13 20:15:29 +0000126}
127
128/* Zebra route add and delete treatment. */
pauldc63bfd2005-10-25 23:31:05 +0000129static int
Feng Luc99f3482014-10-16 09:52:36 +0800130rip_zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
131 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000132{
133 struct stream *s;
134 struct zapi_ipv4 api;
135 unsigned long ifindex;
136 struct in_addr nexthop;
137 struct prefix_ipv4 p;
138
139 s = zclient->ibuf;
140 ifindex = 0;
141 nexthop.s_addr = 0;
142
143 /* Type, flags, message. */
144 api.type = stream_getc (s);
145 api.flags = stream_getc (s);
146 api.message = stream_getc (s);
147
148 /* IPv4 prefix. */
149 memset (&p, 0, sizeof (struct prefix_ipv4));
150 p.family = AF_INET;
151 p.prefixlen = stream_getc (s);
152 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
153
154 /* Nexthop, ifindex, distance, metric. */
155 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
156 {
157 api.nexthop_num = stream_getc (s);
158 nexthop.s_addr = stream_get_ipv4 (s);
159 }
160 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
161 {
162 api.ifindex_num = stream_getc (s);
163 ifindex = stream_getl (s);
164 }
165 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
166 api.distance = stream_getc (s);
vincentfbf5d032005-09-29 11:25:50 +0000167 else
168 api.distance = 255;
paul718e3742002-12-13 20:15:29 +0000169 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
170 api.metric = stream_getl (s);
vincentfbf5d032005-09-29 11:25:50 +0000171 else
172 api.metric = 0;
paul718e3742002-12-13 20:15:29 +0000173
174 /* Then fetch IPv4 prefixes. */
175 if (command == ZEBRA_IPV4_ROUTE_ADD)
vincentfbf5d032005-09-29 11:25:50 +0000176 rip_redistribute_add (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex,
177 &nexthop, api.metric, api.distance);
paul718e3742002-12-13 20:15:29 +0000178 else
179 rip_redistribute_delete (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex);
180
181 return 0;
182}
183
184void
pauldc63bfd2005-10-25 23:31:05 +0000185rip_zclient_reset (void)
paul718e3742002-12-13 20:15:29 +0000186{
187 zclient_reset (zclient);
188}
189
190/* RIP route-map set for redistribution */
pauldc63bfd2005-10-25 23:31:05 +0000191static void
hasso98b718a2004-10-11 12:57:57 +0000192rip_routemap_set (int type, const char *name)
paul718e3742002-12-13 20:15:29 +0000193{
194 if (rip->route_map[type].name)
195 free(rip->route_map[type].name);
196
197 rip->route_map[type].name = strdup (name);
198 rip->route_map[type].map = route_map_lookup_by_name (name);
199}
200
pauldc63bfd2005-10-25 23:31:05 +0000201static void
hasso8a676be2004-10-08 06:36:38 +0000202rip_redistribute_metric_set (int type, unsigned int metric)
paul718e3742002-12-13 20:15:29 +0000203{
204 rip->route_map[type].metric_config = 1;
205 rip->route_map[type].metric = metric;
206}
207
pauldc63bfd2005-10-25 23:31:05 +0000208static int
hasso8a676be2004-10-08 06:36:38 +0000209rip_metric_unset (int type, unsigned int metric)
paul718e3742002-12-13 20:15:29 +0000210{
211#define DONT_CARE_METRIC_RIP 17
212 if (metric != DONT_CARE_METRIC_RIP &&
213 rip->route_map[type].metric != metric)
214 return 1;
215 rip->route_map[type].metric_config = 0;
216 rip->route_map[type].metric = 0;
217 return 0;
218}
219
220/* RIP route-map unset for redistribution */
pauldc63bfd2005-10-25 23:31:05 +0000221static int
hasso98b718a2004-10-11 12:57:57 +0000222rip_routemap_unset (int type, const char *name)
paul718e3742002-12-13 20:15:29 +0000223{
224 if (! rip->route_map[type].name ||
225 (name != NULL && strcmp(rip->route_map[type].name,name)))
226 return 1;
227
228 free (rip->route_map[type].name);
229 rip->route_map[type].name = NULL;
230 rip->route_map[type].map = NULL;
231
232 return 0;
233}
David Lamparter6b0655a2014-06-04 06:53:35 +0200234
paul718e3742002-12-13 20:15:29 +0000235/* Redistribution types */
236static struct {
237 int type;
238 int str_min_len;
hasso8a676be2004-10-08 06:36:38 +0000239 const char *str;
paul718e3742002-12-13 20:15:29 +0000240} redist_type[] = {
241 {ZEBRA_ROUTE_KERNEL, 1, "kernel"},
242 {ZEBRA_ROUTE_CONNECT, 1, "connected"},
243 {ZEBRA_ROUTE_STATIC, 1, "static"},
244 {ZEBRA_ROUTE_OSPF, 1, "ospf"},
Matthieu Boutier9c58fbd2012-02-09 21:51:17 +0100245 {ZEBRA_ROUTE_BGP, 2, "bgp"},
246 {ZEBRA_ROUTE_BABEL, 2, "babel"},
paul718e3742002-12-13 20:15:29 +0000247 {0, 0, NULL}
248};
249
250DEFUN (router_zebra,
251 router_zebra_cmd,
252 "router zebra",
253 "Enable a routing process\n"
254 "Make connection to zebra daemon\n")
255{
256 vty->node = ZEBRA_NODE;
257 zclient->enable = 1;
258 zclient_start (zclient);
259 return CMD_SUCCESS;
260}
261
262DEFUN (no_router_zebra,
263 no_router_zebra_cmd,
264 "no router zebra",
265 NO_STR
266 "Enable a routing process\n"
267 "Make connection to zebra daemon\n")
268{
269 zclient->enable = 0;
270 zclient_stop (zclient);
271 return CMD_SUCCESS;
272}
273
Stephen Hemminger2c239702009-12-10 19:16:05 +0300274#if 0
pauldc63bfd2005-10-25 23:31:05 +0000275static int
paul718e3742002-12-13 20:15:29 +0000276rip_redistribute_set (int type)
277{
Feng Luc99f3482014-10-16 09:52:36 +0800278 if (vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000279 return CMD_SUCCESS;
280
Feng Luc99f3482014-10-16 09:52:36 +0800281 vrf_bitmap_set (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000282
283 if (zclient->sock > 0)
ajs634f9ea2005-04-11 15:51:40 +0000284 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
paul718e3742002-12-13 20:15:29 +0000285
286 return CMD_SUCCESS;
287}
Stephen Hemminger2c239702009-12-10 19:16:05 +0300288#endif
paul718e3742002-12-13 20:15:29 +0000289
pauldc63bfd2005-10-25 23:31:05 +0000290static int
paul718e3742002-12-13 20:15:29 +0000291rip_redistribute_unset (int type)
292{
Feng Luc99f3482014-10-16 09:52:36 +0800293 if (! vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000294 return CMD_SUCCESS;
295
Feng Luc99f3482014-10-16 09:52:36 +0800296 vrf_bitmap_unset (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000297
298 if (zclient->sock > 0)
Feng Luc99f3482014-10-16 09:52:36 +0800299 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type,
300 VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000301
302 /* Remove the routes from RIP table. */
303 rip_redistribute_withdraw (type);
304
305 return CMD_SUCCESS;
306}
307
308int
309rip_redistribute_check (int type)
310{
Feng Luc99f3482014-10-16 09:52:36 +0800311 return vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000312}
313
314void
pauldc63bfd2005-10-25 23:31:05 +0000315rip_redistribute_clean (void)
paul718e3742002-12-13 20:15:29 +0000316{
317 int i;
318
319 for (i = 0; redist_type[i].str; i++)
320 {
Feng Luc99f3482014-10-16 09:52:36 +0800321 if (vrf_bitmap_check (zclient->redist[redist_type[i].type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000322 {
323 if (zclient->sock > 0)
324 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
Feng Luc99f3482014-10-16 09:52:36 +0800325 zclient, redist_type[i].type,
326 VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000327
Feng Luc99f3482014-10-16 09:52:36 +0800328 vrf_bitmap_unset (zclient->redist[redist_type[i].type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000329
330 /* Remove the routes from RIP table. */
331 rip_redistribute_withdraw (redist_type[i].type);
332 }
333 }
334}
335
336DEFUN (rip_redistribute_rip,
337 rip_redistribute_rip_cmd,
338 "redistribute rip",
339 "Redistribute information from another routing protocol\n"
340 "Routing Information Protocol (RIP)\n")
341{
Feng Luc99f3482014-10-16 09:52:36 +0800342 vrf_bitmap_set (zclient->redist[ZEBRA_ROUTE_RIP], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000343 return CMD_SUCCESS;
344}
345
346DEFUN (no_rip_redistribute_rip,
347 no_rip_redistribute_rip_cmd,
348 "no redistribute rip",
349 NO_STR
350 "Redistribute information from another routing protocol\n"
351 "Routing Information Protocol (RIP)\n")
352{
Feng Luc99f3482014-10-16 09:52:36 +0800353 vrf_bitmap_unset (zclient->redist[ZEBRA_ROUTE_RIP], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000354 return CMD_SUCCESS;
355}
356
357DEFUN (rip_redistribute_type,
358 rip_redistribute_type_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000359 "redistribute " QUAGGA_REDIST_STR_RIPD,
360 REDIST_STR
361 QUAGGA_REDIST_HELP_STR_RIPD)
paul718e3742002-12-13 20:15:29 +0000362{
363 int i;
364
365 for(i = 0; redist_type[i].str; i++)
366 {
367 if (strncmp (redist_type[i].str, argv[0],
368 redist_type[i].str_min_len) == 0)
369 {
paul0a589352004-05-08 11:48:26 +0000370 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800371 redist_type[i].type, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000372 return CMD_SUCCESS;
373 }
374 }
375
376 vty_out(vty, "Invalid type %s%s", argv[0],
377 VTY_NEWLINE);
378
379 return CMD_WARNING;
380}
381
382DEFUN (no_rip_redistribute_type,
383 no_rip_redistribute_type_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000384 "no redistribute " QUAGGA_REDIST_STR_RIPD,
paul718e3742002-12-13 20:15:29 +0000385 NO_STR
Paul Jakma9a57dc62006-06-30 16:58:53 +0000386 REDIST_STR
387 QUAGGA_REDIST_HELP_STR_RIPD)
paul718e3742002-12-13 20:15:29 +0000388{
389 int i;
390
391 for (i = 0; redist_type[i].str; i++)
392 {
393 if (strncmp(redist_type[i].str, argv[0],
394 redist_type[i].str_min_len) == 0)
395 {
396 rip_metric_unset (redist_type[i].type, DONT_CARE_METRIC_RIP);
397 rip_routemap_unset (redist_type[i].type,NULL);
398 rip_redistribute_unset (redist_type[i].type);
399 return CMD_SUCCESS;
400 }
401 }
402
403 vty_out(vty, "Invalid type %s%s", argv[0],
404 VTY_NEWLINE);
405
406 return CMD_WARNING;
407}
408
409DEFUN (rip_redistribute_type_routemap,
410 rip_redistribute_type_routemap_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000411 "redistribute " QUAGGA_REDIST_STR_RIPD " route-map WORD",
412 REDIST_STR
413 QUAGGA_REDIST_HELP_STR_RIPD
paul718e3742002-12-13 20:15:29 +0000414 "Route map reference\n"
415 "Pointer to route-map entries\n")
416{
417 int i;
418
419 for (i = 0; redist_type[i].str; i++) {
420 if (strncmp(redist_type[i].str, argv[0],
421 redist_type[i].str_min_len) == 0)
422 {
423 rip_routemap_set (redist_type[i].type, argv[1]);
Feng Luc99f3482014-10-16 09:52:36 +0800424 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type,
425 VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000426 return CMD_SUCCESS;
427 }
428 }
429
430 vty_out(vty, "Invalid type %s%s", argv[0],
431 VTY_NEWLINE);
432
433 return CMD_WARNING;
434}
435
436DEFUN (no_rip_redistribute_type_routemap,
437 no_rip_redistribute_type_routemap_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000438 "no redistribute " QUAGGA_REDIST_STR_RIPD " route-map WORD",
paul718e3742002-12-13 20:15:29 +0000439 NO_STR
Paul Jakma9a57dc62006-06-30 16:58:53 +0000440 REDIST_STR
441 QUAGGA_REDIST_HELP_STR_RIPD
paul718e3742002-12-13 20:15:29 +0000442 "Route map reference\n"
443 "Pointer to route-map entries\n")
444{
445 int i;
446
447 for (i = 0; redist_type[i].str; i++)
448 {
449 if (strncmp(redist_type[i].str, argv[0],
450 redist_type[i].str_min_len) == 0)
451 {
452 if (rip_routemap_unset (redist_type[i].type,argv[1]))
453 return CMD_WARNING;
454 rip_redistribute_unset (redist_type[i].type);
455 return CMD_SUCCESS;
456 }
457 }
458
459 vty_out(vty, "Invalid type %s%s", argv[0],
460 VTY_NEWLINE);
461
462 return CMD_WARNING;
463}
464
465DEFUN (rip_redistribute_type_metric,
466 rip_redistribute_type_metric_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000467 "redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16>",
468 REDIST_STR
469 QUAGGA_REDIST_HELP_STR_RIPD
paul718e3742002-12-13 20:15:29 +0000470 "Metric\n"
471 "Metric value\n")
472{
473 int i;
474 int metric;
475
476 metric = atoi (argv[1]);
477
478 for (i = 0; redist_type[i].str; i++) {
479 if (strncmp(redist_type[i].str, argv[0],
480 redist_type[i].str_min_len) == 0)
481 {
482 rip_redistribute_metric_set (redist_type[i].type, metric);
Feng Luc99f3482014-10-16 09:52:36 +0800483 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type,
484 VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000485 return CMD_SUCCESS;
486 }
487 }
488
489 vty_out(vty, "Invalid type %s%s", argv[0],
490 VTY_NEWLINE);
491
492 return CMD_WARNING;
493}
494
495DEFUN (no_rip_redistribute_type_metric,
496 no_rip_redistribute_type_metric_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000497 "no redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16>",
paul718e3742002-12-13 20:15:29 +0000498 NO_STR
Paul Jakma9a57dc62006-06-30 16:58:53 +0000499 REDIST_STR
500 QUAGGA_REDIST_HELP_STR_RIPD
paul718e3742002-12-13 20:15:29 +0000501 "Metric\n"
502 "Metric value\n")
503{
504 int i;
505
506 for (i = 0; redist_type[i].str; i++)
507 {
508 if (strncmp(redist_type[i].str, argv[0],
509 redist_type[i].str_min_len) == 0)
510 {
511 if (rip_metric_unset (redist_type[i].type, atoi(argv[1])))
512 return CMD_WARNING;
513 rip_redistribute_unset (redist_type[i].type);
514 return CMD_SUCCESS;
515 }
516 }
517
518 vty_out(vty, "Invalid type %s%s", argv[0],
519 VTY_NEWLINE);
520
521 return CMD_WARNING;
522}
523
hasso16705132003-05-25 14:49:19 +0000524DEFUN (rip_redistribute_type_metric_routemap,
525 rip_redistribute_type_metric_routemap_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000526 "redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16> route-map WORD",
527 REDIST_STR
528 QUAGGA_REDIST_HELP_STR_RIPD
hasso16705132003-05-25 14:49:19 +0000529 "Metric\n"
530 "Metric value\n"
531 "Route map reference\n"
532 "Pointer to route-map entries\n")
533{
534 int i;
535 int metric;
536
537 metric = atoi (argv[1]);
538
539 for (i = 0; redist_type[i].str; i++) {
540 if (strncmp(redist_type[i].str, argv[0],
541 redist_type[i].str_min_len) == 0)
542 {
543 rip_redistribute_metric_set (redist_type[i].type, metric);
544 rip_routemap_set (redist_type[i].type, argv[2]);
Feng Luc99f3482014-10-16 09:52:36 +0800545 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type,
546 VRF_DEFAULT);
hasso16705132003-05-25 14:49:19 +0000547 return CMD_SUCCESS;
548 }
549 }
550
551 vty_out(vty, "Invalid type %s%s", argv[0],
552 VTY_NEWLINE);
553
554 return CMD_WARNING;
555}
556
557
paul718e3742002-12-13 20:15:29 +0000558DEFUN (no_rip_redistribute_type_metric_routemap,
559 no_rip_redistribute_type_metric_routemap_cmd,
Paul Jakma9a57dc62006-06-30 16:58:53 +0000560 "no redistribute " QUAGGA_REDIST_STR_RIPD
561 " metric <0-16> route-map WORD",
paul718e3742002-12-13 20:15:29 +0000562 NO_STR
Paul Jakma9a57dc62006-06-30 16:58:53 +0000563 REDIST_STR
564 QUAGGA_REDIST_HELP_STR_RIPD
paul718e3742002-12-13 20:15:29 +0000565 "Metric\n"
566 "Metric value\n"
567 "Route map reference\n"
568 "Pointer to route-map entries\n")
569{
570 int i;
571
572 for (i = 0; redist_type[i].str; i++)
573 {
574 if (strncmp(redist_type[i].str, argv[0],
575 redist_type[i].str_min_len) == 0)
576 {
577 if (rip_metric_unset (redist_type[i].type, atoi(argv[1])))
578 return CMD_WARNING;
579 if (rip_routemap_unset (redist_type[i].type, argv[2]))
580 {
581 rip_redistribute_metric_set(redist_type[i].type, atoi(argv[1]));
582 return CMD_WARNING;
583 }
584 rip_redistribute_unset (redist_type[i].type);
585 return CMD_SUCCESS;
586 }
587 }
588
589 vty_out(vty, "Invalid type %s%s", argv[0],
590 VTY_NEWLINE);
591
592 return CMD_WARNING;
593}
David Lamparter6b0655a2014-06-04 06:53:35 +0200594
paul718e3742002-12-13 20:15:29 +0000595/* Default information originate. */
596
597DEFUN (rip_default_information_originate,
598 rip_default_information_originate_cmd,
599 "default-information originate",
600 "Control distribution of default route\n"
601 "Distribute a default route\n")
602{
603 struct prefix_ipv4 p;
604
605 if (! rip->default_information)
606 {
607 memset (&p, 0, sizeof (struct prefix_ipv4));
608 p.family = AF_INET;
609
610 rip->default_information = 1;
611
vincentfbf5d032005-09-29 11:25:50 +0000612 rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0,
613 NULL, 0, 0);
paul718e3742002-12-13 20:15:29 +0000614 }
615
616 return CMD_SUCCESS;
617}
618
619DEFUN (no_rip_default_information_originate,
620 no_rip_default_information_originate_cmd,
621 "no default-information originate",
622 NO_STR
623 "Control distribution of default route\n"
624 "Distribute a default route\n")
625{
626 struct prefix_ipv4 p;
627
628 if (rip->default_information)
629 {
630 memset (&p, 0, sizeof (struct prefix_ipv4));
631 p.family = AF_INET;
632
633 rip->default_information = 0;
634
hasso16705132003-05-25 14:49:19 +0000635 rip_redistribute_delete (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0);
paul718e3742002-12-13 20:15:29 +0000636 }
637
638 return CMD_SUCCESS;
639}
David Lamparter6b0655a2014-06-04 06:53:35 +0200640
paul718e3742002-12-13 20:15:29 +0000641/* RIP configuration write function. */
pauldc63bfd2005-10-25 23:31:05 +0000642static int
paul718e3742002-12-13 20:15:29 +0000643config_write_zebra (struct vty *vty)
644{
645 if (! zclient->enable)
646 {
647 vty_out (vty, "no router zebra%s", VTY_NEWLINE);
648 return 1;
649 }
Feng Luc99f3482014-10-16 09:52:36 +0800650 else if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_RIP], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000651 {
652 vty_out (vty, "router zebra%s", VTY_NEWLINE);
653 vty_out (vty, " no redistribute rip%s", VTY_NEWLINE);
654 return 1;
655 }
656 return 0;
657}
658
659int
660config_write_rip_redistribute (struct vty *vty, int config_mode)
661{
662 int i;
paul718e3742002-12-13 20:15:29 +0000663
664 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
Feng Luc99f3482014-10-16 09:52:36 +0800665 if (i != zclient->redist_default &&
666 vrf_bitmap_check (zclient->redist[i], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000667 {
668 if (config_mode)
669 {
670 if (rip->route_map[i].metric_config)
671 {
672 if (rip->route_map[i].name)
673 vty_out (vty, " redistribute %s metric %d route-map %s%s",
ajsf52d13c2005-10-01 17:38:06 +0000674 zebra_route_string(i), rip->route_map[i].metric,
paul718e3742002-12-13 20:15:29 +0000675 rip->route_map[i].name,
676 VTY_NEWLINE);
677 else
678 vty_out (vty, " redistribute %s metric %d%s",
ajsf52d13c2005-10-01 17:38:06 +0000679 zebra_route_string(i), rip->route_map[i].metric,
paul718e3742002-12-13 20:15:29 +0000680 VTY_NEWLINE);
681 }
682 else
683 {
684 if (rip->route_map[i].name)
685 vty_out (vty, " redistribute %s route-map %s%s",
ajsf52d13c2005-10-01 17:38:06 +0000686 zebra_route_string(i), rip->route_map[i].name,
paul718e3742002-12-13 20:15:29 +0000687 VTY_NEWLINE);
688 else
ajsf52d13c2005-10-01 17:38:06 +0000689 vty_out (vty, " redistribute %s%s", zebra_route_string(i),
paul718e3742002-12-13 20:15:29 +0000690 VTY_NEWLINE);
691 }
692 }
693 else
ajsf52d13c2005-10-01 17:38:06 +0000694 vty_out (vty, " %s", zebra_route_string(i));
paul718e3742002-12-13 20:15:29 +0000695 }
696 return 0;
697}
698
699/* Zebra node structure. */
Stephen Hemminger7fc626d2008-12-01 11:10:34 -0800700static struct cmd_node zebra_node =
paul718e3742002-12-13 20:15:29 +0000701{
702 ZEBRA_NODE,
703 "%s(config-router)# ",
704};
705
Feng Luc99f3482014-10-16 09:52:36 +0800706static void
707rip_zebra_connected (struct zclient *zclient)
708{
709 zclient_send_requests (zclient, VRF_DEFAULT);
710}
711
paul718e3742002-12-13 20:15:29 +0000712void
713rip_zclient_init ()
714{
715 /* Set default value to the zebra client structure. */
716 zclient = zclient_new ();
717 zclient_init (zclient, ZEBRA_ROUTE_RIP);
Feng Luc99f3482014-10-16 09:52:36 +0800718 zclient->zebra_connected = rip_zebra_connected;
paul718e3742002-12-13 20:15:29 +0000719 zclient->interface_add = rip_interface_add;
720 zclient->interface_delete = rip_interface_delete;
721 zclient->interface_address_add = rip_interface_address_add;
722 zclient->interface_address_delete = rip_interface_address_delete;
723 zclient->ipv4_route_add = rip_zebra_read_ipv4;
724 zclient->ipv4_route_delete = rip_zebra_read_ipv4;
725 zclient->interface_up = rip_interface_up;
726 zclient->interface_down = rip_interface_down;
727
728 /* Install zebra node. */
729 install_node (&zebra_node, config_write_zebra);
730
731 /* Install command elements to zebra node. */
732 install_element (CONFIG_NODE, &router_zebra_cmd);
733 install_element (CONFIG_NODE, &no_router_zebra_cmd);
734 install_default (ZEBRA_NODE);
735 install_element (ZEBRA_NODE, &rip_redistribute_rip_cmd);
736 install_element (ZEBRA_NODE, &no_rip_redistribute_rip_cmd);
737
738 /* Install command elements to rip node. */
739 install_element (RIP_NODE, &rip_redistribute_type_cmd);
740 install_element (RIP_NODE, &rip_redistribute_type_routemap_cmd);
741 install_element (RIP_NODE, &rip_redistribute_type_metric_cmd);
hasso16705132003-05-25 14:49:19 +0000742 install_element (RIP_NODE, &rip_redistribute_type_metric_routemap_cmd);
paul718e3742002-12-13 20:15:29 +0000743 install_element (RIP_NODE, &no_rip_redistribute_type_cmd);
744 install_element (RIP_NODE, &no_rip_redistribute_type_routemap_cmd);
745 install_element (RIP_NODE, &no_rip_redistribute_type_metric_cmd);
746 install_element (RIP_NODE, &no_rip_redistribute_type_metric_routemap_cmd);
747 install_element (RIP_NODE, &rip_default_information_originate_cmd);
748 install_element (RIP_NODE, &no_rip_default_information_originate_cmd);
749}