]> git.proxmox.com Git - mirror_frr.git/blob - babeld/babel_zebra.c
Merge pull request #1026 from qlyoung/no-ospf6
[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 /* Zebra node structure. */
59 struct cmd_node zebra_node =
60 {
61 ZEBRA_NODE,
62 "%s(config-router)# ",
63 1 /* vtysh? yes */
64 };
65
66
67 /* Zebra route add and delete treatment (ipv6). */
68 static int
69 babel_zebra_read_ipv6 (int command, struct zclient *zclient,
70 zebra_size_t length, vrf_id_t vrf)
71 {
72 struct stream *s;
73 struct zapi_ipv6 api;
74 unsigned long ifindex = -1;
75 struct in6_addr nexthop;
76 struct prefix_ipv6 prefix;
77
78 s = zclient->ibuf;
79 ifindex = 0;
80 memset (&nexthop, 0, sizeof (struct in6_addr));
81 memset (&api, 0, sizeof(struct zapi_ipv6));
82 memset (&prefix, 0, sizeof (struct prefix_ipv6));
83
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);
89
90 /* IPv6 prefix. */
91 prefix.family = AF_INET6;
92 prefix.prefixlen = stream_getc (s);
93 stream_get (&prefix.prefix, s, PSIZE (prefix.prefixlen));
94
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));
99 }
100 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) {
101 api.ifindex_num = stream_getc (s);
102 ifindex = stream_getl (s);
103 }
104 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
105 api.distance = stream_getc (s);
106 else
107 api.distance = 0;
108 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
109 api.metric = stream_getl (s);
110 else
111 api.metric = 0;
112
113 if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD)
114 babel_ipv6_route_add(&api, &prefix, ifindex, &nexthop);
115 else
116 babel_ipv6_route_delete(&api, &prefix, ifindex);
117
118 return 0;
119 }
120
121 static int
122 babel_zebra_read_ipv4 (int command, struct zclient *zclient,
123 zebra_size_t length, vrf_id_t vrf)
124 {
125 struct stream *s;
126 struct zapi_ipv4 api;
127 unsigned long ifindex = -1;
128 struct in_addr nexthop;
129 struct prefix_ipv4 prefix;
130
131 s = zclient->ibuf;
132 ifindex = 0;
133 memset (&nexthop, 0, sizeof (struct in_addr));
134 memset (&api, 0, sizeof(struct zapi_ipv4));
135 memset (&prefix, 0, sizeof (struct prefix_ipv4));
136
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);
142
143 /* IPv6 prefix. */
144 prefix.family = AF_INET;
145 prefix.prefixlen = stream_getc (s);
146 stream_get (&prefix.prefix, s, PSIZE (prefix.prefixlen));
147
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));
152 }
153 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) {
154 api.ifindex_num = stream_getc (s);
155 ifindex = stream_getl (s);
156 }
157 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
158 api.distance = stream_getc (s);
159 else
160 api.distance = 0;
161 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
162 api.metric = stream_getl (s);
163 else
164 api.metric = 0;
165
166 if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) {
167 babel_ipv4_route_add(&api, &prefix, ifindex, &nexthop);
168 } else {
169 babel_ipv4_route_delete(&api, &prefix, ifindex);
170 }
171
172 return 0;
173 }
174
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 ">",
179 NO_STR
180 "Redistribute\n"
181 "Redistribute IPv4 routes\n"
182 FRR_IP_REDIST_HELP_STR_BABELD
183 "Redistribute IPv6 routes\n"
184 FRR_IP6_REDIST_HELP_STR_BABELD)
185 {
186 int negate = 0;
187 int family;
188 int afi;
189 int type;
190 int idx = 0;
191
192 if (argv_find(argv, argc, "no", &idx))
193 negate = 1;
194 argv_find(argv, argc, "redistribute", &idx);
195 family = str2family(argv[idx + 1]->text);
196 if (family < 0)
197 return CMD_WARNING_CONFIG_FAILED;
198
199 afi = family2afi(family);
200 if (!afi)
201 return CMD_WARNING_CONFIG_FAILED;
202
203 type = proto_redistnum(afi, argv[idx + 2]->text);
204 if (type < 0) {
205 vty_out (vty, "Invalid type %s\n", argv[idx + 2]->arg);
206 return CMD_WARNING_CONFIG_FAILED;
207 }
208
209 if (!negate)
210 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type, 0, VRF_DEFAULT);
211 else {
212 zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type, 0, VRF_DEFAULT);
213 /* perhaps should we remove xroutes having the same type... */
214 }
215 return CMD_SUCCESS;
216 }
217
218 #ifndef NO_DEBUG
219 /* [Babel Command] */
220 DEFUN (debug_babel,
221 debug_babel_cmd,
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"
226 "Kernel messages\n"
227 "Filter messages\n"
228 "Timeout messages\n"
229 "Interface messages\n"
230 "Route messages\n"
231 "All messages\n")
232 {
233 int i;
234
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;
239 return CMD_SUCCESS;
240 }
241 }
242
243 vty_out (vty, "Invalid type %s\n", argv[2]->arg);
244
245 return CMD_WARNING_CONFIG_FAILED;
246 }
247
248 /* [Babel Command] */
249 DEFUN (no_debug_babel,
250 no_debug_babel_cmd,
251 "no debug babel <common|kernel|filter|timeout|interface|route|all>",
252 NO_STR
253 "Disable debug messages for specific or all part.\n"
254 "Babel information\n"
255 "Common messages (default)\n"
256 "Kernel messages\n"
257 "Filter messages\n"
258 "Timeout messages\n"
259 "Interface messages\n"
260 "Route messages\n"
261 "All messages\n")
262 {
263 int i;
264
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;
269 return CMD_SUCCESS;
270 }
271 }
272
273 vty_out (vty, "Invalid type %s\n", argv[3]->arg);
274
275 return CMD_WARNING_CONFIG_FAILED;
276 }
277 #endif /* NO_DEBUG */
278
279 /* Output "debug" statement lines, if necessary. */
280 int
281 debug_babel_config_write (struct vty * vty)
282 {
283 #ifdef NO_DEBUG
284 return 0;
285 #else
286 int i, lines = 0;
287
288 if (debug == BABEL_DEBUG_ALL)
289 {
290 vty_out (vty, "debug babel all\n");
291 lines++;
292 }
293 else
294 for (i = 0; debug_type[i].str != NULL; i++)
295 if
296 (
297 debug_type[i].type != BABEL_DEBUG_ALL
298 && CHECK_FLAG (debug, debug_type[i].type)
299 )
300 {
301 vty_out (vty, "debug babel %s\n", debug_type[i].str);
302 lines++;
303 }
304 if (lines)
305 {
306 vty_out (vty, "!\n");
307 lines++;
308 }
309 return lines;
310 #endif /* NO_DEBUG */
311 }
312
313 DEFUN_NOSH (show_debugging_babel,
314 show_debugging_babel_cmd,
315 "show debugging [babel]",
316 SHOW_STR
317 DEBUG_STR
318 "Babel")
319 {
320 vty_out(vty, "BABEL debugging status\n");
321
322 debug_babel_config_write(vty);
323
324 return CMD_SUCCESS;
325 }
326
327 static void
328 babel_zebra_connected (struct zclient *zclient)
329 {
330 zclient_send_reg_requests (zclient, VRF_DEFAULT);
331 }
332
333 void babelz_zebra_init(void)
334 {
335 zclient = zclient_new(master);
336 zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0);
337
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;
349
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);
356
357 install_element(VIEW_NODE, &show_debugging_babel_cmd);
358 }
359
360 static int
361 zebra_config_write (struct vty *vty)
362 {
363 if (! zclient->enable)
364 {
365 vty_out (vty, "no router zebra\n");
366 return 1;
367 }
368 else if (! vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_BABEL], VRF_DEFAULT))
369 {
370 vty_out (vty, "router zebra\n");
371 vty_out (vty, " no redistribute babel\n");
372 return 1;
373 }
374 return 0;
375 }
376
377 void
378 babel_zebra_close_connexion(void)
379 {
380 zclient_stop(zclient);
381 zclient_free(zclient);
382 }