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 */
314 babel_zebra_connected (struct zclient
*zclient
)
316 zclient_send_reg_requests (zclient
, VRF_DEFAULT
);
319 void babelz_zebra_init(void)
321 zclient
= zclient_new(master
);
322 zclient_init(zclient
, ZEBRA_ROUTE_BABEL
, 0);
324 zclient
->zebra_connected
= babel_zebra_connected
;
325 zclient
->interface_add
= babel_interface_add
;
326 zclient
->interface_delete
= babel_interface_delete
;
327 zclient
->interface_up
= babel_interface_up
;
328 zclient
->interface_down
= babel_interface_down
;
329 zclient
->interface_address_add
= babel_interface_address_add
;
330 zclient
->interface_address_delete
= babel_interface_address_delete
;
331 zclient
->redistribute_route_ipv4_add
= babel_zebra_read_ipv4
;
332 zclient
->redistribute_route_ipv4_del
= babel_zebra_read_ipv4
;
333 zclient
->redistribute_route_ipv6_add
= babel_zebra_read_ipv6
;
334 zclient
->redistribute_route_ipv6_del
= babel_zebra_read_ipv6
;
336 install_node (&zebra_node
, zebra_config_write
);
337 install_element(BABEL_NODE
, &babel_redistribute_type_cmd
);
338 install_element(ENABLE_NODE
, &debug_babel_cmd
);
339 install_element(ENABLE_NODE
, &no_debug_babel_cmd
);
340 install_element(CONFIG_NODE
, &debug_babel_cmd
);
341 install_element(CONFIG_NODE
, &no_debug_babel_cmd
);
345 zebra_config_write (struct vty
*vty
)
347 if (! zclient
->enable
)
349 vty_out (vty
, "no router zebra\n");
352 else if (! vrf_bitmap_check (zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_BABEL
], VRF_DEFAULT
))
354 vty_out (vty
, "router zebra\n");
355 vty_out (vty
, " no redistribute babel\n");
362 babel_zebra_close_connexion(void)
364 zclient_stop(zclient
);
365 zclient_free(zclient
);