]> git.proxmox.com Git - mirror_frr.git/blob - ripngd/ripng_zebra.c
Expand #defines in command strings
[mirror_frr.git] / ripngd / ripng_zebra.c
1 /*
2 * RIPngd and zebra interface.
3 * Copyright (C) 1998, 1999 Kunihiro Ishiguro
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23 #include <zebra.h>
24
25 #include "command.h"
26 #include "prefix.h"
27 #include "table.h"
28 #include "stream.h"
29 #include "memory.h"
30 #include "routemap.h"
31 #include "zclient.h"
32 #include "log.h"
33
34 #include "ripngd/ripngd.h"
35 #include "ripngd/ripng_debug.h"
36
37 /* All information about zebra. */
38 struct zclient *zclient = NULL;
39
40 /* Send ECMP routes to zebra. */
41 static void
42 ripng_zebra_ipv6_send (struct route_node *rp, u_char cmd)
43 {
44 static struct in6_addr **nexthops = NULL;
45 static ifindex_t *ifindexes = NULL;
46 static unsigned int nexthops_len = 0;
47
48 struct list *list = (struct list *)rp->info;
49 struct zapi_ipv6 api;
50 struct listnode *listnode = NULL;
51 struct ripng_info *rinfo = NULL;
52 int count = 0;
53
54 if (vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_RIPNG], VRF_DEFAULT))
55 {
56 api.vrf_id = VRF_DEFAULT;
57 api.type = ZEBRA_ROUTE_RIPNG;
58 api.instance = 0;
59 api.flags = 0;
60 api.message = 0;
61 api.safi = SAFI_UNICAST;
62
63 if (nexthops_len < listcount (list))
64 {
65 nexthops_len = listcount (list);
66 nexthops = XREALLOC (MTYPE_TMP, nexthops,
67 nexthops_len * sizeof (struct in6_addr *));
68 ifindexes = XREALLOC (MTYPE_TMP, ifindexes,
69 nexthops_len * sizeof (unsigned int));
70 }
71
72 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
73 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
74 for (ALL_LIST_ELEMENTS_RO (list, listnode, rinfo))
75 {
76 nexthops[count] = &rinfo->nexthop;
77 ifindexes[count] = rinfo->ifindex;
78 count++;
79 if (cmd == ZEBRA_IPV6_ROUTE_ADD)
80 SET_FLAG (rinfo->flags, RIPNG_RTF_FIB);
81 else
82 UNSET_FLAG (rinfo->flags, RIPNG_RTF_FIB);
83 }
84
85 api.nexthop = nexthops;
86 api.nexthop_num = count;
87 api.ifindex = ifindexes;
88 api.ifindex_num = count;
89
90 rinfo = listgetdata (listhead (list));
91
92 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
93 api.metric = rinfo->metric;
94
95 zapi_ipv6_route (cmd, zclient,
96 (struct prefix_ipv6 *)&rp->p, &api);
97
98 if (IS_RIPNG_DEBUG_ZEBRA)
99 {
100 if (ripng->ecmp)
101 zlog_debug ("%s: %s/%d nexthops %d",
102 (cmd == ZEBRA_IPV6_ROUTE_ADD) ? \
103 "Install into zebra" : "Delete from zebra",
104 inet6_ntoa (rp->p.u.prefix6), rp->p.prefixlen, count);
105 else
106 zlog_debug ("%s: %s/%d",
107 (cmd == ZEBRA_IPV6_ROUTE_ADD) ? \
108 "Install into zebra" : "Delete from zebra",
109 inet6_ntoa (rp->p.u.prefix6), rp->p.prefixlen);
110 }
111 }
112 }
113
114 /* Add/update ECMP routes to zebra. */
115 void
116 ripng_zebra_ipv6_add (struct route_node *rp)
117 {
118 ripng_zebra_ipv6_send (rp, ZEBRA_IPV6_ROUTE_ADD);
119 }
120
121 /* Delete ECMP routes from zebra. */
122 void
123 ripng_zebra_ipv6_delete (struct route_node *rp)
124 {
125 ripng_zebra_ipv6_send (rp, ZEBRA_IPV6_ROUTE_DELETE);
126 }
127
128 /* Zebra route add and delete treatment. */
129 static int
130 ripng_zebra_read_ipv6 (int command, struct zclient *zclient,
131 zebra_size_t length, vrf_id_t vrf_id)
132 {
133 struct stream *s;
134 struct zapi_ipv6 api;
135 unsigned long ifindex;
136 struct in6_addr nexthop;
137 struct prefix_ipv6 p;
138
139 s = zclient->ibuf;
140 ifindex = 0;
141 memset (&nexthop, 0, sizeof (struct in6_addr));
142
143 /* Type, flags, message. */
144 api.type = stream_getc (s);
145 api.instance = stream_getw (s);
146 api.flags = stream_getc (s);
147 api.message = stream_getc (s);
148
149 /* IPv6 prefix. */
150 memset (&p, 0, sizeof (struct prefix_ipv6));
151 p.family = AF_INET6;
152 p.prefixlen = stream_getc (s);
153 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
154
155 /* Nexthop, ifindex, distance, metric. */
156 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
157 {
158 api.nexthop_num = stream_getc (s);
159 stream_get (&nexthop, s, 16);
160 }
161 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
162 {
163 api.ifindex_num = stream_getc (s);
164 ifindex = stream_getl (s);
165 }
166 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
167 api.distance = stream_getc (s);
168 else
169 api.distance = 0;
170 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
171 api.metric = stream_getl (s);
172 else
173 api.metric = 0;
174
175 if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD)
176 ripng_redistribute_add (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex, &nexthop);
177 else
178 ripng_redistribute_delete (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex);
179
180 return 0;
181 }
182
183 void
184 ripng_zclient_reset (void)
185 {
186 zclient_reset (zclient);
187 }
188
189 static int
190 ripng_redistribute_unset (int type)
191 {
192
193 if (! vrf_bitmap_check (zclient->redist[AFI_IP6][type], VRF_DEFAULT))
194 return CMD_SUCCESS;
195
196 vrf_bitmap_set (zclient->redist[AFI_IP6][type], VRF_DEFAULT);
197
198 if (zclient->sock > 0)
199 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP6, type, 0, VRF_DEFAULT);
200
201 ripng_redistribute_withdraw (type);
202
203 return CMD_SUCCESS;
204 }
205
206 int
207 ripng_redistribute_check (int type)
208 {
209 return vrf_bitmap_check (zclient->redist[AFI_IP6][type], VRF_DEFAULT);
210 }
211
212 static void
213 ripng_redistribute_metric_set (int type, int metric)
214 {
215 ripng->route_map[type].metric_config = 1;
216 ripng->route_map[type].metric = metric;
217 }
218
219 static int
220 ripng_redistribute_metric_unset (int type)
221 {
222 ripng->route_map[type].metric_config = 0;
223 ripng->route_map[type].metric = 0;
224 return 0;
225 }
226
227 static void
228 ripng_redistribute_routemap_set (int type, const char *name)
229 {
230 if (ripng->route_map[type].name)
231 free (ripng->route_map[type].name);
232
233 ripng->route_map[type].name = strdup (name);
234 ripng->route_map[type].map = route_map_lookup_by_name (name);
235 }
236
237 static void
238 ripng_redistribute_routemap_unset (int type)
239 {
240 if (ripng->route_map[type].name)
241 free (ripng->route_map[type].name);
242
243 ripng->route_map[type].name = NULL;
244 ripng->route_map[type].map = NULL;
245 }
246
247 /* Redistribution types */
248 static struct {
249 int type;
250 int str_min_len;
251 const char *str;
252 } redist_type[] = {
253 {ZEBRA_ROUTE_KERNEL, 1, "kernel"},
254 {ZEBRA_ROUTE_CONNECT, 1, "connected"},
255 {ZEBRA_ROUTE_STATIC, 1, "static"},
256 {ZEBRA_ROUTE_OSPF6, 1, "ospf6"},
257 {ZEBRA_ROUTE_BGP, 2, "bgp"},
258 {0, 0, NULL}
259 };
260
261 void
262 ripng_redistribute_clean ()
263 {
264 int i;
265
266 for (i = 0; redist_type[i].str; i++)
267 {
268 if (vrf_bitmap_check (zclient->redist[AFI_IP6][redist_type[i].type], VRF_DEFAULT))
269 {
270 if (zclient->sock > 0)
271 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
272 zclient, AFI_IP6, redist_type[i].type, 0,
273 VRF_DEFAULT);
274
275 vrf_bitmap_unset (zclient->redist[AFI_IP6][redist_type[i].type], VRF_DEFAULT);
276
277 /* Remove the routes from RIPng table. */
278 ripng_redistribute_withdraw (redist_type[i].type);
279 }
280 }
281 }
282
283 DEFUN (router_zebra,
284 router_zebra_cmd,
285 "router zebra",
286 "Enable a routing process\n"
287 "Make connection to zebra daemon\n")
288 {
289 vty->node = ZEBRA_NODE;
290 zclient->enable = 1;
291 zclient_start (zclient);
292 return CMD_SUCCESS;
293 }
294
295 DEFUN (no_router_zebra,
296 no_router_zebra_cmd,
297 "no router zebra",
298 NO_STR
299 "Disable a routing process\n"
300 "Stop connection to zebra daemon\n")
301 {
302 zclient->enable = 0;
303 zclient_stop (zclient);
304 return CMD_SUCCESS;
305 }
306
307 DEFUN (ripng_redistribute_ripng,
308 ripng_redistribute_ripng_cmd,
309 "redistribute ripng",
310 "Redistribute information from another routing protocol\n"
311 "RIPng route\n")
312 {
313 vrf_bitmap_set (zclient->redist[AFI_IP6][ZEBRA_ROUTE_RIPNG], VRF_DEFAULT);
314 return CMD_SUCCESS;
315 }
316
317 DEFUN (no_ripng_redistribute_ripng,
318 no_ripng_redistribute_ripng_cmd,
319 "no redistribute ripng",
320 NO_STR
321 "Redistribute information from another routing protocol\n"
322 "RIPng route\n")
323 {
324 vrf_bitmap_unset (zclient->redist[AFI_IP6][ZEBRA_ROUTE_RIPNG], VRF_DEFAULT);
325 return CMD_SUCCESS;
326 }
327
328 DEFUN (ripng_redistribute_type,
329 ripng_redistribute_type_cmd,
330 "redistribute <kernel|connected|static|ospf6|isis|bgp|table>",
331 "Redistribute\n"
332 QUAGGA_REDIST_HELP_STR_RIPNGD)
333 {
334 int type;
335
336 type = proto_redistnum(AFI_IP6, argv[2]->arg);
337
338 if (type < 0)
339 {
340 vty_out(vty, "Invalid type %s%s", argv[2]->arg, VTY_NEWLINE);
341 return CMD_WARNING;
342 }
343
344 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0, VRF_DEFAULT);
345 return CMD_SUCCESS;
346 }
347
348 /*
349 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
350 * "no redistribute <kernel|connected|static|ospf6|isis|bgp|table> metric <0-16> route-map WORD",
351 * NO_STR
352 * "Redistribute\n"
353 * QUAGGA_REDIST_HELP_STR_RIPNGD
354 * "Route map reference\n"
355 * "Pointer to route-map entries\n"
356 *
357 * "no redistribute <kernel|connected|static|ospf6|isis|bgp|table> metric <0-16>",
358 * NO_STR
359 * "Redistribute\n"
360 * QUAGGA_REDIST_HELP_STR_RIPNGD
361 * "Metric\n"
362 * "Metric value\n"
363 *
364 * "no redistribute <kernel|connected|static|ospf6|isis|bgp|table> route-map WORD",
365 * NO_STR
366 * "Redistribute\n"
367 * QUAGGA_REDIST_HELP_STR_RIPNGD
368 * "Route map reference\n"
369 * "Pointer to route-map entries\n"
370 *
371 */
372 DEFUN (no_ripng_redistribute_type,
373 no_ripng_redistribute_type_cmd,
374 "no redistribute <kernel|connected|static|ospf6|isis|bgp|table>",
375 NO_STR
376 "Redistribute\n"
377 QUAGGA_REDIST_HELP_STR_RIPNGD)
378 {
379 int type;
380
381 type = proto_redistnum(AFI_IP6, argv[3]->arg);
382
383 if (type < 0)
384 {
385 vty_out(vty, "Invalid type %s%s", argv[3]->arg, VTY_NEWLINE);
386 return CMD_WARNING;
387 }
388
389 ripng_redistribute_metric_unset (type);
390 ripng_redistribute_routemap_unset (type);
391 return ripng_redistribute_unset (type);
392 }
393
394
395 DEFUN (ripng_redistribute_type_metric,
396 ripng_redistribute_type_metric_cmd,
397 "redistribute <kernel|connected|static|ospf6|isis|bgp|table> metric (0-16)",
398 "Redistribute\n"
399 QUAGGA_REDIST_HELP_STR_RIPNGD
400 "Metric\n"
401 "Metric value\n")
402 {
403 int idx_protocol = 1;
404 int idx_number = 3;
405 int type;
406 int metric;
407
408 metric = atoi (argv[idx_number]->arg);
409 type = proto_redistnum(AFI_IP6, argv[idx_protocol]->arg);
410
411 if (type < 0)
412 {
413 vty_out(vty, "Invalid type %s%s", argv[idx_protocol]->arg, VTY_NEWLINE);
414 return CMD_WARNING;
415 }
416
417 ripng_redistribute_metric_set (type, metric);
418 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0,
419 VRF_DEFAULT);
420 return CMD_SUCCESS;
421 }
422
423
424 DEFUN (ripng_redistribute_type_routemap,
425 ripng_redistribute_type_routemap_cmd,
426 "redistribute <kernel|connected|static|ospf6|isis|bgp|table> route-map WORD",
427 "Redistribute\n"
428 QUAGGA_REDIST_HELP_STR_RIPNGD
429 "Route map reference\n"
430 "Pointer to route-map entries\n")
431 {
432 int idx_protocol = 1;
433 int idx_word = 3;
434 int type;
435
436 type = proto_redistnum(AFI_IP6, argv[idx_protocol]->arg);
437
438 if (type < 0)
439 {
440 vty_out(vty, "Invalid type %s%s", argv[idx_protocol]->arg, VTY_NEWLINE);
441 return CMD_WARNING;
442 }
443
444 ripng_redistribute_routemap_set (type, argv[idx_word]->arg);
445 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0,
446 VRF_DEFAULT);
447 return CMD_SUCCESS;
448 }
449
450
451 DEFUN (ripng_redistribute_type_metric_routemap,
452 ripng_redistribute_type_metric_routemap_cmd,
453 "redistribute <kernel|connected|static|ospf6|isis|bgp|table> metric (0-16) route-map WORD",
454 "Redistribute\n"
455 QUAGGA_REDIST_HELP_STR_RIPNGD
456 "Metric\n"
457 "Metric value\n"
458 "Route map reference\n"
459 "Pointer to route-map entries\n")
460 {
461 int idx_protocol = 1;
462 int idx_number = 3;
463 int idx_word = 5;
464 int type;
465 int metric;
466
467 type = proto_redistnum(AFI_IP6, argv[idx_protocol]->arg);
468 metric = atoi (argv[idx_number]->arg);
469
470 if (type < 0)
471 {
472 vty_out(vty, "Invalid type %s%s", argv[idx_protocol]->arg, VTY_NEWLINE);
473 return CMD_WARNING;
474 }
475
476 ripng_redistribute_metric_set (type, metric);
477 ripng_redistribute_routemap_set (type, argv[idx_word]->arg);
478 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0, VRF_DEFAULT);
479 return CMD_SUCCESS;
480 }
481
482
483 void
484 ripng_redistribute_write (struct vty *vty, int config_mode)
485 {
486 int i;
487
488 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
489 if (i != zclient->redist_default &&
490 vrf_bitmap_check (zclient->redist[AFI_IP6][i], VRF_DEFAULT))
491 {
492 if (config_mode)
493 {
494 if (ripng->route_map[i].metric_config)
495 {
496 if (ripng->route_map[i].name)
497 vty_out (vty, " redistribute %s metric %d route-map %s%s",
498 zebra_route_string(i), ripng->route_map[i].metric,
499 ripng->route_map[i].name, VTY_NEWLINE);
500 else
501 vty_out (vty, " redistribute %s metric %d%s",
502 zebra_route_string(i), ripng->route_map[i].metric,
503 VTY_NEWLINE);
504 }
505 else
506 {
507 if (ripng->route_map[i].name)
508 vty_out (vty, " redistribute %s route-map %s%s",
509 zebra_route_string(i), ripng->route_map[i].name,
510 VTY_NEWLINE);
511 else
512 vty_out (vty, " redistribute %s%s", zebra_route_string(i),
513 VTY_NEWLINE);
514 }
515 }
516 else
517 vty_out (vty, " %s", zebra_route_string(i));
518 }
519 }
520
521 /* RIPng configuration write function. */
522 static int
523 zebra_config_write (struct vty *vty)
524 {
525 if (! zclient->enable)
526 {
527 vty_out (vty, "no router zebra%s", VTY_NEWLINE);
528 return 1;
529 }
530 else if (! vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_RIPNG], VRF_DEFAULT))
531 {
532 vty_out (vty, "router zebra%s", VTY_NEWLINE);
533 vty_out (vty, " no redistribute ripng%s", VTY_NEWLINE);
534 return 1;
535 }
536 return 0;
537 }
538
539 /* Zebra node structure. */
540 static struct cmd_node zebra_node =
541 {
542 ZEBRA_NODE,
543 "%s(config-router)# ",
544 };
545
546 static void
547 ripng_zebra_connected (struct zclient *zclient)
548 {
549 zclient_send_reg_requests (zclient, VRF_DEFAULT);
550 }
551
552 /* Initialize zebra structure and it's commands. */
553 void
554 zebra_init (struct thread_master *master)
555 {
556 /* Allocate zebra structure. */
557 zclient = zclient_new(master);
558 zclient_init (zclient, ZEBRA_ROUTE_RIPNG, 0);
559
560 zclient->zebra_connected = ripng_zebra_connected;
561 zclient->interface_up = ripng_interface_up;
562 zclient->interface_down = ripng_interface_down;
563 zclient->interface_add = ripng_interface_add;
564 zclient->interface_delete = ripng_interface_delete;
565 zclient->interface_address_add = ripng_interface_address_add;
566 zclient->interface_address_delete = ripng_interface_address_delete;
567 zclient->ipv4_route_add = NULL;
568 zclient->ipv4_route_delete = NULL;
569 zclient->redistribute_route_ipv4_add = NULL;
570 zclient->redistribute_route_ipv4_del = NULL;
571 zclient->ipv6_route_add = ripng_zebra_read_ipv6;
572 zclient->ipv6_route_delete = ripng_zebra_read_ipv6;
573 zclient->redistribute_route_ipv6_add = ripng_zebra_read_ipv6;
574 zclient->redistribute_route_ipv6_del = ripng_zebra_read_ipv6;
575
576 /* Install zebra node. */
577 install_node (&zebra_node, zebra_config_write);
578
579 /* Install command element for zebra node. */
580 install_element (CONFIG_NODE, &router_zebra_cmd);
581 install_element (CONFIG_NODE, &no_router_zebra_cmd);
582 install_default (ZEBRA_NODE);
583 install_element (ZEBRA_NODE, &ripng_redistribute_ripng_cmd);
584 install_element (ZEBRA_NODE, &no_ripng_redistribute_ripng_cmd);
585
586 /* Install command elements to ripng node */
587 install_element (RIPNG_NODE, &ripng_redistribute_type_cmd);
588 install_element (RIPNG_NODE, &ripng_redistribute_type_routemap_cmd);
589 install_element (RIPNG_NODE, &ripng_redistribute_type_metric_cmd);
590 install_element (RIPNG_NODE, &ripng_redistribute_type_metric_routemap_cmd);
591 install_element (RIPNG_NODE, &no_ripng_redistribute_type_cmd);
592 }