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