]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_vty_fabricd.c
isisd: retrofit 'set-overload-bit' and 'set-attached-bit' cmds
[mirror_frr.git] / isisd / isis_vty_fabricd.c
1 /*
2 * IS-IS Rout(e)ing protocol - isis_vty_fabricd.c
3 *
4 * This file contains the CLI that is specific to OpenFabric
5 *
6 * Copyright (C) 2018 Christian Franke, for NetDEF, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public Licenseas published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; see the file COPYING; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22 #include <zebra.h>
23
24 #include "command.h"
25
26 #include "isisd/isisd.h"
27 #include "isisd/isis_vty_common.h"
28 #include "isisd/fabricd.h"
29 #include "isisd/isis_tlvs.h"
30 #include "isisd/isis_misc.h"
31 #include "isisd/isis_lsp.h"
32 #include "isisd/isis_csm.h"
33 #include "isisd/isis_circuit.h"
34
35 DEFUN (fabric_tier,
36 fabric_tier_cmd,
37 "fabric-tier (0-14)",
38 "Statically configure the tier to advertise\n"
39 "Tier to advertise\n")
40 {
41 VTY_DECLVAR_CONTEXT(isis_area, area);
42
43 uint8_t tier = atoi(argv[1]->arg);
44
45 fabricd_configure_tier(area, tier);
46 return CMD_SUCCESS;
47 }
48
49 DEFUN (no_fabric_tier,
50 no_fabric_tier_cmd,
51 "no fabric-tier [(0-14)]",
52 NO_STR
53 "Statically configure the tier to advertise\n"
54 "Tier to advertise\n")
55 {
56 VTY_DECLVAR_CONTEXT(isis_area, area);
57
58 fabricd_configure_tier(area, ISIS_TIER_UNDEFINED);
59 return CMD_SUCCESS;
60 }
61
62 DEFUN (triggered_csnp,
63 triggered_csnp_cmd,
64 "triggered-csnp-delay (100-10000) [always]",
65 "Configure the delay for triggered CSNPs\n"
66 "Delay in milliseconds\n"
67 "Trigger CSNP for all LSPs, not only circuit-scoped\n")
68 {
69 VTY_DECLVAR_CONTEXT(isis_area, area);
70
71 int csnp_delay = atoi(argv[1]->arg);
72 bool always_send_csnp = (argc == 3);
73
74 fabricd_configure_triggered_csnp(area, csnp_delay, always_send_csnp);
75 return CMD_SUCCESS;
76 }
77
78 DEFUN (no_triggered_csnp,
79 no_triggered_csnp_cmd,
80 "no triggered-csnp-delay [(100-10000) [always]]",
81 NO_STR
82 "Configure the delay for triggered CSNPs\n"
83 "Delay in milliseconds\n"
84 "Trigger CSNP for all LSPs, not only circuit-scoped\n")
85 {
86 VTY_DECLVAR_CONTEXT(isis_area, area);
87
88 fabricd_configure_triggered_csnp(area, FABRICD_DEFAULT_CSNP_DELAY,
89 false);
90 return CMD_SUCCESS;
91 }
92
93 static void lsp_print_flooding(struct vty *vty, struct isis_lsp *lsp)
94 {
95 char lspid[255];
96
97 lspid_print(lsp->hdr.lsp_id, lspid, true, true);
98 vty_out(vty, "Flooding information for %s\n", lspid);
99
100 if (!lsp->flooding_neighbors[TX_LSP_NORMAL]) {
101 vty_out(vty, " Never received.\n");
102 return;
103 }
104
105 vty_out(vty, " Last received on: %s (",
106 lsp->flooding_interface ?
107 lsp->flooding_interface : "(null)");
108
109 time_t uptime = time(NULL) - lsp->flooding_time;
110 struct tm *tm = gmtime(&uptime);
111
112 if (uptime < ONE_DAY_SECOND)
113 vty_out(vty, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min,
114 tm->tm_sec);
115 else if (uptime < ONE_WEEK_SECOND)
116 vty_out(vty, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour,
117 tm->tm_min);
118 else
119 vty_out(vty, "%02dw%dd%02dh", tm->tm_yday / 7,
120 tm->tm_yday - ((tm->tm_yday / 7) * 7),
121 tm->tm_hour);
122 vty_out(vty, " ago)\n");
123
124 if (lsp->flooding_circuit_scoped) {
125 vty_out(vty, " Received as circuit-scoped LSP, so not "
126 "flooded.\n");
127 return;
128 }
129
130 for (enum isis_tx_type type = TX_LSP_NORMAL;
131 type <= TX_LSP_CIRCUIT_SCOPED; type++) {
132 struct listnode *node;
133 uint8_t *neighbor_id;
134
135 vty_out(vty, " %s:\n",
136 (type == TX_LSP_NORMAL) ? "RF" : "DNR");
137 for (ALL_LIST_ELEMENTS_RO(lsp->flooding_neighbors[type],
138 node, neighbor_id)) {
139 vty_out(vty, " %s\n",
140 print_sys_hostname(neighbor_id));
141 }
142 }
143 }
144
145 DEFUN (show_lsp_flooding,
146 show_lsp_flooding_cmd,
147 "show openfabric flooding [WORD]",
148 SHOW_STR
149 PROTO_HELP
150 "Flooding information\n"
151 "LSP ID\n")
152 {
153 const char *lspid = NULL;
154
155 if (argc == 4)
156 lspid = argv[3]->arg;
157
158 struct listnode *node;
159 struct isis_area *area;
160
161 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
162 dict_t *lspdb = area->lspdb[ISIS_LEVEL2 - 1];
163
164 vty_out(vty, "Area %s:\n", area->area_tag ?
165 area->area_tag : "null");
166
167 if (lspid) {
168 struct isis_lsp *lsp = lsp_for_arg(lspid, lspdb);
169
170 if (lsp)
171 lsp_print_flooding(vty, lsp);
172
173 continue;
174 }
175
176 for (dnode_t *dnode = dict_first(lspdb); dnode;
177 dnode = dict_next(lspdb, dnode)) {
178 lsp_print_flooding(vty, dnode_get(dnode));
179 vty_out(vty, "\n");
180 }
181 }
182
183 return CMD_SUCCESS;
184 }
185
186 DEFUN (ip_router_isis,
187 ip_router_isis_cmd,
188 "ip router " PROTO_NAME " WORD",
189 "Interface Internet Protocol config commands\n"
190 "IP router interface commands\n"
191 PROTO_HELP
192 "Routing process tag\n")
193 {
194 int idx_afi = 0;
195 int idx_word = 3;
196 VTY_DECLVAR_CONTEXT(interface, ifp);
197 struct isis_circuit *circuit;
198 struct isis_area *area;
199 const char *af = argv[idx_afi]->arg;
200 const char *area_tag = argv[idx_word]->arg;
201
202 /* Prevent more than one area per circuit */
203 circuit = circuit_scan_by_ifp(ifp);
204 if (circuit && circuit->area) {
205 if (strcmp(circuit->area->area_tag, area_tag)) {
206 vty_out(vty, "ISIS circuit is already defined on %s\n",
207 circuit->area->area_tag);
208 return CMD_ERR_NOTHING_TODO;
209 }
210 }
211
212 area = isis_area_lookup(area_tag);
213 if (!area)
214 area = isis_area_create(area_tag);
215
216 if (!circuit || !circuit->area) {
217 circuit = isis_circuit_create(area, ifp);
218
219 if (circuit->state != C_STATE_CONF
220 && circuit->state != C_STATE_UP) {
221 vty_out(vty,
222 "Couldn't bring up interface, please check log.\n");
223 return CMD_WARNING_CONFIG_FAILED;
224 }
225 }
226
227 bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router;
228 if (af[2] != '\0')
229 ipv6 = true;
230 else
231 ip = true;
232
233 isis_circuit_af_set(circuit, ip, ipv6);
234 return CMD_SUCCESS;
235 }
236
237 DEFUN (ip6_router_isis,
238 ip6_router_isis_cmd,
239 "ipv6 router " PROTO_NAME " WORD",
240 "Interface Internet Protocol config commands\n"
241 "IP router interface commands\n"
242 PROTO_HELP
243 "Routing process tag\n")
244 {
245 return ip_router_isis(self, vty, argc, argv);
246 }
247
248 DEFUN (no_ip_router_isis,
249 no_ip_router_isis_cmd,
250 "no <ip|ipv6> router " PROTO_NAME " WORD",
251 NO_STR
252 "Interface Internet Protocol config commands\n"
253 "IP router interface commands\n"
254 "IP router interface commands\n"
255 PROTO_HELP
256 "Routing process tag\n")
257 {
258 int idx_afi = 1;
259 int idx_word = 4;
260 VTY_DECLVAR_CONTEXT(interface, ifp);
261 struct isis_area *area;
262 struct isis_circuit *circuit;
263 const char *af = argv[idx_afi]->arg;
264 const char *area_tag = argv[idx_word]->arg;
265
266 area = isis_area_lookup(area_tag);
267 if (!area) {
268 vty_out(vty, "Can't find ISIS instance %s\n",
269 area_tag);
270 return CMD_ERR_NO_MATCH;
271 }
272
273 circuit = circuit_lookup_by_ifp(ifp, area->circuit_list);
274 if (!circuit) {
275 vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name);
276 return CMD_ERR_NO_MATCH;
277 }
278
279 bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router;
280 if (af[2] != '\0')
281 ipv6 = false;
282 else
283 ip = false;
284
285 isis_circuit_af_set(circuit, ip, ipv6);
286 return CMD_SUCCESS;
287 }
288
289 DEFUN (set_overload_bit,
290 set_overload_bit_cmd,
291 "set-overload-bit",
292 "Set overload bit to avoid any transit traffic\n")
293 {
294 VTY_DECLVAR_CONTEXT(isis_area, area);
295
296 isis_area_overload_bit_set(area, true);
297 return CMD_SUCCESS;
298 }
299
300 DEFUN (no_set_overload_bit,
301 no_set_overload_bit_cmd,
302 "no set-overload-bit",
303 "Reset overload bit to accept transit traffic\n"
304 "Reset overload bit\n")
305 {
306 VTY_DECLVAR_CONTEXT(isis_area, area);
307
308 isis_area_overload_bit_set(area, false);
309 return CMD_SUCCESS;
310 }
311
312 void isis_vty_daemon_init(void)
313 {
314 install_element(ROUTER_NODE, &fabric_tier_cmd);
315 install_element(ROUTER_NODE, &no_fabric_tier_cmd);
316 install_element(ROUTER_NODE, &triggered_csnp_cmd);
317 install_element(ROUTER_NODE, &no_triggered_csnp_cmd);
318
319 install_element(ENABLE_NODE, &show_lsp_flooding_cmd);
320
321 install_element(INTERFACE_NODE, &ip_router_isis_cmd);
322 install_element(INTERFACE_NODE, &ip6_router_isis_cmd);
323 install_element(INTERFACE_NODE, &no_ip_router_isis_cmd);
324
325 install_element(ROUTER_NODE, &set_overload_bit_cmd);
326 install_element(ROUTER_NODE, &no_set_overload_bit_cmd);
327 }