summaryrefslogtreecommitdiffstats
path: root/bgpd
diff options
context:
space:
mode:
authorPradosh Mohapatra <pmohapat@cumulusnetworks.com>2013-09-12 03:37:07 +0000
committerDavid Lamparter <equinox@opensourcerouting.org>2014-05-19 23:25:46 +0200
commit5d804b439a4138c77f81de30c64f923e2b5c1340 (patch)
treeb63e3dc3a266d42311392e57c37e2b0a9855ff0b /bgpd
parent5f9adb5d26d3af31b00c02084468e9f92b461b01 (diff)
downloadquagga-5d804b439a4138c77f81de30c64f923e2b5c1340.tar.bz2
quagga-5d804b439a4138c77f81de30c64f923e2b5c1340.tar.xz
bgpd: support TTL-security with iBGP
Traditionally, ttl-security feature has been associated with EBGP sessions as those identify directly connected external peers. The GTSM RFC (rfc 5082) does not make any restrictions on type of peering. In fact, it is beneficial to support ttl-security for both EBGP and IBGP sessions. Specifically, in data centers, there are directly connected IBGP peerings that will benefit from the protection ttl-security provides. Signed-off-by: Dinesh G Dutt <ddutt@cumulusnetworks.com> Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com> [DL: function refactoring split out into previous 2 patches. changes: - bgp_set_socket_ttl(): ret type int -> void - is_ebgp_multihop_configured(): stripped peer == NULL check - comments/whitespace] Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'bgpd')
-rw-r--r--bgpd/bgp_network.c43
-rw-r--r--bgpd/bgp_vty.c6
-rw-r--r--bgpd/bgpd.c31
3 files changed, 54 insertions, 26 deletions
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index 93bb1d9b..6c7cf54c 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -148,11 +148,44 @@ bgp_update_sock_send_buffer_size (int fd)
static void
bgp_set_socket_ttl (struct peer *peer, int bgp_sock)
{
- if (peer->sort == BGP_PEER_EBGP) {
- sockopt_ttl (peer->su.sa.sa_family, bgp_sock, peer->ttl);
- if (peer->gtsm_hops)
- sockopt_minttl (peer->su.sa.sa_family, bgp_sock, MAXTTL + 1 - peer->gtsm_hops);
- }
+ char buf[INET_ADDRSTRLEN];
+ int ret;
+
+ /* In case of peer is EBGP, we should set TTL for this connection. */
+ if (!peer->gtsm_hops && (peer_sort (peer) == BGP_PEER_EBGP))
+ {
+ ret = sockopt_ttl (peer->su.sa.sa_family, bgp_sock, peer->ttl);
+ if (ret)
+ {
+ zlog_err ("%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
+ __func__,
+ inet_ntop (AF_INET, &peer->remote_id, buf, sizeof(buf)),
+ errno);
+ }
+ }
+ else if (peer->gtsm_hops)
+ {
+ /* On Linux, setting minttl without setting ttl seems to mess with the
+ outgoing ttl. Therefore setting both.
+ */
+ ret = sockopt_ttl (peer->su.sa.sa_family, bgp_sock, MAXTTL);
+ if (ret)
+ {
+ zlog_err ("%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
+ __func__,
+ inet_ntop (AF_INET, &peer->remote_id, buf, sizeof(buf)),
+ errno);
+ }
+ ret = sockopt_minttl (peer->su.sa.sa_family, bgp_sock,
+ MAXTTL + 1 - peer->gtsm_hops);
+ if (ret)
+ {
+ zlog_err ("%s: Can't set MinTTL on peer (rtrid %s) socket, err = %d",
+ __func__,
+ inet_ntop (AF_INET, &peer->remote_id, buf, sizeof(buf)),
+ errno);
+ }
+ }
}
/* Accept bgp connection. */
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index bfa1f204..b4d765af 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -7857,6 +7857,12 @@ bgp_show_peer (struct vty *vty, struct peer *p)
vty_out (vty, " External BGP neighbor may be up to %d hops away.%s",
p->ttl, VTY_NEWLINE);
}
+ else
+ {
+ if (p->gtsm_hops > 0)
+ vty_out (vty, " Internal BGP neighbor may be up to %d hops away.%s",
+ p->gtsm_hops, VTY_NEWLINE);
+ }
/* Local address. */
if (p->su_local)
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index afd0dbd2..88d13ed8 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -4419,21 +4419,21 @@ static int is_ebgp_multihop_configured (struct peer *peer)
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
group = peer->group;
- if (group->conf->ttl != 1)
+ if ((peer_sort(peer) != BGP_PEER_IBGP) &&
+ (group->conf->ttl != 1))
return 1;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
{
- if (peer1->sort == BGP_PEER_IBGP)
- continue;
-
- if (peer1->ttl != 1)
+ if ((peer_sort (peer1) != BGP_PEER_IBGP) &&
+ (peer1->ttl != 1))
return 1;
}
}
else
{
- if (peer->ttl != 1)
+ if ((peer_sort(peer) != BGP_PEER_IBGP) &&
+ (peer->ttl != 1))
return 1;
}
return 0;
@@ -4449,9 +4449,6 @@ peer_ttl_security_hops_set (struct peer *peer, int gtsm_hops)
zlog_debug ("peer_ttl_security_hops_set: set gtsm_hops to %d for %s", gtsm_hops, peer->host);
- if (peer->sort == BGP_PEER_IBGP)
- return BGP_ERR_NO_IBGP_WITH_TTLHACK;
-
/* 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
@@ -4466,6 +4463,7 @@ peer_ttl_security_hops_set (struct peer *peer, int gtsm_hops)
return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
/* specify MAXTTL on outgoing packets */
+ /* Routine handles iBGP peers correctly */
ret = peer_ebgp_multihop_set (peer, MAXTTL);
if (ret != 0)
return ret;
@@ -4475,7 +4473,7 @@ peer_ttl_security_hops_set (struct peer *peer, int gtsm_hops)
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
- if (peer->fd >= 0 && peer->sort != BGP_PEER_IBGP)
+ if (peer->fd >= 0)
sockopt_minttl (peer->su.sa.sa_family, peer->fd, MAXTTL + 1 - gtsm_hops);
}
else
@@ -4483,9 +4481,6 @@ peer_ttl_security_hops_set (struct peer *peer, int gtsm_hops)
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
{
- if (peer->sort == BGP_PEER_IBGP)
- continue;
-
peer->gtsm_hops = group->conf->gtsm_hops;
/* Change setting of existing peer
@@ -4520,9 +4515,6 @@ peer_ttl_security_hops_unset (struct peer *peer)
zlog_debug ("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s", peer->host);
- if (peer->sort == 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;
@@ -4532,7 +4524,7 @@ peer_ttl_security_hops_unset (struct peer *peer)
opeer = peer;
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
- if (peer->fd >= 0 && peer->sort != BGP_PEER_IBGP)
+ if (peer->fd >= 0)
sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0);
}
else
@@ -4540,9 +4532,6 @@ peer_ttl_security_hops_unset (struct peer *peer)
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
{
- if (peer->sort == BGP_PEER_IBGP)
- continue;
-
peer->gtsm_hops = 0;
if (peer->fd >= 0)
@@ -4865,7 +4854,7 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
VTY_NEWLINE);
/* ttl-security hops */
- if (peer->sort != BGP_PEER_IBGP && peer->gtsm_hops != 0)
+ if (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);