summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_open_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_open_state.c')
-rw-r--r--bgpd/bgp_open_state.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/bgpd/bgp_open_state.c b/bgpd/bgp_open_state.c
new file mode 100644
index 00000000..76c4b4bd
--- /dev/null
+++ b/bgpd/bgp_open_state.c
@@ -0,0 +1,138 @@
+/* BGP Open State -- functions
+ * Copyright (C) 2009 Chris Hall (GMCH), Highwayman
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "bgpd/bgp_open_state.h"
+#include "bgpd/bgp_peer.h"
+
+#include "lib/memory.h"
+
+
+#include "bgpd/bgpd.h"
+
+/*==============================================================================
+ * BGP Open State.
+ *
+ * This structure encapsulates all the information that may be sent/received
+ * in a BGP OPEN Message.
+ *
+ */
+
+/* Initialise new bgp_open_state structure -- allocate if required.
+ *
+ */
+extern bgp_open_state
+bgp_open_state_init_new(bgp_open_state state)
+{
+ if (state == NULL)
+ state = XCALLOC(MTYPE_BGP_OPEN_STATE, sizeof(struct bgp_open_state)) ;
+ else
+ memset(state, 0, sizeof(struct bgp_open_state)) ;
+
+ return state ;
+} ;
+
+extern bgp_open_state
+bgp_open_state_free(bgp_open_state state)
+{
+ if (state != NULL)
+ XFREE(MTYPE_BGP_OPEN_STATE, state) ;
+ return NULL ;
+} ;
+
+/*==============================================================================
+ * Construct new bgp_open_state for the given peer -- allocate if required.
+ *
+ * Initialises the structure according to the current peer state.
+ */
+
+extern bgp_session
+bgp_peer_open_state_init_new(bgp_open_state state, bgp_peer peer)
+{
+ safi_t safi ;
+ afi_t afi ;
+ qafx_num_t qafx ;
+
+ state = bgp_open_state_init_new(state) ; /* allocate if req. Zeroise. */
+
+ /* Choose the appropriate ASN */
+ if (peer->change_local_as)
+ state->my_as = peer->change_local_as ;
+ else
+ state->my_as = peer->local_as ;
+
+ /* Choose the appropriate hold time */
+ if (peer->config & PEER_CONFIG_TIMER)
+ state->holdtime = peer->holdtime ;
+ else
+ state->holdtime = peer->bgp->default_holdtime ;
+
+ /* Set our bgpd_id */
+ state->bgp_id = peer->local_id ;
+
+ /* Announce self as AS4 speaker if required */
+ state->can_as4 = ((peer->cap & PEER_CAP_AS4_ADV) != 0) ;
+
+ /* Fill in the supported AFI/SAFI */
+
+ for (afi = qAFI_MIN ; afi <= qAFI_MAX ; ++afi)
+ for (safi = qSAFI_MIN ; safi <= qSAFI_MAX ; ++safi)
+ if (peer->afc[afi][safi])
+ state->can_mp_ext |= quafi_bit(qafx_num_from_qAFI_qSAFI(afi, safi)) ;
+
+ /* Route refresh. */
+ state->can_r_refresh = (peer->cap & PEER_CAP_REFRESH_ADV)
+ ? (bgp_cap_form_old | bgp_cap_form_new)
+ : bgp_cap_form_none ;
+
+ /* ORF capability. */
+ for (afi = qAFI_MIN ; afi <= qAFI_MAX ; ++afi)
+ for (safi = qSAFI_MIN ; safi <= qSAFI_MAX ; ++safi)
+ {
+ if (peer->af_flags[afi][safi] & PEER_FLAG_ORF_PREFIX_SM)
+ state->can_orf_prefix_send |=
+ quafi_bit(qafx_num_from_qAFI_qSAFI(afi, safi)) ;
+ if (peer->af_flags[afi][safi] & PEER_FLAG_ORF_PREFIX_RM)
+ state->can_orf_prefix_recv |=
+ quafi_bit(qafx_num_from_qAFI_qSAFI(afi, safi)) ;
+ } ;
+
+ state->can_orf_prefix = (state->can_orf_prefix_send |
+ state->can_orf_prefix_recv)
+ ? (bgp_cap_form_old | bgp_cap_form_new)
+ : bgp_cap_form_none ;
+
+ /* Graceful restart capability */
+ /* TODO: check that support graceful restart for all supported AFI/SAFI */
+ if (bgp_flag_check(peer->bgp, BGP_FLAG_GRACEFUL_RESTART))
+ {
+ state->can_g_restart = state->can_mp_ext ;
+ state->restart_time = peer->bgp->restart_time ;
+ }
+ else
+ {
+ state->can_g_restart = 0 ;
+ state->restart_time = 0 ;
+ } ;
+
+ /* TODO: check not restarting and not preserving forwarding state (?) */
+ state->can_nsf = 0 ;
+ state->restarting = 0 ;
+} ;