mirror of
				https://git.proxmox.com/git/mirror_frr
				synced 2025-11-04 03:29:06 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			201 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			201 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* VPN Related functions
 | 
						|
   Copyright (C) 2017 6WIND
 | 
						|
 | 
						|
This file is part of FRRouting
 | 
						|
 | 
						|
FRRouting is free software; you can redistribute it and/or modify it
 | 
						|
under the terms of the GNU General Public License as published by the
 | 
						|
Free Software Foundation; either version 2, or (at your option) any
 | 
						|
later version.
 | 
						|
 | 
						|
FRRouting is distributed in the hope that it will be useful, but
 | 
						|
WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
General Public License for more details.
 | 
						|
 | 
						|
You should have received a copy of the GNU General Public License
 | 
						|
along with FRRouting; see the file COPYING.  If not, write to the Free
 | 
						|
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
						|
02111-1307, USA.  */
 | 
						|
 | 
						|
#include <zebra.h>
 | 
						|
#include "command.h"
 | 
						|
#include "prefix.h"
 | 
						|
#include "lib/json.h"
 | 
						|
 | 
						|
#include "bgpd/bgpd.h"
 | 
						|
#include "bgpd/bgp_route.h"
 | 
						|
#include "bgpd/bgp_table.h"
 | 
						|
#include "bgpd/bgp_attr.h"
 | 
						|
#include "bgpd/bgp_mplsvpn.h"
 | 
						|
#include "bgpd/bgp_vpn.h"
 | 
						|
 | 
						|
int
 | 
						|
