summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Hall <GMCH@hestia.halldom.com>2010-08-04 11:20:31 +0100
committerChris Hall <GMCH@hestia.halldom.com>2010-08-04 11:20:31 +0100
commit11fe7d1d77cfd7b29ea14cc05b7fb2ea6ba13b74 (patch)
tree09b66e2a01eac2c3a8f610fed5bec9fbb062abfb
parent4af8f7adc4fe05de92cb11912af029c623feb821 (diff)
downloadquagga-11fe7d1d77cfd7b29ea14cc05b7fb2ea6ba13b74.tar.bz2
quagga-11fe7d1d77cfd7b29ea14cc05b7fb2ea6ba13b74.tar.xz
Fix various capability flags so that sessions are restarted.
For some reason (unknown) changing the following did NOT restart any active session: neighbor dont-capability-negotiate neighbor override-capability neighbor strict-capability-match since these can all change the nature of a session, this seems to be a (long time) bug, and has been fixed. Also, per RFC 5492: if (during OpenSent and OpenConfirm) get a NOTIFICATION: "Open/Unsupported Optional Parameter", treat that as "don't understand capabilities" and suppress sending of capabilities. Advanced to "ex05".
-rw-r--r--bgpd/bgp_common.h23
-rw-r--r--bgpd/bgp_connection.c5
-rw-r--r--bgpd/bgp_connection.h7
-rw-r--r--bgpd/bgp_fsm.c20
-rw-r--r--bgpd/bgp_msg_read.c10
-rw-r--r--bgpd/bgp_msg_write.c21
-rw-r--r--bgpd/bgp_open.c4
-rw-r--r--bgpd/bgp_open_state.c49
-rw-r--r--bgpd/bgp_open_state.h12
-rw-r--r--bgpd/bgp_peer.c12
-rw-r--r--bgpd/bgp_peer.h49
-rw-r--r--bgpd/bgp_session.c1
-rw-r--r--bgpd/bgp_session.h11
-rw-r--r--bgpd/bgpd.c8
-rwxr-xr-xconfigure.ac2
15 files changed, 167 insertions, 67 deletions
diff --git a/bgpd/bgp_common.h b/bgpd/bgp_common.h
index 67d1afb0..0d2395ed 100644
--- a/bgpd/bgp_common.h
+++ b/bgpd/bgp_common.h
@@ -168,7 +168,7 @@ enum qafx_num
qafx_num_undef = -1, /* No defined AFI/SAFI */
qafx_num_min = 0, /* minimum valid qafx */
- qafx_num_first = 0, /* first "real" qafx */
+ qafx_num_first = 0, /* all first..last are "real" qafx */
qafx_ipv4_unicast = 0, /* iAFI = 1, iSAFI = 1 */
qafx_ipv4_multicast = 1, /* iAFI = 1, iSAFI = 2 */
@@ -186,6 +186,9 @@ enum qafx_num
qafx_count /* number of qafx */
} ;
+CONFIRM(qafx_num_other > qafx_num_last) ;
+CONFIRM(qafx_num_other == qafx_num_max) ;
+
/*------------------------------------------------------------------------------
* A qafx_set_t is a set of qafx_bit_t -- a bit-vector
*/
@@ -194,9 +197,12 @@ typedef qafx_bit_t qafx_set_t ;
enum qafx_bit
{
+ qafx_bits_min = 0,
+
qafx_set_empty = 0,
- qafx_bits_min = (1 << qafx_num_min),
+ qafx_first_bit = (1 << qafx_num_first),
+ /* first..last are all "real" qafx */
qafx_ipv4_unicast_bit = (1 << qafx_ipv4_unicast),
qafx_ipv4_multicast_bit = (1 << qafx_ipv4_multicast),
@@ -206,11 +212,22 @@ enum qafx_bit
qafx_ipv6_multicast_bit = (1 << qafx_ipv6_multicast),
qafx_ipv6_mpls_vpn_bit = (1 << qafx_ipv6_mpls_vpn),
+ qafx_last_bit = (1 << qafx_num_last),
+
qafx_other_bit = (1 << qafx_num_other),
- qafx_bits_max = (1 << qafx_count) - 1
+ qafx_bits_max = (1 << qafx_count) - 1,
+
+ qafx_known_bits = (1 << (qafx_num_last + 1)) - 1
} ;
+CONFIRM(qafx_known_bits == ( qafx_ipv4_unicast_bit
+ | qafx_ipv4_multicast_bit
+ | qafx_ipv4_mpls_vpn_bit
+ | qafx_ipv6_unicast_bit
+ | qafx_ipv6_multicast_bit
+ | qafx_ipv6_mpls_vpn_bit )) ;
+
/*------------------------------------------------------------------------------
* Conversions qafx_num <-> qafx_bit
*
diff --git a/bgpd/bgp_connection.c b/bgpd/bgp_connection.c
index cdcfc10e..4a8109a3 100644
--- a/bgpd/bgp_connection.c
+++ b/bgpd/bgp_connection.c
@@ -130,6 +130,7 @@ bgp_connection_init_new(bgp_connection connection, bgp_session session,
* * fsm_active not active
* * notification NULL -- none received or sent
* * err no error, so far
+ * * cap_suppress do not suppress capabilities
* * su_local NULL -- no address, yet
* * su_remote NULL -- no address, yet
* * hold_timer_interval none -- set when connection is opened
@@ -275,12 +276,15 @@ bgp_connection_make_primary(bgp_connection connection)
assert(session->connections[bgp_connection_secondary] == NULL) ;
/* Move the open_state to the session.
+ * Copy the state of the cap_suppress flag
* Change the connection host to drop the primary/secondary distinction.
* Copy the negotiated hold_timer_interval and keepalive_timer_interval
* Copy the su_local and su_remote
*/
bgp_open_state_set_mov(&session->open_recv, &connection->open_recv) ;
+ session->cap_suppress = connection->cap_suppress ;
+
if (connection->host != NULL)
XFREE(MTYPE_BGP_PEER_HOST, connection->host) ;
bgp_connection_init_host(connection, "") ;
@@ -596,6 +600,7 @@ bgp_connection_add_pending(bgp_connection connection, mqueue_block mqb,
* Does not touch:
*
* * state of the connection (including exception and follow-on event)
+ * * capabilities suppress flag
* * timers -- FSM looks after those
*
* NB: nothing can be written until bgp_connection_start() has been called.
diff --git a/bgpd/bgp_connection.h b/bgpd/bgp_connection.h
index 58afc2ae..9e7d4086 100644
--- a/bgpd/bgp_connection.h
+++ b/bgpd/bgp_connection.h
@@ -160,6 +160,13 @@ struct bgp_connection
bgp_notify notification ; /* if any sent/received */
int err ; /* erno, if any */
+ bool cap_suppress ; /* capability send suppress
+ always set false when connection
+ initialised. Set if get
+ NOTIFICATION that other end does
+ not do capabilities. Copied to
+ session when established. */
+
bgp_open_state open_recv ; /* the open received. */
qps_file qf ; /* qpselect file structure */
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 9df8a955..b1c085bd 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -1945,12 +1945,28 @@ static bgp_fsm_action(bgp_fsm_error)
*
* Next state will be sIdle, except if is sEstablished, when will be sStopping.
*
- * NB: requires the session LOCKED
+ * Per RFC 5492: if get a NOTIFICATION: "Open/Unsupported Optional Parameter"
+ * then suppress sending of capabilities.
+ *
+ * If didn't send capabilities the last time, doesn't make any
+ * difference if suppress them from now on !
*
- * TODO: deal with: BGP_NOMC_OPEN/BGP_NOMS_O_OPTION & squash capabilities.
+ * NB: requires the session LOCKED
*/
static bgp_fsm_action(bgp_fsm_recv_nom)
{
+ if (connection->state != bgp_fsm_sEstablished)
+ {
+ if ( (connection->notification->code == BGP_NOMC_OPEN)
+ && (connection->notification->subcode == BGP_NOMS_O_OPTION) )
+ {
+ if (!connection->cap_suppress)
+ BGP_FSM_DEBUG(connection, "Suppressing Capabilities") ;
+
+ connection->cap_suppress = true ;
+ } ;
+ } ;
+
return bgp_fsm_catch(connection, next_state) ;
} ;
diff --git a/bgpd/bgp_msg_read.c b/bgpd/bgp_msg_read.c
index e0bbfef9..3c78bcec 100644
--- a/bgpd/bgp_msg_read.c
+++ b/bgpd/bgp_msg_read.c
@@ -670,11 +670,13 @@ bgp_msg_open_option_parse (bgp_connection connection, bgp_notify notification,
*
* 2) the local AFI/SAFI must be the same as the remote AFI/SAFI.
*
- * TODO: verify that (2) should be checked *before* any "OVERRIDE".
+ * NB: cap_override and cap_strict are mutually exclusive
+ *
+ * TODO: what about graceful restart and no CAP-MP ??
*/
if (session->cap_strict)
{
- /* Treat any unsuppprted capability as an error. */
+ /* Treat any unsupported capability as an error. */
if (bgp_notify_get_subcode(notification) == BGP_NOMS_O_CAPABILITY)
return -1 ;
@@ -1237,6 +1239,10 @@ bgp_msg_capability_orf_entry(bgp_connection connection, uint8_t cap_code,
*
* Returns: 0 => OK
* -1 => malformed !
+ *
+ * TODO: RFC 4724 suggests "implicit" IPv4/Unicast if no CAP-MP
+ * TODO: RFC 4760 says MUST CAP-MP if propose to use CAP-MP !
+ *
*/
static int
bgp_msg_capability_restart (bgp_connection connection, sucker sr)
diff --git a/bgpd/bgp_msg_write.c b/bgpd/bgp_msg_write.c
index ee4a510c..21e48d69 100644
--- a/bgpd/bgp_msg_write.c
+++ b/bgpd/bgp_msg_write.c
@@ -167,7 +167,8 @@ bgp_msg_send_keepalive(bgp_connection connection, bool must_send)
*/
static void
-bgp_open_options(struct stream *s, bgp_open_state open_state) ;
+bgp_open_options(struct stream *s, bgp_open_state open_state,
+ bool cap_suppress) ;
static void
bgp_open_capability_orf (struct stream *s, iAFI_t afi, iSAFI_t safi,
@@ -205,7 +206,7 @@ bgp_msg_send_open(bgp_connection connection, bgp_open_state open_state)
stream_put_ipv4(s, open_state->bgp_id) ;
/* Set OPEN message options */
- bgp_open_options(s, open_state) ;
+ bgp_open_options(s, open_state, connection->cap_suppress) ;
/* Set BGP message length. */
length = bgp_packet_set_size(s) ;
@@ -213,12 +214,20 @@ bgp_msg_send_open(bgp_connection connection, bgp_open_state open_state)
if (BGP_DEBUG (normal, NORMAL))
{
char buf[INET_ADDRSTRLEN] ;
+ const char* no_cap ;
+
+ if (!open_state->can_capability)
+ no_cap = " (sans capabilities)" ;
+ else if (connection->cap_suppress)
+ no_cap = " (capabilities suppressed)" ;
+ else
+ no_cap = "" ;
inet_ntop(AF_INET, &open_state->bgp_id, buf, INET_ADDRSTRLEN) ;
- zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
+ zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s%s",
connection->host, BGP_VERSION_4, open_state->my_as,
- open_state->holdtime, buf) ;
+ open_state->holdtime, buf, no_cap) ;
} ;
@@ -251,7 +260,7 @@ enum
* Creates an empty options part of there are no capabilities to set.
*/
static void
-bgp_open_options(struct stream *s, bgp_open_state open_state)
+bgp_open_options(struct stream *s, bgp_open_state open_state, bool cap_suppress)
{
u_char len ;
unsigned long cp ;
@@ -264,7 +273,7 @@ bgp_open_options(struct stream *s, bgp_open_state open_state)
stream_putc(s, 0);
/* If do not send capability, quit now -- zero options. */
- if (!open_state->can_capability)
+ if (!open_state->can_capability || cap_suppress)
return;
/* TODO: RFC 5492 (2009): SHOULD send only one Capability Option !! */
diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
index ab9acf63..80b90683 100644
--- a/bgpd/bgp_open.c
+++ b/bgpd/bgp_open.c
@@ -938,8 +938,8 @@ bgp_open_capability (struct stream *s, struct peer *peer)
stream_putc (s, 0);
/* Do not send capability. */
- if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
- || CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
+ if (// ! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN) ||
+ CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
return;
/* IPv4 unicast. */
diff --git a/bgpd/bgp_open_state.c b/bgpd/bgp_open_state.c
index 49d1604b..9ca9617e 100644
--- a/bgpd/bgp_open_state.c
+++ b/bgpd/bgp_open_state.c
@@ -132,10 +132,8 @@ bgp_peer_open_state_init_new(bgp_open_state state, bgp_peer peer)
/* Set our bgpd_id */
state->bgp_id = peer->local_id.s_addr ;
- /* Do not send capability. */ /* TODO: can_capability? */
- state->can_capability =
- CHECK_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
- && (! CHECK_FLAG(peer->flags, PEER_FLAG_DONT_CAPABILITY) ) ;
+ /* Whether to send capability or not */
+ state->can_capability = ! CHECK_FLAG(peer->flags, PEER_FLAG_DONT_CAPABILITY) ;
/* Announce self as AS4 speaker always */
if (!bm->as2_speaker)
@@ -295,6 +293,31 @@ bgp_open_state_afi_safi_cap(bgp_open_state state, unsigned index)
/* Received an open, update the peer's state
*
+ * Takes the peer->session->open_recv and fills in:
+ *
+ * peer->v_holdtime ) per negotiated values
+ * peer->v_keepalive )
+ *
+ * peer->remote_id.s_addr
+ *
+ * peer->cap ) updated per open_recv -- assumes all recv flags
+ * peer->af_cap ) have been cleared.
+ *
+ * peer->v_gr_restart set to value received (if any)
+ *
+ * peer->afc_recv set/cleared according to what is advertised
+ * BUT if !open_recv->can_capability or
+ * neighbor override-capability, then
+ * all flags are cleared.
+ *
+ * peer->afc_nego set/cleared according to what is advertised and
+ * what is activated.
+ * BUT if !open_recv->can_capability or
+ * neighbor override-capability, then
+ * set everything which has been activated.
+ *
+ *
+ *
* NB: for safety, best to have the session locked -- though won't, in fact,
* change any of this information after the session is established.
*/
@@ -311,6 +334,10 @@ bgp_peer_open_state_receive(bgp_peer peer)
/* Check neighbor as number. */
assert(open_recv->my_as == peer->as);
+ /* If had to suppress sending of capabilities, note that */
+ if (session->cap_suppress)
+ SET_FLAG (peer->cap, PEER_CAP_SUPPRESSED) ;
+
/* holdtime */
/* From the rfc: A reasonable maximum time between KEEPALIVE messages
would be one third of the Hold Time interval. KEEPALIVE messages
@@ -335,16 +362,13 @@ bgp_peer_open_state_receive(bgp_peer peer)
/* AFI/SAFI -- as received, or assumed or overridden */
- if (!open_recv->can_capability ||
- CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
+ if (!open_recv->can_capability || session->cap_override)
{
/* There were no capabilities, or are OVERRIDING AFI/SAFI, so force
- * not having received any AFI/SAFI, but apply this set.
+ * not having received any AFI/SAFI, but apply all known.
*/
recv = 0 ;
- qbs = qafx_ipv4_unicast_bit | qafx_ipv4_multicast_bit |
- qafx_ipv6_unicast_bit | qafx_ipv6_multicast_bit |
- qafx_ipv4_mpls_vpn_bit ;
+ qbs = qafx_known_bits ;
}
else
{
@@ -361,6 +385,11 @@ bgp_peer_open_state_receive(bgp_peer peer)
{
peer->afc_recv[afi][safi] = recv ;
peer->afc_nego[afi][safi] = peer->afc[afi][safi] ;
+ }
+ else
+ {
+ peer->afc_recv[afi][safi] = 0 ;
+ peer->afc_nego[afi][safi] = 0 ;
} ;
} ;
diff --git a/bgpd/bgp_open_state.h b/bgpd/bgp_open_state.h
index 8ef109bd..8c30712b 100644
--- a/bgpd/bgp_open_state.h
+++ b/bgpd/bgp_open_state.h
@@ -92,9 +92,9 @@ struct bgp_open_state
unsigned holdtime ; /* in seconds */
bgp_id_t bgp_id ; /* an IPv4 address -- *network order* */
- int can_capability ; /* false => don't do capabilities */
+ bool can_capability ; /* false => don't do capabilities */
- int can_as4 ; /* true/false */
+ bool can_as4 ;
as2_t my_as2 ; /* AS2 from OPEN message */
qafx_set_t can_mp_ext ; /* will accept, may send these */
@@ -105,14 +105,14 @@ struct bgp_open_state
qafx_set_t can_orf_prefix_send ; /* wish to send ORF Prefix-List */
qafx_set_t can_orf_prefix_recv ; /* will accept ORF Prefix-List */
- int can_dynamic ;
+ bool can_dynamic ;
- int can_g_restart ; /* can do graceful restart */
+ bool can_g_restart ; /* can do graceful restart */
qafx_set_t can_preserve ; /* can preserve forwarding for these */
qafx_set_t has_preserved ; /* has preserved forwarding for these */
- int has_restarted ; /* Restart State flag */
- int restart_time ; /* Restart Time in seconds */
+ bool has_restarted ; /* Restart State flag */
+ unsigned restart_time ; /* Restart Time in seconds */
struct vector unknowns ; /* list of bgp_cap_unknown */
struct vector afi_safi ; /* various afi/safi capabilities */
diff --git a/bgpd/bgp_peer.c b/bgpd/bgp_peer.c
index 625e1d99..34dfdc79 100644
--- a/bgpd/bgp_peer.c
+++ b/bgpd/bgp_peer.c
@@ -313,10 +313,6 @@ bgp_session_has_established(bgp_session session)
/* Install next hop, as required. */
bgp_nexthop_set(peer->su_local, peer->su_remote, &peer->nexthop, peer) ;
- /* Reset capability open status flag. */
- if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN))
- SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
-
/* Clear last notification data -- Routing Engine private field */
bgp_notify_unset(&(peer->session->notification));
@@ -740,8 +736,6 @@ bgp_peer_new (struct bgp *bgp)
}
peer->orf_plist[afi][safi] = NULL;
}
- SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
-
/* Create buffers. */
peer->ibuf = stream_new (BGP_MAX_PACKET_SIZE);
peer->obuf = stream_fifo_new ();
@@ -1417,6 +1411,9 @@ bgp_peer_map_peer_down(peer_down_t why_down)
case PEER_DOWN_AF_ACTIVATE:
case PEER_DOWN_RMAP_BIND:
case PEER_DOWN_RMAP_UNBIND:
+ case PEER_DOWN_DONT_CAPABILITY:
+ case PEER_DOWN_OVERRIDE_CAPABILITY:
+ case PEER_DOWN_STRICT_CAP_MATCH:
case PEER_DOWN_CAPABILITY_CHANGE:
case PEER_DOWN_PASSIVE_CHANGE:
case PEER_DOWN_MULTIHOP_CHANGE:
@@ -1755,6 +1752,9 @@ const char *peer_down_str[] =
[PEER_DOWN_AF_ACTIVATE] = "Address family activated",
[PEER_DOWN_RMAP_BIND] = "Peer-group add member",
[PEER_DOWN_RMAP_UNBIND] = "Peer-group delete member",
+ [PEER_DOWN_DONT_CAPABILITY] = "dont-capability-negotiate changed",
+ [PEER_DOWN_OVERRIDE_CAPABILITY] = "override-capability changed",
+ [PEER_DOWN_STRICT_CAP_MATCH] = "strict-capability-match changed",
[PEER_DOWN_CAPABILITY_CHANGE] = "Capability changed",
[PEER_DOWN_PASSIVE_CHANGE] = "Passive config change",
[PEER_DOWN_MULTIHOP_CHANGE] = "Multihop config change",
diff --git a/bgpd/bgp_peer.h b/bgpd/bgp_peer.h
index 32d29d54..37738a63 100644
--- a/bgpd/bgp_peer.h
+++ b/bgpd/bgp_peer.h
@@ -120,24 +120,27 @@ enum PEER_DOWN {
PEER_DOWN_CONFIG_CHANGE, /* Unspecified config change */
- PEER_DOWN_RID_CHANGE, /* 'bgp router-id' */
- PEER_DOWN_REMOTE_AS_CHANGE, /* 'neighbor remote-as' */
- PEER_DOWN_LOCAL_AS_CHANGE, /* 'neighbor local-as' */
- PEER_DOWN_CLID_CHANGE, /* 'bgp cluster-id' */
- PEER_DOWN_CONFED_ID_CHANGE, /* 'bgp confederation identifier' */
- PEER_DOWN_CONFED_PEER_CHANGE, /* 'bgp confederation peer' */
- PEER_DOWN_RR_CLIENT_CHANGE, /* 'neighbor route-reflector-client' */
- PEER_DOWN_RS_CLIENT_CHANGE, /* 'neighbor route-server-client' */
- PEER_DOWN_UPDATE_SOURCE_CHANGE, /* 'neighbor update-source' */
- PEER_DOWN_AF_ACTIVATE, /* 'neighbor activate' */
- PEER_DOWN_RMAP_BIND, /* 'neighbor peer-group' */
- PEER_DOWN_RMAP_UNBIND, /* 'no neighbor peer-group' */
- PEER_DOWN_CAPABILITY_CHANGE, /* 'neighbor capability' */
- PEER_DOWN_PASSIVE_CHANGE, /* 'neighbor passive' */
- PEER_DOWN_MULTIHOP_CHANGE, /* 'neighbor multihop' */
- PEER_DOWN_AF_DEACTIVATE, /* 'no neighbor activate' */
- PEER_DOWN_PASSWORD_CHANGE, /* password changed */
- PEER_DOWN_ALLOWAS_IN_CHANGE, /* allowas-in change */
+ PEER_DOWN_RID_CHANGE, /* 'bgp router-id' */
+ PEER_DOWN_REMOTE_AS_CHANGE, /* 'neighbor remote-as' */
+ PEER_DOWN_LOCAL_AS_CHANGE, /* 'neighbor local-as' */
+ PEER_DOWN_CLID_CHANGE, /* 'bgp cluster-id' */
+ PEER_DOWN_CONFED_ID_CHANGE, /* 'bgp confederation identifier' */
+ PEER_DOWN_CONFED_PEER_CHANGE, /* 'bgp confederation peer' */
+ PEER_DOWN_RR_CLIENT_CHANGE, /* 'neighbor route-reflector-client' */
+ PEER_DOWN_RS_CLIENT_CHANGE, /* 'neighbor route-server-client' */
+ PEER_DOWN_UPDATE_SOURCE_CHANGE, /* 'neighbor update-source' */
+ PEER_DOWN_AF_ACTIVATE, /* 'neighbor activate' */
+ PEER_DOWN_RMAP_BIND, /* 'neighbor peer-group' */
+ PEER_DOWN_RMAP_UNBIND, /* 'no neighbor peer-group' */
+ PEER_DOWN_DONT_CAPABILITY, /* 'neighbor dont-capability-negotiate' */
+ PEER_DOWN_OVERRIDE_CAPABILITY, /* 'neighbor override-capability' */
+ PEER_DOWN_STRICT_CAP_MATCH, /* 'neighbor strict-capability-match' */
+ PEER_DOWN_CAPABILITY_CHANGE, /* 'neighbor capability' */
+ PEER_DOWN_PASSIVE_CHANGE, /* 'neighbor passive' */
+ PEER_DOWN_MULTIHOP_CHANGE, /* 'neighbor multihop' */
+ PEER_DOWN_AF_DEACTIVATE, /* 'no neighbor activate' */
+ PEER_DOWN_PASSWORD_CHANGE, /* password changed */
+ PEER_DOWN_ALLOWAS_IN_CHANGE, /* allowas-in change */
/* Other actions that cause a session to be reset */
@@ -271,6 +274,8 @@ struct peer
#define PEER_CAP_AS4_ADV (1 << 7) /* as4 advertised */
#define PEER_CAP_AS4_RCV (1 << 8) /* as4 received */
+#define PEER_CAP_SUPPRESSED (1 << 9) /* none sent */
+
#define PEER_CAP_AS4_BOTH (PEER_CAP_AS4_ADV + PEER_CAP_AS4_RCV)
#define PEER_CAP_AS4_USE(peer) \
(((peer)->cap & PEER_CAP_AS4_BOTH) == PEER_CAP_AS4_BOTH)
@@ -334,11 +339,9 @@ struct peer
u_int16_t sflags;
#define PEER_STATUS_REAL_PEER (1 << 0) /* not group conf or peer_self */
#define PEER_STATUS_PREFIX_OVERFLOW (1 << 1) /* prefix-overflow */
-#define PEER_STATUS_CAPABILITY_OPEN (1 << 2) /* capability open send */
-#define PEER_STATUS_HAVE_ACCEPT (1 << 3) /* accept peer's parent */
-#define PEER_STATUS_GROUP (1 << 4) /* peer-group conf */
-#define PEER_STATUS_NSF_MODE (1 << 5) /* NSF aware peer */
-#define PEER_STATUS_NSF_WAIT (1 << 6) /* wait comeback peer */
+#define PEER_STATUS_GROUP (1 << 3) /* peer-group conf */
+#define PEER_STATUS_NSF_MODE (1 << 4) /* NSF aware peer */
+#define PEER_STATUS_NSF_WAIT (1 << 5) /* wait comeback peer */
/* Peer status af flags (reset in bgp_stop) */
u_int16_t af_sflags[AFI_MAX][SAFI_MAX];
diff --git a/bgpd/bgp_session.c b/bgpd/bgp_session.c
index 9de8678a..a734ba99 100644
--- a/bgpd/bgp_session.c
+++ b/bgpd/bgp_session.c
@@ -146,6 +146,7 @@ bgp_session_init_new(bgp_peer peer)
* connect -- unset, false
* listen -- unset, false
*
+ * cap_suppress -- unset, false
* cap_override -- unset, false
* cap_strict -- unset, false
*
diff --git a/bgpd/bgp_session.h b/bgpd/bgp_session.h
index 79b6f1a4..ccc7a28e 100644
--- a/bgpd/bgp_session.h
+++ b/bgpd/bgp_session.h
@@ -150,8 +150,15 @@ struct bgp_session
bool connect ; /* initiate connections */
bool listen ; /* listen for connections */
- bool cap_override ; /* override ... TODO: what ? */
- bool cap_strict ; /* strict... TODO: what ? */
+ bool cap_suppress ; /* always set false when session is
+ enabled. Set to state of connection
+ when session is established */
+
+ bool cap_override ; /* assume other end can do all afi/safi
+ this end has active */
+ bool cap_strict ; /* must recognise all capabilities
+ received and have exact afi/safi
+ match */
int ttl ; /* TTL to set, if not zero */
unsigned short port ; /* destination port for peer */
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index f9e2ed93..8820014c 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -1932,7 +1932,7 @@ struct peer_flag_action
* NB: change actions are peer_change_none or peer_change_reset ONLY.
* (The peer->flags apply to all afi/safi.)
*
- * NB: PEER_FLAG_LOCAL_AS_NO_PREPEND is dealt with eslewhere.
+ * NB: PEER_FLAG_LOCAL_AS_NO_PREPEND is dealt with elsewhere.
*
* NB: all flags are set/cleared individually.
*/
@@ -1943,11 +1943,11 @@ static const struct peer_flag_action peer_flag_action_list[] =
{ PEER_FLAG_SHUTDOWN,
false, peer_change_reset, PEER_DOWN_USER_SHUTDOWN },
{ PEER_FLAG_DONT_CAPABILITY,
- false, peer_change_none, PEER_DOWN_NULL },
+ false, peer_change_reset, PEER_DOWN_DONT_CAPABILITY },
{ PEER_FLAG_OVERRIDE_CAPABILITY,
- false, peer_change_none, PEER_DOWN_NULL },
+ false, peer_change_reset, PEER_DOWN_OVERRIDE_CAPABILITY },
{ PEER_FLAG_STRICT_CAP_MATCH,
- false, peer_change_none, PEER_DOWN_NULL },
+ false, peer_change_reset, PEER_DOWN_STRICT_CAP_MATCH },
{ PEER_FLAG_DYNAMIC_CAPABILITY,
false, peer_change_reset, PEER_DOWN_CAPABILITY_CHANGE },
{ PEER_FLAG_DISABLE_CONNECTED_CHECK,
diff --git a/configure.ac b/configure.ac
index 8f8db362..a4c411bb 100755
--- a/configure.ac
+++ b/configure.ac
@@ -8,7 +8,7 @@
## $Id$
AC_PREREQ(2.53)
-AC_INIT(Quagga, 0.99.15ex04, [http://bugzilla.quagga.net])
+AC_INIT(Quagga, 0.99.15ex05, [http://bugzilla.quagga.net])
AC_CONFIG_SRCDIR(lib/zebra.h)
AC_CONFIG_MACRO_DIR([m4])