]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd-hostname-cap.patch
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 01:29:16 +0000 (18:29 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 01:29:16 +0000 (18:29 -0700)
bgpd: Exchange hostname capability and display hostnames in outputs

This patch adds a hostname capability. The node's hostname and
domainname are exchanged in the new capability and used in show command
outputs based on a knob enabled by the user. The hostname and domainname
can be a maximum of 64 chars long, each.

Signed-off-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com>
bgpd/bgp_debug.c
bgpd/bgp_fsm.c
bgpd/bgp_open.c
bgpd/bgp_open.h
bgpd/bgp_route.c
bgpd/bgp_vty.c
bgpd/bgpd.c
bgpd/bgpd.h

index ed39e5e24f9d4098fb1d2cf7ab66379086341220..4b1bb8c39e8fd4e973c3937a1e69c4ba27ceff73 100644 (file)
@@ -183,13 +183,20 @@ bgp_find_peer (struct vty *vty, const char *peer_str)
   int ret;
   union sockunion su;
   struct bgp *bgp;
+  struct peer *peer;
 
   bgp = vty->index;
   ret = str2sockunion (peer_str, &su);
 
   /* 'swpX' string */
   if (ret < 0)
-    return peer_lookup_by_conf_if (bgp, peer_str);
+    {
+      peer = peer_lookup_by_conf_if (bgp, peer_str);
+      if (!peer)
+       peer = peer_lookup_by_hostname (bgp, peer_str);
+
+      return peer;
+    }
   else
     return peer_lookup (bgp, &su);
 }
index a1a1ca23ba5a80e3b73d4b52fbf7c30cd359611b..6089cbd94a88d9187e5b8155fa846a7133049300 100644 (file)
@@ -159,6 +159,10 @@ peer_xfer_conn(struct peer *from_peer)
   from_peer->last_event = last_evt;
   from_peer->last_major_event = last_maj_evt;
   peer->remote_id = from_peer->remote_id;
+  if (from_peer->hostname != NULL)
+    peer->hostname = XSTRDUP(MTYPE_HOST, from_peer->hostname);
+  if (from_peer->domainname != NULL)
+    peer->domainname = XSTRDUP(MTYPE_HOST, from_peer->domainname);
 
   for (afi = AFI_IP; afi < AFI_MAX; afi++)
     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
index de24d435a288e9901b7556637452a72642b44363..9fcd64bd2dca9491fc3bf329746e09a6cef3675d 100644 (file)
@@ -451,7 +451,86 @@ bgp_capability_addpath (struct peer *peer, struct capability_header *hdr)
   return 0;
 }
 
