]> git.proxmox.com Git - mirror_frr.git/blame - babeld/babel_zebra.c
bgpd: unify ipv4/ipv6 zebra-tx functions
[mirror_frr.git] / babeld / babel_zebra.c
CommitLineData
ca10883e
DS
1/*
2Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
3
4Permission is hereby granted, free of charge, to any person obtaining a copy
5of this software and associated documentation files (the "Software"), to deal
6in the Software without restriction, including without limitation the rights
7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20THE 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
35void babelz_zebra_init(void);
36
37
38/* we must use a pointer because of zclient.c's functions (new, free). */
39struct zclient *zclient;
ca10883e
DS
40
41/* Debug types */
42static struct {
43 int type;
44 int str_min_len;
45 const char *str;
46} debug_type[] = {
47 {BABEL_DEBUG_COMMON, 1, "common"},
48 {BABEL_DEBUG_KERNEL, 1, "kernel"},
49 {BABEL_DEBUG_FILTER, 1, "filter"},
50 {BABEL_DEBUG_TIMEOUT, 1, "timeout"},
51 {BABEL_DEBUG_IF, 1, "interface"},
52 {BABEL_DEBUG_ROUTE, 1, "route"},
53 {BABEL_DEBUG_ALL, 1, "all"},
54 {0, 0, NULL}
55};
56
ca10883e
DS
57/* Zebra route add and delete treatment (ipv6). */
58static int
59babel_zebra_read_ipv6 (int command, struct zclient *zclient,
0eb167b9 60 zebra_size_t length, vrf_id_t vrf)
ca10883e
DS
61{
62 struct stream *s;
63 struct zapi_ipv6 api;
64 unsigned long ifindex = -1;
65 struct in6_addr nexthop;
c125d1d4 66 struct prefix_ipv6 prefix, src_p;
ca10883e
DS
67
68 s = zclient->ibuf;
69 ifindex = 0;
70 memset (&nexthop, 0, sizeof (struct in6_addr));
71 memset (&api, 0, sizeof(struct zapi_ipv6));
72 memset (&prefix, 0, sizeof (struct prefix_ipv6));
73
74 /* Type, flags, message. */
75 api.type = stream_getc (s);
e9047736
DS
76 api.instance = stream_getw (s);
77 api.flags = stream_getl (s);
ca10883e
DS
78 api.message = stream_getc (s);
79
80 /* IPv6 prefix. */
81 prefix.family = AF_INET6;
e959008b 82 prefix.prefixlen = MIN (IPV6_MAX_PREFIXLEN, stream_getc (s));
ca10883e
DS
83 stream_get (&prefix.prefix, s, PSIZE (prefix.prefixlen));
84
c125d1d4
RW
85 memset(&src_p, 0, sizeof(src_p));
86 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
87 src_p.family = AF_INET6;
88 src_p.prefixlen = stream_getc(s);
89 stream_get(&src_p.prefix, s, PSIZE(src_p.prefixlen));
90 }
91 if (src_p.prefixlen)
92 /* we completely ignore srcdest routes for now. */
93 return 0;
94
ca10883e
DS
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
e9047736 113 if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD)
ca10883e
DS
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
121static int
122babel_zebra_read_ipv4 (int command, struct zclient *zclient,
0eb167b9 123 zebra_size_t length, vrf_id_t vrf)
ca10883e
DS
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);
e9047736
DS
139 api.instance = stream_getw (s);
140 api.flags = stream_getl (s);
ca10883e
DS
141 api.message = stream_getc (s);
142
e959008b 143 /* IPv4 prefix. */
ca10883e 144 prefix.family = AF_INET;
e959008b 145 prefix.prefixlen = MIN (IPV4_MAX_PREFIXLEN, stream_getc (s));
ca10883e
DS
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
e9047736 166 if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) {
ca10883e
DS
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
ca10883e
DS
175/* [Babel Command] */
176DEFUN (babel_redistribute_type,
177 babel_redistribute_type_cmd,
dd8765ca
RW
178 "[no] redistribute <ipv4 " FRR_IP_REDIST_STR_BABELD "|ipv6 " FRR_IP6_REDIST_STR_BABELD ">",
179 NO_STR
ca10883e 180 "Redistribute\n"
dd8765ca
RW
181 "Redistribute IPv4 routes\n"
182 FRR_IP_REDIST_HELP_STR_BABELD
183 "Redistribute IPv6 routes\n"
184 FRR_IP6_REDIST_HELP_STR_BABELD)
ca10883e 185{
dd8765ca
RW
186 int negate = 0;
187 int family;
188 int afi;
ca10883e 189 int type;
dd8765ca 190 int idx = 0;
ca10883e 191
dd8765ca
RW
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)
f1a05de9 197 return CMD_WARNING_CONFIG_FAILED;
ca10883e 198
dd8765ca
RW
199 afi = family2afi(family);
200 if (!afi)
201 return CMD_WARNING_CONFIG_FAILED;
ca10883e 202
dd8765ca 203 type = proto_redistnum(afi, argv[idx + 2]->text);
ca10883e 204 if (type < 0) {
dd8765ca 205 vty_out (vty, "Invalid type %s\n", argv[idx + 2]->arg);
f1a05de9 206 return CMD_WARNING_CONFIG_FAILED;
ca10883e
DS
207 }
208
dd8765ca
RW
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 }
ca10883e
DS
215 return CMD_SUCCESS;
216}
217
218#ifndef NO_DEBUG
219/* [Babel Command] */
220DEFUN (debug_babel,
221 debug_babel_cmd,
f7bf422e 222 "debug babel <common|kernel|filter|timeout|interface|route|all>",
ca10883e
DS
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
5c7571d4 243 vty_out (vty, "Invalid type %s\n", argv[2]->arg);
ca10883e 244
f1a05de9 245 return CMD_WARNING_CONFIG_FAILED;
ca10883e
DS
246}
247
248/* [Babel Command] */
249DEFUN (no_debug_babel,
250 no_debug_babel_cmd,
f7bf422e 251 "no debug babel <common|kernel|filter|timeout|interface|route|all>",
ca10883e
DS
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
5c7571d4 273 vty_out (vty, "Invalid type %s\n", argv[3]->arg);
ca10883e 274
f1a05de9 275 return CMD_WARNING_CONFIG_FAILED;
ca10883e
DS
276}
277#endif /* NO_DEBUG */
278
279/* Output "debug" statement lines, if necessary. */
280int
281debug_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 {
5c7571d4 290 vty_out (vty, "debug babel all\n");
ca10883e
DS
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 {
5c7571d4 301 vty_out (vty, "debug babel %s\n", debug_type[i].str);
ca10883e
DS
302 lines++;
303 }
304 if (lines)
305 {
5c7571d4 306 vty_out (vty, "!\n");
ca10883e
DS
307 lines++;
308 }
309 return lines;
310#endif /* NO_DEBUG */
311}
312
87f6dc50
DS
313DEFUN_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
abdcf266
DS
327static void
328babel_zebra_connected (struct zclient *zclient)
329{
330 zclient_send_reg_requests (zclient, VRF_DEFAULT);
331}
332
ca10883e
DS
333void babelz_zebra_init(void)
334{
335 zclient = zclient_new(master);
336 zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0);
337
abdcf266 338 zclient->zebra_connected = babel_zebra_connected;
ca10883e
DS
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
ca10883e 350 install_element(BABEL_NODE, &babel_redistribute_type_cmd);
ca10883e
DS
351 install_element(ENABLE_NODE, &debug_babel_cmd);
352 install_element(ENABLE_NODE, &no_debug_babel_cmd);
353 install_element(CONFIG_NODE, &debug_babel_cmd);
354 install_element(CONFIG_NODE, &no_debug_babel_cmd);
87f6dc50
DS
355
356 install_element(VIEW_NODE, &show_debugging_babel_cmd);
ca10883e
DS
357}
358
ca10883e
DS
359void
360babel_zebra_close_connexion(void)
361{
362 zclient_stop(zclient);
6b02aecb 363 zclient_free(zclient);
ca10883e 364}