}
}
-static void
+int
bgp_set_socket_ttl (struct peer *peer, int bgp_sock)
{
char buf[INET_ADDRSTRLEN];
__func__,
inet_ntop (AF_INET, &peer->remote_id, buf, sizeof(buf)),
errno);
+ return ret;
}
}
else if (peer->gtsm_hops)
__func__,
inet_ntop (AF_INET, &peer->remote_id, buf, sizeof(buf)),
errno);
+ return ret;
}
ret = sockopt_minttl (peer->su.sa.sa_family, bgp_sock,
MAXTTL + 1 - peer->gtsm_hops);
__func__,
inet_ntop (AF_INET, &peer->remote_id, buf, sizeof(buf)),
errno);
+ return ret;
}
}
+
+ return ret;
}
/* Accept bgp connection. */
peer_delete(peer1->doppelganger);
}
- bgp_set_socket_ttl (peer1, bgp_sock);
+ if (bgp_set_socket_ttl (peer1, bgp_sock) < 0)
+ if (bgp_debug_neighbor_events(peer1))
+ zlog_debug ("[Event] Unable to set min/max TTL on peer %s, Continuing",
+ peer1->host);
peer = peer_create (&su, peer1->conf_if, peer1->bgp, peer1->local_as,
peer1->as, peer1->as_type, 0, 0);
/* Set socket send buffer size */
bgp_update_sock_send_buffer_size(peer->fd);
- bgp_set_socket_ttl (peer, peer->fd);
+ if (bgp_set_socket_ttl (peer, peer->fd) < 0)
+ return -1;
sockopt_reuseaddr (peer->fd);
sockopt_reuseport (peer->fd);
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->fd >= 0 && peer->sort != BGP_PEER_IBGP)
- sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
+ {
+ if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ else
+ bgp_session_reset(peer);
+ }
}
else
{
peer->ttl = group->conf->ttl;
- if (peer->fd >= 0)
- sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
+ if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ else
+ bgp_session_reset(peer);
}
}
return 0;
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
- if (peer->fd >= 0 && peer->sort != BGP_PEER_IBGP)
- sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
+ if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ else
+ bgp_session_reset(peer);
}
else
{
continue;
peer->ttl = 1;
-
+
if (peer->fd >= 0)
- sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
+ {
+ if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ else
+ bgp_session_reset(peer);
+ }
}
}
return 0;
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 ((peer->gtsm_hops == 0) && (peer->sort != BGP_PEER_IBGP))
{
if (is_ebgp_multihop_configured (peer))
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;
- }
-
- peer->gtsm_hops = gtsm_hops;
+ if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+ {
+ peer->gtsm_hops = gtsm_hops;
- if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
- {
- if (peer->fd >= 0)
- sockopt_minttl (peer->su.sa.sa_family, peer->fd,
- MAXTTL + 1 - gtsm_hops);
- if (peer->status != Established && peer->doppelganger)
- sockopt_minttl (peer->su.sa.sa_family, peer->doppelganger->fd,
- MAXTTL + 1 - gtsm_hops);
+ /* Calling ebgp multihop also resets the session.
+ * On restart, NHT will get setup correctly as will the
+ * min & max ttls on the socket. The return value is
+ * irrelevant.
+ */
+ ret = peer_ebgp_multihop_set (peer, MAXTTL);
+
+ if (ret != 0)
+ return ret;
+ }
+ else
+ {
+ group = peer->group;
+ for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
+ {
+ peer->gtsm_hops = group->conf->gtsm_hops;
+
+ /* Calling ebgp multihop also resets the session.
+ * On restart, NHT will get setup correctly as will the
+ * min & max ttls on the socket. The return value is
+ * irrelevant.
+ */
+ ret = peer_ebgp_multihop_set (peer, MAXTTL);
+ }
+ }
}
else
{
- group = peer->group;
- for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
+ /* Post the first gtsm setup or if its ibgp, maxttl setting isn't
+ * necessary, just set the minttl.
+ */
+ if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
- peer->gtsm_hops = group->conf->gtsm_hops;
+ peer->gtsm_hops = gtsm_hops;
- /* Change setting of existing peer
- * established then change value (may break connectivity)
- * not established yet (teardown session and restart)
- * no session then do nothing (will get handled by next connection)
- */
- if (peer->status == Established)
+ if (peer->fd >= 0)
+ sockopt_minttl (peer->su.sa.sa_family, peer->fd,
+ MAXTTL + 1 - gtsm_hops);
+ if ((peer->status < Established) && peer->doppelganger &&
+ (peer->doppelganger->fd >= 0))
+ sockopt_minttl (peer->su.sa.sa_family, peer->doppelganger->fd,
+ MAXTTL + 1 - gtsm_hops);
+ }
+ else
+ {
+ group = peer->group;
+ for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
{
+ peer->gtsm_hops = group->conf->gtsm_hops;
+
+ /* Change setting of existing peer
+ * established then change value (may break connectivity)
+ * not established yet (teardown session and restart)
+ * no session then do nothing (will get handled by next connection)
+ */
if (peer->fd >= 0 && peer->gtsm_hops != 0)
sockopt_minttl (peer->su.sa.sa_family, peer->fd,
MAXTTL + 1 - peer->gtsm_hops);
- }
- else if (peer->status < Established)
- {
- if (bgp_debug_neighbor_events(peer))
- zlog_debug ("%s Min-ttl changed", peer->host);
- bgp_session_reset(peer);
+ if ((peer->status < Established) && peer->doppelganger &&
+ (peer->doppelganger->fd >= 0))
+ sockopt_minttl (peer->su.sa.sa_family, peer->doppelganger->fd,
+ MAXTTL + 1 - gtsm_hops);
+
}
}
}
{
struct peer_group *group;
struct listnode *node, *nnode;
- struct peer *opeer;
+ int ret = 0;
zlog_debug ("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s", peer->host);
else
peer->gtsm_hops = 0;
- opeer = peer;
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
- if (peer->fd >= 0)
- sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0);
+ /* Invoking ebgp_multihop_set will set the TTL back to the original
+ * value as well as restting the NHT and such. The session is reset.
+ */
+ if (peer->sort == BGP_PEER_EBGP)
+ ret = peer_ebgp_multihop_unset (peer);
+ else
+ {
+ if (peer->fd >= 0)
+ sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0);
- if (peer->status != Established && peer->doppelganger)
- sockopt_minttl (peer->su.sa.sa_family, peer->doppelganger->fd, 0);
+ if ((peer->status < Established) && peer->doppelganger &&
+ (peer->doppelganger->fd >= 0))
+ sockopt_minttl (peer->su.sa.sa_family,
+ peer->doppelganger->fd, 0);
+ }
}
else
{
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
{
peer->gtsm_hops = 0;
-
- if (peer->fd >= 0)
- sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0);
+ if (peer->sort == BGP_PEER_EBGP)
+ ret = peer_ebgp_multihop_unset (peer);
+ else
+ {
+ if (peer->fd >= 0)
+ sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0);
- if (peer->status != Established && peer->doppelganger)
- sockopt_minttl (peer->su.sa.sa_family, peer->doppelganger->fd, 0);
+ if ((peer->status < Established) && peer->doppelganger &&
+ (peer->doppelganger->fd >= 0))
+ sockopt_minttl (peer->su.sa.sa_family,
+ peer->doppelganger->fd, 0);
+ }
}
}
- return peer_ebgp_multihop_unset (opeer);
+ return 0;
}
/*