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_getc (s
);
147 api
.message
= stream_getc (s
);
150 memset (&p
, 0, sizeof (struct prefix_ipv6
));
152 p
.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 <kernel|connected|static|ospf6|isis|bgp|table>",
332 QUAGGA_REDIST_HELP_STR_RIPNGD
)
336 type
= proto_redistnum(AFI_IP6
, argv
[2]->arg
);
340 vty_out(vty
, "Invalid type %s%s", argv
[2]->arg
, VTY_NEWLINE
);
344 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0, VRF_DEFAULT
);
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",
353 * QUAGGA_REDIST_HELP_STR_RIPNGD
354 * "Route map reference\n"
355 * "Pointer to route-map entries\n"
357 * "no redistribute <kernel|connected|static|ospf6|isis|bgp|table> metric <0-16>",
360 * QUAGGA_REDIST_HELP_STR_RIPNGD
364 * "no redistribute <kernel|connected|static|ospf6|isis|bgp|table> route-map WORD",
367 * QUAGGA_REDIST_HELP_STR_RIPNGD
368 * "Route map reference\n"
369 * "Pointer to route-map entries\n"
372 DEFUN (no_ripng_redistribute_type
,
373 no_ripng_redistribute_type_cmd
,
374 "no redistribute <kernel|connected|static|ospf6|isis|bgp|table>",
377 QUAGGA_REDIST_HELP_STR_RIPNGD
)
381 type
= proto_redistnum(AFI_IP6
, argv
[3]->arg
);
385 vty_out(vty
, "Invalid type %s%s", argv
[3]->arg
, VTY_NEWLINE
);
389 ripng_redistribute_metric_unset (type
);
390 ripng_redistribute_routemap_unset (type
);
391 return ripng_redistribute_unset (type
);
395 DEFUN (ripng_redistribute_type_metric
,
396 ripng_redistribute_type_metric_cmd
,
397 "redistribute <kernel|connected|static|ospf6|isis|bgp|table> metric (0-16)",
399 QUAGGA_REDIST_HELP_STR_RIPNGD
403 int idx_protocol
= 1;
408 metric
= atoi (argv
[idx_number
]->arg
);
409 type
= proto_redistnum(AFI_IP6
, argv
[idx_protocol
]->arg
);
413 vty_out(vty
, "Invalid type %s%s", argv
[idx_protocol
]->arg
, VTY_NEWLINE
);
417 ripng_redistribute_metric_set (type
, metric
);
418 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0,
424 DEFUN (ripng_redistribute_type_routemap
,
425 ripng_redistribute_type_routemap_cmd
,
426 "redistribute <kernel|connected|static|ospf6|isis|bgp|table> route-map WORD",
428 QUAGGA_REDIST_HELP_STR_RIPNGD
429 "Route map reference\n"
430 "Pointer to route-map entries\n")
432 int idx_protocol
= 1;
436 type
= proto_redistnum(AFI_IP6
, argv
[idx_protocol
]->arg
);
440 vty_out(vty
, "Invalid type %s%s", argv
[idx_protocol
]->arg
, VTY_NEWLINE
);
444 ripng_redistribute_routemap_set (type
, argv
[idx_word
]->arg
);
445 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0,
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",
455 QUAGGA_REDIST_HELP_STR_RIPNGD
458 "Route map reference\n"
459 "Pointer to route-map entries\n")
461 int idx_protocol
= 1;
467 type
= proto_redistnum(AFI_IP6
, argv
[idx_protocol
]->arg
);
468 metric
= atoi (argv
[idx_number
]->arg
);
472 vty_out(vty
, "Invalid type %s%s", argv
[idx_protocol
]->arg
, VTY_NEWLINE
);
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
);
484 ripng_redistribute_write (struct vty
*vty
, int config_mode
)
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
))
494 if (ripng
->route_map
[i
].metric_config
)
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
);
501 vty_out (vty
, " redistribute %s metric %d%s",
502 zebra_route_string(i
), ripng
->route_map
[i
].metric
,
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
,
512 vty_out (vty
, " redistribute %s%s", zebra_route_string(i
),
517 vty_out (vty
, " %s", zebra_route_string(i
));
521 /* RIPng configuration write function. */
523 zebra_config_write (struct vty
*vty
)
525 if (! zclient
->enable
)
527 vty_out (vty
, "no router zebra%s", VTY_NEWLINE
);
530 else if (! vrf_bitmap_check (zclient
->redist
[AFI_IP6
][ZEBRA_ROUTE_RIPNG
], VRF_DEFAULT
))
532 vty_out (vty
, "router zebra%s", VTY_NEWLINE
);
533 vty_out (vty
, " no redistribute ripng%s", VTY_NEWLINE
);
539 /* Zebra node structure. */
540 static struct cmd_node zebra_node
=
543 "%s(config-router)# ",
547 ripng_zebra_connected (struct zclient
*zclient
)
549 zclient_send_reg_requests (zclient
, VRF_DEFAULT
);
552 /* Initialize zebra structure and it's commands. */
554 zebra_init (struct thread_master
*master
)
556 /* Allocate zebra structure. */
557 zclient
= zclient_new(master
);
558 zclient_init (zclient
, ZEBRA_ROUTE_RIPNG
, 0);
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
;
576 /* Install zebra node. */
577 install_node (&zebra_node
, zebra_config_write
);
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
);
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
);