]> git.proxmox.com Git - mirror_frr.git/blob - babeld/babel_zebra.c
Merge pull request #13086 from donaldsharp/suppress_fib_pending
[mirror_frr.git] / babeld / babel_zebra.c
1 // SPDX-License-Identifier: MIT
2 /*
3 Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
4 */
5
6 /* FRR's includes */
7 #include <zebra.h>
8 #include "command.h"
9 #include "zclient.h"
10 #include "stream.h"
11
12 /* babel's includes*/
13 #include "babel_zebra.h"
14 #include "babel_interface.h"
15 #include "xroute.h"
16 #include "util.h"
17
18 void babelz_zebra_init(void);
19
20
21 /* we must use a pointer because of zclient.c's functions (new, free). */
22 struct zclient *zclient;
23
24 /* Debug types */
25 static const struct {
26 int type;
27 int str_min_len;
28 const char *str;
29 } debug_type[] = {
30 {BABEL_DEBUG_COMMON, 1, "common"},
31 {BABEL_DEBUG_KERNEL, 1, "kernel"},
32 {BABEL_DEBUG_FILTER, 1, "filter"},
33 {BABEL_DEBUG_TIMEOUT, 1, "timeout"},
34 {BABEL_DEBUG_IF, 1, "interface"},
35 {BABEL_DEBUG_ROUTE, 1, "route"},
36 {BABEL_DEBUG_ALL, 1, "all"},
37 {0, 0, NULL}
38 };
39
40 /* Zebra route add and delete treatment. */
41 static int
42 babel_zebra_read_route (ZAPI_CALLBACK_ARGS)
43 {
44 struct zapi_route api;
45
46 if (zapi_route_decode(zclient->ibuf, &api) < 0)
47 return -1;
48
49 /* we completely ignore srcdest routes for now. */
50 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
51 return 0;
52
53 if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD) {
54 babel_route_add(&api);
55 } else {
56 babel_route_delete(&api);
57 }
58
59 return 0;
60 }
61
62 /* [Babel Command] */
63 DEFUN (babel_redistribute_type,
64 babel_redistribute_type_cmd,
65 "[no] redistribute <ipv4 " FRR_IP_REDIST_STR_BABELD "|ipv6 " FRR_IP6_REDIST_STR_BABELD ">",
66 NO_STR
67 "Redistribute\n"
68 "Redistribute IPv4 routes\n"
69 FRR_IP_REDIST_HELP_STR_BABELD
70 "Redistribute IPv6 routes\n"
71 FRR_IP6_REDIST_HELP_STR_BABELD)
72 {
73 int negate = 0;
74 int family;
75 int afi;
76 int type;
77 int idx = 0;
78
79 if (argv_find(argv, argc, "no", &idx))
80 negate = 1;
81 argv_find(argv, argc, "redistribute", &idx);
82 family = str2family(argv[idx + 1]->text);
83 if (family < 0)
84 return CMD_WARNING_CONFIG_FAILED;
85
86 afi = family2afi(family);
87 if (!afi)
88 return CMD_WARNING_CONFIG_FAILED;
89
90 type = proto_redistnum(afi, argv[idx + 2]->text);
91 if (type < 0) {
92 vty_out (vty, "Invalid type %s\n", argv[idx + 2]->arg);
93 return CMD_WARNING_CONFIG_FAILED;
94 }
95
96 if (!negate)
97 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type, 0, VRF_DEFAULT);
98 else {
99 zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type, 0, VRF_DEFAULT);
100 /* perhaps should we remove xroutes having the same type... */
101 }
102 return CMD_SUCCESS;
103 }
104
105 #ifndef NO_DEBUG
106 /* [Babel Command] */
107 DEFUN (debug_babel,
108 debug_babel_cmd,
109 "debug babel <common|kernel|filter|timeout|interface|route|all>",
110 "Enable debug messages for specific or all part.\n"
111 "Babel information\n"
112 "Common messages (default)\n"
113 "Kernel messages\n"
114 "Filter messages\n"
115 "Timeout messages\n"
116 "Interface messages\n"
117 "Route messages\n"
118 "All messages\n")
119 {
120 int i;
121
122 for(i = 0; debug_type[i].str != NULL; i++) {
123 if (strncmp (debug_type[i].str, argv[2]->arg,
124 debug_type[i].str_min_len) == 0) {
125 SET_FLAG(debug, debug_type[i].type);
126 return CMD_SUCCESS;
127 }
128 }
129
130 vty_out (vty, "Invalid type %s\n", argv[2]->arg);
131
132 return CMD_WARNING_CONFIG_FAILED;
133 }
134
135 /* [Babel Command] */
136 DEFUN (no_debug_babel,
137 no_debug_babel_cmd,
138 "no debug babel <common|kernel|filter|timeout|interface|route|all>",
139 NO_STR
140 "Disable debug messages for specific or all part.\n"
141 "Babel information\n"
142 "Common messages (default)\n"
143 "Kernel messages\n"
144 "Filter messages\n"
145 "Timeout messages\n"
146 "Interface messages\n"
147 "Route messages\n"
148 "All messages\n")
149 {
150 int i;
151
152 for (i = 0; debug_type[i].str; i++) {
153 if (strncmp(debug_type[i].str, argv[3]->arg,
154 debug_type[i].str_min_len) == 0) {
155 UNSET_FLAG(debug, debug_type[i].type);
156 return CMD_SUCCESS;
157 }
158 }
159
160 vty_out (vty, "Invalid type %s\n", argv[3]->arg);
161
162 return CMD_WARNING_CONFIG_FAILED;
163 }
164 #endif /* NO_DEBUG */
165
166 /* Output "debug" statement lines, if necessary. */
167 int
168 debug_babel_config_write (struct vty * vty)
169 {
170 #ifdef NO_DEBUG
171 return 0;
172 #else
173 int i, lines = 0;
174
175 if (debug == BABEL_DEBUG_ALL)
176 {
177 vty_out (vty, "debug babel all\n");
178 lines++;
179 }
180 else
181 {
182 for (i = 0; debug_type[i].str != NULL; i++)
183 {
184 if (debug_type[i].type != BABEL_DEBUG_ALL
185 && CHECK_FLAG (debug, debug_type[i].type))
186 {
187 vty_out (vty, "debug babel %s\n", debug_type[i].str);
188 lines++;
189 }
190 }
191 }
192
193 if (lines)
194 {
195 vty_out (vty, "!\n");
196 lines++;
197 }
198 return lines;
199 #endif /* NO_DEBUG */
200 }
201
202 DEFUN_NOSH (show_debugging_babel,
203 show_debugging_babel_cmd,
204 "show debugging [babel]",
205 SHOW_STR
206 DEBUG_STR
207 "Babel")
208 {
209 vty_out(vty, "BABEL debugging status\n");
210
211 debug_babel_config_write(vty);
212
213 cmd_show_lib_debugs(vty);
214
215 return CMD_SUCCESS;
216 }
217
218 static void
219 babel_zebra_connected (struct zclient *zclient)
220 {
221 zclient_send_reg_requests (zclient, VRF_DEFAULT);
222 }
223
224 static zclient_handler *const babel_handlers[] = {
225 [ZEBRA_INTERFACE_ADDRESS_ADD] = babel_interface_address_add,
226 [ZEBRA_INTERFACE_ADDRESS_DELETE] = babel_interface_address_delete,
227 [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = babel_zebra_read_route,
228 [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = babel_zebra_read_route,
229 };
230
231 void babelz_zebra_init(void)
232 {
233 zclient = zclient_new(master, &zclient_options_default, babel_handlers,
234 array_size(babel_handlers));
235 zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0, &babeld_privs);
236
237 zclient->zebra_connected = babel_zebra_connected;
238
239 install_element(BABEL_NODE, &babel_redistribute_type_cmd);
240 install_element(ENABLE_NODE, &debug_babel_cmd);
241 install_element(ENABLE_NODE, &no_debug_babel_cmd);
242 install_element(CONFIG_NODE, &debug_babel_cmd);
243 install_element(CONFIG_NODE, &no_debug_babel_cmd);
244
245 install_element(ENABLE_NODE, &show_debugging_babel_cmd);
246 }
247
248 void
249 babel_zebra_close_connexion(void)
250 {
251 zclient_stop(zclient);
252 zclient_free(zclient);
253 }