-static const struct message capcode_str[] =
+static int
+bgp_capability_hostname (struct peer *peer, struct capability_header *hdr)
+{
+  struct stream *s = BGP_INPUT (peer);
+  char str[BGP_MAX_HOSTNAME+1];
+  size_t end = stream_get_getp (s) + hdr->length;
+  u_char len;
+
+  SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_RCV);
+
+  len = stream_getc(s);
+  if (stream_get_getp(s) + len > end)
+    {
+      zlog_warn("%s: Received malformed hostname capability from peer %s",
+               __FUNCTION__, peer->host);
+      return -1;
+    }
+
+  if (len > BGP_MAX_HOSTNAME)
+    {
+      stream_get(str, s, BGP_MAX_HOSTNAME);
+      stream_forward_getp(s, len-BGP_MAX_HOSTNAME);
+      len = BGP_MAX_HOSTNAME;  /* to set the '\0' below */
+    }
+  else if (len)
+    stream_get(str, s, len);
+
+  if (len)
+    {
+      str[len] = '\0';
+
+      if (peer->hostname != NULL)
+       XFREE(MTYPE_HOST, peer->hostname);
+
+      if (peer->domainname != NULL)
+       XFREE(MTYPE_HOST, peer->domainname);
+
+      peer->hostname = XSTRDUP(MTYPE_HOST, str);
+    }
+
+  if (stream_get_getp(s) +1 > end)
+    {
+      zlog_warn("%s: Received invalid domain name len (hostname capability) from peer %s",
+               __FUNCTION__, peer->host);
+      return -1;
+    }
+
+  len = stream_getc(s);
+  if (stream_get_getp(s) + len > end)
+    {
+      zlog_warn("%s: Received runt domain name (hostname capability) from peer %s",
+               __FUNCTION__, peer->host);
+      return -1;
+    }
+
+  if (len > BGP_MAX_HOSTNAME)
+    {
+      stream_get(str, s, BGP_MAX_HOSTNAME);
+      stream_forward_getp(s, len-BGP_MAX_HOSTNAME);
+      len = BGP_MAX_HOSTNAME;  /* to set the '\0' below */
+    }
+  else if (len)
+    stream_get(str, s, len);
+
+  if (len)
+    {
+      str[len] = '\0';
+      peer->domainname = XSTRDUP(MTYPE_HOST, str);
+    }
+
+  if (bgp_debug_neighbor_events(peer))
+    {
+      zlog_debug("%s received hostname %s, domainname %s",
+                peer->host, peer->hostname, peer->domainname);
+    }
+
+  return 0;
+}
+
+  static const struct message capcode_str[] =
 {
   { CAPABILITY_CODE_MP,                        "MultiProtocol Extensions"      },
   { CAPABILITY_CODE_REFRESH,           "Route Refresh"                 },
@@ -463,6 +542,7 @@ static const struct message capcode_str[] =
   { CAPABILITY_CODE_DYNAMIC_OLD,       "Dynamic (Old)"                 },
   { CAPABILITY_CODE_REFRESH_OLD,       "Route Refresh (Old)"           },
   { CAPABILITY_CODE_ORF_OLD,           "ORF (Old)"                     },
+  { CAPABILITY_CODE_HOSTNAME,           "Hostname"                      },
 };
 static const int capcode_str_max = array_size(capcode_str);
 
@@ -479,6 +559,7 @@ static const size_t cap_minsizes[] =
   [CAPABILITY_CODE_DYNAMIC_OLD]        = CAPABILITY_CODE_DYNAMIC_LEN,
   [CAPABILITY_CODE_REFRESH_OLD]        = CAPABILITY_CODE_REFRESH_LEN,
   [CAPABILITY_CODE_ORF_OLD]    = sizeof (struct capability_orf_entry),
+  [CAPABILITY_CODE_HOSTNAME]    = CAPABILITY_CODE_MIN_HOSTNAME_LEN,
 };
 
 /**
@@ -543,6 +624,7 @@ bgp_capability_parse (struct peer *peer, size_t length, int *mp_capability,
           case CAPABILITY_CODE_ADDPATH:
           case CAPABILITY_CODE_DYNAMIC:
           case CAPABILITY_CODE_DYNAMIC_OLD:
+         case CAPABILITY_CODE_HOSTNAME:
               /* Check length. */
               if (caphdr.length < cap_minsizes[caphdr.code])
                 {
@@ -617,6 +699,10 @@ bgp_capability_parse (struct peer *peer, size_t length, int *mp_capability,
             if (bgp_capability_addpath (peer, &caphdr))
               return -1;
             break;
+          case CAPABILITY_CODE_HOSTNAME:
+            if (bgp_capability_hostname (peer, &caphdr))
+              return -1;
+            break;
           default:
             if (caphdr.code > 128)
               {
@@ -951,6 +1037,7 @@ bgp_open_capability (struct stream *s, struct peer *peer)
   as_t local_as;
   u_int32_t restart_time;
   u_char afi_safi_count = 0;
+  struct utsname names;
 
   /* Remember current pointer for Opt Parm Len. */
   cp = stream_get_endp (s);
@@ -1097,6 +1184,51 @@ bgp_open_capability (struct stream *s, struct peer *peer)
       stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
     }
 
+  /* Hostname capability */
+  uname(&names);
+  if (names.nodename[0] != '\0')
+    {
+      SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_ADV);
+      stream_putc (s, BGP_OPEN_OPT_CAP);
+      rcapp = stream_get_endp(s);      /* Ptr to length placeholder */
+      stream_putc(s, 0);               /* dummy len for now */
+      stream_putc (s, CAPABILITY_CODE_HOSTNAME);
+      capp = stream_get_endp(s);
+      stream_putc(s, 0);               /* dummy len for now */
+      len = strlen(names.nodename);
+      if (len > BGP_MAX_HOSTNAME)
+       len = BGP_MAX_HOSTNAME;
+
+      stream_putc(s, len);
+      stream_put(s, names.nodename, len);
+#ifdef _GNU_SOURCE
+      if ((names.domainname[0] != '\0') &&
+         (strcmp(names.domainname, "(none)") != 0))
+       {
+         len = strlen(names.domainname);
+         if (len > BGP_MAX_HOSTNAME)
+           len = BGP_MAX_HOSTNAME;
+
+         stream_putc(s, len);
+         stream_put(s, names.domainname, len);
+       }
+       else
+#endif
+       {
+         stream_putc(s, 0);    /* 0 length */
+       }
+
+      /* Set the lengths straight */
+      len = stream_get_endp(s) - rcapp - 1;
+      stream_putc_at(s, rcapp, len);
+      len = stream_get_endp(s) - capp - 1;
+      stream_putc_at(s, capp, len);
+
+      if (bgp_debug_neighbor_events(peer))
+       zlog_debug("%s Sending hostname cap with hn = %s, dn = %s",
+                  peer->host, names.nodename, names.domainname);
+    }
+
   /* Sending base graceful-restart capability irrespective of the config */
   SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);
   stream_putc (s, BGP_OPEN_OPT_CAP);
