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"},
262 ripng_redistribute_clean ()
266 for (i
= 0; redist_type
[i
].str
; i
++)
268 if (vrf_bitmap_check (zclient
->redist
[AFI_IP6
][redist_type
[i
].type
], VRF_DEFAULT
))
270 if (zclient
->sock
> 0)
271 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
,
272 zclient
, AFI_IP6
, redist_type
[i
].type
, 0,
275 vrf_bitmap_unset (zclient
->redist
[AFI_IP6
][redist_type
[i
].type
], VRF_DEFAULT
);
277 /* Remove the routes from RIPng table. */
278 ripng_redistribute_withdraw (redist_type
[i
].type
);
286 "Enable a routing process\n"
287 "Make connection to zebra daemon\n")
289 vty
->node
= ZEBRA_NODE
;
291 zclient_start (zclient
);
295 DEFUN (no_router_zebra
,
299 "Disable a routing process\n"
300 "Stop connection to zebra daemon\n")
303 zclient_stop (zclient
);
307 DEFUN (ripng_redistribute_ripng
,
308 ripng_redistribute_ripng_cmd
,
309 "redistribute ripng",
310 "Redistribute information from another routing protocol\n"
313 vrf_bitmap_set (zclient
->redist
[AFI_IP6
][ZEBRA_ROUTE_RIPNG
], VRF_DEFAULT
);
317 DEFUN (no_ripng_redistribute_ripng
,
318 no_ripng_redistribute_ripng_cmd
,
319 "no redistribute ripng",
321 "Redistribute information from another routing protocol\n"
324 vrf_bitmap_unset (zclient
->redist
[AFI_IP6
][ZEBRA_ROUTE_RIPNG
], VRF_DEFAULT
);
328 DEFUN (ripng_redistribute_type
,
329 ripng_redistribute_type_cmd
,
330 "redistribute " QUAGGA_REDIST_STR_RIPNGD
,
332 QUAGGA_REDIST_HELP_STR_RIPNGD
)
336 type
= proto_redistnum(AFI_IP6
, argv
[0]);
340 vty_out(vty
, "Invalid type %s%s", argv
[0], VTY_NEWLINE
);
344 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0, VRF_DEFAULT
);
348 DEFUN (no_ripng_redistribute_type
,
349 no_ripng_redistribute_type_cmd
,
350 "no redistribute " QUAGGA_REDIST_STR_RIPNGD
,
353 QUAGGA_REDIST_HELP_STR_RIPNGD
)
357 type
= proto_redistnum(AFI_IP6
, argv
[0]);
361 vty_out(vty
, "Invalid type %s%s", argv
[0], VTY_NEWLINE
);
365 ripng_redistribute_metric_unset (type
);
366 ripng_redistribute_routemap_unset (type
);
367 return ripng_redistribute_unset (type
);
371 DEFUN (ripng_redistribute_type_metric
,
372 ripng_redistribute_type_metric_cmd
,
373 "redistribute " QUAGGA_REDIST_STR_RIPNGD
" metric <0-16>",
375 QUAGGA_REDIST_HELP_STR_RIPNGD
382 metric
= atoi (argv
[1]);
383 type
= proto_redistnum(AFI_IP6
, argv
[0]);
387 vty_out(vty
, "Invalid type %s%s", argv
[0], VTY_NEWLINE
);
391 ripng_redistribute_metric_set (type
, metric
);
392 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0,
397 ALIAS (no_ripng_redistribute_type
,
398 no_ripng_redistribute_type_metric_cmd
,
399 "no redistribute " QUAGGA_REDIST_STR_RIPNGD
" metric <0-16>",
402 QUAGGA_REDIST_HELP_STR_RIPNGD
406 DEFUN (ripng_redistribute_type_routemap
,
407 ripng_redistribute_type_routemap_cmd
,
408 "redistribute " QUAGGA_REDIST_STR_RIPNGD
" route-map WORD",
410 QUAGGA_REDIST_HELP_STR_RIPNGD
411 "Route map reference\n"
412 "Pointer to route-map entries\n")
416 type
= proto_redistnum(AFI_IP6
, argv
[0]);
420 vty_out(vty
, "Invalid type %s%s", argv
[0], VTY_NEWLINE
);
424 ripng_redistribute_routemap_set (type
, argv
[1]);
425 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0,
430 ALIAS (no_ripng_redistribute_type
,
431 no_ripng_redistribute_type_routemap_cmd
,
432 "no redistribute " QUAGGA_REDIST_STR_RIPNGD
" route-map WORD",
435 QUAGGA_REDIST_HELP_STR_RIPNGD
436 "Route map reference\n"
437 "Pointer to route-map entries\n")
439 DEFUN (ripng_redistribute_type_metric_routemap
,
440 ripng_redistribute_type_metric_routemap_cmd
,
441 "redistribute " QUAGGA_REDIST_STR_RIPNGD
" metric <0-16> route-map WORD",
443 QUAGGA_REDIST_HELP_STR_RIPNGD
446 "Route map reference\n"
447 "Pointer to route-map entries\n")
452 type
= proto_redistnum(AFI_IP6
, argv
[0]);
453 metric
= atoi (argv
[1]);
457 vty_out(vty
, "Invalid type %s%s", argv
[0], VTY_NEWLINE
);
461 ripng_redistribute_metric_set (type
, metric
);
462 ripng_redistribute_routemap_set (type
, argv
[2]);
463 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0, VRF_DEFAULT
);
467 ALIAS (no_ripng_redistribute_type
,
468 no_ripng_redistribute_type_metric_routemap_cmd
,
469 "no redistribute " QUAGGA_REDIST_STR_RIPNGD
" metric <0-16> route-map WORD",
472 QUAGGA_REDIST_HELP_STR_RIPNGD
473 "Route map reference\n"
474 "Pointer to route-map entries\n")
477 ripng_redistribute_write (struct vty
*vty
, int config_mode
)
481 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
482 if (i
!= zclient
->redist_default
&&
483 vrf_bitmap_check (zclient
->redist
[AFI_IP6
][i
], VRF_DEFAULT
))
487 if (ripng
->route_map
[i
].metric_config
)
489 if (ripng
->route_map
[i
].name
)
490 vty_out (vty
, " redistribute %s metric %d route-map %s%s",
491 zebra_route_string(i
), ripng
->route_map
[i
].metric
,
492 ripng
->route_map
[i
].name
, VTY_NEWLINE
);
494 vty_out (vty
, " redistribute %s metric %d%s",
495 zebra_route_string(i
), ripng
->route_map
[i
].metric
,
500 if (ripng
->route_map
[i
].name
)
501 vty_out (vty
, " redistribute %s route-map %s%s",
502 zebra_route_string(i
), ripng
->route_map
[i
].name
,
505 vty_out (vty
, " redistribute %s%s", zebra_route_string(i
),
510 vty_out (vty
, " %s", zebra_route_string(i
));
514 /* RIPng configuration write function. */
516 zebra_config_write (struct vty
*vty
)
518 if (! zclient
->enable
)
520 vty_out (vty
, "no router zebra%s", VTY_NEWLINE
);
523 else if (! vrf_bitmap_check (zclient
->redist
[AFI_IP6
][ZEBRA_ROUTE_RIPNG
], VRF_DEFAULT
))
525 vty_out (vty
, "router zebra%s", VTY_NEWLINE
);
526 vty_out (vty
, " no redistribute ripng%s", VTY_NEWLINE
);
532 /* Zebra node structure. */
533 static struct cmd_node zebra_node
=
536 "%s(config-router)# ",
540 ripng_zebra_connected (struct zclient
*zclient
)
542 zclient_send_reg_requests (zclient
, VRF_DEFAULT
);
545 /* Initialize zebra structure and it's commands. */
547 zebra_init (struct thread_master
*master
)
549 /* Allocate zebra structure. */
550 zclient
= zclient_new(master
);
551 zclient_init (zclient
, ZEBRA_ROUTE_RIPNG
, 0);
553 zclient
->zebra_connected
= ripng_zebra_connected
;
554 zclient
->interface_up
= ripng_interface_up
;
555 zclient
->interface_down
= ripng_interface_down
;
556 zclient
->interface_add
= ripng_interface_add
;
557 zclient
->interface_delete
= ripng_interface_delete
;
558 zclient
->interface_address_add
= ripng_interface_address_add
;
559 zclient
->interface_address_delete
= ripng_interface_address_delete
;
560 zclient
->redistribute_route_ipv6_add
= ripng_zebra_read_ipv6
;
561 zclient
->redistribute_route_ipv6_del
= ripng_zebra_read_ipv6
;
563 /* Install zebra node. */
564 install_node (&zebra_node
, zebra_config_write
);
566 /* Install command element for zebra node. */
567 install_element (CONFIG_NODE
, &router_zebra_cmd
);
568 install_element (CONFIG_NODE
, &no_router_zebra_cmd
);
569 install_default (ZEBRA_NODE
);
570 install_element (ZEBRA_NODE
, &ripng_redistribute_ripng_cmd
);
571 install_element (ZEBRA_NODE
, &no_ripng_redistribute_ripng_cmd
);
573 /* Install command elements to ripng node */
574 install_element (RIPNG_NODE
, &ripng_redistribute_type_cmd
);
575 install_element (RIPNG_NODE
, &ripng_redistribute_type_routemap_cmd
);
576 install_element (RIPNG_NODE
, &ripng_redistribute_type_metric_cmd
);
577 install_element (RIPNG_NODE
, &ripng_redistribute_type_metric_routemap_cmd
);
578 install_element (RIPNG_NODE
, &no_ripng_redistribute_type_cmd
);
579 install_element (RIPNG_NODE
, &no_ripng_redistribute_type_routemap_cmd
);
580 install_element (RIPNG_NODE
, &no_ripng_redistribute_type_metric_cmd
);
581 install_element (RIPNG_NODE
, &no_ripng_redistribute_type_metric_routemap_cmd
);