Import Upstream version 1.2.2
[quagga-debian.git] / bgpd / bgp_encap.c
1
2 /*
3  * This file created by LabN Consulting, L.L.C.
4  *
5  *
6  * This file is based on bgp_mplsvpn.c which is Copyright (C) 2000
7  * Kunihiro Ishiguro <kunihiro@zebra.org>
8  *
9  */
10
11 /* 
12
13 This file is part of GNU Zebra.
14
15 GNU Zebra is free software; you can redistribute it and/or modify it
16 under the terms of the GNU General Public License as published by the
17 Free Software Foundation; either version 2, or (at your option) any
18 later version.
19
20 GNU Zebra is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23 General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with GNU Zebra; see the file COPYING.  If not, write to the Free
27 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
28 02111-1307, USA.  */
29
30 #include <zebra.h>
31
32 #include "command.h"
33 #include "prefix.h"
34 #include "log.h"
35 #include "memory.h"
36 #include "stream.h"
37 #include "filter.h"
38
39 #include "bgpd/bgpd.h"
40 #include "bgpd/bgp_table.h"
41 #include "bgpd/bgp_route.h"
42 #include "bgpd/bgp_attr.h"
43 #include "bgpd/bgp_ecommunity.h"
44 #include "bgpd/bgp_mplsvpn.h"
45 #include "bgpd/bgp_vty.h"
46 #include "bgpd/bgp_encap.h"
47
48 static u_int16_t
49 decode_rd_type (u_char *pnt)
50 {
51   u_int16_t v;
52   
53   v = ((u_int16_t) *pnt++ << 8);
54   v |= (u_int16_t) *pnt;
55   return v;
56 }
57
58
59 static void
60 decode_rd_as (u_char *pnt, struct rd_as *rd_as)
61 {
62   rd_as->as  = (u_int16_t) *pnt++ << 8;
63   rd_as->as |= (u_int16_t) *pnt++;
64   
65   rd_as->val  = ((u_int32_t) *pnt++) << 24;
66   rd_as->val |= ((u_int32_t) *pnt++) << 16;
67   rd_as->val |= ((u_int32_t) *pnt++) << 8;
68   rd_as->val |= (u_int32_t) *pnt;
69 }
70
71 static void
72 decode_rd_as4 (u_char *pnt, struct rd_as *rd_as)
73 {
74   rd_as->as  = (u_int32_t) *pnt++ << 24;
75   rd_as->as |= (u_int32_t) *pnt++ << 16;
76   rd_as->as |= (u_int32_t) *pnt++ << 8;
77   rd_as->as |= (u_int32_t) *pnt++;
78   
79   rd_as->val  = ((u_int32_t) *pnt++ << 8);
80   rd_as->val |= (u_int32_t) *pnt;
81 }
82
83 static void
84 decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
85 {
86   memcpy (&rd_ip->ip, pnt, 4);
87   pnt += 4;
88   
89   rd_ip->val = ((u_int16_t) *pnt++ << 8);
90   rd_ip->val |= (u_int16_t) *pnt;
91 }
92
93 static void
94 ecom2prd(struct ecommunity *ecom, struct prefix_rd *prd)
95 {
96     int i;
97
98     memset(prd, 0, sizeof(struct prefix_rd));
99     prd->family = AF_UNSPEC;
100     prd->prefixlen = 64;
101
102     if (!ecom)
103         return;
104
105     for (i = 0; i < (ecom->size * ECOMMUNITY_SIZE); i += ECOMMUNITY_SIZE) {
106
107         uint8_t *ep;
108
109         ep = ecom->val + i;
110
111         switch (ep[0]) {
112             default:
113                 continue;
114
115             case 0x80:
116             case 0x81:
117             case 0x82:
118                 if (ep[1] == 0x0) {
119                     prd->val[1] = ep[0] & 0x03;
120                     memcpy(prd->val + 2, ep + 2, 6);
121                     return;
122                 }
123         }
124     }
125 }
126
127 int
128 bgp_nlri_parse_encap(
129     struct peer         *peer,
130     struct attr         *attr,          /* Need even for withdraw */
131     struct bgp_nlri     *packet)
132 {
133   u_char *pnt;
134   u_char *lim;
135   afi_t afi = packet->afi;
136   struct prefix p;
137   int psize = 0;
138   int prefixlen;
139   struct rd_as rd_as;
140   struct rd_ip rd_ip;
141   struct prefix_rd prd;
142   struct ecommunity *pEcom = NULL;
143   u_int16_t rdtype = 0xffff;
144   char buf[BUFSIZ];
145
146   /* Check peer status. */
147   if (peer->status != Established)
148     return 0;
149   
150   /* Make prefix_rd */
151   if (attr && attr->extra && attr->extra->ecommunity)
152       pEcom = attr->extra->ecommunity;
153
154   ecom2prd(pEcom, &prd);
155   memset(&rd_as, 0, sizeof(rd_as));
156   memset(&rd_ip, 0, sizeof(rd_ip));
157
158   if (pEcom) {
159
160       rdtype = (prd.val[0] << 8) | prd.val[1];
161
162       /* Decode RD value. */
163       if (rdtype == RD_TYPE_AS)
164         decode_rd_as (prd.val + 2, &rd_as);
165       else if (rdtype == RD_TYPE_IP)
166         decode_rd_ip (prd.val + 2, &rd_ip);
167       else if (rdtype == RD_TYPE_AS4)
168         decode_rd_as4 (prd.val + 2, &rd_as);
169       else
170         {
171           zlog_err ("Invalid RD type %d", rdtype);
172         }
173
174   }
175
176   /*
177    * NB: this code was based on the MPLS VPN code, which supported RDs.
178    * For the moment we are retaining the underlying RIB structure that
179    * keeps a per-RD radix tree, but since the RDs are not carried over
180    * the wire, we set the RD internally to 0.
181    */
182   prd.family = AF_UNSPEC;
183   prd.prefixlen = 64;
184   memset(prd.val, 0, sizeof(prd.val));
185
186   pnt = packet->nlri;
187   lim = pnt + packet->length;
188
189   for (; pnt < lim; pnt += psize)
190     {
191       /* Clear prefix structure. */
192       memset (&p, 0, sizeof (struct prefix));
193
194       /* Fetch prefix length. */
195       prefixlen = *pnt++;
196       p.family = afi2family(afi);
197       if (p.family == 0) {
198         /* bad afi, shouldn't happen */
199         zlog_warn("%s: bad afi %d, dropping incoming route", __func__, afi);
200         continue;
201       }
202       psize = PSIZE (prefixlen);
203
204       p.prefixlen = prefixlen;
205       memcpy (&p.u.prefix, pnt, psize);
206
207       if (pnt + psize > lim)
208         return -1;
209
210
211       if (rdtype == RD_TYPE_AS)
212         zlog_info ("rd-as %u:%u prefix %s/%d", rd_as.as, rd_as.val,
213                    inet_ntop (p.family, &p.u.prefix, buf, BUFSIZ),
214                    p.prefixlen);
215       else if (rdtype == RD_TYPE_IP)
216         zlog_info ("rd-ip %s:%u prefix %s/%d", inet_ntoa (rd_ip.ip),
217                    rd_ip.val,
218                    inet_ntop (p.family, &p.u.prefix, buf, BUFSIZ),
219                    p.prefixlen);
220       else if (rdtype == RD_TYPE_AS4)
221         zlog_info ("rd-as4 %u:%u prefix %s/%d", rd_as.as, rd_as.val,
222                    inet_ntop (p.family, &p.u.prefix, buf, BUFSIZ),
223                    p.prefixlen);
224       else
225         zlog_info ("rd unknown, default to 0:0 prefix %s/%d",
226             inet_ntop (p.family, &p.u.prefix, buf, BUFSIZ),
227             p.prefixlen);
228
229       if (attr) {
230         bgp_update (peer, &p, attr, afi, SAFI_ENCAP,
231                     ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL, 0);
232       } else {
233         bgp_withdraw (peer, &p, attr, afi, SAFI_ENCAP,
234                       ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL);
235       }
236     }
237
238   /* Packet length consistency check. */
239   if (pnt != lim)
240     return -1;
241
242   return 0;
243 }
244
245
246 /* TBD: these routes should probably all be host routes */
247
248 /* For testing purpose, static route of ENCAP. */
249 DEFUN (encap_network,
250        encap_network_cmd,
251        "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
252        "Specify a network to announce via BGP\n"
253        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
254        "Specify Route Distinguisher\n"
255        "ENCAP Route Distinguisher\n"
256        "BGP tag\n"
257        "tag value\n")
258 {
259   return bgp_static_set_safi (SAFI_ENCAP, vty, argv[0], argv[1], argv[2], NULL);
260 }
261
262 /* For testing purpose, static route of ENCAP. */
263 DEFUN (no_encap_network,
264        no_encap_network_cmd,
265        "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
266        NO_STR
267        "Specify a network to announce via BGP\n"
268        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
269        "Specify Route Distinguisher\n"
270        "ENCAP Route Distinguisher\n"
271        "BGP tag\n"
272        "tag value\n")
273 {
274   return bgp_static_unset_safi (SAFI_ENCAP, vty, argv[0], argv[1], argv[2]);
275 }
276
277 static int
278 show_adj_route_encap (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
279 {
280   struct bgp *bgp;
281   struct bgp_table *table;
282   struct bgp_node *rn;
283   struct bgp_node *rm;
284   struct attr *attr;
285   int rd_header;
286   int header = 1;
287   char v4_header[] = "   Network          Next Hop            Metric LocPrf Weight Path%s";
288
289   bgp = bgp_get_default ();
290   if (bgp == NULL)
291     {
292       vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
293       return CMD_WARNING;
294     }
295
296   for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_ENCAP]); rn;
297        rn = bgp_route_next (rn))
298     {
299       if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
300         continue;
301
302       if ((table = rn->info) != NULL)
303         {
304           rd_header = 1;
305
306           for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
307             if ((attr = rm->info) != NULL)
308               {
309                 if (header)
310                   {
311                     vty_out (vty, "BGP table version is 0, local router ID is %s%s",
312                              inet_ntoa (bgp->router_id), VTY_NEWLINE);
313                     vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
314                              VTY_NEWLINE);
315                     vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
316                              VTY_NEWLINE, VTY_NEWLINE);
317                     vty_out (vty, v4_header, VTY_NEWLINE);
318                     header = 0;
319                   }
320
321                 if (rd_header)
322                   {
323                     u_int16_t type;
324                     struct rd_as rd_as;
325                     struct rd_ip rd_ip;
326                     u_char *pnt;
327
328                     pnt = rn->p.u.val;
329
330                     vty_out (vty, "Route Distinguisher: ");
331
332                     /* Decode RD type. */
333                     type = decode_rd_type (pnt);
334
335                     switch (type) {
336
337                     case RD_TYPE_AS:
338                       decode_rd_as (pnt + 2, &rd_as);
339                       vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
340                       break;
341
342                     case RD_TYPE_IP:
343                       decode_rd_ip (pnt + 2, &rd_ip);
344                       vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
345                       break;
346
347                     default:
348                       vty_out (vty, "unknown RD type");
349                     }
350
351
352                     vty_out (vty, "%s", VTY_NEWLINE);
353                     rd_header = 0;
354                   }
355                 route_vty_out_tmp (vty, &rm->p, attr, SAFI_ENCAP);
356               }
357         }
358     }
359   return CMD_SUCCESS;
360 }
361
362 enum bgp_show_type
363 {
364   bgp_show_type_normal,
365   bgp_show_type_regexp,
366   bgp_show_type_prefix_list,
367   bgp_show_type_filter_list,
368   bgp_show_type_neighbor,
369   bgp_show_type_cidr_only,
370   bgp_show_type_prefix_longer,
371   bgp_show_type_community_all,
372   bgp_show_type_community,
373   bgp_show_type_community_exact,
374   bgp_show_type_community_list,
375   bgp_show_type_community_list_exact
376 };
377
378 static int
379 bgp_show_encap (
380     struct vty *vty,
381     afi_t afi,
382     struct prefix_rd *prd,
383     enum bgp_show_type type,
384     void *output_arg,
385     int tags)
386 {
387   struct bgp *bgp;
388   struct bgp_table *table;
389   struct bgp_node *rn;
390   struct bgp_node *rm;
391   struct bgp_info *ri;
392   int rd_header;
393   int header = 1;
394   char v4_header[] = "   Network          Next Hop            Metric LocPrf Weight Path%s";
395   char v4_header_tag[] = "   Network          Next Hop      In tag/Out tag%s";
396
397   unsigned long output_count = 0;
398   unsigned long total_count  = 0;
399
400   bgp = bgp_get_default ();
401   if (bgp == NULL)
402     {
403       vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
404       return CMD_WARNING;
405     }
406
407   if ((afi != AFI_IP) && (afi != AFI_IP6)) {
408       vty_out (vty, "Afi %d not supported%s", afi, VTY_NEWLINE);
409       return CMD_WARNING;
410   }
411   
412   for (rn = bgp_table_top (bgp->rib[afi][SAFI_ENCAP]); rn; rn = bgp_route_next (rn))
413     {
414       if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
415         continue;
416
417       if ((table = rn->info) != NULL)
418         {
419           rd_header = 1;
420
421           for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
422             for (ri = rm->info; ri; ri = ri->next)
423               {
424                 total_count++;
425                 if (type == bgp_show_type_neighbor)
426                   {
427                     union sockunion *su = output_arg;
428
429                     if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
430                       continue;
431                   }
432                 if (header)
433                   {
434                     if (tags)
435                       vty_out (vty, v4_header_tag, VTY_NEWLINE);
436                     else
437                       {
438                         vty_out (vty, "BGP table version is 0, local router ID is %s%s",
439                                  inet_ntoa (bgp->router_id), VTY_NEWLINE);
440                         vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
441                                  VTY_NEWLINE);
442                         vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
443                                  VTY_NEWLINE, VTY_NEWLINE);
444                         vty_out (vty, v4_header, VTY_NEWLINE);
445                       }
446                     header = 0;
447                   }
448
449                 if (rd_header)
450                   {
451                     u_int16_t type;
452                     struct rd_as rd_as;
453                     struct rd_ip rd_ip;
454                     u_char *pnt;
455
456                     pnt = rn->p.u.val;
457
458                     /* Decode RD type. */
459                     type = decode_rd_type (pnt);
460
461                     vty_out (vty, "Route Distinguisher: ");
462
463                     switch (type) {
464
465                     case RD_TYPE_AS:
466                       decode_rd_as (pnt + 2, &rd_as);
467                       vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
468                       break;
469
470                     case RD_TYPE_IP:
471                       decode_rd_ip (pnt + 2, &rd_ip);
472                       vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
473                       break;
474
475                     default:
476                       vty_out (vty, "Unknown RD type");
477                       break;
478                     }
479
480                     vty_out (vty, "%s", VTY_NEWLINE);             
481                     rd_header = 0;
482                   }
483                 if (tags)
484                   route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_ENCAP);
485                 else
486                   route_vty_out (vty, &rm->p, ri, 0, SAFI_ENCAP);
487                 output_count++;
488               }
489         }
490     }
491
492   if (output_count == 0)
493     {
494         vty_out (vty, "No prefixes displayed, %ld exist%s", total_count, VTY_NEWLINE);
495     }
496   else
497     vty_out (vty, "%sDisplayed %ld out of %ld total prefixes%s",
498              VTY_NEWLINE, output_count, total_count, VTY_NEWLINE);
499
500   return CMD_SUCCESS;
501 }
502
503 DEFUN (show_bgp_ipv4_encap,
504        show_bgp_ipv4_encap_cmd,
505        "show bgp ipv4 encap",
506        SHOW_STR
507        BGP_STR
508        "Address Family\n"
509        "Display ENCAP NLRI specific information\n")
510 {
511   return bgp_show_encap (vty, AFI_IP, NULL, bgp_show_type_normal, NULL, 0);
512 }
513
514 DEFUN (show_bgp_ipv6_encap,
515        show_bgp_ipv6_encap_cmd,
516        "show bgp ipv6 encap",
517        SHOW_STR
518        BGP_STR
519        "Address Family\n"
520        "Display ENCAP NLRI specific information\n")
521 {
522   return bgp_show_encap (vty, AFI_IP6, NULL, bgp_show_type_normal, NULL, 0);
523 }
524
525 DEFUN (show_bgp_ipv4_encap_rd,
526        show_bgp_ipv4_encap_rd_cmd,
527        "show bgp ipv4 encap rd ASN:nn_or_IP-address:nn",
528        SHOW_STR
529        BGP_STR
530        "Address Family\n"
531        "Display ENCAP NLRI specific information\n"
532        "Display information for a route distinguisher\n"
533        "ENCAP Route Distinguisher\n")
534 {
535   int ret;
536   struct prefix_rd prd;
537
538   ret = str2prefix_rd (argv[0], &prd);
539   if (! ret)
540     {
541       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
542       return CMD_WARNING;
543     }
544   return bgp_show_encap (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 0);
545 }
546
547 DEFUN (show_bgp_ipv6_encap_rd,
548        show_bgp_ipv6_encap_rd_cmd,
549        "show bgp ipv6 encap rd ASN:nn_or_IP-address:nn",
550        SHOW_STR
551        BGP_STR
552        "Address Family\n"
553        "Display ENCAP NLRI specific information\n"
554        "Display information for a route distinguisher\n"
555        "ENCAP Route Distinguisher\n"
556        "Display BGP tags for prefixes\n")
557 {
558   int ret;
559   struct prefix_rd prd;
560
561   ret = str2prefix_rd (argv[0], &prd);
562   if (! ret)
563     {
564       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
565       return CMD_WARNING;
566     }
567   return bgp_show_encap (vty, AFI_IP6, &prd, bgp_show_type_normal, NULL, 0);
568 }
569
570 DEFUN (show_bgp_ipv4_encap_tags,
571        show_bgp_ipv4_encap_tags_cmd,
572        "show bgp ipv4 encap tags",
573        SHOW_STR
574        BGP_STR
575        "Address Family\n"
576        "Display ENCAP NLRI specific information\n"
577        "Display BGP tags for prefixes\n")
578 {
579   return bgp_show_encap (vty, AFI_IP, NULL, bgp_show_type_normal, NULL,  1);
580 }
581
582 DEFUN (show_bgp_ipv6_encap_tags,
583        show_bgp_ipv6_encap_tags_cmd,
584        "show bgp ipv6 encap tags",
585        SHOW_STR
586        BGP_STR
587        "Address Family\n"
588        "Display ENCAP NLRI specific information\n"
589        "Display BGP tags for prefixes\n")
590 {
591   return bgp_show_encap (vty, AFI_IP6, NULL, bgp_show_type_normal, NULL,  1);
592 }
593
594
595 DEFUN (show_bgp_ipv4_encap_rd_tags,
596        show_bgp_ipv4_encap_rd_tags_cmd,
597        "show bgp ipv4 encap rd ASN:nn_or_IP-address:nn tags",
598        SHOW_STR
599        BGP_STR
600        "Address Family\n"
601        "Display ENCAP NLRI specific information\n"
602        "Display information for a route distinguisher\n"
603        "ENCAP Route Distinguisher\n"
604        "Display BGP tags for prefixes\n")
605 {
606   int ret;
607   struct prefix_rd prd;
608
609   ret = str2prefix_rd (argv[0], &prd);
610   if (! ret)
611     {
612       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
613       return CMD_WARNING;
614     }
615   return bgp_show_encap (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 1);
616 }
617
618 DEFUN (show_bgp_ipv6_encap_rd_tags,
619        show_bgp_ipv6_encap_rd_tags_cmd,
620        "show bgp ipv6 encap rd ASN:nn_or_IP-address:nn tags",
621        SHOW_STR
622        BGP_STR
623        "Address Family\n"
624        "Display ENCAP NLRI specific information\n"
625        "Display information for a route distinguisher\n"
626        "ENCAP Route Distinguisher\n"
627        "Display BGP tags for prefixes\n")
628 {
629   int ret;
630   struct prefix_rd prd;
631
632   ret = str2prefix_rd (argv[0], &prd);
633   if (! ret)
634     {
635       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
636       return CMD_WARNING;
637     }
638   return bgp_show_encap (vty, AFI_IP6, &prd, bgp_show_type_normal, NULL, 1);
639 }
640
641 DEFUN (show_bgp_ipv4_encap_neighbor_routes,
642        show_bgp_ipv4_encap_neighbor_routes_cmd,
643        "show bgp ipv4 encap neighbors A.B.C.D routes",
644        SHOW_STR
645        BGP_STR
646        "Address Family\n"
647        "Display ENCAP NLRI specific information\n"
648        "Detailed information on TCP and BGP neighbor connections\n"
649        "Neighbor to display information about\n"
650        "Display routes learned from neighbor\n")
651 {
652   union sockunion su;
653   struct peer *peer;
654
655   if (str2sockunion(argv[0], &su))
656     {
657       vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
658                return CMD_WARNING;
659     }
660
661   peer = peer_lookup (NULL, &su);
662   if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP])
663     {
664       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
665       return CMD_WARNING;
666     }
667
668   return bgp_show_encap (vty, AFI_IP, NULL, bgp_show_type_neighbor, &su, 0);
669 }
670
671 DEFUN (show_bgp_ipv6_encap_neighbor_routes,
672        show_bgp_ipv6_encap_neighbor_routes_cmd,
673        "show bgp ipv6 encap neighbors A.B.C.D routes",
674        SHOW_STR
675        BGP_STR
676        "Address Family\n"
677        "Display ENCAP NLRI specific information\n"
678        "Detailed information on TCP and BGP neighbor connections\n"
679        "Neighbor to display information about\n"
680        "Display routes learned from neighbor\n")
681 {
682   union sockunion su;
683   struct peer *peer;
684   
685   if (str2sockunion(argv[0], &su))
686     {
687       vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
688                return CMD_WARNING;
689     }
690
691   peer = peer_lookup (NULL, &su);
692   if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP])
693     {
694       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
695       return CMD_WARNING;
696     }
697
698   return bgp_show_encap (vty, AFI_IP6, NULL, bgp_show_type_neighbor, &su, 0);
699 }
700
701 DEFUN (show_bgp_ipv4_encap_rd_neighbor_routes,
702        show_bgp_ipv4_encap_rd_neighbor_routes_cmd,
703        "show bgp ipv4 encap rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) routes",
704        SHOW_STR
705        BGP_STR
706        "Address Family\n"
707        "Display ENCAP NLRI specific information\n"
708        "Display information for a route distinguisher\n"
709        "ENCAP Route Distinguisher\n"
710        "Detailed information on TCP and BGP neighbor connections\n"
711        "Neighbor to display information about\n"
712        "Neighbor to display information about\n"
713        "Display routes learned from neighbor\n")
714 {
715   int ret;
716   union sockunion su;
717   struct peer *peer;
718   struct prefix_rd prd;
719
720   ret = str2prefix_rd (argv[0], &prd);
721   if (! ret)
722     {
723       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
724       return CMD_WARNING;
725     }
726
727   if (str2sockunion(argv[1], &su))
728     {
729       vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE);
730                return CMD_WARNING;
731     }
732
733   peer = peer_lookup (NULL, &su);
734   if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP])
735     {
736       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
737       return CMD_WARNING;
738     }
739
740   return bgp_show_encap (vty, AFI_IP, &prd, bgp_show_type_neighbor, &su, 0);
741 }
742
743 DEFUN (show_bgp_ipv6_encap_rd_neighbor_routes,
744        show_bgp_ipv6_encap_rd_neighbor_routes_cmd,
745        "show bgp ipv6 encap rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) routes",
746        SHOW_STR
747        BGP_STR
748        "Address Family\n"
749        "Display ENCAP NLRI specific information\n"
750        "Display information for a route distinguisher\n"
751        "ENCAP Route Distinguisher\n"
752        "Detailed information on TCP and BGP neighbor connections\n"
753        "Neighbor to display information about\n"
754        "Neighbor to display information about\n"
755        "Display routes learned from neighbor\n")
756 {
757   int ret;
758   union sockunion su;
759   struct peer *peer;
760   struct prefix_rd prd;
761
762   ret = str2prefix_rd (argv[0], &prd);
763   if (! ret)
764     {
765       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
766       return CMD_WARNING;
767     }
768
769   if (str2sockunion(argv[1], &su))
770     {
771       vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE);
772                return CMD_WARNING;
773     }
774
775   peer = peer_lookup (NULL, &su);
776   if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP])
777     {
778       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
779       return CMD_WARNING;
780     }
781
782   return bgp_show_encap (vty, AFI_IP6, &prd, bgp_show_type_neighbor, &su, 0);
783 }
784
785 DEFUN (show_bgp_ipv4_encap_neighbor_advertised_routes,
786        show_bgp_ipv4_encap_neighbor_advertised_routes_cmd,
787        "show bgp ipv4 encap neighbors A.B.C.D advertised-routes",
788        SHOW_STR
789        BGP_STR
790        "Address Family\n"
791        "Display ENCAP NLRI specific information\n"
792        "Detailed information on TCP and BGP neighbor connections\n"
793        "Neighbor to display information about\n"
794        "Display the routes advertised to a BGP neighbor\n")
795 {
796   int ret;
797   struct peer *peer;
798   union sockunion su;
799
800   ret = str2sockunion (argv[0], &su);
801   if (ret < 0)
802     {
803       vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
804       return CMD_WARNING;
805     }
806   peer = peer_lookup (NULL, &su);
807   if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP])
808     {
809       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
810       return CMD_WARNING;
811     }
812
813   return show_adj_route_encap (vty, peer, NULL);
814 }
815
816 DEFUN (show_bgp_ipv6_encap_neighbor_advertised_routes,
817        show_bgp_ipv6_encap_neighbor_advertised_routes_cmd,
818        "show bgp ipv6 encap neighbors A.B.C.D advertised-routes",
819        SHOW_STR
820        BGP_STR
821        "Address Family\n"
822        "Display ENCAP NLRI specific information\n"
823        "Detailed information on TCP and BGP neighbor connections\n"
824        "Neighbor to display information about\n"
825        "Display the routes advertised to a BGP neighbor\n")
826 {
827   int ret;
828   struct peer *peer;
829   union sockunion su;
830
831   ret = str2sockunion (argv[0], &su);
832   if (ret < 0)
833     {
834       vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
835       return CMD_WARNING;
836     }
837   peer = peer_lookup (NULL, &su);
838   if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP])
839     {
840       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
841       return CMD_WARNING;
842     }
843
844   return show_adj_route_encap (vty, peer, NULL);
845 }
846
847 DEFUN (show_bgp_ipv4_encap_rd_neighbor_advertised_routes,
848        show_bgp_ipv4_encap_rd_neighbor_advertised_routes_cmd,
849        "show bgp ipv4 encap rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) advertised-routes",
850        SHOW_STR
851        BGP_STR
852        "Address Family\n"
853        "Display ENCAP NLRI specific information\n"
854        "Display information for a route distinguisher\n"
855        "ENCAP Route Distinguisher\n"
856        "Detailed information on TCP and BGP neighbor connections\n"
857        "Neighbor to display information about\n"
858        "Neighbor to display information about\n"
859        "Display the routes advertised to a BGP neighbor\n")
860 {
861   int ret;
862   struct peer *peer;
863   struct prefix_rd prd;
864   union sockunion su;
865
866   ret = str2sockunion (argv[1], &su);
867   if (ret < 0)
868     {
869       vty_out (vty, "%% Malformed address: %s%s", argv[1], VTY_NEWLINE);
870       return CMD_WARNING;
871     }
872   peer = peer_lookup (NULL, &su);
873   if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP])
874     {
875       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
876       return CMD_WARNING;
877     }
878
879   ret = str2prefix_rd (argv[0], &prd);
880   if (! ret)
881     {
882       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
883       return CMD_WARNING;
884     }
885
886   return show_adj_route_encap (vty, peer, &prd);
887 }
888
889 DEFUN (show_bgp_ipv6_encap_rd_neighbor_advertised_routes,
890        show_bgp_ipv6_encap_rd_neighbor_advertised_routes_cmd,
891        "show bgp ipv6 encap rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) advertised-routes",
892        SHOW_STR
893        BGP_STR
894        "Address Family\n"
895        "Display ENCAP NLRI specific information\n"
896        "Display information for a route distinguisher\n"
897        "ENCAP Route Distinguisher\n"
898        "Detailed information on TCP and BGP neighbor connections\n"
899        "Neighbor to display information about\n"
900        "Neighbor to display information about\n"
901        "Display the routes advertised to a BGP neighbor\n")
902 {
903   int ret;
904   struct peer *peer;
905   struct prefix_rd prd;
906   union sockunion su;
907
908   ret = str2sockunion (argv[1], &su);
909   if (ret < 0)
910     {
911       vty_out (vty, "%% Malformed address: %s%s", argv[1], VTY_NEWLINE);
912       return CMD_WARNING;
913     }
914   peer = peer_lookup (NULL, &su);
915   if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP])
916     {
917       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
918       return CMD_WARNING;
919     }
920
921   ret = str2prefix_rd (argv[0], &prd);
922   if (! ret)
923     {
924       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
925       return CMD_WARNING;
926     }
927
928   return show_adj_route_encap (vty, peer, &prd);
929 }
930
931 void
932 bgp_encap_init (void)
933 {
934   install_element (BGP_ENCAP_NODE, &encap_network_cmd);
935   install_element (BGP_ENCAP_NODE, &no_encap_network_cmd);
936
937   install_element (VIEW_NODE, &show_bgp_ipv4_encap_cmd);
938   install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_cmd);
939   install_element (VIEW_NODE, &show_bgp_ipv4_encap_tags_cmd);
940   install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_tags_cmd);
941   install_element (VIEW_NODE, &show_bgp_ipv4_encap_neighbor_routes_cmd);
942   install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_neighbor_routes_cmd);
943   install_element (VIEW_NODE, &show_bgp_ipv4_encap_neighbor_advertised_routes_cmd);
944   install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_neighbor_advertised_routes_cmd);
945
946   install_element (VIEW_NODE, &show_bgp_ipv6_encap_cmd);
947   install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_cmd);
948   install_element (VIEW_NODE, &show_bgp_ipv6_encap_tags_cmd);
949   install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_tags_cmd);
950   install_element (VIEW_NODE, &show_bgp_ipv6_encap_neighbor_routes_cmd);
951   install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_neighbor_routes_cmd);
952   install_element (VIEW_NODE, &show_bgp_ipv6_encap_neighbor_advertised_routes_cmd);
953   install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_neighbor_advertised_routes_cmd);
954 }