]> git.proxmox.com Git - mirror_frr.git/blame - babeld/babel_zebra.c
zebra: Refactor kernel_rtm to be a bit smarter about how it handles options
[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
74489921 57/* Zebra route add and delete treatment. */
ca10883e 58static int
74489921
RW
59babel_zebra_read_route (int command, struct zclient *zclient,
60 zebra_size_t length, vrf_id_t vrf)
ca10883e 61{
74489921 62 struct zapi_route api;
ca10883e 63
74489921
RW
64 if (zapi_route_decode(zclient->ibuf, &api) < 0)
65 return -1;
ca10883e 66
74489921
RW
67 /* we completely ignore srcdest routes for now. */
68 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
69 return 0;
ca10883e 70
74489921
RW
71 if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD) {
72 babel_route_add(&api);
ca10883e 73 } else {
74489921 74 babel_route_delete(&api);
ca10883e
DS
75 }
76
77 return 0;
78}
79
ca10883e
DS
80/* [Babel Command] */
81DEFUN (babel_redistribute_type,
82 babel_redistribute_type_cmd,
dd8765ca
RW
83 "[no] redistribute <ipv4 " FRR_IP_REDIST_STR_BABELD "|ipv6 " FRR_IP6_REDIST_STR_BABELD ">",
84 NO_STR
ca10883e 85 "Redistribute\n"
dd8765ca
RW
86 "Redistribute IPv4 routes\n"
87 FRR_IP_REDIST_HELP_STR_BABELD
88 "Redistribute IPv6 routes\n"
89 FRR_IP6_REDIST_HELP_STR_BABELD)
ca10883e 90{
dd8765ca
RW
91 int negate = 0;
92 int family;
93 int afi;
ca10883e 94 int type;
dd8765ca 95 int idx = 0;
ca10883e 96
dd8765ca
RW
97 if (argv_find(argv, argc, "no", &idx))
98 negate = 1;
99 argv_find(argv, argc, "redistribute", &idx);
100 family = str2family(argv[idx + 1]->text);
101 if (family < 0)
f1a05de9 102 return CMD_WARNING_CONFIG_FAILED;
ca10883e 103
dd8765ca
RW
104 afi = family2afi(family);
105 if (!afi)
106 return CMD_WARNING_CONFIG_FAILED;
ca10883e 107
dd8765ca 108 type = proto_redistnum(afi, argv[idx + 2]->text);
ca10883e 109 if (type < 0) {
dd8765ca 110 vty_out (vty, "Invalid type %s\n", argv[idx + 2]->arg);
f1a05de9 111 return CMD_WARNING_CONFIG_FAILED;
ca10883e
DS
112 }
113
dd8765ca
RW
114 if (!negate)
115 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type, 0, VRF_DEFAULT);
116 else {
117 zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type, 0, VRF_DEFAULT);
118 /* perhaps should we remove xroutes having the same type... */
119 }
ca10883e
DS
120 return CMD_SUCCESS;
121}
122
123#ifndef NO_DEBUG
124/* [Babel Command] */
125DEFUN (debug_babel,
126 debug_babel_cmd,
f7bf422e 127 "debug babel <common|kernel|filter|timeout|interface|route|all>",
ca10883e
DS
128 "Enable debug messages for specific or all part.\n"
129 "Babel information\n"
130 "Common messages (default)\n"
131 "Kernel messages\n"
132 "Filter messages\n"
133 "Timeout messages\n"
134 "Interface messages\n"
135 "Route messages\n"
136 "All messages\n")
137{
138 int i;
139
140 for(i = 0; debug_type[i].str != NULL; i++) {
141 if (strncmp (debug_type[i].str, argv[2]->arg,
142 debug_type[i].str_min_len) == 0) {
143 debug |= debug_type[i].type;
144 return CMD_SUCCESS;
145 }
146 }
147
5c7571d4 148 vty_out (vty, "Invalid type %s\n", argv[2]->arg);
ca10883e 149
f1a05de9 150 return CMD_WARNING_CONFIG_FAILED;
ca10883e
DS
151}
152
153/* [Babel Command] */
154DEFUN (no_debug_babel,
155 no_debug_babel_cmd,
f7bf422e 156 "no debug babel <common|kernel|filter|timeout|interface|route|all>",
ca10883e
DS
157 NO_STR
158 "Disable debug messages for specific or all part.\n"
159 "Babel information\n"
160 "Common messages (default)\n"
161 "Kernel messages\n"
162 "Filter messages\n"
163 "Timeout messages\n"
164 "Interface messages\n"
165 "Route messages\n"
166 "All messages\n")
167{
168 int i;
169
170 for (i = 0; debug_type[i].str; i++) {
171 if (strncmp(debug_type[i].str, argv[3]->arg,
172 debug_type[i].str_min_len) == 0) {
173 debug &= ~debug_type[i].type;
174 return CMD_SUCCESS;
175 }
176 }
177
5c7571d4 178 vty_out (vty, "Invalid type %s\n", argv[3]->arg);
ca10883e 179
f1a05de9 180 return CMD_WARNING_CONFIG_FAILED;
ca10883e
DS
181}
182#endif /* NO_DEBUG */
183
184/* Output "debug" statement lines, if necessary. */
185int
186debug_babel_config_write (struct vty * vty)
187{
188#ifdef NO_DEBUG
189 return 0;
190#else
191 int i, lines = 0;
192
193 if (debug == BABEL_DEBUG_ALL)
194 {
5c7571d4 195 vty_out (vty, "debug babel all\n");
ca10883e
DS
196 lines++;
197 }
198 else
199 for (i = 0; debug_type[i].str != NULL; i++)
200 if
201 (
202 debug_type[i].type != BABEL_DEBUG_ALL
203 && CHECK_FLAG (debug, debug_type[i].type)
204 )
205 {
5c7571d4 206 vty_out (vty, "debug babel %s\n", debug_type[i].str);
ca10883e
DS
207 lines++;
208 }
209 if (lines)
210 {
5c7571d4 211 vty_out (vty, "!\n");
ca10883e
DS
212 lines++;
213 }
214 return lines;
215#endif /* NO_DEBUG */
216}
217
87f6dc50
DS
218DEFUN_NOSH (show_debugging_babel,
219 show_debugging_babel_cmd,
220 "show debugging [babel]",
221 SHOW_STR
222 DEBUG_STR
223 "Babel")
224{
225 vty_out(vty, "BABEL debugging status\n");
226
227 debug_babel_config_write(vty);
228
229 return CMD_SUCCESS;
230}
231
abdcf266
DS
232static void
233babel_zebra_connected (struct zclient *zclient)
234{
235 zclient_send_reg_requests (zclient, VRF_DEFAULT);
236}
237
ca10883e
DS
238void babelz_zebra_init(void)
239{
26f63a1e 240 zclient = zclient_new(master, &zclient_options_default);
342213ea 241 zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0, &babeld_privs);
ca10883e 242
abdcf266 243 zclient->zebra_connected = babel_zebra_connected;
ca10883e
DS
244 zclient->interface_add = babel_interface_add;
245 zclient->interface_delete = babel_interface_delete;
246 zclient->interface_up = babel_interface_up;
247 zclient->interface_down = babel_interface_down;
248 zclient->interface_address_add = babel_interface_address_add;
249 zclient->interface_address_delete = babel_interface_address_delete;
74489921
RW
250 zclient->redistribute_route_add = babel_zebra_read_route;
251 zclient->redistribute_route_del = babel_zebra_read_route;
ca10883e 252
ca10883e 253 install_element(BABEL_NODE, &babel_redistribute_type_cmd);
ca10883e
DS
254 install_element(ENABLE_NODE, &debug_babel_cmd);
255 install_element(ENABLE_NODE, &no_debug_babel_cmd);
256 install_element(CONFIG_NODE, &debug_babel_cmd);
257 install_element(CONFIG_NODE, &no_debug_babel_cmd);
87f6dc50
DS
258
259 install_element(VIEW_NODE, &show_debugging_babel_cmd);
ca10883e
DS
260}
261
ca10883e
DS
262void
263babel_zebra_close_connexion(void)
264{
265 zclient_stop(zclient);
6b02aecb 266 zclient_free(zclient);
ca10883e 267}