index da6f29d2ab49ad9fa8a38f81e85616f44c612d0a..a818141fc3723e8fbb303cc41068d68ab45ed6d6 100644 (file)
@@ -79,6 +79,7 @@ struct capability_gr
 #define CAPABILITY_CODE_ADDPATH        69 /* Addpath Capability */
 #define CAPABILITY_CODE_REFRESH_OLD   128 /* Route Refresh Capability(cisco) */
 #define CAPABILITY_CODE_ORF_OLD       130 /* Cooperative Route Filtering Capability(cisco) */
+#define CAPABILITY_CODE_HOSTNAME      131 /* Advertise hostname capabilty */
 
 /* Capability Length */
 #define CAPABILITY_CODE_MP_LEN          4
@@ -87,6 +88,7 @@ struct capability_gr
 #define CAPABILITY_CODE_RESTART_LEN     2 /* Receiving only case */
 #define CAPABILITY_CODE_AS4_LEN         4
 #define CAPABILITY_CODE_ADDPATH_LEN     4
+#define CAPABILITY_CODE_MIN_HOSTNAME_LEN 2
 
 /* Cooperative Route Filtering Capability.  */
 
index 530009d62d5349b2d33eb85fa6f1d569ac1486b7..aaba609924fbdddfecfee2b69de064dd8d2279a7 100644 (file)
@@ -7115,7 +7115,16 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
             {
               json_string = json_object_new_string(sockunion2str (&binfo->peer->su, buf, SU_ADDRSTRLEN));
               json_object_object_add(json_path, "peer-ip", json_string);
-
+             if (binfo->peer->hostname)
+               {
+                 json_string = json_object_new_string(binfo->peer->hostname);
+                 json_object_object_add(json_path, "peer-hostname", json_string);
+               }
+             if (binfo->peer->domainname)
+               {
+                 json_string = json_object_new_string(binfo->peer->domainname);
+                 json_object_object_add(json_path, "peer-domainname", json_string);
+               }
               if (binfo->peer->conf_if)
                 {
                   json_string = json_object_new_string(binfo->peer->conf_if);
@@ -7125,9 +7134,23 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
           else
             {
               if (binfo->peer->conf_if)
-                vty_out (vty, " from %s", binfo->peer->conf_if);
+               {
+                 if (binfo->peer->hostname &&
+                     bgp_flag_check(binfo->peer->bgp, BGP_FLAG_SHOW_HOSTNAME))
+                   vty_out (vty, " from %s(%s)", binfo->peer->hostname,
+                            binfo->peer->conf_if);
+                 else
+                   vty_out (vty, " from %s", binfo->peer->conf_if);
+               }
               else
-                vty_out (vty, " from %s", sockunion2str (&binfo->peer->su, buf, SU_ADDRSTRLEN));
+               {
+                 if (binfo->peer->hostname &&
+                     bgp_flag_check(binfo->peer->bgp, BGP_FLAG_SHOW_HOSTNAME))
+                   vty_out (vty, " from %s(%s)", binfo->peer->hostname,
+                            binfo->peer->host);
+                 else
+                   vty_out (vty, " from %s", sockunion2str (&binfo->peer->su, buf, SU_ADDRSTRLEN));
+               }
 
              if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
                vty_out (vty, " (%s)", inet_ntoa (attr->extra->originator_id));
@@ -7891,6 +7914,13 @@ route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
        {
           if (json)
             {
+             if (peer->hostname)
+               {
+                  json_string = json_object_new_string(peer->hostname);
+                  json_object_array_add(json_adv_to, json_string);
+
+                 /* TODO: Have to add domain name here too */
+               }
               if (peer->conf_if)
                 {
                   json_string = json_object_new_string(peer->conf_if);
@@ -7907,10 +7937,21 @@ route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
              if (! first)
                vty_out (vty, "  Advertised to non peer-group peers:%s ", VTY_NEWLINE);
 
-              if (peer->conf_if)
-                vty_out (vty, " %s", peer->conf_if);
-              else
-                vty_out (vty, " %s", sockunion2str (&peer->su, buf1, SU_ADDRSTRLEN));
+             if (peer->hostname && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME))
+               {
+                 if (peer->conf_if)
+                   vty_out (vty, " %s(%s)", peer->hostname, peer->conf_if);
+                 else
+                   vty_out (vty, " %s(%s)", peer->hostname,
+                            sockunion2str (&peer->su, buf1, SU_ADDRSTRLEN));
+               }
+             else
+               {
+                 if (peer->conf_if)
+                   vty_out (vty, " %s", peer->conf_if);
+                 else
+                   vty_out (vty, " %s", sockunion2str (&peer->su, buf1, SU_ADDRSTRLEN));
+               }
             }
            first = 1;
        }
@@ -11001,8 +11042,13 @@ peer_lookup_in_view (struct vty *vty, const char *view_name,
       peer = peer_lookup_by_conf_if (bgp, ip_str);
       if (!peer)
         {
-          vty_out (vty, "%% Malformed address or name: %s%s", ip_str, VTY_NEWLINE);
-          return NULL;
+         /* search for peer by hostname */
+         peer = peer_lookup_by_hostname(bgp, ip_str);
+         if (!peer)
+           {
+             vty_out (vty, "%% Malformed address or name: %s%s", ip_str, VTY_NEWLINE);
+             return NULL;
+           }
         }
       return peer;
     }
@@ -11487,9 +11533,16 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi)
    * on just vty_read()).
    */
   thread_execute (bm->master, bgp_peer_count_walker, &pcounts, 0);
-  
-  vty_out (vty, "Prefix counts for %s, %s%s", 
-           peer->host, afi_safi_print (afi, safi), VTY_NEWLINE);
+
+  if (peer->hostname && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME))
+    {
+      vty_out (vty, "Prefix counts for %s/%s, %s%s",
+              peer->hostname, peer->host, afi_safi_print (afi, safi),
+              VTY_NEWLINE);
+    }
+  else
+    vty_out (vty, "Prefix counts for %s, %s%s",
+            peer->host, afi_safi_print (afi, safi), VTY_NEWLINE);
   vty_out (vty, "PfxCt: %ld%s", peer->pcount[afi][safi], VTY_NEWLINE);
   vty_out (vty, "%sCounts from RIB table walk:%s%s", 
            VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
index f63b1504ecf60612cd62a32e60466afb73f1efbf..64057a3f6c1972c7ce24d00c25ee637f713a3afb 100644 (file)
@@ -115,8 +115,11 @@ peer_lookup_vty (struct vty *vty, const char *ip_str)
       peer = peer_lookup_by_conf_if (bgp, ip_str);
       if (!peer)
         {
-          vty_out (vty, "%% Malformed address or name: %s%s", ip_str, VTY_NEWLINE);
-          return NULL;
+         if ((peer = peer_lookup_by_hostname(bgp, ip_str)) == NULL)
+           {
+             vty_out (vty, "%% Malformed address or name: %s%s", ip_str, VTY_NEWLINE);
+             return NULL;
+           }
         }
     }
   else
