[prev in list] [next in list] [prev in thread] [next in thread] 

List:       quagga-dev
Subject:    [quagga-dev 8136] Re: [PATCH 05/10] BGP: GTSM support
From:       Balaji G <balajig81 () gmail ! com>
Date:       2010-08-08 14:09:41
Message-ID: AANLkTi=iVCZYk_XE84f-OcvN3wpRK568-VswKMZxcS+E () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Applied, Thanks.

Cheers,
  - Balaji


On Sun, Aug 8, 2010 at 4:40 PM, Balaji G <balajig81@gmail.com> wrote:

> Hi Stephen
>
> When i do a git apply --check on this patch, i get the following error.
>
> error: patch failed: lib/sockunion.c:537
> error: lib/sockunion.c: patch does not apply
> error: patch failed: lib/sockunion.h:102
> error: lib/sockunion.h: patch does not apply
>
>
> Thanks,
> Cheers,
>   - Balaji
>
>
>
>
>
>
>
> On Thu, Aug 5, 2010 at 10:56 PM, Stephen Hemminger <shemminger@vyatta.com>wrote:
>
>> This is a revison of previously submitted patch to
>> add support for BGP TTL security.
>>  http://www.gossamer-threads.com/lists/quagga/dev/17389
>>
>> I fixed a number of problems like allowing hops value to
>> be cleared, adn setting TTL on listen socket.
>>
>> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
>>
>> ---
>>  bgpd/bgp_network.c |   18 +++++-
>>  bgpd/bgp_vty.c     |   52 +++++++++++++++--
>>  bgpd/bgpd.c        |  158
>> ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>  bgpd/bgpd.h        |    7 ++
>>  lib/sockunion.c    |   22 +++++++
>>  lib/sockunion.h    |    1
>>  6 files changed, 248 insertions(+), 10 deletions(-)
>>
>> --- a/bgpd/bgp_network.c        2010-08-05 09:56:06.000000000 -0700
>> +++ b/bgpd/bgp_network.c        2010-08-05 10:01:36.001117598 -0700
>> @@ -173,8 +173,12 @@ bgp_accept (struct thread *thread)
>>     }
>>
>>   /* In case of peer is EBGP, we should set TTL for this connection.  */
>> -  if (peer_sort (peer1) == BGP_PEER_EBGP)
>> +  if (peer_sort (peer1) == BGP_PEER_EBGP) {
>>     sockopt_ttl (peer1->su.sa.sa_family, bgp_sock, peer1->ttl);
>> +    if (peer1->gtsm_hops)
>> +      sockopt_minttl (peer1->su.sa.sa_family, bgp_sock,
>> +                     MAXTTL + 1 - peer1->gtsm_hops);
>> +  }
>>
>>   /* Make dummy peer until read Open packet. */
>>   if (BGP_DEBUG (events, EVENTS))
>> @@ -314,8 +318,12 @@ bgp_connect (struct peer *peer)
>>     return -1;
>>
>>   /* If we can get socket for the peer, adjest TTL and make connection. */
>> -  if (peer_sort (peer) == BGP_PEER_EBGP)
>> +  if (peer_sort (peer) == BGP_PEER_EBGP) {
>>     sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
>> +    if (peer->gtsm_hops)
>> +      sockopt_minttl (peer->su.sa.sa_family, peer->fd,
>> +                     MAXTTL + 1 - peer->gtsm_hops);
>> +  }
>>
>>   sockopt_reuseaddr (peer->fd);
>>   sockopt_reuseport (peer->fd);
>> @@ -463,6 +471,9 @@ bgp_socket (unsigned short port, const c
>>          continue;
>>        }
>>
>> +      /* if we intend to implement ttl-security, this socket needs
>> ttl=255 */
>> +      sockopt_ttl (ainfo->ai_family, sock, MAXTTL);
>> +
>>       ret = bgp_listener (sock, ainfo->ai_addr, ainfo->ai_addrlen);
>>       if (ret == 0)
>>        ++count;
>> @@ -495,6 +506,9 @@ bgp_socket (unsigned short port, const c
>>       return sock;
>>     }
>>
>> +  /* if we intend to implement ttl-security, this socket needs ttl=255 */
>> +  sockopt_ttl (AF_INET, sock, MAXTTL);
>> +
>>   memset (&sin, 0, sizeof (struct sockaddr_in));
>>   sin.sin_family = AF_INET;
>>   sin.sin_port = htons (port);
>> --- a/bgpd/bgp_vty.c    2010-08-05 09:46:42.000000000 -0700
>> +++ b/bgpd/bgp_vty.c    2010-08-05 10:01:12.479632027 -0700
>> @@ -213,6 +213,9 @@ bgp_vty_return (struct vty *vty, int ret
>>     case BGP_ERR_TCPSIG_FAILED:
>>       str = "Error while applying TCP-Sig to session(s)";
>>       break;
>> +    case BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK:
>> +      str = "ebgp-multihop and ttl-security cannot be configured
>> together";
>> +      break;
>>     }
>>   if (str)
>>     {
>> @@ -2636,9 +2639,8 @@ peer_ebgp_multihop_set_vty (struct vty *
>>   else
>>     VTY_GET_INTEGER_RANGE ("TTL", ttl, ttl_str, 1, 255);
>>
>> -  peer_ebgp_multihop_set (peer, ttl);
>> -
>> -  return CMD_SUCCESS;
>> +  return bgp_vty_return (vty,
>> +                        peer_ebgp_multihop_set (peer, ttl) );
>>  }
>>
>>  static int
>> @@ -2650,9 +2652,7 @@ peer_ebgp_multihop_unset_vty (struct vty
>>   if (! peer)
>>     return CMD_WARNING;
>>
>> -  peer_ebgp_multihop_unset (peer);
>> -
>> -  return CMD_SUCCESS;
>> +  return bgp_vty_return (vty, peer_ebgp_multihop_unset (peer));
>>  }
>>
>>  /* neighbor ebgp-multihop. */
>> @@ -3954,6 +3954,42 @@ DEFUN (no_neighbor_allowas_in,
>>   return bgp_vty_return (vty, ret);
>>  }
>>
>> +DEFUN (neighbor_ttl_security,
>> +       neighbor_ttl_security_cmd,
>> +       NEIGHBOR_CMD2 "ttl-security hops <1-254>",
>> +       NEIGHBOR_STR
>> +       NEIGHBOR_ADDR_STR2
>> +       "Specify the maximum number of hops to the BGP peer\n")
>> +{
>> +  struct peer *peer;
>> +  int gtsm_hops;
>> +
>> +  peer = peer_and_group_lookup_vty (vty, argv[0]);
>> +  if (! peer)
>> +    return CMD_WARNING;
>> +
>> +  VTY_GET_INTEGER_RANGE ("", gtsm_hops, argv[1], 1, 254);
>> +
>> +  return bgp_vty_return (vty, peer_ttl_security_hops_set (peer,
>> gtsm_hops));
>> +}
>> +
>> +DEFUN (no_neighbor_ttl_security,
>> +       no_neighbor_ttl_security_cmd,
>> +       NO_NEIGHBOR_CMD2 "ttl-security hops <1-254>",
>> +       NO_STR
>> +       NEIGHBOR_STR
>> +       NEIGHBOR_ADDR_STR2
>> +       "Specify the maximum number of hops to the BGP peer\n")
>> +{
>> +  struct peer *peer;
>> +
>> +  peer = peer_and_group_lookup_vty (vty, argv[0]);
>> +  if (! peer)
>> +    return CMD_WARNING;
>> +
>> +  return bgp_vty_return (vty, peer_ttl_security_hops_unset (peer));
>> +}
>> +
>>  /* Address family configuration.  */
>>  DEFUN (address_family_ipv4,
>>        address_family_ipv4_cmd,
>> @@ -9909,6 +9945,10 @@ bgp_vty_init (void)
>>   install_element (BGP_IPV6_NODE,
>> &no_bgp_redistribute_ipv6_metric_rmap_cmd);
>>  #endif /* HAVE_IPV6 */
>>
>> +  /* ttl_security commands */
>> +  install_element (BGP_NODE, &neighbor_ttl_security_cmd);
>> +  install_element (BGP_NODE, &no_neighbor_ttl_security_cmd);
>> +
>>   /* "show bgp memory" commands. */
>>   install_element (VIEW_NODE, &show_bgp_memory_cmd);
>>   install_element (RESTRICTED_NODE, &show_bgp_memory_cmd);
>> --- a/bgpd/bgpd.c       2010-08-05 09:46:42.000000000 -0700
>> +++ b/bgpd/bgpd.c       2010-08-05 10:02:53.716931995 -0700
>> @@ -1379,6 +1379,7 @@ peer_group_get (struct bgp *bgp, const c
>>   group->conf->group = group;
>>   group->conf->as = 0;
>>   group->conf->ttl = 1;
>> +  group->conf->gtsm_hops = 0;
>>   group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
>>   UNSET_FLAG (group->conf->config, PEER_CONFIG_TIMER);
>>   UNSET_FLAG (group->conf->config, PEER_CONFIG_CONNECT);
>> @@ -1416,6 +1417,9 @@ peer_group2peer_config_copy (struct peer
>>   /* TTL */
>>   peer->ttl = conf->ttl;
>>
>> +  /* GTSM hops */
>> +  peer->gtsm_hops = conf->gtsm_hops;
>> +
>>   /* Weight */
>>   peer->weight = conf->weight;
>>
>> @@ -2663,10 +2667,36 @@ peer_ebgp_multihop_set (struct peer *pee
>>  {
>>   struct peer_group *group;
>>   struct listnode *node, *nnode;
>> +  struct peer *peer1;
>>
>>   if (peer_sort (peer) == BGP_PEER_IBGP)
>>     return 0;
>>
>> +  /* see comment in peer_ttl_security_hops_set() */
>> +  if (ttl != MAXTTL)
>> +    {
>> +      if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
>> +        {
>> +          group = peer->group;
>> +          if (group->conf->gtsm_hops != 0)
>> +            return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
>> +
>> +          for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
>> +            {
>> +              if (peer_sort (peer1) == BGP_PEER_IBGP)
>> +                continue;
>> +
>> +              if (peer1->gtsm_hops != 0)
>> +                return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
>> +            }
>> +        }
>> +      else
>> +        {
>> +          if (peer->gtsm_hops != 0)
>> +            return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
>> +        }
>> +    }
>> +
>>   peer->ttl = ttl;
>>
>>   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
>> @@ -2700,6 +2730,9 @@ peer_ebgp_multihop_unset (struct peer *p
>>   if (peer_sort (peer) == BGP_PEER_IBGP)
>>     return 0;
>>
>> +  if (peer->gtsm_hops != 0 && peer->ttl != MAXTTL)
>> +      return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
>> +
>>   if (peer_group_active (peer))
>>     peer->ttl = peer->group->conf->ttl;
>>   else
>> @@ -4331,6 +4364,122 @@ peer_maximum_prefix_unset (struct peer *
>>   return 0;
>>  }
>>
>> +/* Set # of hops between us and BGP peer. */
>> +int
>> +peer_ttl_security_hops_set (struct peer *peer, int gtsm_hops)
>> +{
>> +  struct peer_group *group;
>> +  struct listnode *node, *nnode;
>> +  struct peer *peer1;
>> +  int ret;
>> +
>> +  zlog_debug ("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
>> gtsm_hops, peer->host);
>> +
>> +  if (peer_sort (peer) == BGP_PEER_IBGP)
>> +    return 0;
>> +
>> +  /* We cannot configure ttl-security hops when ebgp-multihop is already
>> +     set.  For non peer-groups, the check is simple.  For peer-groups,
>> it's
>> +     slightly messy, because we need to check both the peer-group
>> structure
>> +     and all peer-group members for any trace of ebgp-multihop
>> configuration
>> +     before actually applying the ttl-security rules.  Cisco really made
>> a
>> +     mess of this configuration parameter, and OpenBGPD got it right.
>> +  */
>> +  if (peer->gtsm_hops == 0) {
>> +    if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
>> +      {
>> +       group = peer->group;
>> +       if (group->conf->ttl != 1)
>> +         return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
>> +
>> +       for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
>> +         {
>> +           if (peer_sort (peer1) == BGP_PEER_IBGP)
>> +             continue;
>> +
>> +           if (peer1->ttl != 1)
>> +             return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
>> +         }
>> +      }
>> +    else
>> +      {
>> +       if (peer->ttl != 1)
>> +         return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
>> +      }
>> +
>> +    /* specify MAXTTL on outgoing packets */
>> +    ret = peer_ebgp_multihop_set (peer, MAXTTL);
>> +    if (ret != 0)
>> +      return ret;
>> +  }
>> +
>> +  peer->gtsm_hops = gtsm_hops;
>> +
>> +  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
>> +    {
>> +      if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
>> +       sockopt_minttl (peer->su.sa.sa_family, peer->fd, MAXTTL + 1 -
>> gtsm_hops);
>> +    }
>> +  else
>> +    {
>> +      group = peer->group;
>> +      for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
>> +       {
>> +         if (peer_sort (peer) == BGP_PEER_IBGP)
>> +           continue;
>> +
>> +         peer->gtsm_hops = group->conf->gtsm_hops;
>> +
>> +         if (peer->fd >= 0 && peer->gtsm_hops != 0)
>> +            sockopt_minttl (peer->su.sa.sa_family, peer->fd, MAXTTL + 1 -
>> peer->gtsm_hops);
>> +       }
>> +    }
>> +
>> +  return 0;
>> +}
>> +
>> +int
>> +peer_ttl_security_hops_unset (struct peer *peer)
>> +{
>> +  struct peer_group *group;
>> +  struct listnode *node, *nnode;
>> +  struct peer *opeer;
>> +
>> +  zlog_debug ("peer_ttl_security_hops_unset: set gtsm_hops to zero for
>> %s", peer->host);
>> +
>> +  if (peer_sort (peer) == BGP_PEER_IBGP)
>> +      return 0;
>> +
>> +  /* if a peer-group member, then reset to peer-group default rather than
>> 0 */
>> +  if (peer_group_active (peer))
>> +    peer->gtsm_hops = peer->group->conf->gtsm_hops;
>> +  else
>> +    peer->gtsm_hops = 0;
>> +
>> +  opeer = peer;
>> +  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
>> +    {
>> +      if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
>> +       sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0);
>> +    }
>> +  else
>> +    {
>> +      group = peer->group;
>> +      for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
>> +       {
>> +         if (peer_sort (peer) == BGP_PEER_IBGP)
>> +           continue;
>> +
>> +         peer->gtsm_hops = 0;
>> +
>> +         if (peer->fd >= 0)
>> +           sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0);
>> +       }
>> +    }
>> +
>> +  return peer_ebgp_multihop_unset (opeer);
>> +}
>> +
>>  int
>>  peer_clear (struct peer *peer)
>>  {
>> @@ -4635,12 +4784,19 @@ bgp_config_write_peer (struct vty *vty,
>>          vty_out (vty, " neighbor %s passive%s", addr, VTY_NEWLINE);
>>
>>       /* EBGP multihop.  */
>> -      if (peer_sort (peer) != BGP_PEER_IBGP && peer->ttl != 1)
>> +      if (peer_sort (peer) != BGP_PEER_IBGP && peer->ttl != 1 &&
>> +                   !(peer->gtsm_hops != 0 && peer->ttl == MAXTTL))
>>         if (! peer_group_active (peer) ||
>>            g_peer->ttl != peer->ttl)
>>          vty_out (vty, " neighbor %s ebgp-multihop %d%s", addr, peer->ttl,
>>                   VTY_NEWLINE);
>>
>> +     /* ttl-security hops */
>> +      if (peer_sort (peer) != BGP_PEER_IBGP && peer->gtsm_hops != 0)
>> +        if (! peer_group_active (peer) || g_peer->gtsm_hops !=
>> peer->gtsm_hops)
>> +          vty_out (vty, " neighbor %s ttl-security hops %d%s", addr,
>> +                   peer->gtsm_hops, VTY_NEWLINE);
>> +
>>       /* disable-connected-check.  */
>>       if (CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
>>        if (! peer_group_active (peer) ||
>> --- a/bgpd/bgpd.h       2010-08-05 09:46:42.000000000 -0700
>> +++ b/bgpd/bgpd.h       2010-08-05 10:01:12.487631170 -0700
>> @@ -303,6 +303,7 @@ struct peer
>>   /* Peer information */
>>   int fd;                      /* File descriptor */
>>   int ttl;                     /* TTL of TCP connection to the peer. */
>> +  int gtsm_hops;               /* minimum hopcount to peer */
>>   char *desc;                  /* Description of the peer. */
>>   unsigned short port;          /* Destination port for peer */
>>   char *host;                  /* Printable address of the peer. */
>> @@ -800,7 +801,8 @@ enum bgp_clear_type
>>  #define BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP  -27
>>  #define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS    -28
>>  #define BGP_ERR_TCPSIG_FAILED                  -29
>> -#define BGP_ERR_MAX                             -30
>> +#define BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK  -30
>> +#define BGP_ERR_MAX                            -31
>>
>>  extern struct bgp_master *bm;
>>
>> @@ -953,4 +955,7 @@ extern int peer_maximum_prefix_unset (st
>>  extern int peer_clear (struct peer *);
>>  extern int peer_clear_soft (struct peer *, afi_t, safi_t, enum
>> bgp_clear_type);
>>
>> +extern int peer_ttl_security_hops_set (struct peer *, int);
>> +extern int peer_ttl_security_hops_unset (struct peer *);
>> +
>>  #endif /* _QUAGGA_BGPD_H */
>> --- a/lib/sockunion.c   2010-08-05 09:56:08.000000000 -0700
>> +++ b/lib/sockunion.c   2010-08-05 10:01:12.487631170 -0700
>> @@ -537,6 +537,28 @@ sockopt_cork (int sock, int onoff)
>>  #endif
>>  }
>>
>> +int
>> +sockopt_minttl (int family, int sock, int minttl)
>> +{
>> +#ifdef IP_MINTTL
>> +  int ret;
>> +
>> +  ret = setsockopt (sock, IPPROTO_IP, IP_MINTTL, &minttl,
>> sizeof(minttl));
>> +  if (ret < 0)
>> +    {
>> +      zlog (NULL, LOG_WARNING,
>> +           "can't set sockopt IP_MINTTL to %d on socket %d: %s",
>> +           minttl, sock, safe_strerror (errno));
>> +      return -1;
>> +    }
>> +
>> +  return 0;
>> +#else
>> +  errno = EOPNOTSUPP;
>> +  return -1;
>> +#endif /* IP_MINTTL */
>> +}
>> +
>>  /* If same family and same prefix return 1. */
>>  int
>>  sockunion_same (union sockunion *su1, union sockunion *su2)
>> --- a/lib/sockunion.h   2010-08-05 09:56:08.000000000 -0700
>> +++ b/lib/sockunion.h   2010-08-05 10:01:12.487631170 -0700
>> @@ -102,6 +102,7 @@ extern int sockopt_reuseport (int);
>>  extern int sockunion_bind (int sock, union sockunion *,
>>                            unsigned short, union sockunion *);
>>  extern int sockopt_ttl (int family, int sock, int ttl);
>> +extern int sockopt_minttl (int family, int sock, int minttl);
>>  extern int sockopt_cork (int sock, int onoff);
>>  extern int sockunion_socket (union sockunion *su);
>>  extern const char *inet_sutop (union sockunion *su, char *str);
>>
>>
>> _______________________________________________
>> Quagga-dev mailing list
>> Quagga-dev@lists.quagga.net
>> http://lists.quagga.net/mailman/listinfo/quagga-dev
>>
>
>

[Attachment #5 (text/html)]

Applied, Thanks.<br><br>Cheers,<br>   - Balaji<br><br><br><div class="gmail_quote">On \
Sun, Aug 8, 2010 at 4:40 PM, Balaji G <span dir="ltr">&lt;<a \
href="mailto:balajig81@gmail.com">balajig81@gmail.com</a>&gt;</span> wrote:<br> \
<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px \
solid rgb(204, 204, 204); padding-left: 1ex;">Hi Stephen <br><br>When i do a git \
apply --check on this patch, i get the following error.<br> <br>error: patch failed: \
lib/sockunion.c:537<br>error: lib/sockunion.c: patch does not apply<br>error: patch \
                failed: lib/sockunion.h:102<br>
error: lib/sockunion.h: patch does not apply<br><br><br>Thanks,<br>Cheers,<br><font \
color="#888888">   - Balaji</font><div><div></div><div \
class="h5"><br><br><br><br><br><br><br><div class="gmail_quote">On Thu, Aug 5, 2010 \
at 10:56 PM, Stephen Hemminger <span dir="ltr">&lt;<a \
href="mailto:shemminger@vyatta.com" \
target="_blank">shemminger@vyatta.com</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px \
solid rgb(204, 204, 204); padding-left: 1ex;">This is a revison of previously \
submitted patch to<br> add support for BGP TTL security.<br>
   <a href="http://www.gossamer-threads.com/lists/quagga/dev/17389" \
target="_blank">http://www.gossamer-threads.com/lists/quagga/dev/17389</a><br> <br>
I fixed a number of problems like allowing hops value to<br>
be cleared, adn setting TTL on listen socket.<br>
<br>
Signed-off-by: Stephen Hemminger &lt;<a href="mailto:shemminger@vyatta.com" \
target="_blank">shemminger@vyatta.com</a>&gt;<br> <br>
---<br>
  bgpd/bgp_network.c |    18 +++++-<br>
  bgpd/bgp_vty.c       |    52 +++++++++++++++--<br>
  bgpd/bgpd.c            |   158 \
++++++++++++++++++++++++++++++++++++++++++++++++++++-<br>  bgpd/bgpd.h            |   \
7 ++<br>  lib/sockunion.c      |    22 +++++++<br>
  lib/sockunion.h      |      1<br>
  6 files changed, 248 insertions(+), 10 deletions(-)<br>
<br>
--- a/bgpd/bgp_network.c            2010-08-05 09:56:06.000000000 -0700<br>
+++ b/bgpd/bgp_network.c            2010-08-05 10:01:36.001117598 -0700<br>
@@ -173,8 +173,12 @@ bgp_accept (struct thread *thread)<br>
       }<br>
<br>
    /* In case of peer is EBGP, we should set TTL for this connection.   */<br>
-   if (peer_sort (peer1) == BGP_PEER_EBGP)<br>
+   if (peer_sort (peer1) == BGP_PEER_EBGP) {<br>
       sockopt_ttl (peer1-&gt;su.sa.sa_family, bgp_sock, peer1-&gt;ttl);<br>
+      if (peer1-&gt;gtsm_hops)<br>
+         sockopt_minttl (peer1-&gt;su.sa.sa_family, bgp_sock,<br>
+                               MAXTTL + 1 - peer1-&gt;gtsm_hops);<br>
+   }<br>
<br>
    /* Make dummy peer until read Open packet. */<br>
    if (BGP_DEBUG (events, EVENTS))<br>
@@ -314,8 +318,12 @@ bgp_connect (struct peer *peer)<br>
       return -1;<br>
<br>
    /* If we can get socket for the peer, adjest TTL and make connection. */<br>
-   if (peer_sort (peer) == BGP_PEER_EBGP)<br>
+   if (peer_sort (peer) == BGP_PEER_EBGP) {<br>
       sockopt_ttl (peer-&gt;su.sa.sa_family, peer-&gt;fd, peer-&gt;ttl);<br>
+      if (peer-&gt;gtsm_hops)<br>
+         sockopt_minttl (peer-&gt;su.sa.sa_family, peer-&gt;fd,<br>
+                               MAXTTL + 1 - peer-&gt;gtsm_hops);<br>
+   }<br>
<br>
    sockopt_reuseaddr (peer-&gt;fd);<br>
    sockopt_reuseport (peer-&gt;fd);<br>
@@ -463,6 +471,9 @@ bgp_socket (unsigned short port, const c<br>
               continue;<br>
            }<br>
<br>
+         /* if we intend to implement ttl-security, this socket needs ttl=255 */<br>
+         sockopt_ttl (ainfo-&gt;ai_family, sock, MAXTTL);<br>
+<br>
          ret = bgp_listener (sock, ainfo-&gt;ai_addr, ainfo-&gt;ai_addrlen);<br>
          if (ret == 0)<br>
            ++count;<br>
@@ -495,6 +506,9 @@ bgp_socket (unsigned short port, const c<br>
          return sock;<br>
       }<br>
<br>
+   /* if we intend to implement ttl-security, this socket needs ttl=255 */<br>
+   sockopt_ttl (AF_INET, sock, MAXTTL);<br>
+<br>
    memset (&amp;sin, 0, sizeof (struct sockaddr_in));<br>
    sin.sin_family = AF_INET;<br>
    sin.sin_port = htons (port);<br>
--- a/bgpd/bgp_vty.c      2010-08-05 09:46:42.000000000 -0700<br>
+++ b/bgpd/bgp_vty.c      2010-08-05 10:01:12.479632027 -0700<br>
@@ -213,6 +213,9 @@ bgp_vty_return (struct vty *vty, int ret<br>
       case BGP_ERR_TCPSIG_FAILED:<br>
          str = &quot;Error while applying TCP-Sig to session(s)&quot;;<br>
          break;<br>
+      case BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK:<br>
+         str = &quot;ebgp-multihop and ttl-security cannot be configured \
together&quot;;<br> +         break;<br>
       }<br>
    if (str)<br>
       {<br>
@@ -2636,9 +2639,8 @@ peer_ebgp_multihop_set_vty (struct vty *<br>
    else<br>
       VTY_GET_INTEGER_RANGE (&quot;TTL&quot;, ttl, ttl_str, 1, 255);<br>
<br>
-   peer_ebgp_multihop_set (peer, ttl);<br>
-<br>
-   return CMD_SUCCESS;<br>
+   return bgp_vty_return (vty,<br>
+                                    peer_ebgp_multihop_set (peer, ttl) );<br>
  }<br>
<br>
  static int<br>
@@ -2650,9 +2652,7 @@ peer_ebgp_multihop_unset_vty (struct vty<br>
    if (! peer)<br>
       return CMD_WARNING;<br>
<br>
-   peer_ebgp_multihop_unset (peer);<br>
-<br>
-   return CMD_SUCCESS;<br>
+   return bgp_vty_return (vty, peer_ebgp_multihop_unset (peer));<br>
  }<br>
<br>
  /* neighbor ebgp-multihop. */<br>
@@ -3954,6 +3954,42 @@ DEFUN (no_neighbor_allowas_in,<br>
    return bgp_vty_return (vty, ret);<br>
  }<br>
<br>
+DEFUN (neighbor_ttl_security,<br>
+          neighbor_ttl_security_cmd,<br>
+          NEIGHBOR_CMD2 &quot;ttl-security hops &lt;1-254&gt;&quot;,<br>
+          NEIGHBOR_STR<br>
+          NEIGHBOR_ADDR_STR2<br>
+          &quot;Specify the maximum number of hops to the BGP peer\n&quot;)<br>
+{<br>
+   struct peer *peer;<br>
+   int gtsm_hops;<br>
+<br>
+   peer = peer_and_group_lookup_vty (vty, argv[0]);<br>
+   if (! peer)<br>
+      return CMD_WARNING;<br>
+<br>
+   VTY_GET_INTEGER_RANGE (&quot;&quot;, gtsm_hops, argv[1], 1, 254);<br>
+<br>
+   return bgp_vty_return (vty, peer_ttl_security_hops_set (peer, gtsm_hops));<br>
+}<br>
+<br>
+DEFUN (no_neighbor_ttl_security,<br>
+          no_neighbor_ttl_security_cmd,<br>
+          NO_NEIGHBOR_CMD2 &quot;ttl-security hops &lt;1-254&gt;&quot;,<br>
+          NO_STR<br>
+          NEIGHBOR_STR<br>
+          NEIGHBOR_ADDR_STR2<br>
+          &quot;Specify the maximum number of hops to the BGP peer\n&quot;)<br>
+{<br>
+   struct peer *peer;<br>
+<br>
+   peer = peer_and_group_lookup_vty (vty, argv[0]);<br>
+   if (! peer)<br>
+      return CMD_WARNING;<br>
+<br>
+   return bgp_vty_return (vty, peer_ttl_security_hops_unset (peer));<br>
+}<br>
+<br>
  /* Address family configuration.   */<br>
  DEFUN (address_family_ipv4,<br>
            address_family_ipv4_cmd,<br>
@@ -9909,6 +9945,10 @@ bgp_vty_init (void)<br>
    install_element (BGP_IPV6_NODE, \
&amp;no_bgp_redistribute_ipv6_metric_rmap_cmd);<br>  #endif /* HAVE_IPV6 */<br>
<br>
+   /* ttl_security commands */<br>
+   install_element (BGP_NODE, &amp;neighbor_ttl_security_cmd);<br>
+   install_element (BGP_NODE, &amp;no_neighbor_ttl_security_cmd);<br>
+<br>
    /* &quot;show bgp memory&quot; commands. */<br>
    install_element (VIEW_NODE, &amp;show_bgp_memory_cmd);<br>
    install_element (RESTRICTED_NODE, &amp;show_bgp_memory_cmd);<br>
--- a/bgpd/bgpd.c          2010-08-05 09:46:42.000000000 -0700<br>
+++ b/bgpd/bgpd.c          2010-08-05 10:02:53.716931995 -0700<br>
@@ -1379,6 +1379,7 @@ peer_group_get (struct bgp *bgp, const c<br>
    group-&gt;conf-&gt;group = group;<br>
    group-&gt;conf-&gt;as = 0;<br>
    group-&gt;conf-&gt;ttl = 1;<br>
+   group-&gt;conf-&gt;gtsm_hops = 0;<br>
    group-&gt;conf-&gt;v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;<br>
    UNSET_FLAG (group-&gt;conf-&gt;config, PEER_CONFIG_TIMER);<br>
    UNSET_FLAG (group-&gt;conf-&gt;config, PEER_CONFIG_CONNECT);<br>
@@ -1416,6 +1417,9 @@ peer_group2peer_config_copy (struct peer<br>
    /* TTL */<br>
    peer-&gt;ttl = conf-&gt;ttl;<br>
<br>
+   /* GTSM hops */<br>
+   peer-&gt;gtsm_hops = conf-&gt;gtsm_hops;<br>
+<br>
    /* Weight */<br>
    peer-&gt;weight = conf-&gt;weight;<br>
<br>
@@ -2663,10 +2667,36 @@ peer_ebgp_multihop_set (struct peer *pee<br>
  {<br>
    struct peer_group *group;<br>
    struct listnode *node, *nnode;<br>
+   struct peer *peer1;<br>
<br>
    if (peer_sort (peer) == BGP_PEER_IBGP)<br>
       return 0;<br>
<br>
+   /* see comment in peer_ttl_security_hops_set() */<br>
+   if (ttl != MAXTTL)<br>
+      {<br>
+         if (CHECK_FLAG (peer-&gt;sflags, PEER_STATUS_GROUP))<br>
+            {<br>
+               group = peer-&gt;group;<br>
+               if (group-&gt;conf-&gt;gtsm_hops != 0)<br>
+                  return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;<br>
+<br>
+               for (ALL_LIST_ELEMENTS (group-&gt;peer, node, nnode, peer1))<br>
+                  {<br>
+                     if (peer_sort (peer1) == BGP_PEER_IBGP)<br>
+                        continue;<br>
+<br>
+                     if (peer1-&gt;gtsm_hops != 0)<br>
+                        return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;<br>
+                  }<br>
+            }<br>
+         else<br>
+            {<br>
+               if (peer-&gt;gtsm_hops != 0)<br>
+                  return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;<br>
+            }<br>
+      }<br>
+<br>
    peer-&gt;ttl = ttl;<br>
<br>
    if (! CHECK_FLAG (peer-&gt;sflags, PEER_STATUS_GROUP))<br>
@@ -2700,6 +2730,9 @@ peer_ebgp_multihop_unset (struct peer *p<br>
    if (peer_sort (peer) == BGP_PEER_IBGP)<br>
       return 0;<br>
<br>
+   if (peer-&gt;gtsm_hops != 0 &amp;&amp; peer-&gt;ttl != MAXTTL)<br>
+         return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;<br>
+<br>
    if (peer_group_active (peer))<br>
       peer-&gt;ttl = peer-&gt;group-&gt;conf-&gt;ttl;<br>
    else<br>
@@ -4331,6 +4364,122 @@ peer_maximum_prefix_unset (struct peer *<br>
    return 0;<br>
  }<br>
<br>
+/* Set # of hops between us and BGP peer. */<br>
+int<br>
+peer_ttl_security_hops_set (struct peer *peer, int gtsm_hops)<br>
+{<br>
+   struct peer_group *group;<br>
+   struct listnode *node, *nnode;<br>
+   struct peer *peer1;<br>
+   int ret;<br>
+<br>
+   zlog_debug (&quot;peer_ttl_security_hops_set: set gtsm_hops to %d for %s&quot;, \
gtsm_hops, peer-&gt;host);<br> +<br>
+   if (peer_sort (peer) == BGP_PEER_IBGP)<br>
+      return 0;<br>
+<br>
+   /* We cannot configure ttl-security hops when ebgp-multihop is already<br>
+       set.   For non peer-groups, the check is simple.   For peer-groups, \
it&#39;s<br> +       slightly messy, because we need to check both the peer-group \
structure<br> +       and all peer-group members for any trace of ebgp-multihop \
configuration<br> +       before actually applying the ttl-security rules.   Cisco \
really made a<br> +       mess of this configuration parameter, and OpenBGPD got it \
right.<br> +   */<br>
+   if (peer-&gt;gtsm_hops == 0) {<br>
+      if (CHECK_FLAG (peer-&gt;sflags, PEER_STATUS_GROUP))<br>
+         {<br>
+          group = peer-&gt;group;<br>
+          if (group-&gt;conf-&gt;ttl != 1)<br>
+             return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;<br>
+<br>
+          for (ALL_LIST_ELEMENTS (group-&gt;peer, node, nnode, peer1))<br>
+             {<br>
+                if (peer_sort (peer1) == BGP_PEER_IBGP)<br>
+                   continue;<br>
+<br>
+                if (peer1-&gt;ttl != 1)<br>
+                   return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;<br>
+             }<br>
+         }<br>
+      else<br>
+         {<br>
+          if (peer-&gt;ttl != 1)<br>
+             return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;<br>
+         }<br>
+<br>
+      /* specify MAXTTL on outgoing packets */<br>
+      ret = peer_ebgp_multihop_set (peer, MAXTTL);<br>
+      if (ret != 0)<br>
+         return ret;<br>
+   }<br>
+<br>
+   peer-&gt;gtsm_hops = gtsm_hops;<br>
+<br>
+   if (! CHECK_FLAG (peer-&gt;sflags, PEER_STATUS_GROUP))<br>
+      {<br>
+         if (peer-&gt;fd &gt;= 0 &amp;&amp; peer_sort (peer) != BGP_PEER_IBGP)<br>
+          sockopt_minttl (peer-&gt;su.sa.sa_family, peer-&gt;fd, MAXTTL + 1 - \
gtsm_hops);<br> +      }<br>
+   else<br>
+      {<br>
+         group = peer-&gt;group;<br>
+         for (ALL_LIST_ELEMENTS (group-&gt;peer, node, nnode, peer))<br>
+          {<br>
+             if (peer_sort (peer) == BGP_PEER_IBGP)<br>
+                continue;<br>
+<br>
+             peer-&gt;gtsm_hops = group-&gt;conf-&gt;gtsm_hops;<br>
+<br>
+             if (peer-&gt;fd &gt;= 0 &amp;&amp; peer-&gt;gtsm_hops != 0)<br>
+                  sockopt_minttl (peer-&gt;su.sa.sa_family, peer-&gt;fd, MAXTTL + 1 \
- peer-&gt;gtsm_hops);<br> +          }<br>
+      }<br>
+<br>
+   return 0;<br>
+}<br>
+<br>
+int<br>
+peer_ttl_security_hops_unset (struct peer *peer)<br>
+{<br>
+   struct peer_group *group;<br>
+   struct listnode *node, *nnode;<br>
+   struct peer *opeer;<br>
+<br>
+   zlog_debug (&quot;peer_ttl_security_hops_unset: set gtsm_hops to zero for \
%s&quot;, peer-&gt;host);<br> +<br>
+   if (peer_sort (peer) == BGP_PEER_IBGP)<br>
+         return 0;<br>
+<br>
+   /* if a peer-group member, then reset to peer-group default rather than 0 */<br>
+   if (peer_group_active (peer))<br>
+      peer-&gt;gtsm_hops = peer-&gt;group-&gt;conf-&gt;gtsm_hops;<br>
+   else<br>
+      peer-&gt;gtsm_hops = 0;<br>
+<br>
+   opeer = peer;<br>
+   if (! CHECK_FLAG (peer-&gt;sflags, PEER_STATUS_GROUP))<br>
+      {<br>
+         if (peer-&gt;fd &gt;= 0 &amp;&amp; peer_sort (peer) != BGP_PEER_IBGP)<br>
+          sockopt_minttl (peer-&gt;su.sa.sa_family, peer-&gt;fd, 0);<br>
+      }<br>
+   else<br>
+      {<br>
+         group = peer-&gt;group;<br>
+         for (ALL_LIST_ELEMENTS (group-&gt;peer, node, nnode, peer))<br>
+          {<br>
+             if (peer_sort (peer) == BGP_PEER_IBGP)<br>
+                continue;<br>
+<br>
+             peer-&gt;gtsm_hops = 0;<br>
+<br>
+             if (peer-&gt;fd &gt;= 0)<br>
+                sockopt_minttl (peer-&gt;su.sa.sa_family, peer-&gt;fd, 0);<br>
+          }<br>
+      }<br>
+<br>
+   return peer_ebgp_multihop_unset (opeer);<br>
+}<br>
+<br>
  int<br>
  peer_clear (struct peer *peer)<br>
  {<br>
@@ -4635,12 +4784,19 @@ bgp_config_write_peer (struct vty *vty,<br>
               vty_out (vty, &quot; neighbor %s passive%s&quot;, addr, \
VTY_NEWLINE);<br> <br>
          /* EBGP multihop.   */<br>
-         if (peer_sort (peer) != BGP_PEER_IBGP &amp;&amp; peer-&gt;ttl != 1)<br>
+         if (peer_sort (peer) != BGP_PEER_IBGP &amp;&amp; peer-&gt;ttl != 1 \
&amp;&amp;<br> +                            !(peer-&gt;gtsm_hops != 0 &amp;&amp; \
peer-&gt;ttl == MAXTTL))<br>  if (! peer_group_active (peer) ||<br>
                  g_peer-&gt;ttl != peer-&gt;ttl)<br>
               vty_out (vty, &quot; neighbor %s ebgp-multihop %d%s&quot;, addr, \
peer-&gt;ttl,<br>  VTY_NEWLINE);<br>
<br>
+       /* ttl-security hops */<br>
+         if (peer_sort (peer) != BGP_PEER_IBGP &amp;&amp; peer-&gt;gtsm_hops != \
0)<br> +            if (! peer_group_active (peer) || g_peer-&gt;gtsm_hops != \
peer-&gt;gtsm_hops)<br> +               vty_out (vty, &quot; neighbor %s ttl-security \
hops %d%s&quot;, addr,<br> +                            peer-&gt;gtsm_hops, \
VTY_NEWLINE);<br> +<br>
          /* disable-connected-check.   */<br>
          if (CHECK_FLAG (peer-&gt;flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))<br>
            if (! peer_group_active (peer) ||<br>
--- a/bgpd/bgpd.h          2010-08-05 09:46:42.000000000 -0700<br>
+++ b/bgpd/bgpd.h          2010-08-05 10:01:12.487631170 -0700<br>
@@ -303,6 +303,7 @@ struct peer<br>
    /* Peer information */<br>
    int fd;                                 /* File descriptor */<br>
    int ttl;                               /* TTL of TCP connection to the peer. \
*/<br> +   int gtsm_hops;                      /* minimum hopcount to peer */<br>
    char *desc;                           /* Description of the peer. */<br>
    unsigned short port;               /* Destination port for peer */<br>
    char *host;                           /* Printable address of the peer. */<br>
@@ -800,7 +801,8 @@ enum bgp_clear_type<br>
  #define BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP   -27<br>
  #define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS      -28<br>
  #define BGP_ERR_TCPSIG_FAILED                           -29<br>
-#define BGP_ERR_MAX                                           -30<br>
+#define BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK   -30<br>
+#define BGP_ERR_MAX                                          -31<br>
<br>
  extern struct bgp_master *bm;<br>
<br>
@@ -953,4 +955,7 @@ extern int peer_maximum_prefix_unset (st<br>
  extern int peer_clear (struct peer *);<br>
  extern int peer_clear_soft (struct peer *, afi_t, safi_t, enum bgp_clear_type);<br>
<br>
+extern int peer_ttl_security_hops_set (struct peer *, int);<br>
+extern int peer_ttl_security_hops_unset (struct peer *);<br>
+<br>
  #endif /* _QUAGGA_BGPD_H */<br>
--- a/lib/sockunion.c    2010-08-05 09:56:08.000000000 -0700<br>
+++ b/lib/sockunion.c    2010-08-05 10:01:12.487631170 -0700<br>
@@ -537,6 +537,28 @@ sockopt_cork (int sock, int onoff)<br>
  #endif<br>
  }<br>
<br>
+int<br>
+sockopt_minttl (int family, int sock, int minttl)<br>
+{<br>
+#ifdef IP_MINTTL<br>
+   int ret;<br>
+<br>
+   ret = setsockopt (sock, IPPROTO_IP, IP_MINTTL, &amp;minttl, sizeof(minttl));<br>
+   if (ret &lt; 0)<br>
+      {<br>
+         zlog (NULL, LOG_WARNING,<br>
+                &quot;can&#39;t set sockopt IP_MINTTL to %d on socket %d: \
%s&quot;,<br> +                minttl, sock, safe_strerror (errno));<br>
+         return -1;<br>
+      }<br>
+<br>
+   return 0;<br>
+#else<br>
+   errno = EOPNOTSUPP;<br>
+   return -1;<br>
+#endif /* IP_MINTTL */<br>
+}<br>
+<br>
  /* If same family and same prefix return 1. */<br>
  int<br>
  sockunion_same (union sockunion *su1, union sockunion *su2)<br>
--- a/lib/sockunion.h    2010-08-05 09:56:08.000000000 -0700<br>
+++ b/lib/sockunion.h    2010-08-05 10:01:12.487631170 -0700<br>
@@ -102,6 +102,7 @@ extern int sockopt_reuseport (int);<br>
  extern int sockunion_bind (int sock, union sockunion *,<br>
                                          unsigned short, union sockunion *);<br>
  extern int sockopt_ttl (int family, int sock, int ttl);<br>
+extern int sockopt_minttl (int family, int sock, int minttl);<br>
  extern int sockopt_cork (int sock, int onoff);<br>
  extern int sockunion_socket (union sockunion *su);<br>
  extern const char *inet_sutop (union sockunion *su, char *str);<br>
<br>
<br>
_______________________________________________<br>
Quagga-dev mailing list<br>
<a href="mailto:Quagga-dev@lists.quagga.net" \
target="_blank">Quagga-dev@lists.quagga.net</a><br> <a \
href="http://lists.quagga.net/mailman/listinfo/quagga-dev" \
target="_blank">http://lists.quagga.net/mailman/listinfo/quagga-dev</a><br> \
</blockquote></div><br> </div></div></blockquote></div><br>



_______________________________________________
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
http://lists.quagga.net/mailman/listinfo/quagga-dev


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic