bgp_mplsvpn.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744
  1. /* MPLS-VPN
  2. Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
  3. This file is part of GNU Zebra.
  4. GNU Zebra is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by the
  6. Free Software Foundation; either version 2, or (at your option) any
  7. later version.
  8. GNU Zebra is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Zebra; see the file COPYING. If not, write to the Free
  14. Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  15. 02111-1307, USA. */
  16. #include <zebra.h>
  17. #include "command.h"
  18. #include "prefix.h"
  19. #include "log.h"
  20. #include "memory.h"
  21. #include "stream.h"
  22. #include "bgpd/bgpd.h"
  23. #include "bgpd/bgp_table.h"
  24. #include "bgpd/bgp_route.h"
  25. #include "bgpd/bgp_attr.h"
  26. #include "bgpd/bgp_mplsvpn.h"
  27. static u_int16_t
  28. decode_rd_type (u_char *pnt)
  29. {
  30. u_int16_t v;
  31. v = ((u_int16_t) *pnt++ << 8);
  32. v |= (u_int16_t) *pnt;
  33. return v;
  34. }
  35. u_int32_t
  36. decode_label (u_char *pnt)
  37. {
  38. u_int32_t l;
  39. l = ((u_int32_t) *pnt++ << 12);
  40. l |= (u_int32_t) *pnt++ << 4;
  41. l |= (u_int32_t) ((*pnt & 0xf0) >> 4);
  42. return l;
  43. }
  44. static void
  45. decode_rd_as (u_char *pnt, struct rd_as *rd_as)
  46. {
  47. rd_as->as = (u_int16_t) *pnt++ << 8;
  48. rd_as->as |= (u_int16_t) *pnt++;
  49. rd_as->val = ((u_int32_t) *pnt++ << 24);
  50. rd_as->val |= ((u_int32_t) *pnt++ << 16);
  51. rd_as->val |= ((u_int32_t) *pnt++ << 8);
  52. rd_as->val |= (u_int32_t) *pnt;
  53. }
  54. static void
  55. decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
  56. {
  57. memcpy (&rd_ip->ip, pnt, 4);
  58. pnt += 4;
  59. rd_ip->val = ((u_int16_t) *pnt++ << 8);
  60. rd_ip->val |= (u_int16_t) *pnt;
  61. }
  62. int
  63. bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr,
  64. struct bgp_nlri *packet)
  65. {
  66. u_char *pnt;
  67. u_char *lim;
  68. struct prefix p;
  69. int psize;
  70. int prefixlen;
  71. u_int16_t type;
  72. struct rd_as rd_as;
  73. struct rd_ip rd_ip;
  74. struct prefix_rd prd;
  75. u_char *tagpnt;
  76. /* Check peer status. */
  77. if (peer->status != Established)
  78. return 0;
  79. /* Make prefix_rd */
  80. prd.family = AF_UNSPEC;
  81. prd.prefixlen = 64;
  82. pnt = packet->nlri;
  83. lim = pnt + packet->length;
  84. for (; pnt < lim; pnt += psize)
  85. {
  86. /* Clear prefix structure. */
  87. memset (&p, 0, sizeof (struct prefix));
  88. /* Fetch prefix length. */
  89. prefixlen = *pnt++;
  90. p.family = AF_INET;
  91. psize = PSIZE (prefixlen);
  92. if (prefixlen < 88)
  93. {
  94. zlog_err ("prefix length is less than 88: %d", prefixlen);
  95. return -1;
  96. }
  97. /* XXX: Not doing anything with the label */
  98. decode_label (pnt);
  99. /* Copyr label to prefix. */
  100. tagpnt = pnt;;
  101. /* Copy routing distinguisher to rd. */
  102. memcpy (&prd.val, pnt + 3, 8);
  103. /* Decode RD type. */
  104. type = decode_rd_type (pnt + 3);
  105. /* Decode RD value. */
  106. if (type == RD_TYPE_AS)
  107. decode_rd_as (pnt + 5, &rd_as);
  108. else if (type == RD_TYPE_IP)
  109. decode_rd_ip (pnt + 5, &rd_ip);
  110. else
  111. {
  112. zlog_err ("Invalid RD type %d", type);
  113. return -1;
  114. }
  115. p.prefixlen = prefixlen - 88;
  116. memcpy (&p.u.prefix, pnt + 11, psize - 11);
  117. #if 0
  118. if (type == RD_TYPE_AS)
  119. zlog_info ("prefix %ld:%ld:%ld:%s/%d", label, rd_as.as, rd_as.val,
  120. inet_ntoa (p.u.prefix4), p.prefixlen);
  121. else if (type == RD_TYPE_IP)
  122. zlog_info ("prefix %ld:%s:%ld:%s/%d", label, inet_ntoa (rd_ip.ip),
  123. rd_ip.val, inet_ntoa (p.u.prefix4), p.prefixlen);
  124. #endif /* 0 */
  125. if (pnt + psize > lim)
  126. return -1;
  127. if (attr)
  128. bgp_update (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
  129. ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
  130. else
  131. bgp_withdraw (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
  132. ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
  133. }
  134. /* Packet length consistency check. */
  135. if (pnt != lim)
  136. return -1;
  137. return 0;
  138. }
  139. int
  140. str2prefix_rd (const char *str, struct prefix_rd *prd)
  141. {
  142. int ret;
  143. char *p;
  144. char *p2;
  145. struct stream *s;
  146. char *half;
  147. struct in_addr addr;
  148. s = stream_new (8);
  149. prd->family = AF_UNSPEC;
  150. prd->prefixlen = 64;
  151. p = strchr (str, ':');
  152. if (! p)
  153. return 0;
  154. if (! all_digit (p + 1))
  155. return 0;
  156. half = XMALLOC (MTYPE_TMP, (p - str) + 1);
  157. memcpy (half, str, (p - str));
  158. half[p - str] = '\0';
  159. p2 = strchr (str, '.');
  160. if (! p2)
  161. {
  162. if (! all_digit (half))
  163. {
  164. XFREE (MTYPE_TMP, half);
  165. return 0;
  166. }
  167. stream_putw (s, RD_TYPE_AS);
  168. stream_putw (s, atoi (half));
  169. stream_putl (s, atol (p + 1));
  170. }
  171. else
  172. {
  173. ret = inet_aton (half, &addr);
  174. if (! ret)
  175. {
  176. XFREE (MTYPE_TMP, half);
  177. return 0;
  178. }
  179. stream_putw (s, RD_TYPE_IP);
  180. stream_put_in_addr (s, &addr);
  181. stream_putw (s, atol (p + 1));
  182. }
  183. memcpy (prd->val, s->data, 8);
  184. return 1;
  185. }
  186. int
  187. str2tag (const char *str, u_char *tag)
  188. {
  189. unsigned long l;
  190. char *endptr;
  191. u_int32_t t;
  192. if (*str == '-')
  193. return 0;
  194. errno = 0;
  195. l = strtoul (str, &endptr, 10);
  196. if (*endptr != '\0' || errno || l > UINT32_MAX)
  197. return 0;
  198. t = (u_int32_t) l;
  199. tag[0] = (u_char)(t >> 12);
  200. tag[1] = (u_char)(t >> 4);
  201. tag[2] = (u_char)(t << 4);
  202. return 1;
  203. }
  204. char *
  205. prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
  206. {
  207. u_char *pnt;
  208. u_int16_t type;
  209. struct rd_as rd_as;
  210. struct rd_ip rd_ip;
  211. if (size < RD_ADDRSTRLEN)
  212. return NULL;
  213. pnt = prd->val;
  214. type = decode_rd_type (pnt);
  215. if (type == RD_TYPE_AS)
  216. {
  217. decode_rd_as (pnt + 2, &rd_as);
  218. snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
  219. return buf;
  220. }
  221. else if (type == RD_TYPE_IP)
  222. {
  223. decode_rd_ip (pnt + 2, &rd_ip);
  224. snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
  225. return buf;
  226. }
  227. return NULL;
  228. }
  229. /* For testing purpose, static route of MPLS-VPN. */
  230. DEFUN (vpnv4_network,
  231. vpnv4_network_cmd,
  232. "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
  233. "Specify a network to announce via BGP\n"
  234. "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
  235. "Specify Route Distinguisher\n"
  236. "VPN Route Distinguisher\n"
  237. "BGP tag\n"
  238. "tag value\n")
  239. {
  240. return bgp_static_set_vpnv4 (vty, argv[0], argv[1], argv[2]);
  241. }
  242. /* For testing purpose, static route of MPLS-VPN. */
  243. DEFUN (no_vpnv4_network,
  244. no_vpnv4_network_cmd,
  245. "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
  246. NO_STR
  247. "Specify a network to announce via BGP\n"
  248. "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
  249. "Specify Route Distinguisher\n"
  250. "VPN Route Distinguisher\n"
  251. "BGP tag\n"
  252. "tag value\n")
  253. {
  254. return bgp_static_unset_vpnv4 (vty, argv[0], argv[1], argv[2]);
  255. }
  256. static int
  257. show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
  258. {
  259. struct bgp *bgp;
  260. struct bgp_table *table;
  261. struct bgp_node *rn;
  262. struct bgp_node *rm;
  263. struct attr *attr;
  264. int rd_header;
  265. int header = 1;
  266. char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
  267. bgp = bgp_get_default ();
  268. if (bgp == NULL)
  269. {
  270. vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
  271. return CMD_WARNING;
  272. }
  273. for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
  274. rn = bgp_route_next (rn))
  275. {
  276. if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
  277. continue;
  278. if ((table = rn->info) != NULL)
  279. {
  280. rd_header = 1;
  281. for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
  282. if ((attr = rm->info) != NULL)
  283. {
  284. if (header)
  285. {
  286. vty_out (vty, "BGP table version is 0, local router ID is %s%s",
  287. inet_ntoa (bgp->router_id), VTY_NEWLINE);
  288. vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
  289. VTY_NEWLINE);
  290. vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
  291. VTY_NEWLINE, VTY_NEWLINE);
  292. vty_out (vty, v4_header, VTY_NEWLINE);
  293. header = 0;
  294. }
  295. if (rd_header)
  296. {
  297. u_int16_t type;
  298. struct rd_as rd_as;
  299. struct rd_ip rd_ip;
  300. u_char *pnt;
  301. pnt = rn->p.u.val;
  302. /* Decode RD type. */
  303. type = decode_rd_type (pnt);
  304. /* Decode RD value. */
  305. if (type == RD_TYPE_AS)
  306. decode_rd_as (pnt + 2, &rd_as);
  307. else if (type == RD_TYPE_IP)
  308. decode_rd_ip (pnt + 2, &rd_ip);
  309. vty_out (vty, "Route Distinguisher: ");
  310. if (type == RD_TYPE_AS)
  311. vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
  312. else if (type == RD_TYPE_IP)
  313. vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
  314. vty_out (vty, "%s", VTY_NEWLINE);
  315. rd_header = 0;
  316. }
  317. route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN);
  318. }
  319. }
  320. }
  321. return CMD_SUCCESS;
  322. }
  323. enum bgp_show_type
  324. {
  325. bgp_show_type_normal,
  326. bgp_show_type_regexp,
  327. bgp_show_type_prefix_list,
  328. bgp_show_type_filter_list,
  329. bgp_show_type_neighbor,
  330. bgp_show_type_cidr_only,
  331. bgp_show_type_prefix_longer,
  332. bgp_show_type_community_all,
  333. bgp_show_type_community,
  334. bgp_show_type_community_exact,
  335. bgp_show_type_community_list,
  336. bgp_show_type_community_list_exact
  337. };
  338. static int
  339. bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,
  340. void *output_arg, int tags)
  341. {
  342. struct bgp *bgp;
  343. struct bgp_table *table;
  344. struct bgp_node *rn;
  345. struct bgp_node *rm;
  346. struct bgp_info *ri;
  347. int rd_header;
  348. int header = 1;
  349. char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
  350. char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
  351. bgp = bgp_get_default ();
  352. if (bgp == NULL)
  353. {
  354. vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
  355. return CMD_WARNING;
  356. }
  357. for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
  358. {
  359. if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
  360. continue;
  361. if ((table = rn->info) != NULL)
  362. {
  363. rd_header = 1;
  364. for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
  365. for (ri = rm->info; ri; ri = ri->next)
  366. {
  367. if (type == bgp_show_type_neighbor)
  368. {
  369. union sockunion *su = output_arg;
  370. if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
  371. continue;
  372. }
  373. if (header)
  374. {
  375. if (tags)
  376. vty_out (vty, v4_header_tag, VTY_NEWLINE);
  377. else
  378. {
  379. vty_out (vty, "BGP table version is 0, local router ID is %s%s",
  380. inet_ntoa (bgp->router_id), VTY_NEWLINE);
  381. vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
  382. VTY_NEWLINE);
  383. vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
  384. VTY_NEWLINE, VTY_NEWLINE);
  385. vty_out (vty, v4_header, VTY_NEWLINE);
  386. }
  387. header = 0;
  388. }
  389. if (rd_header)
  390. {
  391. u_int16_t type;
  392. struct rd_as rd_as;
  393. struct rd_ip rd_ip;
  394. u_char *pnt;
  395. pnt = rn->p.u.val;
  396. /* Decode RD type. */
  397. type = decode_rd_type (pnt);
  398. /* Decode RD value. */
  399. if (type == RD_TYPE_AS)
  400. decode_rd_as (pnt + 2, &rd_as);
  401. else if (type == RD_TYPE_IP)
  402. decode_rd_ip (pnt + 2, &rd_ip);
  403. vty_out (vty, "Route Distinguisher: ");
  404. if (type == RD_TYPE_AS)
  405. vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
  406. else if (type == RD_TYPE_IP)
  407. vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
  408. vty_out (vty, "%s", VTY_NEWLINE);
  409. rd_header = 0;
  410. }
  411. if (tags)
  412. route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
  413. else
  414. route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
  415. }
  416. }
  417. }
  418. return CMD_SUCCESS;
  419. }
  420. DEFUN (show_ip_bgp_vpnv4_all,
  421. show_ip_bgp_vpnv4_all_cmd,
  422. "show ip bgp vpnv4 all",
  423. SHOW_STR
  424. IP_STR
  425. BGP_STR
  426. "Display VPNv4 NLRI specific information\n"
  427. "Display information about all VPNv4 NLRIs\n")
  428. {
  429. return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0);
  430. }
  431. DEFUN (show_ip_bgp_vpnv4_rd,
  432. show_ip_bgp_vpnv4_rd_cmd,
  433. "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",
  434. SHOW_STR
  435. IP_STR
  436. BGP_STR
  437. "Display VPNv4 NLRI specific information\n"
  438. "Display information for a route distinguisher\n"
  439. "VPN Route Distinguisher\n")
  440. {
  441. int ret;
  442. struct prefix_rd prd;
  443. ret = str2prefix_rd (argv[0], &prd);
  444. if (! ret)
  445. {
  446. vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
  447. return CMD_WARNING;
  448. }
  449. return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0);
  450. }
  451. DEFUN (show_ip_bgp_vpnv4_all_tags,
  452. show_ip_bgp_vpnv4_all_tags_cmd,
  453. "show ip bgp vpnv4 all tags",
  454. SHOW_STR
  455. IP_STR
  456. BGP_STR
  457. "Display VPNv4 NLRI specific information\n"
  458. "Display information about all VPNv4 NLRIs\n"
  459. "Display BGP tags for prefixes\n")
  460. {
  461. return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1);
  462. }
  463. DEFUN (show_ip_bgp_vpnv4_rd_tags,
  464. show_ip_bgp_vpnv4_rd_tags_cmd,
  465. "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
  466. SHOW_STR
  467. IP_STR
  468. BGP_STR
  469. "Display VPNv4 NLRI specific information\n"
  470. "Display information for a route distinguisher\n"
  471. "VPN Route Distinguisher\n"
  472. "Display BGP tags for prefixes\n")
  473. {
  474. int ret;
  475. struct prefix_rd prd;
  476. ret = str2prefix_rd (argv[0], &prd);
  477. if (! ret)
  478. {
  479. vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
  480. return CMD_WARNING;
  481. }
  482. return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1);
  483. }
  484. DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
  485. show_ip_bgp_vpnv4_all_neighbor_routes_cmd,
  486. "show ip bgp vpnv4 all neighbors A.B.C.D routes",
  487. SHOW_STR
  488. IP_STR
  489. BGP_STR
  490. "Display VPNv4 NLRI specific information\n"
  491. "Display information about all VPNv4 NLRIs\n"
  492. "Detailed information on TCP and BGP neighbor connections\n"
  493. "Neighbor to display information about\n"
  494. "Display routes learned from neighbor\n")
  495. {
  496. union sockunion su;
  497. struct peer *peer;
  498. int ret;
  499. ret = str2sockunion (argv[0], &su);
  500. if (ret < 0)
  501. {
  502. vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
  503. return CMD_WARNING;
  504. }
  505. peer = peer_lookup (NULL, &su);
  506. if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
  507. {
  508. vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
  509. return CMD_WARNING;
  510. }
  511. return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0);
  512. }
  513. DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
  514. show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,
  515. "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes",
  516. SHOW_STR
  517. IP_STR
  518. BGP_STR
  519. "Display VPNv4 NLRI specific information\n"
  520. "Display information for a route distinguisher\n"
  521. "VPN Route Distinguisher\n"
  522. "Detailed information on TCP and BGP neighbor connections\n"
  523. "Neighbor to display information about\n"
  524. "Display routes learned from neighbor\n")
  525. {
  526. int ret;
  527. union sockunion su;
  528. struct peer *peer;
  529. struct prefix_rd prd;
  530. ret = str2prefix_rd (argv[0], &prd);
  531. if (! ret)
  532. {
  533. vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
  534. return CMD_WARNING;
  535. }
  536. ret = str2sockunion (argv[1], &su);
  537. if (ret < 0)
  538. {
  539. vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
  540. return CMD_WARNING;
  541. }
  542. peer = peer_lookup (NULL, &su);
  543. if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
  544. {
  545. vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
  546. return CMD_WARNING;
  547. }
  548. return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0);
  549. }
  550. DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
  551. show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,
  552. "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes",
  553. SHOW_STR
  554. IP_STR
  555. BGP_STR
  556. "Display VPNv4 NLRI specific information\n"
  557. "Display information about all VPNv4 NLRIs\n"
  558. "Detailed information on TCP and BGP neighbor connections\n"
  559. "Neighbor to display information about\n"
  560. "Display the routes advertised to a BGP neighbor\n")
  561. {
  562. int ret;
  563. struct peer *peer;
  564. union sockunion su;
  565. ret = str2sockunion (argv[0], &su);
  566. if (ret < 0)
  567. {
  568. vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
  569. return CMD_WARNING;
  570. }
  571. peer = peer_lookup (NULL, &su);
  572. if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
  573. {
  574. vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
  575. return CMD_WARNING;
  576. }
  577. return show_adj_route_vpn (vty, peer, NULL);
  578. }
  579. DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
  580. show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,
  581. "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes",
  582. SHOW_STR
  583. IP_STR
  584. BGP_STR
  585. "Display VPNv4 NLRI specific information\n"
  586. "Display information for a route distinguisher\n"
  587. "VPN Route Distinguisher\n"
  588. "Detailed information on TCP and BGP neighbor connections\n"
  589. "Neighbor to display information about\n"
  590. "Display the routes advertised to a BGP neighbor\n")
  591. {
  592. int ret;
  593. struct peer *peer;
  594. struct prefix_rd prd;
  595. union sockunion su;
  596. ret = str2sockunion (argv[1], &su);
  597. if (ret < 0)
  598. {
  599. vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
  600. return CMD_WARNING;
  601. }
  602. peer = peer_lookup (NULL, &su);
  603. if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
  604. {
  605. vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
  606. return CMD_WARNING;
  607. }
  608. ret = str2prefix_rd (argv[0], &prd);
  609. if (! ret)
  610. {
  611. vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
  612. return CMD_WARNING;
  613. }
  614. return show_adj_route_vpn (vty, peer, &prd);
  615. }
  616. void
  617. bgp_mplsvpn_init (void)
  618. {
  619. install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
  620. install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
  621. install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);
  622. install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);
  623. install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
  624. install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
  625. install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
  626. install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
  627. install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
  628. install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
  629. install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd);
  630. install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd);
  631. install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
  632. install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
  633. install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
  634. install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
  635. install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
  636. install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
  637. }