]>
Commit | Line | Data |
---|---|---|
2fb975da TT |
1 | /* NHRP vty handling |
2 | * Copyright (c) 2014-2015 Timo Teräs | |
3 | * | |
4 | * This file is free software: you may copy, redistribute and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation, either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | */ | |
9 | ||
10 | #include "zebra.h" | |
11 | #include "command.h" | |
12 | #include "zclient.h" | |
13 | #include "stream.h" | |
14 | ||
15 | #include "nhrpd.h" | |
16 | #include "netlink.h" | |
17 | ||
18 | static struct cmd_node zebra_node = { | |
19 | .node = ZEBRA_NODE, | |
20 | .prompt = "%s(config-router)# ", | |
21 | .vtysh = 1, | |
22 | }; | |
23 | ||
24 | static struct cmd_node nhrp_interface_node = { | |
25 | .node = INTERFACE_NODE, | |
26 | .prompt = "%s(config-if)# ", | |
27 | .vtysh = 1, | |
28 | }; | |
29 | ||
819dc8bb | 30 | #define NHRP_DEBUG_FLAGS_CMD "<all|common|event|interface|kernel|route|vici>" |
2fb975da TT |
31 | |
32 | #define NHRP_DEBUG_FLAGS_STR \ | |
33 | "All messages\n" \ | |
34 | "Common messages (default)\n" \ | |
35 | "Event manager messages\n" \ | |
36 | "Interface messages\n" \ | |
37 | "Kernel messages\n" \ | |
38 | "Route messages\n" \ | |
39 | "VICI messages\n" | |
40 | ||
41 | static const struct message debug_flags_desc[] = { | |
42 | { NHRP_DEBUG_ALL, "all" }, | |
43 | { NHRP_DEBUG_COMMON, "common" }, | |
44 | { NHRP_DEBUG_IF, "interface" }, | |
45 | { NHRP_DEBUG_KERNEL, "kernel" }, | |
46 | { NHRP_DEBUG_ROUTE, "route" }, | |
47 | { NHRP_DEBUG_VICI, "vici" }, | |
48 | { NHRP_DEBUG_EVENT, "event" }, | |
49 | { 0, NULL }, | |
50 | }; | |
51 | ||
52 | static const struct message interface_flags_desc[] = { | |
53 | { NHRP_IFF_SHORTCUT, "shortcut" }, | |
54 | { NHRP_IFF_REDIRECT, "redirect" }, | |
55 | { NHRP_IFF_REG_NO_UNIQUE, "registration no-unique" }, | |
56 | { 0, NULL }, | |
57 | }; | |
58 | ||
59 | static int nhrp_vty_return(struct vty *vty, int ret) | |
60 | { | |
61 | static const char * const errmsgs[] = { | |
62 | [NHRP_ERR_FAIL] = "Command failed", | |
63 | [NHRP_ERR_NO_MEMORY] = "Out of memory", | |
64 | [NHRP_ERR_UNSUPPORTED_INTERFACE] = "NHRP not supported on this interface", | |
65 | [NHRP_ERR_NHRP_NOT_ENABLED] = "NHRP not enabled (set 'nhrp network-id' first)", | |
66 | [NHRP_ERR_ENTRY_EXISTS] = "Entry exists already", | |
67 | [NHRP_ERR_ENTRY_NOT_FOUND] = "Entry not found", | |
68 | [NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH] = "Protocol address family does not match command (ip/ipv6 mismatch)", | |
69 | }; | |
70 | const char *str = NULL; | |
71 | char buf[256]; | |
72 | ||
73 | if (ret == NHRP_OK) | |
74 | return CMD_SUCCESS; | |
75 | ||
76 | if (ret > 0 && ret <= (int)ZEBRA_NUM_OF(errmsgs)) | |
77 | if (errmsgs[ret]) | |
78 | str = errmsgs[ret]; | |
79 | ||
80 | if (!str) { | |
81 | str = buf; | |
82 | snprintf(buf, sizeof(buf), "Unknown error %d", ret); | |
83 | } | |
84 | ||
85 | vty_out (vty, "%% %s%s", str, VTY_NEWLINE); | |
86 | ||
87 | return CMD_WARNING; | |
88 | } | |
89 | ||
90 | static int toggle_flag( | |
91 | struct vty *vty, const struct message *flag_desc, | |
92 | const char *name, int on_off, unsigned *flags) | |
93 | { | |
94 | int i; | |
95 | ||
96 | for (i = 0; flag_desc[i].str != NULL; i++) { | |
97 | if (strcmp(flag_desc[i].str, name) != 0) | |
98 | continue; | |
99 | if (on_off) | |
100 | *flags |= flag_desc[i].key; | |
101 | else | |
102 | *flags &= ~flag_desc[i].key; | |
103 | return CMD_SUCCESS; | |
104 | } | |
105 | ||
106 | vty_out(vty, "%% Invalid value %s%s", name, VTY_NEWLINE); | |
107 | return CMD_WARNING; | |
108 | } | |
109 | ||
110 | #ifndef NO_DEBUG | |
111 | ||
112 | DEFUN(show_debugging_nhrp, show_debugging_nhrp_cmd, | |
113 | "show debugging nhrp", | |
114 | SHOW_STR | |
115 | "Debugging information\n" | |
116 | "NHRP configuration\n") | |
117 | { | |
118 | int i; | |
119 | ||
120 | vty_out(vty, "NHRP debugging status:%s", VTY_NEWLINE); | |
121 | ||
122 | for (i = 0; debug_flags_desc[i].str != NULL; i++) { | |
123 | if (debug_flags_desc[i].key == NHRP_DEBUG_ALL) | |
124 | continue; | |
125 | if (!(debug_flags_desc[i].key & debug_flags)) | |
126 | continue; | |
127 | ||
128 | vty_out(vty, " NHRP %s debugging is on%s", | |
129 | debug_flags_desc[i].str, VTY_NEWLINE); | |
130 | } | |
131 | ||
132 | return CMD_SUCCESS; | |
133 | } | |
134 | ||
135 | DEFUN(debug_nhrp, debug_nhrp_cmd, | |
136 | "debug nhrp " NHRP_DEBUG_FLAGS_CMD, | |
137 | "Enable debug messages for specific or all parts.\n" | |
138 | "NHRP information\n" | |
139 | NHRP_DEBUG_FLAGS_STR) | |
140 | { | |
819dc8bb | 141 | return toggle_flag(vty, debug_flags_desc, argv[2]->text, 1, &debug_flags); |
2fb975da TT |
142 | } |
143 | ||
144 | DEFUN(no_debug_nhrp, no_debug_nhrp_cmd, | |
145 | "no debug nhrp " NHRP_DEBUG_FLAGS_CMD, | |
146 | NO_STR | |
147 | "Disable debug messages for specific or all parts.\n" | |
148 | "NHRP information\n" | |
149 | NHRP_DEBUG_FLAGS_STR) | |
150 | { | |
819dc8bb | 151 | return toggle_flag(vty, debug_flags_desc, argv[3]->text, 0, &debug_flags); |
2fb975da TT |
152 | } |
153 | ||
154 | #endif /* NO_DEBUG */ | |
155 | ||
156 | static int nhrp_config_write(struct vty *vty) | |
157 | { | |
158 | #ifndef NO_DEBUG | |
159 | if (debug_flags == NHRP_DEBUG_ALL) { | |
160 | vty_out(vty, "debug nhrp all%s", VTY_NEWLINE); | |
161 | } else { | |
162 | int i; | |
163 | ||
164 | for (i = 0; debug_flags_desc[i].str != NULL; i++) { | |
165 | if (debug_flags_desc[i].key == NHRP_DEBUG_ALL) | |
166 | continue; | |
167 | if (!(debug_flags & debug_flags_desc[i].key)) | |
168 | continue; | |
169 | vty_out(vty, "debug nhrp %s%s", debug_flags_desc[i].str, VTY_NEWLINE); | |
170 | } | |
171 | } | |
172 | vty_out(vty, "!%s", VTY_NEWLINE); | |
173 | #endif /* NO_DEBUG */ | |
174 | ||
175 | if (nhrp_event_socket_path) { | |
176 | vty_out(vty, "nhrp event socket %s%s", | |
177 | nhrp_event_socket_path, VTY_NEWLINE); | |
178 | } | |
179 | if (netlink_nflog_group) { | |
180 | vty_out(vty, "nhrp nflog-group %d%s", | |
181 | netlink_nflog_group, VTY_NEWLINE); | |
182 | } | |
183 | ||
184 | return 0; | |
185 | } | |
186 | ||
187 | #define IP_STR "IP information\n" | |
188 | #define IPV6_STR "IPv6 information\n" | |
819dc8bb | 189 | #define AFI_CMD "<ip|ipv6>" |
2fb975da TT |
190 | #define AFI_STR IP_STR IPV6_STR |
191 | #define NHRP_STR "Next Hop Resolution Protocol functions\n" | |
192 | ||
819dc8bb | 193 | static afi_t cmd_to_afi(const struct cmd_token *tok) |
2fb975da | 194 | { |
819dc8bb | 195 | return strcmp(tok->text, "ipv6") == 0 ? AFI_IP6 : AFI_IP; |
2fb975da TT |
196 | } |
197 | ||
198 | static const char *afi_to_cmd(afi_t afi) | |
199 | { | |
200 | if (afi == AFI_IP6) return "ipv6"; | |
201 | return "ip"; | |
202 | } | |
203 | ||
204 | DEFUN(nhrp_event_socket, nhrp_event_socket_cmd, | |
205 | "nhrp event socket SOCKET", | |
206 | NHRP_STR | |
207 | "Event Manager commands\n" | |
208 | "Event Manager unix socket path\n" | |
209 | "Unix path for the socket") | |
210 | { | |
819dc8bb | 211 | evmgr_set_socket(argv[3]->arg); |
2fb975da TT |
212 | return CMD_SUCCESS; |
213 | } | |
214 | ||
215 | DEFUN(no_nhrp_event_socket, no_nhrp_event_socket_cmd, | |
216 | "no nhrp event socket [SOCKET]", | |
217 | NO_STR | |
218 | NHRP_STR | |
219 | "Event Manager commands\n" | |
220 | "Event Manager unix socket path\n" | |
221 | "Unix path for the socket") | |
222 | { | |
223 | evmgr_set_socket(NULL); | |
224 | return CMD_SUCCESS; | |
225 | } | |
226 | ||
227 | DEFUN(nhrp_nflog_group, nhrp_nflog_group_cmd, | |
819dc8bb | 228 | "nhrp nflog-group (1-65535)", |
2fb975da TT |
229 | NHRP_STR |
230 | "Specify NFLOG group number\n" | |
231 | "NFLOG group number\n") | |
232 | { | |
233 | uint32_t nfgroup; | |
234 | ||
819dc8bb | 235 | VTY_GET_INTEGER_RANGE("nflog-group", nfgroup, argv[2]->arg, 1, 65535); |
2fb975da TT |
236 | netlink_set_nflog_group(nfgroup); |
237 | ||
238 | return CMD_SUCCESS; | |
239 | } | |
240 | ||
241 | DEFUN(no_nhrp_nflog_group, no_nhrp_nflog_group_cmd, | |
819dc8bb | 242 | "no nhrp nflog-group [(1-65535)]", |
2fb975da TT |
243 | NO_STR |
244 | NHRP_STR | |
245 | "Specify NFLOG group number\n" | |
246 | "NFLOG group number\n") | |
247 | { | |
248 | netlink_set_nflog_group(0); | |
249 | return CMD_SUCCESS; | |
250 | } | |
251 | ||
252 | DEFUN(tunnel_protection, tunnel_protection_cmd, | |
819dc8bb | 253 | "tunnel protection vici profile PROFILE [fallback-profile FALLBACK]", |
2fb975da TT |
254 | "NHRP/GRE integration\n" |
255 | "IPsec protection\n" | |
256 | "VICI (StrongSwan)\n" | |
257 | "IPsec profile\n" | |
258 | "IPsec profile name\n" | |
259 | "Fallback IPsec profile\n" | |
260 | "Fallback IPsec profile name\n") | |
261 | { | |
819dc8bb | 262 | VTY_DECLVAR_CONTEXT(interface, ifp); |
2fb975da | 263 | |
819dc8bb DL |
264 | nhrp_interface_set_protection(ifp, argv[4]->arg, |
265 | argc > 6 ? argv[6]->arg : NULL); | |
2fb975da TT |
266 | return CMD_SUCCESS; |
267 | } | |
268 | ||
269 | DEFUN(no_tunnel_protection, no_tunnel_protection_cmd, | |
270 | "no tunnel protection", | |
271 | NO_STR | |
272 | "NHRP/GRE integration\n" | |
273 | "IPsec protection\n") | |
274 | { | |
819dc8bb | 275 | VTY_DECLVAR_CONTEXT(interface, ifp); |
2fb975da TT |
276 | |
277 | nhrp_interface_set_protection(ifp, NULL, NULL); | |
278 | return CMD_SUCCESS; | |
279 | } | |
280 | ||
281 | DEFUN(tunnel_source, tunnel_source_cmd, | |
282 | "tunnel source INTERFACE", | |
283 | "NHRP/GRE integration\n" | |
284 | "Tunnel device binding tracking\n" | |
285 | "Interface name\n") | |
286 | { | |
819dc8bb DL |
287 | VTY_DECLVAR_CONTEXT(interface, ifp); |
288 | nhrp_interface_set_source(ifp, argv[2]->arg); | |
2fb975da TT |
289 | return CMD_SUCCESS; |
290 | } | |
291 | ||
292 | DEFUN(no_tunnel_source, no_tunnel_source_cmd, | |
293 | "no tunnel source", | |
294 | "NHRP/GRE integration\n" | |
295 | "Tunnel device binding tracking\n" | |
296 | "Interface name\n") | |
297 | { | |
819dc8bb | 298 | VTY_DECLVAR_CONTEXT(interface, ifp); |
2fb975da TT |
299 | nhrp_interface_set_source(ifp, NULL); |
300 | return CMD_SUCCESS; | |
301 | } | |
302 | ||
303 | DEFUN(if_nhrp_network_id, if_nhrp_network_id_cmd, | |
819dc8bb | 304 | AFI_CMD " nhrp network-id (1-4294967295)", |
2fb975da TT |
305 | AFI_STR |
306 | NHRP_STR | |
307 | "Enable NHRP and specify network-id\n" | |
308 | "System local ID to specify interface group\n") | |
309 | { | |
819dc8bb | 310 | VTY_DECLVAR_CONTEXT(interface, ifp); |
2fb975da TT |
311 | struct nhrp_interface *nifp = ifp->info; |
312 | afi_t afi = cmd_to_afi(argv[0]); | |
313 | ||
819dc8bb | 314 | VTY_GET_INTEGER_RANGE("network-id", nifp->afi[afi].network_id, argv[3]->arg, 1, 4294967295); |
2fb975da TT |
315 | nhrp_interface_update(ifp); |
316 | ||
317 | return CMD_SUCCESS; | |
318 | } | |
319 | ||
320 | DEFUN(if_no_nhrp_network_id, if_no_nhrp_network_id_cmd, | |
819dc8bb | 321 | "no " AFI_CMD " nhrp network-id [(1-4294967295)]", |
2fb975da TT |
322 | NO_STR |
323 | AFI_STR | |
324 | NHRP_STR | |
325 | "Enable NHRP and specify network-id\n" | |
326 | "System local ID to specify interface group\n") | |
327 | { | |
819dc8bb | 328 | VTY_DECLVAR_CONTEXT(interface, ifp); |
2fb975da | 329 | struct nhrp_interface *nifp = ifp->info; |
819dc8bb | 330 | afi_t afi = cmd_to_afi(argv[1]); |
2fb975da TT |
331 | |
332 | nifp->afi[afi].network_id = 0; | |
333 | nhrp_interface_update(ifp); | |
334 | ||
335 | return CMD_SUCCESS; | |
336 | } | |
337 | ||
338 | DEFUN(if_nhrp_flags, if_nhrp_flags_cmd, | |
819dc8bb | 339 | AFI_CMD " nhrp <shortcut|redirect>", |
2fb975da TT |
340 | AFI_STR |
341 | NHRP_STR | |
342 | "Allow shortcut establishment\n" | |
343 | "Send redirect notifications\n") | |
344 | { | |
819dc8bb | 345 | VTY_DECLVAR_CONTEXT(interface, ifp); |
2fb975da TT |
346 | struct nhrp_interface *nifp = ifp->info; |
347 | afi_t afi = cmd_to_afi(argv[0]); | |
348 | ||
819dc8bb | 349 | return toggle_flag(vty, interface_flags_desc, argv[2]->text, 1, &nifp->afi[afi].flags); |
2fb975da TT |
350 | } |
351 | ||
352 | DEFUN(if_no_nhrp_flags, if_no_nhrp_flags_cmd, | |
819dc8bb | 353 | "no " AFI_CMD " nhrp <shortcut|redirect>", |
2fb975da TT |
354 | NO_STR |
355 | AFI_STR | |
356 | NHRP_STR | |
357 | "Allow shortcut establishment\n" | |
358 | "Send redirect notifications\n") | |
359 | { | |
819dc8bb | 360 | VTY_DECLVAR_CONTEXT(interface, ifp); |
2fb975da | 361 | struct nhrp_interface *nifp = ifp->info; |
819dc8bb | 362 | afi_t afi = cmd_to_afi(argv[1]); |
2fb975da | 363 | |
819dc8bb | 364 | return toggle_flag(vty, interface_flags_desc, argv[3]->text, 0, &nifp->afi[afi].flags); |
2fb975da TT |
365 | } |
366 | ||
367 | DEFUN(if_nhrp_reg_flags, if_nhrp_reg_flags_cmd, | |
819dc8bb | 368 | AFI_CMD " nhrp registration no-unique", |
2fb975da TT |
369 | AFI_STR |
370 | NHRP_STR | |
371 | "Registration configuration\n" | |
372 | "Don't set unique flag\n") | |
373 | { | |
819dc8bb | 374 | VTY_DECLVAR_CONTEXT(interface, ifp); |
2fb975da TT |
375 | struct nhrp_interface *nifp = ifp->info; |
376 | afi_t afi = cmd_to_afi(argv[0]); | |
377 | char name[256]; | |
819dc8bb | 378 | snprintf(name, sizeof(name), "registration %s", argv[3]->text); |
2fb975da TT |
379 | return toggle_flag(vty, interface_flags_desc, name, 1, &nifp->afi[afi].flags); |
380 | } | |
381 | ||
382 | DEFUN(if_no_nhrp_reg_flags, if_no_nhrp_reg_flags_cmd, | |
819dc8bb | 383 | "no " AFI_CMD " nhrp registration no-unique", |
2fb975da TT |
384 | NO_STR |
385 | AFI_STR | |
386 | NHRP_STR | |
387 | "Registration configuration\n" | |
388 | "Don't set unique flag\n") | |
389 | { | |
819dc8bb | 390 | VTY_DECLVAR_CONTEXT(interface, ifp); |
2fb975da | 391 | struct nhrp_interface *nifp = ifp->info; |
819dc8bb | 392 | afi_t afi = cmd_to_afi(argv[1]); |
2fb975da | 393 | char name[256]; |
819dc8bb | 394 | snprintf(name, sizeof(name), "registration %s", argv[4]->text); |
2fb975da TT |
395 | return toggle_flag(vty, interface_flags_desc, name, 0, &nifp->afi[afi].flags); |
396 | } | |
397 | ||
398 | DEFUN(if_nhrp_holdtime, if_nhrp_holdtime_cmd, | |
819dc8bb | 399 | AFI_CMD " nhrp holdtime (1-65000)", |
2fb975da TT |
400 | AFI_STR |
401 | NHRP_STR | |
402 | "Specify NBMA address validity time\n" | |
403 | "Time in seconds that NBMA addresses are advertised valid\n") | |
404 | { | |
819dc8bb | 405 | VTY_DECLVAR_CONTEXT(interface, ifp); |
2fb975da TT |
406 | struct nhrp_interface *nifp = ifp->info; |
407 | afi_t afi = cmd_to_afi(argv[0]); | |
408 | ||
819dc8bb | 409 | VTY_GET_INTEGER_RANGE("holdtime", nifp->afi[afi].holdtime, argv[3]->arg, 1, 65000); |
2fb975da TT |
410 | nhrp_interface_update(ifp); |
411 | ||
412 | return CMD_SUCCESS; | |
413 | } | |
414 | ||
415 | DEFUN(if_no_nhrp_holdtime, if_no_nhrp_holdtime_cmd, | |
819dc8bb | 416 | "no " AFI_CMD " nhrp holdtime [(1-65000)]", |
2fb975da TT |
417 | NO_STR |
418 | AFI_STR | |
419 | NHRP_STR | |
420 | "Specify NBMA address validity time\n" | |
421 | "Time in seconds that NBMA addresses are advertised valid\n") | |
422 | { | |
819dc8bb | 423 | VTY_DECLVAR_CONTEXT(interface, ifp); |
2fb975da | 424 | struct nhrp_interface *nifp = ifp->info; |
819dc8bb | 425 | afi_t afi = cmd_to_afi(argv[1]); |
2fb975da TT |
426 | |
427 | nifp->afi[afi].holdtime = NHRPD_DEFAULT_HOLDTIME; | |
428 | nhrp_interface_update(ifp); | |
429 | ||
430 | return CMD_SUCCESS; | |
431 | } | |
432 | ||
433 | DEFUN(if_nhrp_mtu, if_nhrp_mtu_cmd, | |
819dc8bb | 434 | "ip nhrp mtu <(576-1500)|opennhrp>", |
2fb975da TT |
435 | IP_STR |
436 | NHRP_STR | |
437 | "Configure NHRP advertised MTU\n" | |
438 | "MTU value\n" | |
439 | "Advertise bound interface MTU similar to OpenNHRP") | |
440 | { | |
819dc8bb | 441 | VTY_DECLVAR_CONTEXT(interface, ifp); |
2fb975da TT |
442 | struct nhrp_interface *nifp = ifp->info; |
443 | ||
819dc8bb | 444 | if (argv[3]->arg[0] == 'o') { |
2fb975da TT |
445 | nifp->afi[AFI_IP].configured_mtu = -1; |
446 | } else { | |
819dc8bb | 447 | VTY_GET_INTEGER_RANGE("mtu", nifp->afi[AFI_IP].configured_mtu, argv[3]->arg, 576, 1500); |
2fb975da TT |
448 | } |
449 | nhrp_interface_update_mtu(ifp, AFI_IP); | |
450 | ||
451 | return CMD_SUCCESS; | |
452 | } | |
453 | ||
454 | DEFUN(if_no_nhrp_mtu, if_no_nhrp_mtu_cmd, | |
819dc8bb | 455 | "no ip nhrp mtu [(576-1500)|opennhrp]", |
2fb975da TT |
456 | NO_STR |
457 | IP_STR | |
458 | NHRP_STR | |
459 | "Configure NHRP advertised MTU\n" | |
460 | "MTU value\n" | |
461 | "Advertise bound interface MTU similar to OpenNHRP") | |
462 | { | |
819dc8bb | 463 | VTY_DECLVAR_CONTEXT(interface, ifp); |
2fb975da TT |
464 | struct nhrp_interface *nifp = ifp->info; |
465 | ||
466 | nifp->afi[AFI_IP].configured_mtu = 0; | |
467 | nhrp_interface_update_mtu(ifp, AFI_IP); | |
468 | return CMD_SUCCESS; | |
469 | } | |
470 | ||
471 | DEFUN(if_nhrp_map, if_nhrp_map_cmd, | |
819dc8bb | 472 | AFI_CMD " nhrp map <A.B.C.D|X:X::X:X> <A.B.C.D|local>", |
2fb975da TT |
473 | AFI_STR |
474 | NHRP_STR | |
475 | "Nexthop Server configuration\n" | |
476 | "IPv4 protocol address\n" | |
477 | "IPv6 protocol address\n" | |
478 | "IPv4 NBMA address\n" | |
479 | "Handle protocol address locally\n") | |
480 | { | |
819dc8bb | 481 | VTY_DECLVAR_CONTEXT(interface, ifp); |
2fb975da TT |
482 | afi_t afi = cmd_to_afi(argv[0]); |
483 | union sockunion proto_addr, nbma_addr; | |
484 | struct nhrp_cache *c; | |
485 | ||
819dc8bb | 486 | if (str2sockunion(argv[3]->arg, &proto_addr) < 0 || |
2fb975da TT |
487 | afi2family(afi) != sockunion_family(&proto_addr)) |
488 | return nhrp_vty_return(vty, NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH); | |
489 | ||
490 | c = nhrp_cache_get(ifp, &proto_addr, 1); | |
491 | if (!c) | |
492 | return nhrp_vty_return(vty, NHRP_ERR_FAIL); | |
493 | ||
494 | c->map = 1; | |
819dc8bb | 495 | if (strcmp(argv[4]->text, "local") == 0) { |
2fb975da TT |
496 | nhrp_cache_update_binding(c, NHRP_CACHE_LOCAL, 0, NULL, 0, NULL); |
497 | } else{ | |
819dc8bb | 498 | if (str2sockunion(argv[4]->arg, &nbma_addr) < 0) |
2fb975da TT |
499 | return nhrp_vty_return(vty, NHRP_ERR_FAIL); |
500 | nhrp_cache_update_binding(c, NHRP_CACHE_STATIC, 0, | |
501 | nhrp_peer_get(ifp, &nbma_addr), 0, NULL); | |
502 | } | |
503 | ||
504 | return CMD_SUCCESS; | |
505 | } | |
506 | ||
2d4eab22 | 507 | DEFUN(if_no_nhrp_map, if_no_nhrp_map_cmd, |
c1c17a0f | 508 | "no " AFI_CMD " nhrp map <A.B.C.D|X:X::X:X>", |
2d4eab22 TT |
509 | NO_STR |
510 | AFI_STR | |
511 | NHRP_STR | |
512 | "Nexthop Server configuration\n" | |
513 | "IPv4 protocol address\n" | |
514 | "IPv6 protocol address\n") | |
515 | { | |
516 | VTY_DECLVAR_CONTEXT(interface,ifp); | |
517 | afi_t afi = cmd_to_afi(argv[1]); | |
518 | union sockunion proto_addr; | |
519 | struct nhrp_cache *c; | |
520 | ||
521 | if (str2sockunion(argv[4]->arg, &proto_addr) < 0 || | |
522 | afi2family(afi) != sockunion_family(&proto_addr)) | |
523 | return nhrp_vty_return(vty, NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH); | |
524 | ||
525 | c = nhrp_cache_get(ifp, &proto_addr, 0); | |
526 | if (!c || !c->map) | |
527 | return nhrp_vty_return(vty, NHRP_ERR_ENTRY_NOT_FOUND); | |
528 | ||
529 | nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL); | |
530 | return CMD_SUCCESS; | |
531 | } | |
532 | ||
2fb975da | 533 | DEFUN(if_nhrp_nhs, if_nhrp_nhs_cmd, |
819dc8bb | 534 | AFI_CMD " nhrp nhs <A.B.C.D|X:X::X:X|dynamic> nbma <A.B.C.D|FQDN>", |
2fb975da TT |
535 | AFI_STR |
536 | NHRP_STR | |
537 | "Nexthop Server configuration\n" | |
538 | "IPv4 protocol address\n" | |
539 | "IPv6 protocol address\n" | |
540 | "Automatic detection of protocol address\n" | |
819dc8bb | 541 | "NBMA address\n" |
2fb975da TT |
542 | "IPv4 NBMA address\n" |
543 | "Fully qualified domain name for NBMA address(es)\n") | |
544 | { | |
819dc8bb | 545 | VTY_DECLVAR_CONTEXT(interface, ifp); |
2fb975da TT |
546 | afi_t afi = cmd_to_afi(argv[0]); |
547 | union sockunion proto_addr; | |
548 | int ret; | |
549 | ||
819dc8bb | 550 | if (str2sockunion(argv[3]->arg, &proto_addr) < 0) |
2fb975da TT |
551 | sockunion_family(&proto_addr) = AF_UNSPEC; |
552 | ||
819dc8bb | 553 | ret = nhrp_nhs_add(ifp, afi, &proto_addr, argv[5]->arg); |
2fb975da TT |
554 | return nhrp_vty_return(vty, ret); |
555 | } | |
556 | ||
557 | DEFUN(if_no_nhrp_nhs, if_no_nhrp_nhs_cmd, | |
819dc8bb | 558 | "no " AFI_CMD " nhrp nhs <A.B.C.D|X:X::X:X|dynamic> nbma <A.B.C.D|FQDN>", |
2fb975da TT |
559 | NO_STR |
560 | AFI_STR | |
561 | NHRP_STR | |
562 | "Nexthop Server configuration\n" | |
563 | "IPv4 protocol address\n" | |
564 | "IPv6 protocol address\n" | |
565 | "Automatic detection of protocol address\n" | |
819dc8bb | 566 | "NBMA address\n" |
2fb975da TT |
567 | "IPv4 NBMA address\n" |
568 | "Fully qualified domain name for NBMA address(es)\n") | |
569 | { | |
819dc8bb DL |
570 | VTY_DECLVAR_CONTEXT(interface, ifp); |
571 | afi_t afi = cmd_to_afi(argv[1]); | |
2fb975da TT |
572 | union sockunion proto_addr; |
573 | int ret; | |
574 | ||
819dc8bb | 575 | if (str2sockunion(argv[4]->arg, &proto_addr) < 0) |
2fb975da TT |
576 | sockunion_family(&proto_addr) = AF_UNSPEC; |
577 | ||
819dc8bb | 578 | ret = nhrp_nhs_del(ifp, afi, &proto_addr, argv[6]->arg); |
2fb975da TT |
579 | return nhrp_vty_return(vty, ret); |
580 | } | |
581 | ||
582 | struct info_ctx { | |
583 | struct vty *vty; | |
584 | afi_t afi; | |
585 | int count; | |
586 | }; | |
587 | ||
588 | static void show_ip_nhrp_cache(struct nhrp_cache *c, void *pctx) | |
589 | { | |
590 | struct info_ctx *ctx = pctx; | |
591 | struct vty *vty = ctx->vty; | |
592 | char buf[2][SU_ADDRSTRLEN]; | |
593 | ||
594 | if (ctx->afi != family2afi(sockunion_family(&c->remote_addr))) | |
595 | return; | |
596 | ||
597 | if (!ctx->count) { | |
598 | vty_out(vty, "%-8s %-8s %-24s %-24s %-6s %s%s", | |
599 | "Iface", | |
600 | "Type", | |
601 | "Protocol", | |
602 | "NBMA", | |
603 | "Flags", | |
604 | "Identity", | |
605 | VTY_NEWLINE); | |
606 | } | |
607 | ctx->count++; | |
608 | ||
609 | vty_out(ctx->vty, "%-8s %-8s %-24s %-24s %c%c%c %s%s", | |
610 | c->ifp->name, | |
611 | nhrp_cache_type_str[c->cur.type], | |
612 | sockunion2str(&c->remote_addr, buf[0], sizeof buf[0]), | |
613 | c->cur.peer ? sockunion2str(&c->cur.peer->vc->remote.nbma, buf[1], sizeof buf[1]) : "-", | |
614 | c->used ? 'U' : ' ', | |
615 | c->t_timeout ? 'T' : ' ', | |
616 | c->t_auth ? 'A' : ' ', | |
617 | c->cur.peer ? c->cur.peer->vc->remote.id : "-", | |
618 | VTY_NEWLINE); | |
619 | } | |
620 | ||
0ca036b4 TT |
621 | static void show_ip_nhrp_nhs(struct nhrp_nhs *n, struct nhrp_registration *reg, void *pctx) |
622 | { | |
623 | struct info_ctx *ctx = pctx; | |
624 | struct vty *vty = ctx->vty; | |
625 | char buf[2][SU_ADDRSTRLEN]; | |
626 | ||
627 | if (!ctx->count) { | |
628 | vty_out(vty, "%-8s %-24s %-16s %-16s%s", | |
629 | "Iface", | |
630 | "FQDN", | |
631 | "NBMA", | |
632 | "Protocol", | |
633 | VTY_NEWLINE); | |
634 | } | |
635 | ctx->count++; | |
636 | ||
637 | vty_out(vty, "%-8s %-24s %-16s %-16s%s", | |
638 | n->ifp->name, | |
639 | n->nbma_fqdn, | |
640 | (reg && reg->peer) ? sockunion2str(®->peer->vc->remote.nbma, buf[0], sizeof buf[0]) : "-", | |
641 | sockunion2str(reg ? ®->proto_addr : &n->proto_addr, buf[1], sizeof buf[1]), | |
642 | VTY_NEWLINE); | |
643 | } | |
644 | ||
645 | static void show_ip_nhrp_shortcut(struct nhrp_shortcut *s, void *pctx) | |
646 | { | |
647 | struct info_ctx *ctx = pctx; | |
648 | struct nhrp_cache *c; | |
649 | struct vty *vty = ctx->vty; | |
650 | char buf1[PREFIX_STRLEN], buf2[SU_ADDRSTRLEN]; | |
651 | ||
652 | if (!ctx->count) { | |
653 | vty_out(vty, "%-8s %-24s %-24s %s%s", | |
654 | "Type", | |
655 | "Prefix", | |
656 | "Via", | |
657 | "Identity", | |
658 | VTY_NEWLINE); | |
659 | } | |
660 | ctx->count++; | |
661 | ||
662 | c = s->cache; | |
663 | vty_out(ctx->vty, "%-8s %-24s %-24s %s%s", | |
664 | nhrp_cache_type_str[s->type], | |
665 | prefix2str(s->p, buf1, sizeof buf1), | |
666 | c ? sockunion2str(&c->remote_addr, buf2, sizeof buf2) : "", | |
667 | (c && c->cur.peer) ? c->cur.peer->vc->remote.id : "", | |
668 | VTY_NEWLINE); | |
669 | } | |
670 | ||
2fb975da TT |
671 | static void show_ip_opennhrp_cache(struct nhrp_cache *c, void *pctx) |
672 | { | |
673 | struct info_ctx *ctx = pctx; | |
674 | struct vty *vty = ctx->vty; | |
675 | char buf[SU_ADDRSTRLEN]; | |
676 | ||
677 | if (ctx->afi != family2afi(sockunion_family(&c->remote_addr))) | |
678 | return; | |
679 | ||
680 | vty_out(ctx->vty, | |
681 | "Type: %s%s" | |
682 | "Flags:%s%s%s" | |
683 | "Protocol-Address: %s/%zu%s", | |
684 | nhrp_cache_type_str[c->cur.type], | |
685 | VTY_NEWLINE, | |
686 | (c->cur.peer && c->cur.peer->online) ? " up": "", | |
687 | c->used ? " used": "", | |
688 | VTY_NEWLINE, | |
689 | sockunion2str(&c->remote_addr, buf, sizeof buf), | |
690 | 8 * family2addrsize(sockunion_family(&c->remote_addr)), | |
691 | VTY_NEWLINE); | |
692 | ||
693 | if (c->cur.peer) { | |
694 | vty_out(ctx->vty, | |
695 | "NBMA-Address: %s%s", | |
696 | sockunion2str(&c->cur.peer->vc->remote.nbma, buf, sizeof buf), | |
697 | VTY_NEWLINE); | |
698 | } | |
699 | ||
700 | if (sockunion_family(&c->cur.remote_nbma_natoa) != AF_UNSPEC) { | |
701 | vty_out(ctx->vty, | |
702 | "NBMA-NAT-OA-Address: %s%s", | |
703 | sockunion2str(&c->cur.remote_nbma_natoa, buf, sizeof buf), | |
704 | VTY_NEWLINE); | |
705 | } | |
706 | ||
707 | vty_out(ctx->vty, "%s", VTY_NEWLINE); | |
708 | } | |
709 | ||
2fb975da | 710 | DEFUN(show_ip_nhrp, show_ip_nhrp_cmd, |
0ca036b4 | 711 | "show " AFI_CMD " nhrp [cache|nhs|shortcut|opennhrp]", |
2fb975da TT |
712 | SHOW_STR |
713 | AFI_STR | |
714 | "NHRP information\n" | |
715 | "Forwarding cache information\n" | |
0ca036b4 | 716 | "Next hop server information\n" |
2fb975da TT |
717 | "Shortcut information\n" |
718 | "opennhrpctl style cache dump\n") | |
719 | { | |
720 | struct listnode *node; | |
721 | struct interface *ifp; | |
722 | struct info_ctx ctx = { | |
723 | .vty = vty, | |
819dc8bb | 724 | .afi = cmd_to_afi(argv[1]), |
2fb975da TT |
725 | }; |
726 | ||
819dc8bb DL |
727 | if (argc <= 3 || argv[3]->text[0] == 'c') { |
728 | for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) | |
2fb975da | 729 | nhrp_cache_foreach(ifp, show_ip_nhrp_cache, &ctx); |
0ca036b4 TT |
730 | } else if (argv[3]->text[0] == 'n') { |
731 | for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) | |
732 | nhrp_nhs_foreach(ifp, ctx.afi, show_ip_nhrp_nhs, &ctx); | |
733 | } else if (argv[3]->text[0] == 's') { | |
734 | nhrp_shortcut_foreach(ctx.afi, show_ip_nhrp_shortcut, &ctx); | |
735 | } else { | |
2fb975da TT |
736 | vty_out(vty, "Status: ok%s%s", VTY_NEWLINE, VTY_NEWLINE); |
737 | ctx.count++; | |
819dc8bb | 738 | for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) |
2fb975da | 739 | nhrp_cache_foreach(ifp, show_ip_opennhrp_cache, &ctx); |
2fb975da TT |
740 | } |
741 | ||
742 | if (!ctx.count) { | |
743 | vty_out(vty, "%% No entries%s", VTY_NEWLINE); | |
744 | return CMD_WARNING; | |
745 | } | |
746 | ||
747 | return CMD_SUCCESS; | |
748 | } | |
749 | ||
750 | static void show_dmvpn_entry(struct nhrp_vc *vc, void *ctx) | |
751 | { | |
752 | struct vty *vty = ctx; | |
753 | char buf[2][SU_ADDRSTRLEN]; | |
754 | ||
755 | vty_out(vty, "%-24s %-24s %c %-4d %-24s%s", | |
756 | sockunion2str(&vc->local.nbma, buf[0], sizeof buf[0]), | |
757 | sockunion2str(&vc->remote.nbma, buf[1], sizeof buf[1]), | |
758 | notifier_active(&vc->notifier_list) ? 'n' : ' ', | |
759 | vc->ipsec, | |
760 | vc->remote.id, | |
761 | VTY_NEWLINE); | |
762 | } | |
763 | ||
764 | DEFUN(show_dmvpn, show_dmvpn_cmd, | |
765 | "show dmvpn", | |
766 | SHOW_STR | |
767 | "DMVPN information\n") | |
768 | { | |
769 | vty_out(vty, "%-24s %-24s %-6s %-4s %-24s%s", | |
770 | "Src", | |
771 | "Dst", | |
772 | "Flags", | |
773 | "SAs", | |
774 | "Identity", | |
775 | VTY_NEWLINE); | |
776 | ||
777 | nhrp_vc_foreach(show_dmvpn_entry, vty); | |
778 | ||
779 | return CMD_SUCCESS; | |
780 | } | |
781 | ||
782 | static void clear_nhrp_cache(struct nhrp_cache *c, void *data) | |
783 | { | |
784 | struct info_ctx *ctx = data; | |
785 | if (c->cur.type <= NHRP_CACHE_CACHED) { | |
786 | nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL); | |
787 | ctx->count++; | |
788 | } | |
789 | } | |
790 | ||
791 | static void clear_nhrp_shortcut(struct nhrp_shortcut *s, void *data) | |
792 | { | |
793 | struct info_ctx *ctx = data; | |
794 | nhrp_shortcut_purge(s, 1); | |
795 | ctx->count++; | |
796 | } | |
797 | ||
798 | DEFUN(clear_nhrp, clear_nhrp_cmd, | |
819dc8bb | 799 | "clear " AFI_CMD " nhrp <cache|shortcut>", |
2fb975da TT |
800 | CLEAR_STR |
801 | AFI_STR | |
802 | NHRP_STR | |
803 | "Dynamic cache entries\n" | |
804 | "Shortcut entries\n") | |
805 | { | |
806 | struct listnode *node; | |
807 | struct interface *ifp; | |
808 | struct info_ctx ctx = { | |
809 | .vty = vty, | |
819dc8bb | 810 | .afi = cmd_to_afi(argv[1]), |
2fb975da TT |
811 | .count = 0, |
812 | }; | |
813 | ||
819dc8bb DL |
814 | if (argc <= 3 || argv[3]->text[0] == 'c') { |
815 | for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) | |
2fb975da TT |
816 | nhrp_cache_foreach(ifp, clear_nhrp_cache, &ctx); |
817 | } else { | |
818 | nhrp_shortcut_foreach(ctx.afi, clear_nhrp_shortcut, &ctx); | |
819 | } | |
820 | ||
821 | if (!ctx.count) { | |
822 | vty_out(vty, "%% No entries%s", VTY_NEWLINE); | |
823 | return CMD_WARNING; | |
824 | } | |
825 | ||
826 | vty_out(vty, "%% %d entries cleared%s", ctx.count, VTY_NEWLINE); | |
827 | return CMD_SUCCESS; | |
828 | } | |
829 | ||
830 | struct write_map_ctx { | |
831 | struct vty *vty; | |
832 | int family; | |
833 | const char *aficmd; | |
834 | }; | |
835 | ||
836 | static void interface_config_write_nhrp_map(struct nhrp_cache *c, void *data) | |
837 | { | |
838 | struct write_map_ctx *ctx = data; | |
839 | struct vty *vty = ctx->vty; | |
840 | char buf[2][SU_ADDRSTRLEN]; | |
841 | ||
842 | if (!c->map) return; | |
843 | if (sockunion_family(&c->remote_addr) != ctx->family) return; | |
844 | ||
845 | vty_out(vty, " %s nhrp map %s %s%s", | |
846 | ctx->aficmd, | |
847 | sockunion2str(&c->remote_addr, buf[0], sizeof buf[0]), | |
848 | c->cur.type == NHRP_CACHE_LOCAL ? "local" : | |
849 | sockunion2str(&c->cur.peer->vc->remote.nbma, buf[1], sizeof buf[1]), | |
850 | VTY_NEWLINE); | |
851 | } | |
852 | ||
853 | static int interface_config_write(struct vty *vty) | |
854 | { | |
855 | struct write_map_ctx mapctx; | |
856 | struct listnode *node; | |
857 | struct interface *ifp; | |
858 | struct nhrp_interface *nifp; | |
859 | struct nhrp_nhs *nhs; | |
860 | const char *aficmd; | |
861 | afi_t afi; | |
862 | char buf[SU_ADDRSTRLEN]; | |
863 | int i; | |
864 | ||
819dc8bb | 865 | for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { |
2fb975da TT |
866 | vty_out(vty, "interface %s%s", ifp->name, VTY_NEWLINE); |
867 | if (ifp->desc) | |
868 | vty_out(vty, " description %s%s", ifp->desc, VTY_NEWLINE); | |
869 | ||
870 | nifp = ifp->info; | |
871 | if (nifp->ipsec_profile) { | |
872 | vty_out(vty, " tunnel protection vici profile %s", | |
873 | nifp->ipsec_profile); | |
874 | if (nifp->ipsec_fallback_profile) | |
875 | vty_out(vty, " fallback-profile %s", | |
876 | nifp->ipsec_fallback_profile); | |
877 | vty_out(vty, "%s", VTY_NEWLINE); | |
878 | } | |
879 | if (nifp->source) | |
880 | vty_out(vty, " tunnel source %s%s", | |
881 | nifp->source, VTY_NEWLINE); | |
882 | ||
883 | for (afi = 0; afi < AFI_MAX; afi++) { | |
884 | struct nhrp_afi_data *ad = &nifp->afi[afi]; | |
885 | ||
886 | aficmd = afi_to_cmd(afi); | |
887 | ||
888 | if (ad->network_id) | |
889 | vty_out(vty, " %s nhrp network-id %u%s", | |
890 | aficmd, ad->network_id, | |
891 | VTY_NEWLINE); | |
892 | ||
893 | if (ad->holdtime != NHRPD_DEFAULT_HOLDTIME) | |
894 | vty_out(vty, " %s nhrp holdtime %u%s", | |
895 | aficmd, ad->holdtime, | |
896 | VTY_NEWLINE); | |
897 | ||
898 | if (ad->configured_mtu < 0) | |
899 | vty_out(vty, " %s nhrp mtu opennhrp%s", | |
900 | aficmd, VTY_NEWLINE); | |
901 | else if (ad->configured_mtu) | |
902 | vty_out(vty, " %s nhrp mtu %u%s", | |
903 | aficmd, ad->configured_mtu, | |
904 | VTY_NEWLINE); | |
905 | ||
906 | for (i = 0; interface_flags_desc[i].str != NULL; i++) { | |
907 | if (!(ad->flags & interface_flags_desc[i].key)) | |
908 | continue; | |
909 | vty_out(vty, " %s nhrp %s%s", | |
910 | aficmd, interface_flags_desc[i].str, VTY_NEWLINE); | |
911 | } | |
912 | ||
913 | mapctx = (struct write_map_ctx) { | |
914 | .vty = vty, | |
915 | .family = afi2family(afi), | |
916 | .aficmd = aficmd, | |
917 | }; | |
918 | nhrp_cache_foreach(ifp, interface_config_write_nhrp_map, &mapctx); | |
919 | ||
920 | list_for_each_entry(nhs, &ad->nhslist_head, nhslist_entry) { | |
921 | vty_out(vty, " %s nhrp nhs %s nbma %s%s", | |
922 | aficmd, | |
923 | sockunion_family(&nhs->proto_addr) == AF_UNSPEC ? "dynamic" : sockunion2str(&nhs->proto_addr, buf, sizeof buf), | |
924 | nhs->nbma_fqdn, | |
925 | VTY_NEWLINE); | |
926 | } | |
927 | } | |
928 | ||
929 | vty_out (vty, "!%s", VTY_NEWLINE); | |
930 | } | |
931 | ||
932 | return 0; | |
933 | } | |
934 | ||
935 | void nhrp_config_init(void) | |
936 | { | |
937 | install_node(&zebra_node, nhrp_config_write); | |
938 | install_default(ZEBRA_NODE); | |
939 | ||
940 | /* global commands */ | |
941 | install_element(VIEW_NODE, &show_debugging_nhrp_cmd); | |
942 | install_element(VIEW_NODE, &show_ip_nhrp_cmd); | |
943 | install_element(VIEW_NODE, &show_dmvpn_cmd); | |
2fb975da TT |
944 | install_element(ENABLE_NODE, &clear_nhrp_cmd); |
945 | ||
946 | install_element(ENABLE_NODE, &debug_nhrp_cmd); | |
947 | install_element(ENABLE_NODE, &no_debug_nhrp_cmd); | |
948 | ||
949 | install_element(CONFIG_NODE, &debug_nhrp_cmd); | |
950 | install_element(CONFIG_NODE, &no_debug_nhrp_cmd); | |
951 | ||
952 | install_element(CONFIG_NODE, &nhrp_event_socket_cmd); | |
953 | install_element(CONFIG_NODE, &no_nhrp_event_socket_cmd); | |
954 | install_element(CONFIG_NODE, &nhrp_nflog_group_cmd); | |
955 | install_element(CONFIG_NODE, &no_nhrp_nflog_group_cmd); | |
956 | ||
957 | /* interface specific commands */ | |
958 | install_node(&nhrp_interface_node, interface_config_write); | |
2fb975da | 959 | |
819dc8bb | 960 | if_cmd_init(); |
2fb975da TT |
961 | install_element(INTERFACE_NODE, &tunnel_protection_cmd); |
962 | install_element(INTERFACE_NODE, &no_tunnel_protection_cmd); | |
963 | install_element(INTERFACE_NODE, &tunnel_source_cmd); | |
964 | install_element(INTERFACE_NODE, &no_tunnel_source_cmd); | |
965 | install_element(INTERFACE_NODE, &if_nhrp_network_id_cmd); | |
966 | install_element(INTERFACE_NODE, &if_no_nhrp_network_id_cmd); | |
967 | install_element(INTERFACE_NODE, &if_nhrp_holdtime_cmd); | |
968 | install_element(INTERFACE_NODE, &if_no_nhrp_holdtime_cmd); | |
969 | install_element(INTERFACE_NODE, &if_nhrp_mtu_cmd); | |
970 | install_element(INTERFACE_NODE, &if_no_nhrp_mtu_cmd); | |
971 | install_element(INTERFACE_NODE, &if_nhrp_flags_cmd); | |
972 | install_element(INTERFACE_NODE, &if_no_nhrp_flags_cmd); | |
973 | install_element(INTERFACE_NODE, &if_nhrp_reg_flags_cmd); | |
974 | install_element(INTERFACE_NODE, &if_no_nhrp_reg_flags_cmd); | |
975 | install_element(INTERFACE_NODE, &if_nhrp_map_cmd); | |
2d4eab22 | 976 | install_element(INTERFACE_NODE, &if_no_nhrp_map_cmd); |
2fb975da TT |
977 | install_element(INTERFACE_NODE, &if_nhrp_nhs_cmd); |
978 | install_element(INTERFACE_NODE, &if_no_nhrp_nhs_cmd); | |
979 | } |