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. */
40 static void ripng_zebra_ipv6_send(struct route_node
*rp
, u_char cmd
)
42 struct list
*list
= (struct list
*)rp
->info
;
43 struct zapi_route api
;
44 struct zapi_nexthop
*api_nh
;
45 struct listnode
*listnode
= NULL
;
46 struct ripng_info
*rinfo
= NULL
;
49 memset(&api
, 0, sizeof(api
));
50 api
.vrf_id
= VRF_DEFAULT
;
51 api
.type
= ZEBRA_ROUTE_RIPNG
;
52 api
.safi
= SAFI_UNICAST
;
55 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
56 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
57 if (count
>= MULTIPATH_NUM
)
59 api_nh
= &api
.nexthops
[count
];
60 api_nh
->vrf_id
= VRF_DEFAULT
;
61 api_nh
->gate
.ipv6
= rinfo
->nexthop
;
62 api_nh
->ifindex
= rinfo
->ifindex
;
63 api_nh
->type
= NEXTHOP_TYPE_IPV6_IFINDEX
;
65 if (cmd
== ZEBRA_ROUTE_ADD
)
66 SET_FLAG(rinfo
->flags
, RIPNG_RTF_FIB
);
68 UNSET_FLAG(rinfo
->flags
, RIPNG_RTF_FIB
);
71 api
.nexthop_num
= count
;
73 rinfo
= listgetdata(listhead(list
));
75 SET_FLAG(api
.message
, ZAPI_MESSAGE_METRIC
);
76 api
.metric
= rinfo
->metric
;
79 SET_FLAG(api
.message
, ZAPI_MESSAGE_TAG
);
83 zclient_route_send(cmd
, zclient
, &api
);
85 if (IS_RIPNG_DEBUG_ZEBRA
) {
87 zlog_debug("%s: %s/%d nexthops %d",
88 (cmd
== ZEBRA_ROUTE_ADD
)
89 ? "Install into zebra"
90 : "Delete from zebra",
91 inet6_ntoa(rp
->p
.u
.prefix6
), rp
->p
.prefixlen
,
96 (cmd
== ZEBRA_ROUTE_ADD
) ? "Install into zebra"
97 : "Delete from zebra",
98 inet6_ntoa(rp
->p
.u
.prefix6
), rp
->p
.prefixlen
);
102 /* Add/update ECMP routes to zebra. */
103 void ripng_zebra_ipv6_add(struct route_node
*rp
)
105 ripng_zebra_ipv6_send(rp
, ZEBRA_ROUTE_ADD
);
108 /* Delete ECMP routes from zebra. */
109 void ripng_zebra_ipv6_delete(struct route_node
*rp
)
111 ripng_zebra_ipv6_send(rp
, ZEBRA_ROUTE_DELETE
);
114 /* Zebra route add and delete treatment. */
115 static int ripng_zebra_read_route(int command
, struct zclient
*zclient
,
116 zebra_size_t length
, vrf_id_t vrf_id
)
118 struct zapi_route api
;
119 struct in6_addr nexthop
;
120 unsigned long ifindex
;
122 if (zapi_route_decode(zclient
->ibuf
, &api
) < 0)
125 /* we completely ignore srcdest routes for now. */
126 if (CHECK_FLAG(api
.message
, ZAPI_MESSAGE_SRCPFX
))
129 nexthop
= api
.nexthops
[0].gate
.ipv6
;
130 ifindex
= api
.nexthops
[0].ifindex
;
132 if (command
== ZEBRA_REDISTRIBUTE_ROUTE_ADD
)
133 ripng_redistribute_add(api
.type
, RIPNG_ROUTE_REDISTRIBUTE
,
134 (struct prefix_ipv6
*)&api
.prefix
,
135 ifindex
, &nexthop
, api
.tag
);
137 ripng_redistribute_delete(api
.type
, RIPNG_ROUTE_REDISTRIBUTE
,
138 (struct prefix_ipv6
*)&api
.prefix
,
144 void ripng_zclient_reset(void)
146 zclient_reset(zclient
);
149 static int ripng_redistribute_unset(int type
)
152 if (!vrf_bitmap_check(zclient
->redist
[AFI_IP6
][type
], VRF_DEFAULT
))
155 vrf_bitmap_set(zclient
->redist
[AFI_IP6
][type
], VRF_DEFAULT
);
157 if (zclient
->sock
> 0)
158 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE
, zclient
,
159 AFI_IP6
, type
, 0, VRF_DEFAULT
);
161 ripng_redistribute_withdraw(type
);
166 int ripng_redistribute_check(int type
)
168 return vrf_bitmap_check(zclient
->redist
[AFI_IP6
][type
], VRF_DEFAULT
);
171 static void ripng_redistribute_metric_set(int type
, int metric
)
173 ripng
->route_map
[type
].metric_config
= 1;
174 ripng
->route_map
[type
].metric
= metric
;
177 static int ripng_redistribute_metric_unset(int type
)
179 ripng
->route_map
[type
].metric_config
= 0;
180 ripng
->route_map
[type
].metric
= 0;
184 static void ripng_redistribute_routemap_set(int type
, const char *name
)
186 if (ripng
->route_map
[type
].name
)
187 free(ripng
->route_map
[type
].name
);
189 ripng
->route_map
[type
].name
= strdup(name
);
190 ripng
->route_map
[type
].map
= route_map_lookup_by_name(name
);
193 static void ripng_redistribute_routemap_unset(int type
)
195 if (ripng
->route_map
[type
].name
)
196 free(ripng
->route_map
[type
].name
);
198 ripng
->route_map
[type
].name
= NULL
;
199 ripng
->route_map
[type
].map
= NULL
;
202 /* Redistribution types */
207 } redist_type
[] = {{ZEBRA_ROUTE_KERNEL
, 1, "kernel"},
208 {ZEBRA_ROUTE_CONNECT
, 1, "connected"},
209 {ZEBRA_ROUTE_STATIC
, 1, "static"},
210 {ZEBRA_ROUTE_OSPF6
, 1, "ospf6"},
211 {ZEBRA_ROUTE_BGP
, 2, "bgp"},
212 {ZEBRA_ROUTE_VNC
, 1, "vnc"},
215 void ripng_redistribute_clean()
219 for (i
= 0; redist_type
[i
].str
; i
++) {
220 if (vrf_bitmap_check(
221 zclient
->redist
[AFI_IP6
][redist_type
[i
].type
],
223 if (zclient
->sock
> 0)
224 zebra_redistribute_send(
225 ZEBRA_REDISTRIBUTE_DELETE
, zclient
,
226 AFI_IP6
, redist_type
[i
].type
, 0,
230 zclient
->redist
[AFI_IP6
][redist_type
[i
].type
],
233 /* Remove the routes from RIPng table. */
234 ripng_redistribute_withdraw(redist_type
[i
].type
);
239 DEFUN (ripng_redistribute_type
,
240 ripng_redistribute_type_cmd
,
241 "redistribute " FRR_REDIST_STR_RIPNGD
,
243 FRR_REDIST_HELP_STR_RIPNGD
)
247 char *proto
= argv
[argc
- 1]->text
;
248 type
= proto_redistnum(AFI_IP6
, proto
);
251 vty_out(vty
, "Invalid type %s\n", proto
);
252 return CMD_WARNING_CONFIG_FAILED
;
255 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0,
260 DEFUN (no_ripng_redistribute_type
,
261 no_ripng_redistribute_type_cmd
,
262 "no redistribute " FRR_REDIST_STR_RIPNGD
" [metric (0-16)] [route-map WORD]",
265 FRR_REDIST_HELP_STR_RIPNGD
268 "Route map reference\n"
269 "Pointer to route-map entries\n")
273 char *proto
= argv
[2]->text
;
274 type
= proto_redistnum(AFI_IP6
, proto
);
277 vty_out(vty
, "Invalid type %s\n", proto
);
278 return CMD_WARNING_CONFIG_FAILED
;
281 ripng_redistribute_metric_unset(type
);
282 ripng_redistribute_routemap_unset(type
);
283 return ripng_redistribute_unset(type
);
287 DEFUN (ripng_redistribute_type_metric
,
288 ripng_redistribute_type_metric_cmd
,
289 "redistribute " FRR_REDIST_STR_RIPNGD
" metric (0-16)",
291 FRR_REDIST_HELP_STR_RIPNGD
295 int idx_protocol
= 1;
300 metric
= atoi(argv
[idx_number
]->arg
);
301 type
= proto_redistnum(AFI_IP6
, argv
[idx_protocol
]->text
);
304 vty_out(vty
, "Invalid type %s\n", argv
[idx_protocol
]->text
);
305 return CMD_WARNING_CONFIG_FAILED
;
308 ripng_redistribute_metric_set(type
, metric
);
309 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0,
314 DEFUN (ripng_redistribute_type_routemap
,
315 ripng_redistribute_type_routemap_cmd
,
316 "redistribute " FRR_REDIST_STR_RIPNGD
" route-map WORD",
318 FRR_REDIST_HELP_STR_RIPNGD
319 "Route map reference\n"
320 "Pointer to route-map entries\n")
322 int idx_protocol
= 1;
326 type
= proto_redistnum(AFI_IP6
, argv
[idx_protocol
]->text
);
329 vty_out(vty
, "Invalid type %s\n", argv
[idx_protocol
]->text
);
330 return CMD_WARNING_CONFIG_FAILED
;
333 ripng_redistribute_routemap_set(type
, argv
[idx_word
]->text
);
334 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0,
339 DEFUN (ripng_redistribute_type_metric_routemap
,
340 ripng_redistribute_type_metric_routemap_cmd
,
341 "redistribute " FRR_REDIST_STR_RIPNGD
" metric (0-16) route-map WORD",
343 FRR_REDIST_HELP_STR_RIPNGD
346 "Route map reference\n"
347 "Pointer to route-map entries\n")
349 int idx_protocol
= 1;
355 type
= proto_redistnum(AFI_IP6
, argv
[idx_protocol
]->text
);
356 metric
= atoi(argv
[idx_number
]->arg
);
359 vty_out(vty
, "Invalid type %s\n", argv
[idx_protocol
]->text
);
360 return CMD_WARNING_CONFIG_FAILED
;
363 ripng_redistribute_metric_set(type
, metric
);
364 ripng_redistribute_routemap_set(type
, argv
[idx_word
]->text
);
365 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0,
370 void ripng_redistribute_write(struct vty
*vty
, int config_mode
)
374 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
375 if (i
== zclient
->redist_default
376 || !vrf_bitmap_check(zclient
->redist
[AFI_IP6
][i
],
381 vty_out(vty
, " %s", zebra_route_string(i
));
385 if (ripng
->route_map
[i
].metric_config
) {
386 if (ripng
->route_map
[i
].name
)
388 " redistribute %s metric %d route-map %s\n",
389 zebra_route_string(i
),
390 ripng
->route_map
[i
].metric
,
391 ripng
->route_map
[i
].name
);
393 vty_out(vty
, " redistribute %s metric %d\n",
394 zebra_route_string(i
),
395 ripng
->route_map
[i
].metric
);
397 if (ripng
->route_map
[i
].name
)
398 vty_out(vty
, " redistribute %s route-map %s\n",
399 zebra_route_string(i
),
400 ripng
->route_map
[i
].name
);
402 vty_out(vty
, " redistribute %s\n",
403 zebra_route_string(i
));
408 static void ripng_zebra_connected(struct zclient
*zclient
)
410 zclient_send_reg_requests(zclient
, VRF_DEFAULT
);
413 /* Initialize zebra structure and it's commands. */
414 void zebra_init(struct thread_master
*master
)
416 /* Allocate zebra structure. */
417 zclient
= zclient_new_notify(master
, &zclient_options_default
);
418 zclient_init(zclient
, ZEBRA_ROUTE_RIPNG
, 0, &ripngd_privs
);
420 zclient
->zebra_connected
= ripng_zebra_connected
;
421 zclient
->interface_up
= ripng_interface_up
;
422 zclient
->interface_down
= ripng_interface_down
;
423 zclient
->interface_add
= ripng_interface_add
;
424 zclient
->interface_delete
= ripng_interface_delete
;
425 zclient
->interface_address_add
= ripng_interface_address_add
;
426 zclient
->interface_address_delete
= ripng_interface_address_delete
;
427 zclient
->redistribute_route_add
= ripng_zebra_read_route
;
428 zclient
->redistribute_route_del
= ripng_zebra_read_route
;
430 /* Install command elements to ripng node */
431 install_element(RIPNG_NODE
, &ripng_redistribute_type_cmd
);
432 install_element(RIPNG_NODE
, &ripng_redistribute_type_routemap_cmd
);
433 install_element(RIPNG_NODE
, &ripng_redistribute_type_metric_cmd
);
434 install_element(RIPNG_NODE
,
435 &ripng_redistribute_type_metric_routemap_cmd
);
436 install_element(RIPNG_NODE
, &no_ripng_redistribute_type_cmd
);
439 void ripng_zebra_stop(void)
441 zclient_stop(zclient
);
442 zclient_free(zclient
);