summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_open_state.c
diff options
context:
space:
mode:
authorChris Hall <GMCH@hestia.halldom.com>2010-01-23 11:21:17 +0000
committerChris Hall <GMCH@hestia.halldom.com>2010-01-23 11:21:17 +0000
commit0341d5ce47c301b4a4d92b77a83930da4fdc8fb3 (patch)
treeacff360d75d85e711d65e8d4fbe5139bf19b25e0 /bgpd/bgp_open_state.c
parenteeda1184fa60c5077c2d404d0a8415d11e836ccd (diff)
downloadquagga-0341d5ce47c301b4a4d92b77a83930da4fdc8fb3.tar.bz2
quagga-0341d5ce47c301b4a4d92b77a83930da4fdc8fb3.tar.xz
Blitz on bgp_msg_read, particularly OPEN message handling
In the BGP Engine the OPEN message needs to be processed into the open_recv structure in the *connection*. The OPEN that arrives must be checked for acceptability before it is acknowledged. Later the connection may be discarded in collision resolution, or the connection may become the Established connection, and the open_recv structure is passed to the session and hence to the Peering Engine. modified: bgpd/bgp.h modified: bgpd/bgp_common.c modified: bgpd/bgp_common.h modified: bgpd/bgp_connection.c modified: bgpd/bgp_connection.h modified: bgpd/bgp_fsm.c modified: bgpd/bgp_msg_read.c modified: bgpd/bgp_msg_read.h modified: bgpd/bgp_msg_write.c modified: bgpd/bgp_notification.c modified: bgpd/bgp_notification.h modified: bgpd/bgp_open.h modified: bgpd/bgp_open_state.c modified: bgpd/bgp_open_state.h modified: bgpd/bgp_packet.c modified: bgpd/bgp_session.h modified: lib/distribute.c modified: lib/if_rmap.c modified: lib/qafi_safi.h modified: lib/stream.c modified: lib/stream.h
Diffstat (limited to 'bgpd/bgp_open_state.c')
-rw-r--r--bgpd/bgp_open_state.c73
1 files changed, 50 insertions, 23 deletions
diff --git a/bgpd/bgp_open_state.c b/bgpd/bgp_open_state.c
index a8f880af..3be152cc 100644
--- a/bgpd/bgp_open_state.c
+++ b/bgpd/bgp_open_state.c
@@ -87,6 +87,21 @@ bgp_open_state_unset(bgp_open_state* p_state)
*p_state = NULL ;
} ;
+/*------------------------------------------------------------------------------
+ * Set pointer to open_state and unset source pointer
+ *
+ * Frees any existing open_state at the destination.
+ *
+ * NB: responsibility for the open_state structure passes to the destination.
+ */
+extern void
+bgp_open_state_set_mov(bgp_open_state* p_dst, bgp_open_state* p_src)
+{
+ bgp_open_state_free(*p_dst) ;
+ *p_dst = *p_src ;
+ *p_src = NULL ;
+} ;
+
/*==============================================================================
* Construct new bgp_open_state for the given peer -- allocate if required.
*
@@ -124,6 +139,9 @@ bgp_peer_open_state_init_new(bgp_open_state state, bgp_peer peer)
/* Announce self as AS4 speaker if required */
state->can_as4 = ((peer->cap & PEER_CAP_AS4_ADV) != 0) ;
+ state->my_as2 = (state->my_as > BGP_AS2_MAX ) ? BGP_ASN_TRANS
+ : state->my_as ;
+
/* Fill in the supported AFI/SAFI */
for (afi = qAFI_min ; afi <= qAFI_max ; ++afi)
@@ -169,10 +187,10 @@ bgp_peer_open_state_init_new(bgp_open_state state, bgp_peer peer)
state->restart_time = 0 ;
} ;
- /* TODO: check not restarting and not preserving forwarding state (?) */
+ /* TODO: check not has restarted and not preserving forwarding state (?) */
state->can_preserve = 0 ; /* cannot preserve forwarding */
state->has_preserved = 0 ; /* has not preserved forwarding */
- state->restarting = 0 ; /* is not restarting */
+ state->has_restarted = 0 ; /* has not restarted */
return state;
}
@@ -231,8 +249,10 @@ bgp_peer_open_state_receive(bgp_peer peer)
bgp_session session = peer->session;
bgp_open_state open_send = session->open_send;
bgp_open_state open_recv = session->open_recv;
- int afi;
- int safi;
+ qAFI_t afi;
+ qSAFI_t safi;
+ qafx_bit_t qbs ;
+ int recv ;
/* Check neighbor as number. */
assert(open_recv->my_as == peer->as);
@@ -262,19 +282,36 @@ bgp_peer_open_state_receive(bgp_peer peer)
if (open_recv->can_as4)
SET_FLAG (peer->cap, PEER_CAP_AS4_RCV);
- /* AFI/SAFI */
- /* Ignore capability when override-capability is set. */
+ /* AFI/SAFI -- as received, or assumed or overridden */
+
+ if (!open_recv->can_capability ||
+ CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
+ {
+ /* There were no capabilities, or are OVERRIDING AFI/SAFI, so force
+ * not having received any AFI/SAFI, but apply this set.
+ */
+ recv = 0 ;
+ qbs = qafx_ipv4_unicast_bit | qafx_ipv4_multicast_bit |
+ qafx_ipv6_unicast_bit | qafx_ipv6_multicast_bit |
+ qafx_ipv4_mpls_vpn_bit ;
+ }
+ else
+ {
+ /* Use the AFI/SAFI received, if any. */
+ recv = 1 ;
+ qbs = open_recv->can_mp_ext ;
+ }
+
if (! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
{
for (afi = qAFI_min ; afi <= qAFI_max ; ++afi)
for (safi = qSAFI_min ; safi <= qSAFI_max ; ++safi)
{
- qafx_bit_t qb = qafx_bit(qafx_num_from_qAFI_qSAFI(afi, safi));
- if (qb & open_recv->can_mp_ext)
+ qafx_bit_t qb = qafx_bit_from_qAFI_qSAFI(afi, safi) ;
+ if (qb & qbs)
{
- peer->afc_recv[afi][safi] = 1;
- assert(peer->afc[afi][safi]);
- peer->afc_nego[afi][safi] = 1;
+ peer->afc_recv[afi][safi] = recv ;
+ peer->afc_nego[afi][safi] = peer->afc[afi][safi] ;
}
}
}
@@ -289,7 +326,7 @@ bgp_peer_open_state_receive(bgp_peer peer)
for (afi = qAFI_min ; afi <= qAFI_max ; ++afi)
for (safi = qSAFI_min ; safi <= qSAFI_max ; ++safi)
{
- qafx_bit_t qb = qafx_bit(qafx_num_from_qAFI_qSAFI(afi, safi));
+ qafx_bit_t qb = qafx_bit_from_qAFI_qSAFI(afi, safi);
if (qb & open_recv->can_orf_prefix_send)
SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV);
if (qb & open_recv->can_orf_prefix_recv)
@@ -320,7 +357,7 @@ bgp_peer_open_state_receive(bgp_peer peer)
for (afi = qAFI_min ; afi <= qAFI_max ; ++afi)
for (safi = qSAFI_min ; safi <= qSAFI_max ; ++safi)
{
- qafx_bit_t qb = qafx_bit(qafx_num_from_qAFI_qSAFI(afi, safi));
+ qafx_bit_t qb = qafx_bit_from_qAFI_qSAFI(afi, safi);
if (peer->afc[afi][safi] && (qb & open_recv->can_g_restart))
{
SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV);
@@ -334,14 +371,4 @@ bgp_peer_open_state_receive(bgp_peer peer)
#if 0
int restarting ; /* Restart State flag */
#endif
-
- /* Override capability. */
- if (!open_recv->can_capability || CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
- {
- peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
- peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
- peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
- peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
- }
-
}