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
->gate
.ipv6
= rinfo
->nexthop
;
61 api_nh
->ifindex
= rinfo
->ifindex
;
62 api_nh
->type
= NEXTHOP_TYPE_IPV6_IFINDEX
;
64 if (cmd
== ZEBRA_ROUTE_ADD
)
65 SET_FLAG(rinfo
->flags
, RIPNG_RTF_FIB
);
67 UNSET_FLAG(rinfo
->flags
, RIPNG_RTF_FIB
);
70 api
.nexthop_num
= count
;
72 rinfo
= listgetdata(listhead(list
));
74 SET_FLAG(api
.message
, ZAPI_MESSAGE_METRIC
);
75 api
.metric
= rinfo
->metric
;
78 SET_FLAG(api
.message
, ZAPI_MESSAGE_TAG
);
82 zclient_route_send(cmd
, zclient
, &api
);
84 if (IS_RIPNG_DEBUG_ZEBRA
) {
86 zlog_debug("%s: %s/%d nexthops %d",
87 (cmd
== ZEBRA_ROUTE_ADD
)
88 ? "Install into zebra"
89 : "Delete from zebra",
90 inet6_ntoa(rp
->p
.u
.prefix6
), rp
->p
.prefixlen
,
95 (cmd
== ZEBRA_ROUTE_ADD
) ? "Install into zebra"
96 : "Delete from zebra",
97 inet6_ntoa(rp
->p
.u
.prefix6
), rp
->p
.prefixlen
);
101 /* Add/update ECMP routes to zebra. */
102 void ripng_zebra_ipv6_add(struct route_node
*rp
)
104 ripng_zebra_ipv6_send(rp
, ZEBRA_ROUTE_ADD
);
107 /* Delete ECMP routes from zebra. */
108 void ripng_zebra_ipv6_delete(struct route_node
*rp
)
110 ripng_zebra_ipv6_send(rp
, ZEBRA_ROUTE_DELETE
);
113 /* Zebra route add and delete treatment. */
114 static int ripng_zebra_read_route(int command
, struct zclient
*zclient
,
115 zebra_size_t length
, vrf_id_t vrf_id
)
117 struct zapi_route api
;
118 struct in6_addr nexthop
;
119 unsigned long ifindex
;
121 if (zapi_route_decode(zclient
->ibuf
, &api
) < 0)
124 /* we completely ignore srcdest routes for now. */
125 if (CHECK_FLAG(api
.message
, ZAPI_MESSAGE_SRCPFX
))
128 nexthop
= api
.nexthops
[0].gate
.ipv6
;
129 ifindex
= api
.nexthops
[0].ifindex
;
131 if (command
== ZEBRA_REDISTRIBUTE_ROUTE_ADD
)
132 ripng_redistribute_add(api
.type
, RIPNG_ROUTE_REDISTRIBUTE
,
133 (struct prefix_ipv6
*)&api
.prefix
,
134 ifindex
, &nexthop
, api
.tag
);
136 ripng_redistribute_delete(api
.type
, RIPNG_ROUTE_REDISTRIBUTE
,
137 (struct prefix_ipv6
*)&api
.prefix
,
143 void ripng_zclient_reset(void)
145 zclient_reset(zclient
);
148 static int ripng_redistribute_unset(int type
)
151 if (!vrf_bitmap_check(zclient
->redist
[AFI_IP6
][type
], VRF_DEFAULT
))
154 vrf_bitmap_set(zclient
->redist
[AFI_IP6
][type
], VRF_DEFAULT
);
156 if (zclient
->sock
> 0)
157 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE
, zclient
,
158 AFI_IP6
, type
, 0, VRF_DEFAULT
);
160 ripng_redistribute_withdraw(type
);
165 int ripng_redistribute_check(int type
)
167 return vrf_bitmap_check(zclient
->redist
[AFI_IP6
][type
], VRF_DEFAULT
);
170 static void ripng_redistribute_metric_set(int type
, int metric
)
172 ripng
->route_map
[type
].metric_config
= 1;
173 ripng
->route_map
[type
].metric
= metric
;
176 static int ripng_redistribute_metric_unset(int type
)
178 ripng
->route_map
[type
].metric_config
= 0;
179 ripng
->route_map
[type
].metric
= 0;
183 static void ripng_redistribute_routemap_set(int type
, const char *name
)
185 if (ripng
->route_map
[type
].name
)
186 free(ripng
->route_map
[type
].name
);
188 ripng
->route_map
[type
].name
= strdup(name
);
189 ripng
->route_map
[type
].map
= route_map_lookup_by_name(name
);
192 static void ripng_redistribute_routemap_unset(int type
)
194 if (ripng
->route_map
[type
].name
)
195 free(ripng
->route_map
[type
].name
);
197 ripng
->route_map
[type
].name
= NULL
;
198 ripng
->route_map
[type
].map
= NULL
;
201 /* Redistribution types */
206 } redist_type
[] = {{ZEBRA_ROUTE_KERNEL
, 1, "kernel"},
207 {ZEBRA_ROUTE_CONNECT
, 1, "connected"},
208 {ZEBRA_ROUTE_STATIC
, 1, "static"},
209 {ZEBRA_ROUTE_OSPF6
, 1, "ospf6"},
210 {ZEBRA_ROUTE_BGP
, 2, "bgp"},
211 {ZEBRA_ROUTE_VNC
, 1, "vnc"},
214 void ripng_redistribute_clean()
218 for (i
= 0; redist_type
[i
].str
; i
++) {
219 if (vrf_bitmap_check(
220 zclient
->redist
[AFI_IP6
][redist_type
[i
].type
],
222 if (zclient
->sock
> 0)
223 zebra_redistribute_send(
224 ZEBRA_REDISTRIBUTE_DELETE
, zclient
,
225 AFI_IP6
, redist_type
[i
].type
, 0,
229 zclient
->redist
[AFI_IP6
][redist_type
[i
].type
],
232 /* Remove the routes from RIPng table. */
233 ripng_redistribute_withdraw(redist_type
[i
].type
);
238 DEFUN (ripng_redistribute_type
,
239 ripng_redistribute_type_cmd
,
240 "redistribute " FRR_REDIST_STR_RIPNGD
,
242 FRR_REDIST_HELP_STR_RIPNGD
)
246 char *proto
= argv
[argc
- 1]->text
;
247 type
= proto_redistnum(AFI_IP6
, proto
);
250 vty_out(vty
, "Invalid type %s\n", proto
);
251 return CMD_WARNING_CONFIG_FAILED
;
254 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0,
259 DEFUN (no_ripng_redistribute_type
,
260 no_ripng_redistribute_type_cmd
,
261 "no redistribute " FRR_REDIST_STR_RIPNGD
" [metric (0-16)] [route-map WORD]",
264 FRR_REDIST_HELP_STR_RIPNGD
267 "Route map reference\n"
268 "Pointer to route-map entries\n")
272 char *proto
= argv
[2]->text
;
273 type
= proto_redistnum(AFI_IP6
, proto
);
276 vty_out(vty
, "Invalid type %s\n", proto
);
277 return CMD_WARNING_CONFIG_FAILED
;
280 ripng_redistribute_metric_unset(type
);
281 ripng_redistribute_routemap_unset(type
);
282 return ripng_redistribute_unset(type
);
286 DEFUN (ripng_redistribute_type_metric
,
287 ripng_redistribute_type_metric_cmd
,
288 "redistribute " FRR_REDIST_STR_RIPNGD
" metric (0-16)",
290 FRR_REDIST_HELP_STR_RIPNGD
294 int idx_protocol
= 1;
299 metric
= atoi(argv
[idx_number
]->arg
);
300 type
= proto_redistnum(AFI_IP6
, argv
[idx_protocol
]->text
);
303 vty_out(vty
, "Invalid type %s\n", argv
[idx_protocol
]->text
);
304 return CMD_WARNING_CONFIG_FAILED
;
307 ripng_redistribute_metric_set(type
, metric
);
308 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0,
313 DEFUN (ripng_redistribute_type_routemap
,
314 ripng_redistribute_type_routemap_cmd
,
315 "redistribute " FRR_REDIST_STR_RIPNGD
" route-map WORD",
317 FRR_REDIST_HELP_STR_RIPNGD
318 "Route map reference\n"
319 "Pointer to route-map entries\n")
321 int idx_protocol
= 1;
325 type
= proto_redistnum(AFI_IP6
, argv
[idx_protocol
]->text
);
328 vty_out(vty
, "Invalid type %s\n", argv
[idx_protocol
]->text
);
329 return CMD_WARNING_CONFIG_FAILED
;
332 ripng_redistribute_routemap_set(type
, argv
[idx_word
]->text
);
333 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0,
338 DEFUN (ripng_redistribute_type_metric_routemap
,
339 ripng_redistribute_type_metric_routemap_cmd
,
340 "redistribute " FRR_REDIST_STR_RIPNGD
" metric (0-16) route-map WORD",
342 FRR_REDIST_HELP_STR_RIPNGD
345 "Route map reference\n"
346 "Pointer to route-map entries\n")
348 int idx_protocol
= 1;
354 type
= proto_redistnum(AFI_IP6
, argv
[idx_protocol
]->text
);
355 metric
= atoi(argv
[idx_number
]->arg
);
358 vty_out(vty
, "Invalid type %s\n", argv
[idx_protocol
]->text
);
359 return CMD_WARNING_CONFIG_FAILED
;
362 ripng_redistribute_metric_set(type
, metric
);
363 ripng_redistribute_routemap_set(type
, argv
[idx_word
]->text
);
364 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0,
369 void ripng_redistribute_write(struct vty
*vty
, int config_mode
)
373 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
374 if (i
== zclient
->redist_default
375 || !vrf_bitmap_check(zclient
->redist
[AFI_IP6
][i
],
380 vty_out(vty
, " %s", zebra_route_string(i
));
384 if (ripng
->route_map
[i
].metric_config
) {
385 if (ripng
->route_map
[i
].name
)
387 " redistribute %s metric %d route-map %s\n",
388 zebra_route_string(i
),
389 ripng
->route_map
[i
].metric
,
390 ripng
->route_map
[i
].name
);
392 vty_out(vty
, " redistribute %s metric %d\n",
393 zebra_route_string(i
),
394 ripng
->route_map
[i
].metric
);
396 if (ripng
->route_map
[i
].name
)
397 vty_out(vty
, " redistribute %s route-map %s\n",
398 zebra_route_string(i
),
399 ripng
->route_map
[i
].name
);
401 vty_out(vty
, " redistribute %s\n",
402 zebra_route_string(i
));
407 static void ripng_zebra_connected(struct zclient
*zclient
)
409 zclient_send_reg_requests(zclient
, VRF_DEFAULT
);
412 /* Initialize zebra structure and it's commands. */
413 void zebra_init(struct thread_master
*master
)
415 /* Allocate zebra structure. */
416 zclient
= zclient_new_notify(master
, &zclient_options_default
);
417 zclient_init(zclient
, ZEBRA_ROUTE_RIPNG
, 0, &ripngd_privs
);
419 zclient
->zebra_connected
= ripng_zebra_connected
;
420 zclient
->interface_up
= ripng_interface_up
;
421 zclient
->interface_down
= ripng_interface_down
;
422 zclient
->interface_add
= ripng_interface_add
;
423 zclient
->interface_delete
= ripng_interface_delete
;
424 zclient
->interface_address_add
= ripng_interface_address_add
;
425 zclient
->interface_address_delete
= ripng_interface_address_delete
;
426 zclient
->redistribute_route_add
= ripng_zebra_read_route
;
427 zclient
->redistribute_route_del
= ripng_zebra_read_route
;
429 /* Install command elements to ripng node */
430 install_element(RIPNG_NODE
, &ripng_redistribute_type_cmd
);
431 install_element(RIPNG_NODE
, &ripng_redistribute_type_routemap_cmd
);
432 install_element(RIPNG_NODE
, &ripng_redistribute_type_metric_cmd
);
433 install_element(RIPNG_NODE
,
434 &ripng_redistribute_type_metric_routemap_cmd
);
435 install_element(RIPNG_NODE
, &no_ripng_redistribute_type_cmd
);
438 void ripng_zebra_stop(void)
440 zclient_stop(zclient
);
441 zclient_free(zclient
);