@@ -382,8 +385,12 @@ bgp_clear (struct vty *vty, struct bgp *bgp,  afi_t afi, safi_t safi,
           peer = peer_lookup_by_conf_if (bgp, arg);
           if (!peer)
             {
-              vty_out (vty, "Malformed address or name: %s%s", arg, VTY_NEWLINE);
-              return CMD_WARNING;
+             peer = peer_lookup_by_hostname(bgp, arg);
+             if (!peer)
+               {
+                 vty_out (vty, "Malformed address or name: %s%s", arg, VTY_NEWLINE);
+                 return CMD_WARNING;
+               }
             }
         }
       else
@@ -2106,6 +2113,36 @@ DEFUN (bgp_default_ipv4_unicast,
   return CMD_SUCCESS;
 }
 
+/* Display hostname in certain command outputs */
+DEFUN (bgp_default_show_hostname,
+       bgp_default_show_hostname_cmd,
+       "bgp default show-hostname",
+       "BGP specific commands\n"
+       "Configure BGP defaults\n"
+       "Show hostname in certain command ouputs\n")
+{
+  struct bgp *bgp;
+
+  bgp = vty->index;
+  bgp_flag_set (bgp, BGP_FLAG_SHOW_HOSTNAME);
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_bgp_default_show_hostname,
+       no_bgp_default_show_hostname_cmd,
+       "no bgp default show-hostname",
+       NO_STR
+       "BGP specific commands\n"
+       "Configure BGP defaults\n"
+       "Show hostname in certain command ouputs\n")
+{
+  struct bgp *bgp;
+
+  bgp = vty->index;
+  bgp_flag_unset (bgp, BGP_FLAG_SHOW_HOSTNAME);
+  return CMD_SUCCESS;
+}
+
 /* "bgp import-check" configuration.  */
 DEFUN (bgp_network_import_check,
        bgp_network_import_check_cmd,
@@ -8538,6 +8575,18 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi,
               json_string = json_object_new_string(peer->host);
               json_object_object_add(json_peer, "ip", json_string);
 
+             if (peer->hostname)
+               {
+                 json_string = json_object_new_string(peer->hostname);
+                 json_object_object_add(json_peer, "hostname", json_string);
+               }
+
+             if (peer->domainname)
+               {
+                 json_string = json_object_new_string(peer->domainname);
+                 json_object_object_add(json_peer, "domainname", json_string);
+               }
+
               json_int = json_object_new_int(peer->as);
               json_object_object_add(json_peer, "remote-as", json_int);
 
@@ -8594,7 +8643,11 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi,
                   dn_flag[0] = '*';
                 }
 
