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"},
58 /* Zebra node structure. */
59 struct cmd_node zebra_node
=
62 "%s(config-router)# ",
67 /* Zebra route add and delete treatment (ipv6). */
69 babel_zebra_read_ipv6 (int command
, struct zclient
*zclient
,
70 zebra_size_t length
, vrf_id_t vrf
)
74 unsigned long ifindex
= -1;
75 struct in6_addr nexthop
;
76 struct prefix_ipv6 prefix
;
80 memset (&nexthop
, 0, sizeof (struct in6_addr
));
81 memset (&api
, 0, sizeof(struct zapi_ipv6
));
82 memset (&prefix
, 0, sizeof (struct prefix_ipv6
));
84 /* Type, flags, message. */
85 api
.type
= stream_getc (s
);
86 api
.instance
= stream_getw (s
);
87 api
.flags
= stream_getl (s
);
88 api
.message
= stream_getc (s
);
91 prefix
.family
= AF_INET6
;
92 prefix
.prefixlen
= stream_getc (s
);
93 stream_get (&prefix
.prefix
, s
, PSIZE (prefix
.prefixlen
));
95 /* Nexthop, ifindex, distance, metric. */
96 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
)) {
97 api
.nexthop_num
= stream_getc (s
);
98 stream_get (&nexthop
, s
, sizeof(nexthop
));
100 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
)) {
101 api
.ifindex_num
= stream_getc (s
);
102 ifindex
= stream_getl (s
);
104 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
105 api
.distance
= stream_getc (s
);
108 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
109 api
.metric
= stream_getl (s
);
113 if (command
== ZEBRA_REDISTRIBUTE_IPV6_ADD
)
114 babel_ipv6_route_add(&api
, &prefix
, ifindex
, &nexthop
);
116 babel_ipv6_route_delete(&api
, &prefix
, ifindex
);
122 babel_zebra_read_ipv4 (int command
, struct zclient
*zclient
,
123 zebra_size_t length
, vrf_id_t vrf
)
126 struct zapi_ipv4 api
;
127 unsigned long ifindex
= -1;
128 struct in_addr nexthop
;
129 struct prefix_ipv4 prefix
;
133 memset (&nexthop
, 0, sizeof (struct in_addr
));
134 memset (&api
, 0, sizeof(struct zapi_ipv4
));
135 memset (&prefix
, 0, sizeof (struct prefix_ipv4
));
137 /* Type, flags, message. */
138 api
.type
= stream_getc (s
);
139 api
.instance
= stream_getw (s
);
140 api
.flags
= stream_getl (s
);
141 api
.message
= stream_getc (s
);
144 prefix
.family
= AF_INET
;
145 prefix
.prefixlen
= stream_getc (s
);
146 stream_get (&prefix
.prefix
, s
, PSIZE (prefix
.prefixlen
));
148 /* Nexthop, ifindex, distance, metric. */
149 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
)) {
150 api
.nexthop_num
= stream_getc (s
);
151 stream_get (&nexthop
, s
, sizeof(nexthop
));
153 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
)) {
154 api
.ifindex_num
= stream_getc (s
);
155 ifindex
= stream_getl (s
);
157 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
158 api
.distance
= stream_getc (s
);
161 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
162 api
.metric
= stream_getl (s
);
166 if (command
== ZEBRA_REDISTRIBUTE_IPV4_ADD
) {
167 babel_ipv4_route_add(&api
, &prefix
, ifindex
, &nexthop
);
169 babel_ipv4_route_delete(&api
, &prefix
, ifindex
);
175 /* [Babel Command] */
176 DEFUN (babel_redistribute_type
,
177 babel_redistribute_type_cmd
,
178 "[no] redistribute <ipv4 " FRR_IP_REDIST_STR_BABELD
"|ipv6 " FRR_IP6_REDIST_STR_BABELD
">",
181 "Redistribute IPv4 routes\n"
182 FRR_IP_REDIST_HELP_STR_BABELD
183 "Redistribute IPv6 routes\n"
184 FRR_IP6_REDIST_HELP_STR_BABELD
)
192 if (argv_find(argv
, argc
, "no", &idx
))
194 argv_find(argv
, argc
, "redistribute", &idx
);
195 family
= str2family(argv
[idx
+ 1]->text
);
197 return CMD_WARNING_CONFIG_FAILED
;
199 afi
= family2afi(family
);
201 return CMD_WARNING_CONFIG_FAILED
;
203 type
= proto_redistnum(afi
, argv
[idx
+ 2]->text
);
205 vty_out (vty
, "Invalid type %s\n", argv
[idx
+ 2]->arg
);
206 return CMD_WARNING_CONFIG_FAILED
;
210 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, afi
, type
, 0, VRF_DEFAULT
);
212 zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, afi
, type
, 0, VRF_DEFAULT
);
213 /* perhaps should we remove xroutes having the same type... */
219 /* [Babel Command] */
222 "debug babel <common|kernel|filter|timeout|interface|route|all>",
223 "Enable debug messages for specific or all part.\n"
224 "Babel information\n"
225 "Common messages (default)\n"
229 "Interface messages\n"
235 for(i
= 0; debug_type
[i
].str
!= NULL
; i
++) {
236 if (strncmp (debug_type
[i
].str
, argv
[2]->arg
,
237 debug_type
[i
].str_min_len
) == 0) {
238 debug
|= debug_type
[i
].type
;
243 vty_out (vty
, "Invalid type %s\n", argv
[2]->arg
);
245 return CMD_WARNING_CONFIG_FAILED
;
248 /* [Babel Command] */
249 DEFUN (no_debug_babel
,
251 "no debug babel <common|kernel|filter|timeout|interface|route|all>",
253 "Disable debug messages for specific or all part.\n"
254 "Babel information\n"
255 "Common messages (default)\n"
259 "Interface messages\n"
265 for (i
= 0; debug_type
[i
].str
; i
++) {
266 if (strncmp(debug_type
[i
].str
, argv
[3]->arg
,
267 debug_type
[i
].str_min_len
) == 0) {
268 debug
&= ~debug_type
[i
].type
;
273 vty_out (vty
, "Invalid type %s\n", argv
[3]->arg
);
275 return CMD_WARNING_CONFIG_FAILED
;
277 #endif /* NO_DEBUG */
279 /* Output "debug" statement lines, if necessary. */
281 debug_babel_config_write (struct vty
* vty
)
288 if (debug
== BABEL_DEBUG_ALL
)
290 vty_out (vty
, "debug babel all\n");
294 for (i
= 0; debug_type
[i
].str
!= NULL
; i
++)
297 debug_type
[i
].type
!= BABEL_DEBUG_ALL
298 && CHECK_FLAG (debug
, debug_type
[i
].type
)
301 vty_out (vty
, "debug babel %s\n", debug_type
[i
].str
);
306 vty_out (vty
, "!\n");
310 #endif /* NO_DEBUG */
313 DEFUN_NOSH (show_debugging_babel
,
314 show_debugging_babel_cmd
,
315 "show debugging [babel]",
320 vty_out(vty
, "BABEL debugging status\n");
322 debug_babel_config_write(vty
);
328 babel_zebra_connected (struct zclient
*zclient
)
330 zclient_send_reg_requests (zclient
, VRF_DEFAULT
);
333 void babelz_zebra_init(void)
335 zclient
= zclient_new(master
);
336 zclient_init(zclient
, ZEBRA_ROUTE_BABEL
, 0);
338 zclient
->zebra_connected
= babel_zebra_connected
;
339 zclient
->interface_add
= babel_interface_add
;
340 zclient
->interface_delete
= babel_interface_delete
;
341 zclient
->interface_up
= babel_interface_up
;
342 zclient
->interface_down
= babel_interface_down
;
343 zclient
->interface_address_add
= babel_interface_address_add
;
344 zclient
->interface_address_delete
= babel_interface_address_delete
;
345 zclient
->redistribute_route_ipv4_add
= babel_zebra_read_ipv4
;
346 zclient
->redistribute_route_ipv4_del
= babel_zebra_read_ipv4
;
347 zclient
->redistribute_route_ipv6_add
= babel_zebra_read_ipv6
;
348 zclient
->redistribute_route_ipv6_del
= babel_zebra_read_ipv6
;
350 install_node (&zebra_node
, zebra_config_write
);
351 install_element(BABEL_NODE
, &babel_redistribute_type_cmd
);
352 install_element(ENABLE_NODE
, &debug_babel_cmd
);
353 install_element(ENABLE_NODE
, &no_debug_babel_cmd
);
354 install_element(CONFIG_NODE
, &debug_babel_cmd
);
355 install_element(CONFIG_NODE
, &no_debug_babel_cmd
);
357 install_element(VIEW_NODE
, &show_debugging_babel_cmd
);
361 zebra_config_write (struct vty
*vty
)
363 if (! zclient
->enable
)
365 vty_out (vty
, "no router zebra\n");
368 else if (! vrf_bitmap_check (zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_BABEL
], VRF_DEFAULT
))
370 vty_out (vty
, "router zebra\n");
371 vty_out (vty
, " no redistribute babel\n");
378 babel_zebra_close_connexion(void)
380 zclient_stop(zclient
);
381 zclient_free(zclient
);