show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd,
 | 
						|
                    afi_t afi, safi_t safi, u_char use_json)
 | 
						|
{
 | 
						|
  struct bgp *bgp;
 | 
						|
  struct bgp_table *table;
 | 
						|
  struct bgp_node *rn;
 | 
						|
  struct bgp_node *rm;
 | 
						|
  struct attr *attr;
 | 
						|
  int rd_header;
 | 
						|
  int header = 1;
 | 
						|
  char v4_header[] = "   Network          Next Hop            Metric LocPrf Weight Path%s";
 | 
						|
  json_object *json = NULL;
 | 
						|
  json_object *json_scode = NULL;
 | 
						|
  json_object *json_ocode = NULL;
 | 
						|
  json_object *json_routes = NULL;
 | 
						|
  json_object *json_array = NULL;
 | 
						|
 | 
						|
  bgp = bgp_get_default ();
 | 
						|
  if (bgp == NULL)
 | 
						|
    {
 | 
						|
      if (!use_json)
 | 
						|
        vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
 | 
						|
      return CMD_WARNING;
 | 
						|
    }
 | 
						|
 | 
						|
  if (use_json)
 | 
						|
    {
 | 
						|
      json_scode = json_object_new_object();
 | 
						|
      json_ocode = json_object_new_object();
 | 
						|
      json_routes = json_object_new_object();
 | 
						|
      json = json_object_new_object();
 | 
						|
 | 
						|
      json_object_string_add(json_scode, "suppressed", "s");
 | 
						|
      json_object_string_add(json_scode, "damped", "d");
 | 
						|
      json_object_string_add(json_scode, "history", "h");
 | 
						|
      json_object_string_add(json_scode, "valid", "*");
 | 
						|
      json_object_string_add(json_scode, "best", ">");
 | 
						|
      json_object_string_add(json_scode, "internal", "i");
 | 
						|
 | 
						|
      json_object_string_add(json_ocode, "igp", "i");
 | 
						|
      json_object_string_add(json_ocode, "egp", "e");
 | 
						|
      json_object_string_add(json_ocode, "incomplete", "?");
 | 
						|
    }
 | 
						|
 | 
						|
  for (rn = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); rn;
 | 
						|
       rn = bgp_route_next (rn))
 | 
						|
    {
 | 
						|
      if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
 | 
						|
        continue;
 | 
						|
 | 
						|
      if ((table = rn->info) != NULL)
 | 
						|
        {
 | 
						|
          if (use_json)
 | 
						|
            json_array = json_object_new_array();
 | 
						|
          else
 | 
						|
            json_array = NULL;
 | 
						|
 | 
						|
          rd_header = 1;
 | 
						|
 | 
						|
          for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
 | 
						|
            {
 | 
						|
              if ((attr = rm->info) != NULL)
 | 
						|
                {
 | 
						|
                  if (header)
 | 
						|
                    {
 | 
						|
                      if (use_json)
 | 
						|
                        {
 | 
						|
                          json_object_int_add(json, "bgpTableVersion", 0);
 | 
						|
                          json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
 | 
						|
                          json_object_object_add(json, "bgpStatusCodes", json_scode);
 | 
						|
                          json_object_object_add(json, "bgpOriginCodes", json_ocode);
 | 
						|
                        }
 | 
						|
                      else
 | 
						|
                        {
 | 
						|
                          vty_out (vty, "BGP table version is 0, local router ID is %s%s",
 | 
						|
                                   inet_ntoa (bgp->router_id), VTY_NEWLINE);
 | 
						|
                          vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
 | 
						|
                                   VTY_NEWLINE);
 | 
						|
                          vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
 | 
						|
                                   VTY_NEWLINE, VTY_NEWLINE);
 | 
						|
                          vty_out (vty, v4_header, VTY_NEWLINE);
 | 
						|
                        }
 | 
						|
                      header = 0;
 | 
						|
                    }
 | 
						|
 | 
						|
                  if (rd_header)
 | 
						|
                    {
 | 
						|
                      u_int16_t type;
 | 
						|
                      struct rd_as rd_as;
 | 
						|
                      struct rd_ip rd_ip = {0};
 | 
						|
#if ENABLE_BGP_VNC
 | 
						|
                      struct rd_vnc_eth rd_vnc_eth = {0};
 | 
						|
#endif
 | 
						|
                      u_char *pnt;
 | 
						|
 | 
						|
                      pnt = rn->p.u.val;
 | 
						|
 | 
						|
                      /* Decode RD type. */
 | 
						|
                      type = decode_rd_type (pnt);
 | 
						|
                      /* Decode RD value. */
 | 
						|
                      if (type == RD_TYPE_AS)
 | 
						|
                        decode_rd_as (pnt + 2, &rd_as);
 | 
						|
                      else if (type == RD_TYPE_AS4)
 | 
						|
                        decode_rd_as4 (pnt + 2, &rd_as);
 | 
						|
                      else if (type == RD_TYPE_IP)
 | 
						|
                        decode_rd_ip (pnt + 2, &rd_ip);
 | 
						|
#if ENABLE_BGP_VNC
 | 
						|
                      else if (type == RD_TYPE_VNC_ETH)
 | 
						|
                        decode_rd_vnc_eth (pnt, &rd_vnc_eth);
 | 
						|
#endif
 | 
						|
 | 
						|
                      if (use_json)
 | 
						|
                        {
 | 
						|
                          char buffer[BUFSIZ];
 | 
						|
                          if (type == RD_TYPE_AS || type == RD_TYPE_AS4)
 | 
						|
                            sprintf (buffer, "%u:%d", rd_as.as, rd_as.val);
 | 
						|
                          else if (type == RD_TYPE_IP)
 | 
						|
                            sprintf (buffer, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
 | 
						|
                          json_object_string_add(json_routes, "routeDistinguisher", buffer);
 | 
						|
                        }
 | 
						|
                      else
 | 
						|
                        {
 | 
						|
                          vty_out (vty, "Route Distinguisher: ");
 | 
						|
 | 
						|
                          if (type == RD_TYPE_AS || type == RD_TYPE_AS4)
 | 
						|
                            vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
 | 
						|
                          else if (type == RD_TYPE_IP)
 | 
						|
                            vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
 | 
						|
#if ENABLE_BGP_VNC
 | 
						|
                          else if (type == RD_TYPE_VNC_ETH)
 | 
						|
                            vty_out (vty, "%u:%02x:%02x:%02x:%02x:%02x:%02x", 
 | 
						|
                                     rd_vnc_eth.local_nve_id, 
 | 
						|
                                     rd_vnc_eth.macaddr.octet[0],
 | 
						|
                                     rd_vnc_eth.macaddr.octet[1],
 | 
						|
                                     rd_vnc_eth.macaddr.octet[2],
 | 
						|
                                     rd_vnc_eth.macaddr.octet[3],
 | 
						|
                                     rd_vnc_eth.macaddr.octet[4],
 | 
						|
                                     rd_vnc_eth.macaddr.octet[5]);
 | 
						|
#endif
 | 
						|
 | 
						|
                          vty_out (vty, "%s", VTY_NEWLINE);
 | 
						|
                        }
 | 
						|
                      rd_header = 0;
 | 
						|
                    }
 | 
						|
                  route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN, use_json, json_array);
 | 
						|
                }
 | 
						|
            }
 | 
						|
          if (use_json)
 | 
						|
            {
 | 
						|
              struct prefix *p;
 | 
						|
              char buf_a[BUFSIZ];
 | 
						|
              char buf_b[BUFSIZ];
 | 
						|
              p = &rm->p;
 | 
						|
              sprintf(buf_a, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf_b, BUFSIZ), p->prefixlen);
 | 
						|
              json_object_object_add(json_routes, buf_a, json_array);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
  if (use_json)
 | 
						|
    {
 | 
						|
      json_object_object_add(json, "routes", json_routes);
 | 
						|
      vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
 | 
						|
      json_object_free(json);
 | 
						|
    }
 | 
						|
  return CMD_SUCCESS;
 | 
						|
}
 | 
						|
 |