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_outln (vty
, "Invalid type %s", argv
[1]->arg
);
229 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
, type
, 0, VRF_DEFAULT
);
233 /* [Babel Command] */
234 DEFUN (no_babel_redistribute_type
,
235 no_babel_redistribute_type_cmd
,
236 "no redistribute " FRR_REDIST_STR_BABELD
,
239 FRR_REDIST_HELP_STR_BABELD
)
243 type
= babel_proto_redistnum(argv
[2]->arg
);
246 vty_outln (vty
, "Invalid type %s", argv
[2]->arg
);
250 zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, AFI_IP
, type
, 0, VRF_DEFAULT
);
251 /* perhaps should we remove xroutes having the same type... */
256 /* [Babel Command] */
259 "debug babel <common|kernel|filter|timeout|interface|route|all>",
260 "Enable debug messages for specific or all part.\n"
261 "Babel information\n"
262 "Common messages (default)\n"
266 "Interface messages\n"
272 for(i
= 0; debug_type
[i
].str
!= NULL
; i
++) {
273 if (strncmp (debug_type
[i
].str
, argv
[2]->arg
,
274 debug_type
[i
].str_min_len
) == 0) {
275 debug
|= debug_type
[i
].type
;
280 vty_outln (vty
, "Invalid type %s", argv
[2]->arg
);
285 /* [Babel Command] */
286 DEFUN (no_debug_babel
,
288 "no debug babel <common|kernel|filter|timeout|interface|route|all>",
290 "Disable debug messages for specific or all part.\n"
291 "Babel information\n"
292 "Common messages (default)\n"
296 "Interface messages\n"
302 for (i
= 0; debug_type
[i
].str
; i
++) {
303 if (strncmp(debug_type
[i
].str
, argv
[3]->arg
,
304 debug_type
[i
].str_min_len
) == 0) {
305 debug
&= ~debug_type
[i
].type
;
310 vty_outln (vty
, "Invalid type %s", argv
[3]->arg
);
314 #endif /* NO_DEBUG */
316 /* Output "debug" statement lines, if necessary. */
318 debug_babel_config_write (struct vty
* vty
)
325 if (debug
== BABEL_DEBUG_ALL
)
327 vty_outln (vty
, "debug babel all");
331 for (i
= 0; debug_type
[i
].str
!= NULL
; i
++)
334 debug_type
[i
].type
!= BABEL_DEBUG_ALL
335 && CHECK_FLAG (debug
, debug_type
[i
].type
)
338 vty_outln (vty
, "debug babel %s", debug_type
[i
].str
);
343 vty_outln (vty
, "!");
347 #endif /* NO_DEBUG */
351 babel_zebra_connected (struct zclient
*zclient
)
353 zclient_send_reg_requests (zclient
, VRF_DEFAULT
);
356 void babelz_zebra_init(void)
358 zclient
= zclient_new(master
);
359 zclient_init(zclient
, ZEBRA_ROUTE_BABEL
, 0);
361 zclient
->zebra_connected
= babel_zebra_connected
;
362 zclient
->interface_add
= babel_interface_add
;
363 zclient
->interface_delete
= babel_interface_delete
;
364 zclient
->interface_up
= babel_interface_up
;
365 zclient
->interface_down
= babel_interface_down
;
366 zclient
->interface_address_add
= babel_interface_address_add
;
367 zclient
->interface_address_delete
= babel_interface_address_delete
;
368 zclient
->redistribute_route_ipv4_add
= babel_zebra_read_ipv4
;
369 zclient
->redistribute_route_ipv4_del
= babel_zebra_read_ipv4
;
370 zclient
->redistribute_route_ipv6_add
= babel_zebra_read_ipv6
;
371 zclient
->redistribute_route_ipv6_del
= babel_zebra_read_ipv6
;
373 install_node (&zebra_node
, zebra_config_write
);
374 install_element(BABEL_NODE
, &babel_redistribute_type_cmd
);
375 install_element(BABEL_NODE
, &no_babel_redistribute_type_cmd
);
376 install_element(ENABLE_NODE
, &debug_babel_cmd
);
377 install_element(ENABLE_NODE
, &no_debug_babel_cmd
);
378 install_element(CONFIG_NODE
, &debug_babel_cmd
);
379 install_element(CONFIG_NODE
, &no_debug_babel_cmd
);
383 zebra_config_write (struct vty
*vty
)
385 if (! zclient
->enable
)
387 vty_outln (vty
, "no router zebra");
390 else if (! vrf_bitmap_check (zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_BABEL
], VRF_DEFAULT
))
392 vty_outln (vty
, "router zebra");
393 vty_outln (vty
, " no redistribute babel");
400 babel_zebra_close_connexion(void)
402 zclient_stop(zclient
);
403 zclient_free(zclient
);