]> git.proxmox.com Git - mirror_frr.git/blob - babeld/babel_zebra.c
Merge branch 'master' into PIM_VRF
[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 static void
314 babel_zebra_connected (struct zclient *zclient)
315 {
316 zclient_send_reg_requests (zclient, VRF_DEFAULT);
317 }
318
319 void babelz_zebra_init(void)
320 {
321 zclient = zclient_new(master);
322 zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0);
323
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;
335
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);
342 }
343
344 static int
345 zebra_config_write (struct vty *vty)
346 {
347 if (! zclient->enable)
348 {
349 vty_out (vty, "no router zebra\n");
350 return 1;
351 }
352 else if (! vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_BABEL], VRF_DEFAULT))
353 {
354 vty_out (vty, "router zebra\n");
355 vty_out (vty, " no redistribute babel\n");
356 return 1;
357 }
358 return 0;
359 }
360
361 void
362 babel_zebra_close_connexion(void)
363 {
364 zclient_stop(zclient);
365 zclient_free(zclient);
366 }