-              len = vty_out (vty, "%s%s", dn_flag, peer->host);
+             if (peer->hostname && bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME))
+               len = vty_out (vty, "%s%s(%s)", dn_flag, peer->hostname,
+                              peer->host);
+             else
+               len = vty_out (vty, "%s%s", dn_flag, peer->host);
               len = 16 - len;
 
               if (len < 1)
@@ -9270,8 +9323,17 @@ bgp_show_peer (struct vty *vty, struct peer *p)
   /* Description. */
   if (p->desc)
     vty_out (vty, " Description: %s%s", p->desc, VTY_NEWLINE);
-  
-  /* Peer-group */
+
+  if (p->hostname)
+    {
+      if (p->domainname && (p->domainname[0] != '\0'))
+       vty_out(vty, "Hostname: %s.%s%s", p->hostname, p->domainname,
+               VTY_NEWLINE);
+      else
+       vty_out(vty, "Hostname: %s%s", p->hostname, VTY_NEWLINE);
+    }
+
+      /* Peer-group */
   if (p->group)
     {
       vty_out (vty, " Member of peer-group %s for session parameters%s",
@@ -9456,6 +9518,19 @@ bgp_show_peer (struct vty *vty, struct peer *p)
                  vty_out (vty, "%s", VTY_NEWLINE);
                } 
 
+         /* Hostname capability */
+         if (CHECK_FLAG(p->cap, PEER_CAP_HOSTNAME_ADV) ||
+             CHECK_FLAG(p->cap, PEER_CAP_HOSTNAME_RCV))
+           {
+             vty_out (vty, "    Hostname Capability:");
+             if (CHECK_FLAG (p->cap, PEER_CAP_HOSTNAME_ADV))
+               vty_out (vty, " advertised");
+             if (CHECK_FLAG (p->cap, PEER_CAP_HOSTNAME_RCV))
+               vty_out (vty, " %sreceived",
+                        CHECK_FLAG (p->cap, PEER_CAP_HOSTNAME_ADV) ? "and " : "");
+             vty_out (vty, "%s", VTY_NEWLINE);
+           }
+
          /* Gracefull Restart */
          if (CHECK_FLAG (p->cap, PEER_CAP_RESTART_RCV)
              || CHECK_FLAG (p->cap, PEER_CAP_RESTART_ADV))
@@ -9735,6 +9810,11 @@ bgp_show_neighbor (struct vty *vty, struct bgp *bgp,
             find = 1;
             bgp_show_peer (vty, peer);
           }
+       else if (peer->hostname && !strcmp(peer->hostname, conf_if))
+         {
+            find = 1;
+            bgp_show_peer (vty, peer);
+         }
       }
     else
       {
@@ -11705,6 +11785,10 @@ bgp_vty_init (void)
   install_element (BGP_NODE, &no_bgp_default_local_preference_cmd);
   install_element (BGP_NODE, &no_bgp_default_local_preference_val_cmd);
 
+  /* bgp default show-hostname */
+  install_element (BGP_NODE, &bgp_default_show_hostname_cmd);
+  install_element (BGP_NODE, &no_bgp_default_show_hostname_cmd);
+
   /* "bgp default subgroup-pkt-queue-max" commands. */
   install_element (BGP_NODE, &bgp_default_subgroup_pkt_queue_max_cmd);
   install_element (BGP_NODE, &no_bgp_default_subgroup_pkt_queue_max_cmd);
index bc5aee7e1bea95f8522911ec283ee94a6f634650..b9314e63dcf022fea9cb164ee154252a731152b0 100644 (file)
@@ -1738,7 +1738,12 @@ peer_delete (struct peer *peer)
 
   FOREACH_AFI_SAFI (afi, safi)
     peer_af_delete (peer, afi, safi);
-  
+
+  if (peer->hostname)
+    XFREE(MTYPE_HOST, peer->hostname);
+  if (peer->domainname)
+    XFREE(MTYPE_HOST, peer->domainname);
+
   peer_unlock (peer); /* initial reference */
 
   return 0;
@@ -2732,7 +2737,7 @@ bgp_delete (struct bgp *bgp)
     bgp_close ();
 
   bgp_unlock(bgp);  /* initial reference */
-  
+
   return 0;
 }
 
