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