2 * RIPngd and zebra interface.
3 * Copyright (C) 1998, 1999 Kunihiro Ishiguro
5 * This file is part of GNU Zebra.
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
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.
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
34 #include "ripngd/ripngd.h"
35 #include "ripngd/ripng_debug.h"
37 /* All information about zebra. */
38 struct zclient
*zclient
= NULL
;
40 /* Send ECMP routes to zebra. */
42 ripng_zebra_ipv6_send (struct route_node
*rp
, u_char cmd
)
44 static struct in6_addr
**nexthops
= NULL
;
45 static ifindex_t
*ifindexes
= NULL
;
46 static unsigned int nexthops_len
= 0;
48 struct list
*list
= (struct list
*)rp
->info
;
50 struct listnode
*listnode
= NULL
;
51 struct ripng_info
*rinfo
= NULL
;
54 if (vrf_bitmap_check (zclient
->redist
[AFI_IP6
][ZEBRA_ROUTE_RIPNG
], VRF_DEFAULT
))
56 api
.vrf_id
= VRF_DEFAULT
;
57 api
.type
= ZEBRA_ROUTE_RIPNG
;
61 api
.safi
= SAFI_UNICAST
;
63 if (nexthops_len
< listcount (list
))
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));
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
))
76 nexthops
[count
] = &rinfo
->nexthop
;
77 ifindexes
[count
] = rinfo
->ifindex
;
79 if (cmd
== ZEBRA_IPV6_ROUTE_ADD
)
80 SET_FLAG (rinfo
->flags
, RIPNG_RTF_FIB
);
82 UNSET_FLAG (rinfo
->flags
, RIPNG_RTF_FIB
);
85 api
.nexthop
= nexthops
;
86 api
.nexthop_num
= count
;
87 api
.ifindex
= ifindexes
;
88 api
.ifindex_num
= count
;
90 rinfo
= listgetdata (listhead (list
));
92 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
93 api
.metric
= rinfo
->metric
;
95 zapi_ipv6_route (cmd
, zclient
,
96 (struct prefix_ipv6
*)&rp
->p
, &api
);
98 if (IS_RIPNG_DEBUG_ZEBRA
)
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
);
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
);
114 /* Add/update ECMP routes to zebra. */
116 ripng_zebra_ipv6_add (struct route_node
*rp
)
118 ripng_zebra_ipv6_send (rp
, ZEBRA_IPV6_ROUTE_ADD
);
121 /* Delete ECMP routes from zebra. */
123 ripng_zebra_ipv6_delete (struct route_node
*rp
)
125 ripng_zebra_ipv6_send (rp
, ZEBRA_IPV6_ROUTE_DELETE
);
128 /* Zebra route add and delete treatment. */
130 ripng_zebra_read_ipv6 (int command
, struct zclient
*zclient
,
131 zebra_size_t length
, vrf_id_t vrf_id
)
134 struct zapi_ipv6 api
;
135 unsigned long ifindex
;
136 struct in6_addr nexthop
;
137 struct prefix_ipv6 p
;
141 memset (&nexthop
, 0, sizeof (struct in6_addr
));
143 /* Type, flags, message. */
144 api
.type
= stream_getc (s
);
145 api
.instance
= stream_getw (s
);
146 api
.flags
= stream_getl (s
);
147 api
.message
= stream_getc (s
);
150 memset (&p
, 0, sizeof (struct prefix_ipv6
));
152 p
.prefixlen
= MIN(IPV6_MAX_PREFIXLEN
, stream_getc (s
));
153 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
155 /* Nexthop, ifindex, distance, metric. */
156 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
158 api
.nexthop_num
= stream_getc (s
);
159 stream_get (&nexthop
, s
, 16);
161 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
163 api
.ifindex_num
= stream_getc (s
);
164 ifindex
= stream_getl (s
);
166 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
167 api
.distance
= stream_getc (s
);
170 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
171 api
.metric
= stream_getl (s
);
175 if (command
== ZEBRA_REDISTRIBUTE_IPV6_ADD
)
176 ripng_redistribute_add (api
.type
, RIPNG_ROUTE_REDISTRIBUTE
, &p
, ifindex
, &nexthop
);
178 ripng_redistribute_delete (api
.type
, RIPNG_ROUTE_REDISTRIBUTE
, &p
, ifindex
);
184 ripng_zclient_reset (void)
186 zclient_reset (zclient
);
190 ripng_redistribute_unset (int type
)
193 if (! vrf_bitmap_check (zclient
->redist
[AFI_IP6
][type
], VRF_DEFAULT
))
196 vrf_bitmap_set (zclient
->redist
[AFI_IP6
][type
], VRF_DEFAULT
);
198 if (zclient
->sock
> 0)
199 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, AFI_IP6
, type
, 0, VRF_DEFAULT
);
201 ripng_redistribute_withdraw (type
);
207 ripng_redistribute_check (int type
)
209 return vrf_bitmap_check (zclient
->redist
[AFI_IP6
][type
], VRF_DEFAULT
);
213 ripng_redistribute_metric_set (int type
, int metric
)
215 ripng
->route_map
[type
].metric_config
= 1;
216 ripng
->route_map
[type
].metric
= metric
;
220 ripng_redistribute_metric_unset (int type
)
222 ripng
->route_map
[type
].metric_config
= 0;
223 ripng
->route_map
[type
].metric
= 0;
228 ripng_redistribute_routemap_set (int type
, const char *name
)
230 if (ripng
->route_map
[type
].name
)
231 free (ripng
->route_map
[type
].name
);
233 ripng
->route_map
[type
].name
= strdup (name
);
234 ripng
->route_map
[type
].map
= route_map_lookup_by_name (name
);
238 ripng_redistribute_routemap_unset (int type
)
240 if (ripng
->route_map
[type
].name
)
241 free (ripng
->route_map
[type
].name
);
243 ripng
->route_map
[type
].name
= NULL
;
244 ripng
->route_map
[type
].map
= NULL
;
247 /* Redistribution types */
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 {ZEBRA_ROUTE_VNC
, 1, "vnc"},
263 ripng_redistribute_clean ()
267 for (i
= 0; redist_type
[i
].str
; i
++)
269 if (vrf_bitmap_check (zclient
->redist
[AFI_IP6
][redist_type
[i
].type
], VRF_DEFAULT
))
271 if (zclient
->sock
> 0)
272 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
,
273 zclient
, AFI_IP6
, redist_type
[i
].type
, 0,
276 vrf_bitmap_unset (zclient
->redist
[AFI_IP6
][redist_type
[i
].type
], VRF_DEFAULT
);
278 /* Remove the routes from RIPng table. */
279 ripng_redistribute_withdraw (redist_type
[i
].type
);
287 "Enable a routing process\n"
288 "Make connection to zebra daemon\n")
290 vty
->node
= ZEBRA_NODE
;
292 zclient_start (zclient
);
296 DEFUN (no_router_zebra
,
300 "Disable a routing process\n"
301 "Stop connection to zebra daemon\n")
304 zclient_stop (zclient
);
308 DEFUN (ripng_redistribute_ripng
,
309 ripng_redistribute_ripng_cmd
,
310 "redistribute ripng",
311 "Redistribute information from another routing protocol\n"
314 vrf_bitmap_set (zclient
->redist
[AFI_IP6
][ZEBRA_ROUTE_RIPNG
], VRF_DEFAULT
);
318 DEFUN (no_ripng_redistribute_ripng
,
319 no_ripng_redistribute_ripng_cmd
,
320 "no redistribute ripng",
322 "Redistribute information from another routing protocol\n"
325 vrf_bitmap_unset (zclient
->redist
[AFI_IP6
][ZEBRA_ROUTE_RIPNG
], VRF_DEFAULT
);
329 DEFUN (ripng_redistribute_type
,
330 ripng_redistribute_type_cmd
,
331 "redistribute " QUAGGA_REDIST_STR_RIPNGD
,
333 QUAGGA_REDIST_HELP_STR_RIPNGD
)
337 type
= proto_redistnum(AFI_IP6
, argv
[0]);
341 vty_out(vty
, "Invalid type %s%s", argv
[0], VTY_NEWLINE
);
345 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0, VRF_DEFAULT
);
349 DEFUN (no_ripng_redistribute_type
,
350 no_ripng_redistribute_type_cmd
,
351 "no redistribute " QUAGGA_REDIST_STR_RIPNGD
,
354 QUAGGA_REDIST_HELP_STR_RIPNGD
)
358 type
= proto_redistnum(AFI_IP6
, argv
[0]);
362 vty_out(vty
, "Invalid type %s%s", argv
[0], VTY_NEWLINE
);
366 ripng_redistribute_metric_unset (type
);
367 ripng_redistribute_routemap_unset (type
);
368 return ripng_redistribute_unset (type
);
372 DEFUN (ripng_redistribute_type_metric
,
373 ripng_redistribute_type_metric_cmd
,
374 "redistribute " QUAGGA_REDIST_STR_RIPNGD
" metric <0-16>",
376 QUAGGA_REDIST_HELP_STR_RIPNGD
383 metric
= atoi (argv
[1]);
384 type
= proto_redistnum(AFI_IP6
, argv
[0]);
388 vty_out(vty
, "Invalid type %s%s", argv
[0], VTY_NEWLINE
);
392 ripng_redistribute_metric_set (type
, metric
);
393 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0,
398 ALIAS (no_ripng_redistribute_type
,
399 no_ripng_redistribute_type_metric_cmd
,
400 "no redistribute " QUAGGA_REDIST_STR_RIPNGD
" metric <0-16>",
403 QUAGGA_REDIST_HELP_STR_RIPNGD
407 DEFUN (ripng_redistribute_type_routemap
,
408 ripng_redistribute_type_routemap_cmd
,
409 "redistribute " QUAGGA_REDIST_STR_RIPNGD
" route-map WORD",
411 QUAGGA_REDIST_HELP_STR_RIPNGD
412 "Route map reference\n"
413 "Pointer to route-map entries\n")
417 type
= proto_redistnum(AFI_IP6
, argv
[0]);
421 vty_out(vty
, "Invalid type %s%s", argv
[0], VTY_NEWLINE
);
425 ripng_redistribute_routemap_set (type
, argv
[1]);
426 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0,
431 ALIAS (no_ripng_redistribute_type
,
432 no_ripng_redistribute_type_routemap_cmd
,
433 "no redistribute " QUAGGA_REDIST_STR_RIPNGD
" route-map WORD",
436 QUAGGA_REDIST_HELP_STR_RIPNGD
437 "Route map reference\n"
438 "Pointer to route-map entries\n")
440 DEFUN (ripng_redistribute_type_metric_routemap
,
441 ripng_redistribute_type_metric_routemap_cmd
,
442 "redistribute " QUAGGA_REDIST_STR_RIPNGD
" metric <0-16> route-map WORD",
444 QUAGGA_REDIST_HELP_STR_RIPNGD
447 "Route map reference\n"
448 "Pointer to route-map entries\n")
453 type
= proto_redistnum(AFI_IP6
, argv
[0]);
454 metric
= atoi (argv
[1]);
458 vty_out(vty
, "Invalid type %s%s", argv
[0], VTY_NEWLINE
);
462 ripng_redistribute_metric_set (type
, metric
);
463 ripng_redistribute_routemap_set (type
, argv
[2]);
464 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0, VRF_DEFAULT
);
468 ALIAS (no_ripng_redistribute_type
,
469 no_ripng_redistribute_type_metric_routemap_cmd
,
470 "no redistribute " QUAGGA_REDIST_STR_RIPNGD
" metric <0-16> route-map WORD",
473 QUAGGA_REDIST_HELP_STR_RIPNGD
474 "Route map reference\n"
475 "Pointer to route-map entries\n")
478 ripng_redistribute_write (struct vty
*vty
, int config_mode
)
482 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
483 if (i
!= zclient
->redist_default
&&
484 vrf_bitmap_check (zclient
->redist
[AFI_IP6
][i
], VRF_DEFAULT
))
488 if (ripng
->route_map
[i
].metric_config
)
490 if (ripng
->route_map
[i
].name
)
491 vty_out (vty
, " redistribute %s metric %d route-map %s%s",
492 zebra_route_string(i
), ripng
->route_map
[i
].metric
,
493 ripng
->route_map
[i
].name
, VTY_NEWLINE
);
495 vty_out (vty
, " redistribute %s metric %d%s",
496 zebra_route_string(i
), ripng
->route_map
[i
].metric
,
501 if (ripng
->route_map
[i
].name
)
502 vty_out (vty
, " redistribute %s route-map %s%s",
503 zebra_route_string(i
), ripng
->route_map
[i
].name
,
506 vty_out (vty
, " redistribute %s%s", zebra_route_string(i
),
511 vty_out (vty
, " %s", zebra_route_string(i
));
515 /* RIPng configuration write function. */
517 zebra_config_write (struct vty
*vty
)
519 if (! zclient
->enable
)
521 vty_out (vty
, "no router zebra%s", VTY_NEWLINE
);
524 else if (! vrf_bitmap_check (zclient
->redist
[AFI_IP6
][ZEBRA_ROUTE_RIPNG
], VRF_DEFAULT
))
526 vty_out (vty
, "router zebra%s", VTY_NEWLINE
);
527 vty_out (vty
, " no redistribute ripng%s", VTY_NEWLINE
);
533 /* Zebra node structure. */
534 static struct cmd_node zebra_node
=
537 "%s(config-router)# ",
541 ripng_zebra_connected (struct zclient
*zclient
)
543 zclient_send_reg_requests (zclient
, VRF_DEFAULT
);
546 /* Initialize zebra structure and it's commands. */
548 zebra_init (struct thread_master
*master
)
550 /* Allocate zebra structure. */
551 zclient
= zclient_new(master
);
552 zclient_init (zclient
, ZEBRA_ROUTE_RIPNG
, 0);
554 zclient
->zebra_connected
= ripng_zebra_connected
;
555 zclient
->interface_up
= ripng_interface_up
;
556 zclient
->interface_down
= ripng_interface_down
;
557 zclient
->interface_add
= ripng_interface_add
;
558 zclient
->interface_delete
= ripng_interface_delete
;
559 zclient
->interface_address_add
= ripng_interface_address_add
;
560 zclient
->interface_address_delete
= ripng_interface_address_delete
;
561 zclient
->redistribute_route_ipv6_add
= ripng_zebra_read_ipv6
;
562 zclient
->redistribute_route_ipv6_del
= ripng_zebra_read_ipv6
;
564 /* Install zebra node. */
565 install_node (&zebra_node
, zebra_config_write
);
567 /* Install command element for zebra node. */
568 install_element (CONFIG_NODE
, &router_zebra_cmd
);
569 install_element (CONFIG_NODE
, &no_router_zebra_cmd
);
570 install_default (ZEBRA_NODE
);
571 install_element (ZEBRA_NODE
, &ripng_redistribute_ripng_cmd
);
572 install_element (ZEBRA_NODE
, &no_ripng_redistribute_ripng_cmd
);
574 /* Install command elements to ripng node */
575 install_element (RIPNG_NODE
, &ripng_redistribute_type_cmd
);
576 install_element (RIPNG_NODE
, &ripng_redistribute_type_routemap_cmd
);
577 install_element (RIPNG_NODE
, &ripng_redistribute_type_metric_cmd
);
578 install_element (RIPNG_NODE
, &ripng_redistribute_type_metric_routemap_cmd
);
579 install_element (RIPNG_NODE
, &no_ripng_redistribute_type_cmd
);
580 install_element (RIPNG_NODE
, &no_ripng_redistribute_type_routemap_cmd
);
581 install_element (RIPNG_NODE
, &no_ripng_redistribute_type_metric_cmd
);
582 install_element (RIPNG_NODE
, &no_ripng_redistribute_type_metric_routemap_cmd
);