@@ -2807,6 +2812,35 @@ peer_lookup_by_conf_if (struct bgp *bgp, const char *conf_if)
   return NULL;
 }
 
+struct peer *
+peer_lookup_by_hostname (struct bgp *bgp, const char *hostname)
+{
+  struct peer *peer;
+  struct listnode *node, *nnode;
+
+  if (!hostname)
+    return NULL;
+
+  if (bgp != NULL)
+    {
+      for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
+        if (peer->hostname && !strcmp(peer->hostname, hostname)
+            && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
+          return peer;
+    }
+  else if (bm->bgp != NULL)
+    {
+      struct listnode *bgpnode, *nbgpnode;
+
+      for (ALL_LIST_ELEMENTS (bm->bgp, bgpnode, nbgpnode, bgp))
+        for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
+          if (peer->hostname && !strcmp(peer->hostname, hostname)
+             && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
+            return peer;
+    }
+  return NULL;
+}
+
 struct peer *
 peer_lookup (struct bgp *bgp, union sockunion *su)
 {
@@ -6349,6 +6383,10 @@ bgp_config_write (struct vty *vty)
        vty_out (vty, " bgp default local-preference %d%s",
                 bgp->default_local_pref, VTY_NEWLINE);
 
+      /* BGP default show-hostname */
+      if (bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME))
+       vty_out (vty, " bgp default show-hostname%s", VTY_NEWLINE);
+
       /* BGP default subgroup-pkt-queue-max. */
       if (bgp->default_subgroup_pkt_queue_max != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX)
        vty_out (vty, " bgp default subgroup-pkt-queue-max %d%s",
index 8a2738c734538fa5daf601a502e8b7bc5eed9d01..78cdde62319b88dd78d6f1be87387e4928cdc59a 100644 (file)
@@ -70,6 +70,7 @@ enum bgp_af_index
   for (afi = AFI_IP; afi < AFI_MAX; afi++)             \
     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
 
+#define BGP_MAX_HOSTNAME 64    /* Linux max, is larger than most other sys */
 
 /* BGP master for system wide configurations and variables.  */
 struct bgp_master
@@ -254,6 +255,7 @@ struct bgp
 #define BGP_FLAG_MULTIPATH_RELAX_NO_AS_SET (1 << 17)
 #define BGP_FLAG_FORCE_STATIC_PROCESS     (1 << 18)
 #define BGP_FLAG_IMPORT_CHECK_EXACT_MATCH (1 << 19)
+#define BGP_FLAG_SHOW_HOSTNAME            (1 << 20)
 
   /* BGP Per AF flags */
   u_int16_t af_flags[AFI_MAX][SAFI_MAX];
@@ -563,7 +565,7 @@ struct peer
   u_char afc_recv[AFI_MAX][SAFI_MAX];
 
   /* Capability flags (reset in bgp_stop) */
-  u_int16_t cap;
+  u_int32_t cap;
 #define PEER_CAP_REFRESH_ADV                (1 << 0) /* refresh advertised */
 #define PEER_CAP_REFRESH_OLD_RCV            (1 << 1) /* refresh old received */
 #define PEER_CAP_REFRESH_NEW_RCV            (1 << 2) /* refresh rfc received */
@@ -577,6 +579,8 @@ struct peer
 #define PEER_CAP_RESTART_BIT_RCV            (1 << 10) /* peer restart state */
 #define PEER_CAP_ADDPATH_ADV                (1 << 11) /* addpath advertised */
 #define PEER_CAP_ADDPATH_RCV                (1 << 12) /* addpath received */
+#define PEER_CAP_HOSTNAME_ADV               (1 << 13) /* hostname advertised */
+#define PEER_CAP_HOSTNAME_RCV               (1 << 14) /* hostname received */
 
   /* Capability flags (reset in bgp_stop) */
   u_int16_t af_cap[AFI_MAX][SAFI_MAX];
@@ -805,6 +809,10 @@ u_char last_reset_cause[BGP_MAX_PACKET_SIZE];
 #define PEER_RMAP_TYPE_NOSET          (1 << 5) /* not allow to set commands */
 #define PEER_RMAP_TYPE_IMPORT         (1 << 6) /* neighbor route-map import */
 #define PEER_RMAP_TYPE_EXPORT         (1 << 7) /* neighbor route-map export */
+
+  /* hostname and domainname advertised by host */
+  char *hostname;
+  char *domainname;
 };
 
 #define PEER_PASSWORD_MINLEN   (1)
@@ -1103,6 +1111,7 @@ extern struct bgp *bgp_lookup (as_t, const char *);
 extern struct bgp *bgp_lookup_by_name (const char *);
 extern struct peer *peer_lookup (struct bgp *, union sockunion *);
 extern struct peer *peer_lookup_by_conf_if (struct bgp *, const char *);
+extern struct peer *peer_lookup_by_hostname(struct bgp *, const char *);
 extern struct peer *peer_conf_interface_get(struct bgp *, const char *, afi_t,
                                             safi_t);
 extern void  bgp_peer_conf_if_to_su_update (struct peer *);