nhrp_vty.c 25 KB

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