2 Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30 #include "babel_zebra.h"
31 #include "babel_interface.h"
35 void babelz_zebra_init(void);
38 /* we must use a pointer because of zclient.c's functions (new, free). */
39 struct zclient
*zclient
;
40 static int zebra_config_write (struct vty
*vty
);
48 {BABEL_DEBUG_COMMON
, 1, "common"},
49 {BABEL_DEBUG_KERNEL
, 1, "kernel"},
50 {BABEL_DEBUG_FILTER
, 1, "filter"},
51 {BABEL_DEBUG_TIMEOUT
, 1, "timeout"},
52 {BABEL_DEBUG_IF
, 1, "interface"},
53 {BABEL_DEBUG_ROUTE
, 1, "route"},
54 {BABEL_DEBUG_ALL
, 1, "all"},
61 } proto_redistnum_type
[ZEBRA_ROUTE_MAX
] = {
62 [ZEBRA_ROUTE_BABEL
] = {2, "babel"},
63 [ZEBRA_ROUTE_BGP
] = {2, "bgp"},
64 [ZEBRA_ROUTE_CONNECT
] = {1, "connected"},
65 [ZEBRA_ROUTE_HSLS
] = {1, "hsls"},
66 [ZEBRA_ROUTE_ISIS
] = {1, "isis"},
67 [ZEBRA_ROUTE_KERNEL
] = {1, "kernel"},
68 [ZEBRA_ROUTE_OLSR
] = {2, "olsr"},
69 [ZEBRA_ROUTE_OSPF
] = {2, "ospf"},
70 [ZEBRA_ROUTE_OSPF6
] = {5, "ospf6"},
71 [ZEBRA_ROUTE_RIP
] = {1, "rip"},
72 [ZEBRA_ROUTE_RIPNG
] = {4, "ripng"},
73 [ZEBRA_ROUTE_STATIC
] = {2, "static"},
74 [ZEBRA_ROUTE_SYSTEM
] = {2, "system"},
77 /* Zebra node structure. */
78 struct cmd_node zebra_node
=
81 "%s(config-router)# ",
86 /* Zebra route add and delete treatment (ipv6). */
88 babel_zebra_read_ipv6 (int command
, struct zclient
*zclient
,
89 zebra_size_t length
, vrf_id_t vrf
)
93 unsigned long ifindex
= -1;
94 struct in6_addr nexthop
;
95 struct prefix_ipv6 prefix
;
99 memset (&nexthop
, 0, sizeof (struct in6_addr
));
100 memset (&api
, 0, sizeof(struct zapi_ipv6
));
101 memset (&prefix
, 0, sizeof (struct prefix_ipv6
));
103 /* Type, flags, message. */
104 api
.type
= stream_getc (s
);
105 api
.instance
= stream_getw (s
);
106 api
.flags
= stream_getl (s
);
107 api
.message
= stream_getc (s
);
110 prefix
.family
= AF_INET6
;
111 prefix
.prefixlen
= stream_getc (s
);
112 stream_get (&prefix
.prefix
, s
, PSIZE (prefix
.prefixlen
));
114 /* Nexthop, ifindex, distance, metric. */
115 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
)) {
116 api
.nexthop_num
= stream_getc (s
);
117 stream_get (&nexthop
, s
, sizeof(nexthop
));
119 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
)) {
120 api
.ifindex_num
= stream_getc (s
);
121 ifindex
= stream_getl (s
);
123 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
124 api
.distance
= stream_getc (s
);
127 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
128 api
.metric
= stream_getl (s
);
132 if (command
== ZEBRA_REDISTRIBUTE_IPV6_ADD
)
133 babel_ipv6_route_add(&api
, &prefix
, ifindex
, &nexthop
);
135 babel_ipv6_route_delete(&api
, &prefix
, ifindex
);
141 babel_zebra_read_ipv4 (int command
, struct zclient
*zclient
,
142 zebra_size_t length
, vrf_id_t vrf
)
145 struct zapi_ipv4 api
;
146 unsigned long ifindex
= -1;
147 struct in_addr nexthop
;
148 struct prefix_ipv4 prefix
;
152 memset (&nexthop
, 0, sizeof (struct in_addr
));
153 memset (&api
, 0, sizeof(struct zapi_ipv4
));
154 memset (&prefix
, 0, sizeof (struct prefix_ipv4
));
156 /* Type, flags, message. */
157 api
.type
= stream_getc (s
);
158 api
.instance
= stream_getw (s
);
159 api
.flags
= stream_getl (s
);
160 api
.message
= stream_getc (s
);
163 prefix
.family
= AF_INET
;
164 prefix
.prefixlen
= stream_getc (s
);
165 stream_get (&prefix
.prefix
, s
, PSIZE (prefix
.prefixlen
));
167 /* Nexthop, ifindex, distance, metric. */
168 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
)) {
169 api
.nexthop_num
= stream_getc (s
);
170 stream_get (&nexthop
, s
, sizeof(nexthop
));
172 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
)) {
173 api
.ifindex_num
= stream_getc (s
);
174 ifindex
= stream_getl (s
);
176 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
177 api
.distance
= stream_getc (s
);
180 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
181 api
.metric
= stream_getl (s
);
185 if (command
== ZEBRA_REDISTRIBUTE_IPV4_ADD
) {
186 babel_ipv4_route_add(&api
, &prefix
, ifindex
, &nexthop
);
188 babel_ipv4_route_delete(&api
, &prefix
, ifindex
);
195 babel_proto_redistnum(const char *s
)
202 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
203 if (len
<= (int)strlen(proto_redistnum_type
[i
].str
) &&
204 strncmp(proto_redistnum_type
[i
].str
, s
,
205 proto_redistnum_type
[i
].str_min_len
) == 0) {
213 /* [Babel Command] */
214 DEFUN (babel_redistribute_type
,
215 babel_redistribute_type_cmd
,
216 "redistribute " FRR_REDIST_STR_BABELD
,
218 FRR_REDIST_HELP_STR_BABELD
)
222 type
= babel_proto_redistnum(argv
[1]->arg
);
225 vty_out (vty
, "Invalid type %s\n", argv
[1]->arg
);
226 return CMD_WARNING_CONFIG_FAILED
;
229 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
, type
, 0, VRF_DEFAULT
);
230 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0, VRF_DEFAULT
);
234 /* [Babel Command] */
235 DEFUN (no_babel_redistribute_type
,
236 no_babel_redistribute_type_cmd
,
237 "no redistribute " FRR_REDIST_STR_BABELD
,
240 FRR_REDIST_HELP_STR_BABELD
)
244 type
= babel_proto_redistnum(argv
[2]->arg
);
247 vty_out (vty
, "Invalid type %s\n", argv
[2]->arg
);
248 return CMD_WARNING_CONFIG_FAILED
;
251 zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, AFI_IP
, type
, 0, VRF_DEFAULT
);
252 zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, AFI_IP6
, type
, 0, VRF_DEFAULT
);
253 /* perhaps should we remove xroutes having the same type... */
258 /* [Babel Command] */
261 "debug babel <common|kernel|filter|timeout|interface|route|all>",
262 "Enable debug messages for specific or all part.\n"
263 "Babel information\n"
264 "Common messages (default)\n"
268 "Interface messages\n"
274 for(i
= 0; debug_type
[i
].str
!= NULL
; i
++) {
275 if (strncmp (debug_type
[i
].str
, argv
[2]->arg
,
276 debug_type
[i
].str_min_len
) == 0) {
277 debug
|= debug_type
[i
].type
;
282 vty_out (vty
, "Invalid type %s\n", argv
[2]->arg
);
284 return CMD_WARNING_CONFIG_FAILED
;
287 /* [Babel Command] */
288 DEFUN (no_debug_babel
,
290 "no debug babel <common|kernel|filter|timeout|interface|route|all>",
292 "Disable debug messages for specific or all part.\n"
293 "Babel information\n"
294 "Common messages (default)\n"
298 "Interface messages\n"
304 for (i
= 0; debug_type
[i
].str
; i
++) {
305 if (strncmp(debug_type
[i
].str
, argv
[3]->arg
,
306 debug_type
[i
].str_min_len
) == 0) {
307 debug
&= ~debug_type
[i
].type
;
312 vty_out (vty
, "Invalid type %s\n", argv
[3]->arg
);
314 return CMD_WARNING_CONFIG_FAILED
;
316 #endif /* NO_DEBUG */
318 /* Output "debug" statement lines, if necessary. */
320 debug_babel_config_write (struct vty
* vty
)
327 if (debug
== BABEL_DEBUG_ALL
)
329 vty_out (vty
, "debug babel all\n");
333 for (i
= 0; debug_type
[i
].str
!= NULL
; i
++)
336 debug_type
[i
].type
!= BABEL_DEBUG_ALL
337 && CHECK_FLAG (debug
, debug_type
[i
].type
)
340 vty_out (vty
, "debug babel %s\n", debug_type
[i
].str
);
345 vty_out (vty
, "!\n");
349 #endif /* NO_DEBUG */
353 babel_zebra_connected (struct zclient
*zclient
)
355 zclient_send_reg_requests (zclient
, VRF_DEFAULT
);
358 void babelz_zebra_init(void)
360 zclient
= zclient_new(master
);
361 zclient_init(zclient
, ZEBRA_ROUTE_BABEL
, 0);
363 zclient
->zebra_connected
= babel_zebra_connected
;
364 zclient
->interface_add
= babel_interface_add
;
365 zclient
->interface_delete
= babel_interface_delete
;
366 zclient
->interface_up
= babel_interface_up
;
367 zclient
->interface_down
= babel_interface_down
;
368 zclient
->interface_address_add
= babel_interface_address_add
;
369 zclient
->interface_address_delete
= babel_interface_address_delete
;
370 zclient
->redistribute_route_ipv4_add
= babel_zebra_read_ipv4
;
371 zclient
->redistribute_route_ipv4_del
= babel_zebra_read_ipv4
;
372 zclient
->redistribute_route_ipv6_add
= babel_zebra_read_ipv6
;
373 zclient
->redistribute_route_ipv6_del
= babel_zebra_read_ipv6
;
375 install_node (&zebra_node
, zebra_config_write
);
376 install_element(BABEL_NODE
, &babel_redistribute_type_cmd
);
377 install_element(BABEL_NODE
, &no_babel_redistribute_type_cmd
);
378 install_element(ENABLE_NODE
, &debug_babel_cmd
);
379 install_element(ENABLE_NODE
, &no_debug_babel_cmd
);
380 install_element(CONFIG_NODE
, &debug_babel_cmd
);
381 install_element(CONFIG_NODE
, &no_debug_babel_cmd
);
385 zebra_config_write (struct vty
*vty
)
387 if (! zclient
->enable
)
389 vty_out (vty
, "no router zebra\n");
392 else if (! vrf_bitmap_check (zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_BABEL
], VRF_DEFAULT
))
394 vty_out (vty
, "router zebra\n");
395 vty_out (vty
, " no redistribute babel\n");
402 babel_zebra_close_connexion(void)
404 zclient_stop(zclient
);
405 zclient_free(zclient
);