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 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
33 #include "ripngd/ripngd.h"
34 #include "ripngd/ripng_debug.h"
36 /* All information about zebra. */
37 struct zclient
*zclient
= NULL
;
39 /* Send ECMP routes to zebra. */
41 ripng_zebra_ipv6_send (struct route_node
*rp
, u_char cmd
)
43 static struct in6_addr
**nexthops
= NULL
;
44 static ifindex_t
*ifindexes
= NULL
;
45 static unsigned int nexthops_len
= 0;
47 struct list
*list
= (struct list
*)rp
->info
;
49 struct listnode
*listnode
= NULL
;
50 struct ripng_info
*rinfo
= NULL
;
53 if (vrf_bitmap_check (zclient
->redist
[AFI_IP6
][ZEBRA_ROUTE_RIPNG
], VRF_DEFAULT
))
55 api
.vrf_id
= VRF_DEFAULT
;
56 api
.type
= ZEBRA_ROUTE_RIPNG
;
60 api
.safi
= SAFI_UNICAST
;
62 if (nexthops_len
< listcount (list
))
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));
71 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
72 SET_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
);
73 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
75 nexthops
[count
] = &rinfo
->nexthop
;
76 ifindexes
[count
] = rinfo
->ifindex
;
78 if (cmd
== ZEBRA_IPV6_ROUTE_ADD
)
79 SET_FLAG (rinfo
->flags
, RIPNG_RTF_FIB
);
81 UNSET_FLAG (rinfo
->flags
, RIPNG_RTF_FIB
);
84 api
.nexthop
= nexthops
;
85 api
.nexthop_num
= count
;
86 api
.ifindex
= ifindexes
;
87 api
.ifindex_num
= count
;
89 rinfo
= listgetdata (listhead (list
));
91 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
92 api
.metric
= rinfo
->metric
;
96 SET_FLAG (api
.message
, ZAPI_MESSAGE_TAG
);
100 zapi_ipv6_route (cmd
, zclient
,
101 (struct prefix_ipv6
*)&rp
->p
, NULL
, &api
);
103 if (IS_RIPNG_DEBUG_ZEBRA
)
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
);
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
);
119 /* Add/update ECMP routes to zebra. */
121 ripng_zebra_ipv6_add (struct route_node
*rp
)
123 ripng_zebra_ipv6_send (rp
, ZEBRA_IPV6_ROUTE_ADD
);
126 /* Delete ECMP routes from zebra. */
128 ripng_zebra_ipv6_delete (struct route_node
*rp
)
130 ripng_zebra_ipv6_send (rp
, ZEBRA_IPV6_ROUTE_DELETE
);
133 /* Zebra route add and delete treatment. */
135 ripng_zebra_read_ipv6 (int command
, struct zclient
*zclient
,
136 zebra_size_t length
, vrf_id_t vrf_id
)
139 struct zapi_ipv6 api
;
140 unsigned long ifindex
;
141 struct in6_addr nexthop
;
142 struct prefix_ipv6 p
, src_p
;
146 memset (&nexthop
, 0, sizeof (struct in6_addr
));
148 /* Type, flags, message. */
149 api
.type
= stream_getc (s
);
150 api
.instance
= stream_getw (s
);
151 api
.flags
= stream_getl (s
);
152 api
.message
= stream_getc (s
);
155 memset (&p
, 0, sizeof (struct prefix_ipv6
));
157 p
.prefixlen
= MIN(IPV6_MAX_PREFIXLEN
, stream_getc (s
));
158 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
160 memset (&src_p
, 0, sizeof (struct prefix_ipv6
));
161 src_p
.family
= AF_INET6
;
162 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_SRCPFX
))
164 src_p
.prefixlen
= stream_getc (s
);
165 stream_get (&src_p
.prefix
, s
, PSIZE (src_p
.prefixlen
));
169 /* we completely ignore srcdest routes for now. */
172 /* Nexthop, ifindex, distance, metric. */
173 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
175 api
.nexthop_num
= stream_getc (s
);
176 stream_get (&nexthop
, s
, 16);
178 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
180 api
.ifindex_num
= stream_getc (s
);
181 ifindex
= stream_getl (s
);
183 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
184 api
.distance
= stream_getc (s
);
187 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
188 api
.metric
= stream_getl (s
);
192 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_TAG
))
193 api
.tag
= stream_getl (s
);
197 if (command
== ZEBRA_REDISTRIBUTE_IPV6_ADD
)
198 ripng_redistribute_add (api
.type
, RIPNG_ROUTE_REDISTRIBUTE
, &p
, ifindex
, &nexthop
, api
.tag
);
200 ripng_redistribute_delete (api
.type
, RIPNG_ROUTE_REDISTRIBUTE
, &p
, ifindex
);
206 ripng_zclient_reset (void)
208 zclient_reset (zclient
);
212 ripng_redistribute_unset (int type
)
215 if (! vrf_bitmap_check (zclient
->redist
[AFI_IP6
][type
], VRF_DEFAULT
))
218 vrf_bitmap_set (zclient
->redist
[AFI_IP6
][type
], VRF_DEFAULT
);
220 if (zclient
->sock
> 0)
221 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, AFI_IP6
, type
, 0, VRF_DEFAULT
);
223 ripng_redistribute_withdraw (type
);
229 ripng_redistribute_check (int type
)
231 return vrf_bitmap_check (zclient
->redist
[AFI_IP6
][type
], VRF_DEFAULT
);
235 ripng_redistribute_metric_set (int type
, int metric
)
237 ripng
->route_map
[type
].metric_config
= 1;
238 ripng
->route_map
[type
].metric
= metric
;
242 ripng_redistribute_metric_unset (int type
)
244 ripng
->route_map
[type
].metric_config
= 0;
245 ripng
->route_map
[type
].metric
= 0;
250 ripng_redistribute_routemap_set (int type
, const char *name
)
252 if (ripng
->route_map
[type
].name
)
253 free (ripng
->route_map
[type
].name
);
255 ripng
->route_map
[type
].name
= strdup (name
);
256 ripng
->route_map
[type
].map
= route_map_lookup_by_name (name
);
260 ripng_redistribute_routemap_unset (int type
)
262 if (ripng
->route_map
[type
].name
)
263 free (ripng
->route_map
[type
].name
);
265 ripng
->route_map
[type
].name
= NULL
;
266 ripng
->route_map
[type
].map
= NULL
;
269 /* Redistribution types */
275 {ZEBRA_ROUTE_KERNEL
, 1, "kernel"},
276 {ZEBRA_ROUTE_CONNECT
, 1, "connected"},
277 {ZEBRA_ROUTE_STATIC
, 1, "static"},
278 {ZEBRA_ROUTE_OSPF6
, 1, "ospf6"},
279 {ZEBRA_ROUTE_BGP
, 2, "bgp"},
280 {ZEBRA_ROUTE_VNC
, 1, "vnc"},
285 ripng_redistribute_clean ()
289 for (i
= 0; redist_type
[i
].str
; i
++)
291 if (vrf_bitmap_check (zclient
->redist
[AFI_IP6
][redist_type
[i
].type
], VRF_DEFAULT
))
293 if (zclient
->sock
> 0)
294 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
,
295 zclient
, AFI_IP6
, redist_type
[i
].type
, 0,
298 vrf_bitmap_unset (zclient
->redist
[AFI_IP6
][redist_type
[i
].type
], VRF_DEFAULT
);
300 /* Remove the routes from RIPng table. */
301 ripng_redistribute_withdraw (redist_type
[i
].type
);
306 DEFUN (ripng_redistribute_ripng
,
307 ripng_redistribute_ripng_cmd
,
308 "redistribute ripng",
309 "Redistribute information from another routing protocol\n"
312 vrf_bitmap_set (zclient
->redist
[AFI_IP6
][ZEBRA_ROUTE_RIPNG
], VRF_DEFAULT
);
316 DEFUN (no_ripng_redistribute_ripng
,
317 no_ripng_redistribute_ripng_cmd
,
318 "no redistribute ripng",
320 "Redistribute information from another routing protocol\n"
323 vrf_bitmap_unset (zclient
->redist
[AFI_IP6
][ZEBRA_ROUTE_RIPNG
], VRF_DEFAULT
);
327 DEFUN (ripng_redistribute_type
,
328 ripng_redistribute_type_cmd
,
329 "redistribute " FRR_REDIST_STR_RIPNGD
,
331 FRR_REDIST_HELP_STR_RIPNGD
)
335 char *proto
= argv
[argc
- 1]->text
;
336 type
= proto_redistnum(AFI_IP6
, proto
);
340 vty_out(vty
, "Invalid type %s%s", proto
, 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 " FRR_REDIST_STR_RIPNGD
" [metric (0-16)] [route-map WORD]",
353 FRR_REDIST_HELP_STR_RIPNGD
356 "Route map reference\n"
357 "Pointer to route-map entries\n")
361 char *proto
= argv
[2]->text
;
362 type
= proto_redistnum(AFI_IP6
, proto
);
366 vty_out(vty
, "Invalid type %s%s", proto
, VTY_NEWLINE
);
370 ripng_redistribute_metric_unset (type
);
371 ripng_redistribute_routemap_unset (type
);
372 return ripng_redistribute_unset (type
);
376 DEFUN (ripng_redistribute_type_metric
,
377 ripng_redistribute_type_metric_cmd
,
378 "redistribute " FRR_REDIST_STR_RIPNGD
" metric (0-16)",
380 FRR_REDIST_HELP_STR_RIPNGD
384 int idx_protocol
= 1;
389 metric
= atoi (argv
[idx_number
]->arg
);
390 type
= proto_redistnum(AFI_IP6
, argv
[idx_protocol
]->text
);
394 vty_out(vty
, "Invalid type %s%s", argv
[idx_protocol
]->text
, VTY_NEWLINE
);
398 ripng_redistribute_metric_set (type
, metric
);
399 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0,
404 DEFUN (ripng_redistribute_type_routemap
,
405 ripng_redistribute_type_routemap_cmd
,
406 "redistribute " FRR_REDIST_STR_RIPNGD
" route-map WORD",
408 FRR_REDIST_HELP_STR_RIPNGD
409 "Route map reference\n"
410 "Pointer to route-map entries\n")
412 int idx_protocol
= 1;
416 type
= proto_redistnum(AFI_IP6
, argv
[idx_protocol
]->text
);
420 vty_out(vty
, "Invalid type %s%s", argv
[idx_protocol
]->text
, VTY_NEWLINE
);
424 ripng_redistribute_routemap_set (type
, argv
[idx_word
]->text
);
425 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0,
430 DEFUN (ripng_redistribute_type_metric_routemap
,
431 ripng_redistribute_type_metric_routemap_cmd
,
432 "redistribute " FRR_REDIST_STR_RIPNGD
" metric (0-16) route-map WORD",
434 FRR_REDIST_HELP_STR_RIPNGD
437 "Route map reference\n"
438 "Pointer to route-map entries\n")
440 int idx_protocol
= 1;
446 type
= proto_redistnum(AFI_IP6
, argv
[idx_protocol
]->text
);
447 metric
= atoi (argv
[idx_number
]->arg
);
451 vty_out(vty
, "Invalid type %s%s", argv
[idx_protocol
]->text
, VTY_NEWLINE
);
455 ripng_redistribute_metric_set (type
, metric
);
456 ripng_redistribute_routemap_set (type
, argv
[idx_word
]->text
);
457 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0, VRF_DEFAULT
);
462 ripng_redistribute_write (struct vty
*vty
, int config_mode
)
466 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
467 if (i
!= zclient
->redist_default
&&
468 vrf_bitmap_check (zclient
->redist
[AFI_IP6
][i
], VRF_DEFAULT
))
472 if (ripng
->route_map
[i
].metric_config
)
474 if (ripng
->route_map
[i
].name
)
475 vty_out (vty
, " redistribute %s metric %d route-map %s%s",
476 zebra_route_string(i
), ripng
->route_map
[i
].metric
,
477 ripng
->route_map
[i
].name
, VTY_NEWLINE
);
479 vty_out (vty
, " redistribute %s metric %d%s",
480 zebra_route_string(i
), ripng
->route_map
[i
].metric
,
485 if (ripng
->route_map
[i
].name
)
486 vty_out (vty
, " redistribute %s route-map %s%s",
487 zebra_route_string(i
), ripng
->route_map
[i
].name
,
490 vty_out (vty
, " redistribute %s%s", zebra_route_string(i
),
495 vty_out (vty
, " %s", zebra_route_string(i
));
499 /* RIPng configuration write function. */
501 zebra_config_write (struct vty
*vty
)
503 if (! zclient
->enable
)
505 vty_out (vty
, "no router zebra%s", VTY_NEWLINE
);
508 else if (! vrf_bitmap_check (zclient
->redist
[AFI_IP6
][ZEBRA_ROUTE_RIPNG
], VRF_DEFAULT
))
510 vty_out (vty
, "router zebra%s", VTY_NEWLINE
);
511 vty_out (vty
, " no redistribute ripng%s", VTY_NEWLINE
);
517 /* Zebra node structure. */
518 static struct cmd_node zebra_node
=
521 "%s(config-router)# ",
525 ripng_zebra_connected (struct zclient
*zclient
)
527 zclient_send_reg_requests (zclient
, VRF_DEFAULT
);
530 /* Initialize zebra structure and it's commands. */
532 zebra_init (struct thread_master
*master
)
534 /* Allocate zebra structure. */
535 zclient
= zclient_new(master
);
536 zclient_init (zclient
, ZEBRA_ROUTE_RIPNG
, 0);
538 zclient
->zebra_connected
= ripng_zebra_connected
;
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
;
545 zclient
->redistribute_route_ipv6_add
= ripng_zebra_read_ipv6
;
546 zclient
->redistribute_route_ipv6_del
= ripng_zebra_read_ipv6
;
548 /* Install zebra node. */
549 install_node (&zebra_node
, zebra_config_write
);
551 /* Install command element for zebra node. */
552 install_default (ZEBRA_NODE
);
553 install_element (ZEBRA_NODE
, &ripng_redistribute_ripng_cmd
);
554 install_element (ZEBRA_NODE
, &no_ripng_redistribute_ripng_cmd
);
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
);