]> git.proxmox.com Git - mirror_frr.git/blob - babeld/babel_zebra.c
Merge pull request #805 from Orange-OpenSource/master
[mirror_frr.git] / babeld / babel_zebra.c
1 /*
2 Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
3
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:
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
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
20 THE SOFTWARE.
21 */
22
23 /* FRR's includes */
24 #include <zebra.h>
25 #include "command.h"
26 #include "zclient.h"
27 #include "stream.h"
28
29 /* babel's includes*/
30 #include "babel_zebra.h"
31 #include "babel_interface.h"
32 #include "xroute.h"
33 #include "util.h"
34
35 void babelz_zebra_init(void);
36
37
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);
41
42 /* Debug types */
43 static struct {
44 int type;
45 int str_min_len;
46 const char *str;
47 } debug_type[] = {
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"},
55 {0, 0, NULL}
56 };
57
58 static struct {
59 int str_min_len;
60 const char *str;
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"},
75 };
76
77 /* Zebra node structure. */
78 struct cmd_node zebra_node =
79 {
80 ZEBRA_NODE,
81 "%s(config-router)# ",
82 1 /* vtysh? yes */
83 };
84
85
86 /* Zebra route add and delete treatment (ipv6). */
87 static int
88 babel_zebra_read_ipv6 (int command, struct zclient *zclient,
89 zebra_size_t length, vrf_id_t vrf)
90 {
91 struct stream *s;
92 struct zapi_ipv6 api;
93 unsigned long ifindex = -1;
94 struct in6_addr nexthop;
95 struct prefix_ipv6 prefix;
96
97 s = zclient->ibuf;
98 ifindex = 0;
99 memset (&nexthop, 0, sizeof (struct in6_addr));
100 memset (&api, 0, sizeof(struct zapi_ipv6));
101 memset (&prefix, 0, sizeof (struct prefix_ipv6));
102
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);
108
109 /* IPv6 prefix. */
110 prefix.family = AF_INET6;
111 prefix.prefixlen = stream_getc (s);
112 stream_get (&prefix.prefix, s, PSIZE (prefix.prefixlen));
113
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));
118 }
119 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) {
120 api.ifindex_num = stream_getc (s);
121 ifindex = stream_getl (s);
122 }
123 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
124 api.distance = stream_getc (s);
125 else
126 api.distance = 0;
127 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
128 api.metric = stream_getl (s);
129 else
130 api.metric = 0;
131
132 if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD)
133 babel_ipv6_route_add(&api, &prefix, ifindex, &nexthop);
134 else
135 babel_ipv6_route_delete(&api, &prefix, ifindex);
136
137 return 0;
138 }
139
140 static int
141 babel_zebra_read_ipv4 (int command, struct zclient *zclient,
142 zebra_size_t length, vrf_id_t vrf)
143 {
144 struct stream *s;
145 struct zapi_ipv4 api;
146 unsigned long ifindex = -1;
147 struct in_addr nexthop;
148 struct prefix_ipv4 prefix;
149
150 s = zclient->ibuf;
151 ifindex = 0;
152 memset (&nexthop, 0, sizeof (struct in_addr));
153 memset (&api, 0, sizeof(struct zapi_ipv4));
154 memset (&prefix, 0, sizeof (struct prefix_ipv4));
155
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);
161
162 /* IPv6 prefix. */
163 prefix.family = AF_INET;
164 prefix.prefixlen = stream_getc (s);
165 stream_get (&prefix.prefix, s, PSIZE (prefix.prefixlen));
166
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));
171 }
172 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) {
173 api.ifindex_num = stream_getc (s);
174 ifindex = stream_getl (s);
175 }
176 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
177 api.distance = stream_getc (s);
178 else
179 api.distance = 0;
180 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
181 api.metric = stream_getl (s);
182 else
183 api.metric = 0;
184
185 if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) {
186 babel_ipv4_route_add(&api, &prefix, ifindex, &nexthop);
187 } else {
188 babel_ipv4_route_delete(&api, &prefix, ifindex);
189 }
190
191 return 0;
192 }
193
194 static int
195 babel_proto_redistnum(const char *s)
196 {
197 int i;
198 if (! s)
199 return -1;
200 int len = strlen(s);
201
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) {
206 return i;
207 }
208 }
209
210 return -1;
211 }
212
213 /* [Babel Command] */
214 DEFUN (babel_redistribute_type,
215 babel_redistribute_type_cmd,
216 "redistribute " FRR_REDIST_STR_BABELD,
217 "Redistribute\n"
218 FRR_REDIST_HELP_STR_BABELD)
219 {
220 int type;
221
222 type = babel_proto_redistnum(argv[1]->arg);
223
224 if (type < 0) {
225 vty_out (vty, "Invalid type %s\n", argv[1]->arg);
226 return CMD_WARNING_CONFIG_FAILED;
227 }
228
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);
231 return CMD_SUCCESS;
232 }
233
234 /* [Babel Command] */
235 DEFUN (no_babel_redistribute_type,
236 no_babel_redistribute_type_cmd,
237 "no redistribute " FRR_REDIST_STR_BABELD,
238 NO_STR
239 "Redistribute\n"
240 FRR_REDIST_HELP_STR_BABELD)
241 {
242 int type;
243
244 type = babel_proto_redistnum(argv[2]->arg);
245
246 if (type < 0) {
247 vty_out (vty, "Invalid type %s\n", argv[2]->arg);
248 return CMD_WARNING_CONFIG_FAILED;
249 }
250
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... */
254 return CMD_SUCCESS;
255 }
256
257 #ifndef NO_DEBUG
258 /* [Babel Command] */
259 DEFUN (debug_babel,
260 debug_babel_cmd,
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"
265 "Kernel messages\n"
266 "Filter messages\n"
267 "Timeout messages\n"
268 "Interface messages\n"
269 "Route messages\n"
270 "All messages\n")
271 {
272 int i;
273
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;
278 return CMD_SUCCESS;
279 }
280 }
281
282 vty_out (vty, "Invalid type %s\n", argv[2]->arg);
283
284 return CMD_WARNING_CONFIG_FAILED;
285 }
286
287 /* [Babel Command] */
288 DEFUN (no_debug_babel,
289 no_debug_babel_cmd,
290 "no debug babel <common|kernel|filter|timeout|interface|route|all>",
291 NO_STR
292 "Disable debug messages for specific or all part.\n"
293 "Babel information\n"
294 "Common messages (default)\n"
295 "Kernel messages\n"
296 "Filter messages\n"
297 "Timeout messages\n"
298 "Interface messages\n"
299 "Route messages\n"
300 "All messages\n")
301 {
302 int i;
303
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;
308 return CMD_SUCCESS;
309 }
310 }
311
312 vty_out (vty, "Invalid type %s\n", argv[3]->arg);
313
314 return CMD_WARNING_CONFIG_FAILED;
315 }
316 #endif /* NO_DEBUG */
317
318 /* Output "debug" statement lines, if necessary. */
319 int
320 debug_babel_config_write (struct vty * vty)
321 {
322 #ifdef NO_DEBUG
323 return 0;
324 #else
325 int i, lines = 0;
326
327 if (debug == BABEL_DEBUG_ALL)
328 {
329 vty_out (vty, "debug babel all\n");
330 lines++;
331 }
332 else
333 for (i = 0; debug_type[i].str != NULL; i++)
334 if
335 (
336 debug_type[i].type != BABEL_DEBUG_ALL
337 && CHECK_FLAG (debug, debug_type[i].type)
338 )
339 {
340 vty_out (vty, "debug babel %s\n", debug_type[i].str);
341 lines++;
342 }
343 if (lines)
344 {
345 vty_out (vty, "!\n");
346 lines++;
347 }
348 return lines;
349 #endif /* NO_DEBUG */
350 }
351
352 static void
353 babel_zebra_connected (struct zclient *zclient)
354 {
355 zclient_send_reg_requests (zclient, VRF_DEFAULT);
356 }
357
358 void babelz_zebra_init(void)
359 {
360 zclient = zclient_new(master);
361 zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0);
362
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;
374
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);
382 }
383
384 static int
385 zebra_config_write (struct vty *vty)
386 {
387 if (! zclient->enable)
388 {
389 vty_out (vty, "no router zebra\n");
390 return 1;
391 }
392 else if (! vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_BABEL], VRF_DEFAULT))
393 {
394 vty_out (vty, "router zebra\n");
395 vty_out (vty, " no redistribute babel\n");
396 return 1;
397 }
398 return 0;
399 }
400
401 void
402 babel_zebra_close_connexion(void)
403 {
404 zclient_stop(zclient);
405 zclient_free(zclient);
406 }