summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bgpd/Makefile.am4
-rw-r--r--bgpd/bgp_attr.h3
-rw-r--r--bgpd/bgp_engine.h25
-rw-r--r--bgpd/bgp_main.c37
-rw-r--r--bgpd/bgp_msg_read.c167
-rw-r--r--bgpd/bgp_msg_write.h3
-rw-r--r--bgpd/bgp_network.c2
-rw-r--r--bgpd/bgp_open.c20
-rw-r--r--bgpd/bgp_open.h13
-rw-r--r--bgpd/bgp_open_state.c35
-rw-r--r--bgpd/bgp_open_state.h2
-rw-r--r--bgpd/bgp_packet.c6
-rw-r--r--bgpd/bgp_peer.c267
-rw-r--r--bgpd/bgp_peer.h28
-rw-r--r--bgpd/bgp_peer_index.c31
-rw-r--r--bgpd/bgp_peer_index.h3
-rw-r--r--bgpd/bgp_session.c35
-rw-r--r--bgpd/bgp_session.h2
-rw-r--r--bgpd/bgp_vty.c8
-rw-r--r--lib/memtypes.c1
-rw-r--r--lib/mqueue.h2
-rw-r--r--lib/plist.h1
22 files changed, 344 insertions, 351 deletions
diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
index 50e228f1..55aad179 100644
--- a/bgpd/Makefile.am
+++ b/bgpd/Makefile.am
@@ -18,7 +18,7 @@ libbgp_a_SOURCES = \
bgp_peer.c bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c \
bgp_engine.c bgp_session.c bgp_connection.c \
bgp_common.c bgp_notification.c bgp_peer_index.c bgp_msg_write.c \
- bgp_route_refresh.c bgp_msg_read.c
+ bgp_route_refresh.c bgp_msg_read.c bgp_open_state.c
noinst_HEADERS = \
bgp_aspath.h bgp_attr.h bgp_community.h bgp_debug.h bgp_fsm.h \
@@ -28,7 +28,7 @@ noinst_HEADERS = \
bgp_peer.h bgp_advertise.h bgp_snmp.h bgp_vty.h \
bgp_engine.h bgp_session.h bgp_connection.h \
bgp_common.h bgp_notification.h bgp_peer_index.h bgp_msg_write.h \
- bgp_route_refresh.h bgp.h bgp_msg_read.h
+ bgp_route_refresh.h bgp.h bgp_msg_read.h bgp_open_state.h
bgpd_SOURCES = bgp_main.c
bgpd_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index ed8753bd..d8a08d12 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -21,6 +21,9 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#ifndef _QUAGGA_BGP_ATTR_H
#define _QUAGGA_BGP_ATTR_H
+#include "bgpd/bgp_common.h"
+#include "bgpd/bgpd.h"
+
/* Simple bit mapping. */
#define BITMAP_NBBY 8
diff --git a/bgpd/bgp_engine.h b/bgpd/bgp_engine.h
index 57780dc5..2ffba5d0 100644
--- a/bgpd/bgp_engine.h
+++ b/bgpd/bgp_engine.h
@@ -40,6 +40,7 @@
extern qpn_nexus p_bgp_engine ;
+extern qpn_nexus p_peering_engine ;
extern void
bgp_engine_start(void) ;
@@ -53,7 +54,7 @@ bgp_engine_start(void) ;
/* Send given message to the BGP Engine -- ordinary
*/
Inline void
-bgp_to_engine(mqueue_block mqb)
+bgp_to_bgp_engine(mqueue_block mqb)
{
mqueue_enqueue(p_bgp_engine->queue, mqb, 0) ;
} ;
@@ -61,9 +62,29 @@ bgp_to_engine(mqueue_block mqb)
/* Send given message to the BGP Engine -- priority
*/
Inline void
-bgp_to_engine_priority(mqueue_block mqb)
+bgp_to_bgp_engine_priority(mqueue_block mqb)
{
mqueue_enqueue(p_bgp_engine->queue, mqb, 1) ;
} ;
+/*==============================================================================
+ *
+ */
+
+/* Send given message to the Peering Engine -- ordinary
+ */
+Inline void
+bgp_to_peering_engine(mqueue_block mqb)
+{
+ mqueue_enqueue(p_peering_engine->queue, mqb, 0) ;
+} ;
+
+/* Send given message to the Peering Engine -- priority
+ */
+Inline void
+bgp_to_peering_engine_priority(mqueue_block mqb)
+{
+ mqueue_enqueue(p_peering_engine->queue, mqb, 1) ;
+} ;
+
#endif /* QUAGGA_BGP_ENGINE_H */
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 003b9df0..c53aaba2 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -346,7 +346,25 @@ bgp_exit (int status)
qexit (status);
}
-
+
+/* threaded command*/
+DEFUN_HID_CALL (threaded,
+ threaded_cmd,
+ "threaded",
+ "Use pthreads\n")
+{
+ if (!qpthreads_enabled)
+ init_second_stage(1);
+
+ return CMD_SUCCESS;
+}
+
+static void
+init_second_stage(int pthreads)
+{
+ qlib_init_second_stage(pthreads);
+ bgp_peer_index_mutex_init(NULL);
+}
/* Main routine of bgpd. Treatment of argument and start bgp finite
state machine is handled at here. */
int
@@ -549,21 +567,4 @@ main (int argc, char **argv)
return (0);
}
-/* threaded */
-DEFUN_HID_CALL (threaded,
- threaded_cmd,
- "threaded",
- "Use pthreads\n")
-{
- if (!qpthreads_enabled)
- init_second_stage(1);
- return CMD_SUCCESS;
-}
-
-static void
-init_second_stage(int pthreads)
-{
- qlib_init_second_stage(pthreads);
- bgp_peer_index_mutex_init(NULL);
-}
diff --git a/bgpd/bgp_msg_read.c b/bgpd/bgp_msg_read.c
index 014860cc..020f2f0c 100644
--- a/bgpd/bgp_msg_read.c
+++ b/bgpd/bgp_msg_read.c
@@ -19,9 +19,22 @@
* Boston, MA 02111-1307, USA.
*/
-#include "bgp_msg_read.h"
+#include <zebra.h>
+
+#include "bgpd/bgp_common.h"
+#include "bgpd/bgp_msg_read.h"
+#include "bgpd/bgp_open.h"
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_debug.h"
+#include "bgpd/bgp_aspath.h"
+#include "bgpd/bgp_session.h"
+#include "bgpd/bgp_open_state.h"
+#include "bgpd/bgp_fsm.h"
+
+
/* prototypes */
+static int bgp_msg_marker_all_one (struct stream *s, int length);
static int bgp_msg_open_receive (bgp_connection connection, bgp_size_t size);
static as_t bgp_msg_peek_for_as4_capability (bgp_connection connection,
u_char length);
@@ -33,7 +46,9 @@ static int bgp_msg_capability_parse (bgp_connection connection, size_t length,
u_char **error);
static int bgp_msg_capability_mp (bgp_connection connection,
struct capability_header *hdr);
-static int bgp_capability_orf_entry (bgp_connection connection,
+static int bgp_msg_capability_restart (bgp_connection connection,
+ struct capability_header *caphdr);
+static int bgp_msg_capability_orf_entry (bgp_connection connection,
struct capability_header *hdr);
static int bgp_msg_capability_orf (bgp_connection connection,
struct capability_header *hdr);
@@ -75,7 +90,7 @@ bgp_msg_check_header(bgp_connection connection)
/* Marker check */
if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
- && ! bgp_marker_all_one (connection->ibuf, BGP_MARKER_SIZE))
+ && ! bgp_msg_marker_all_one (connection->ibuf, BGP_MARKER_SIZE))
{
bgp_msg_notify_send (connection, bgp_session_eInvalid_msg,
BGP_NOTIFY_HEADER_ERR,
@@ -128,19 +143,31 @@ bgp_msg_check_header(bgp_connection connection)
return size - BGP_HEADER_SIZE;
}
+/* Marker check. */
+static int
+bgp_msg_marker_all_one (struct stream *s, int length)
+{
+ int i;
+
+ for (i = 0; i < length; i++)
+ if (s->data[i] != 0xff)
+ return 0;
+
+ return 1;
+}
+
/* Deal with the BGP message. MUST remove from ibuf before returns ! */
void
bgp_msg_dispatch(bgp_connection connection)
{
u_char type = 0;
bgp_size_t size;
- int result = 0;
/* Get size and type again. */
size = stream_getw_from (connection->ibuf, BGP_MARKER_SIZE);
type = stream_getc_from (connection->ibuf, BGP_MARKER_SIZE + 2);
- size = size - BGP_HEADER_SIZE;
+ size -= BGP_HEADER_SIZE;
/* Read rest of the packet and call each sort of packet routine */
switch (type)
@@ -176,7 +203,9 @@ bgp_msg_dispatch(bgp_connection connection)
assert(0); /* types already validated */
}
- /* TODO: remove message from ibuf */
+ /* remove message from ibuf */
+ if (connection->ibuf)
+ stream_reset (connection->ibuf);
}
/* Receive BGP open packet and parse it into the session's
@@ -190,9 +219,7 @@ bgp_msg_open_receive (bgp_connection connection, bgp_size_t size)
int ret;
u_char version;
u_char optlen;
- u_int16_t holdtime;
- u_int16_t send_holdtime;
- as_t remote_as;
+ as_t remote_as = 0;
as_t as4 = 0;
struct in_addr remote_id;
int capability;
@@ -204,7 +231,8 @@ bgp_msg_open_receive (bgp_connection connection, bgp_size_t size)
assert(session);
/* To receive the parsed open message */
- session->open_recv = open_recv = bgp_open_state_init_new(session->open_recv);
+ session->open_recv = bgp_open_state_init_new(session->open_recv);
+ open_recv = session->open_recv;
/* Parse open packet. */
version = stream_getc (connection->ibuf);
@@ -235,7 +263,7 @@ bgp_msg_open_receive (bgp_connection connection, bgp_size_t size)
}
/* Just in case we have a silly peer who sends AS4 capability set to 0 */
- if (open_rcvd->can_as4 && !as4)
+ if (open_recv->can_as4 && !as4)
{
zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
session->host);
@@ -274,7 +302,7 @@ bgp_msg_open_receive (bgp_connection connection, bgp_size_t size)
{
/* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
/* If we have got the capability, peer->as4cap must match remote_as */
- if (open_rcvd->can_as4 && as4 != remote_as)
+ if (open_recv->can_as4 && as4 != remote_as)
{
/* raise error, log this, close session */
zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
@@ -288,7 +316,7 @@ bgp_msg_open_receive (bgp_connection connection, bgp_size_t size)
}
/* Set remote router-id */
- open_recv->bgp_id = ntohl(remote_id);
+ open_recv->bgp_id = remote_id.s_addr;
/* Peer BGP version check. */
if (version != BGP_VERSION_4)
@@ -304,7 +332,8 @@ bgp_msg_open_receive (bgp_connection connection, bgp_size_t size)
return -1;
}
- /* Check neighbor as number. */
+ /* TODO: How? Check neighbor as number. */
+#if 0
if (remote_as != session->as)
{
if (BGP_DEBUG (normal, NORMAL))
@@ -316,6 +345,7 @@ bgp_msg_open_receive (bgp_connection connection, bgp_size_t size)
notify_data_remote_as, 2);
return -1;
}
+#endif
/* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
calculate the value of the Hold Timer by using the smaller of its
@@ -334,7 +364,7 @@ bgp_msg_open_receive (bgp_connection connection, bgp_size_t size)
/* Open option part parse. */
if (optlen != 0)
{
- ret = bgp_open_option_parse (connection, optlen, &open_recv->can_capability);
+ ret = bgp_msg_open_option_parse (connection, optlen, &open_recv->can_capability);
if (ret < 0)
return ret;
}
@@ -433,7 +463,7 @@ bgp_msg_peek_for_as4_capability (bgp_connection connection, u_char length)
if (BGP_DEBUG (as4, AS4))
zlog_info ("[AS4] found AS4 capability, about to parse");
as4 = stream_getl (connection->ibuf);
- open_recv->can_as4 = 1;
+ session->open_recv->can_as4 = 1;
goto end;
}
@@ -456,7 +486,7 @@ bgp_msg_open_option_parse (bgp_connection connection, u_char length, int *capabi
u_char error_data[BGP_MAX_PACKET_SIZE];
struct stream *s = connection->ibuf;
size_t end = stream_get_getp (s) + length;
- bpg_session session = connection->session;
+ bgp_session session = connection->session;
assert(session);
ret = 0;
@@ -509,7 +539,7 @@ bgp_msg_open_option_parse (bgp_connection connection, u_char length, int *capabi
ret = -1;
break;
case BGP_OPEN_OPT_CAP:
- ret = bgp_msg_capability_parse (conection, opt_length, &error);
+ ret = bgp_msg_capability_parse (connection, opt_length, &error);
*capability = 1;
break;
default:
@@ -544,7 +574,7 @@ bgp_msg_open_option_parse (bgp_connection connection, u_char length, int *capabi
/* Check local capability does not negotiated with remote
peer. */
- if (open_recv->can_mp_ext != open_send->can_mp_ext)
+ if (session->open_recv->can_mp_ext != session->open_send->can_mp_ext)
{
bgp_msg_notify_send (connection, bgp_session_eOpen_reject,
BGP_NOTIFY_OPEN_ERR,
@@ -557,7 +587,7 @@ bgp_msg_open_option_parse (bgp_connection connection, u_char length, int *capabi
error. */
if (*capability && ! session->cap_override)
{
- if (open_recv->can_mp_ext == 0)
+ if (session->open_recv->can_mp_ext == 0)
{
plog_err (session->log, "%s [Error] No common capability", session->host);
@@ -694,7 +724,7 @@ bgp_msg_capability_parse (bgp_connection connection, size_t length, u_char **err
return -1;
break;
case CAPABILITY_CODE_DYNAMIC:
- open->recv->can_dynamic = 1;
+ open_recv->can_dynamic = 1;
break;
case CAPABILITY_CODE_AS4:
/* Already handled as a special-case parsing of the capabilities
@@ -767,7 +797,74 @@ bgp_msg_capability_mp (bgp_connection connection, struct capability_header *hdr)
}
static int
-bgp_capability_orf_entry (bgp_connection connection, struct capability_header *hdr)
+bgp_msg_capability_restart (bgp_connection connection, struct capability_header *caphdr)
+{
+ struct stream *s = connection->ibuf;
+ bgp_session session = connection->session;
+ bgp_open_state open_recv = session->open_recv;
+ u_int16_t restart_flag_time;
+ int restart_bit = 0;
+ size_t end = stream_get_getp (s) + caphdr->length;
+
+ open_recv->can_g_restart = 1;
+ restart_flag_time = stream_getw(s);
+ if (CHECK_FLAG (restart_flag_time, RESTART_R_BIT))
+ restart_bit = 1;
+ UNSET_FLAG (restart_flag_time, 0xF000);
+ open_recv->restart_time = restart_flag_time;
+
+ if (BGP_DEBUG (normal, NORMAL))
+ {
+ zlog_debug ("%s OPEN has Graceful Restart capability", session->host);
+ zlog_debug ("%s Peer has%srestarted. Restart Time : %d",
+ session->host, restart_bit ? " " : " not ",
+ open_recv->restart_time);
+ }
+
+ /* TODO restart */
+#if 0
+ while (stream_get_getp (s) + 4 < end)
+ {
+ afi_t afi = stream_getw (s);
+ safi_t safi = stream_getc (s);
+ u_char flag = stream_getc (s);
+
+ if (!bgp_afi_safi_valid_indices (afi, &safi))
+ {
+ if (BGP_DEBUG (normal, NORMAL))
+ zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported."
+ " Ignore the Graceful Restart capability",
+ peer->host, afi, safi);
+ }
+ else if (!peer->afc[afi][safi])
+ {
+ if (BGP_DEBUG (normal, NORMAL))
+ zlog_debug ("%s Addr-family %d/%d(afi/safi) not enabled."
+ " Ignore the Graceful Restart capability",
+ peer->host, afi, safi);
+ }
+ else
+ {
+ if (BGP_DEBUG (normal, NORMAL))
+ zlog_debug ("%s Address family %s is%spreserved", peer->host,
+ afi_safi_print (afi, safi),
+ CHECK_FLAG (peer->af_cap[afi][safi],
+ PEER_CAP_RESTART_AF_PRESERVE_RCV)
+ ? " " : " not ");
+
+ SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV);
+ if (CHECK_FLAG (flag, RESTART_F_BIT))
+ SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV);
+
+ }
+ }
+#endif
+ return 0;
+}
+
+
+static int
+bgp_msg_capability_orf_entry (bgp_connection connection, struct capability_header *hdr)
{
struct stream *s = connection->ibuf;
struct capability_orf_entry entry;
@@ -775,8 +872,6 @@ bgp_capability_orf_entry (bgp_connection connection, struct capability_header *h
safi_t safi;
u_char type;
u_char mode;
- u_int16_t sm_cap = 0; /* capability send-mode receive */
- u_int16_t rm_cap = 0; /* capability receive-mode receive */
int i;
bgp_session session = connection->session;
qafx_bit_t qb;
@@ -784,7 +879,7 @@ bgp_capability_orf_entry (bgp_connection connection, struct capability_header *h
assert(session);
/* ORF Entry header */
- bgp_msg_capability_mp_data (s, &entry.mpc);
+ bgp_capability_mp_data (s, &entry.mpc);
entry.num = stream_getc (s);
afi = entry.mpc.afi;
safi = entry.mpc.safi;
@@ -876,9 +971,9 @@ bgp_capability_orf_entry (bgp_connection connection, struct capability_header *h
if (hdr->code == CAPABILITY_CODE_ORF)
- open_recv->can_orf_prefix |= bgp_cap_form_new;
+ session->open_recv->can_orf_prefix |= bgp_cap_form_new;
else if (hdr->code == CAPABILITY_CODE_ORF_OLD)
- open_recv->can_orf_prefix |= bgp_cap_form_old;
+ session->open_recv->can_orf_prefix |= bgp_cap_form_old;
else
{
bgp_msg_capability_orf_not_support (session->host, afi, safi, type, mode);
@@ -889,14 +984,14 @@ bgp_capability_orf_entry (bgp_connection connection, struct capability_header *h
switch (mode)
{
case ORF_MODE_BOTH:
- open_recv->can_orf_prefix_send |= qb;
- open_recv->can_orf_prefix_recv |= qb;
+ session->open_recv->can_orf_prefix_send |= qb;
+ session->open_recv->can_orf_prefix_recv |= qb;
break;
case ORF_MODE_SEND:
- open_recv->can_orf_prefix_send |= qb;
+ session->open_recv->can_orf_prefix_send |= qb;
break;
case ORF_MODE_RECEIVE:
- open_recv->can_orf_prefix_recv |= qb;
+ session->open_recv->can_orf_prefix_recv |= qb;
break;
}
}
@@ -939,7 +1034,7 @@ bgp_msg_capability_orf_not_support (char *host, afi_t afi, safi_t safi,
static int
bgp_msg_update_receive (bgp_connection connection, bgp_size_t size)
{
- /* TODO: got update packet, now what? */
+ bgp_session_update_recv(connection->session, stream_dup(connection->ibuf));
bgp_fsm_event(connection, bgp_fsm_Receive_UPDATE_message);
return 0;
}
@@ -969,9 +1064,9 @@ bgp_msg_notify_receive (bgp_connection connection, bgp_size_t size)
bgp_nom_subcode_t subcode = stream_getc (connection->ibuf);
bgp_size_t expect = size - 2;
- notification = bgp_notify_new(code, subcode, datalen);
+ notification = bgp_notify_new(code, subcode, expect);
notification = bgp_notify_append_data(notification,
- stream_pnt(connection->ibuf), datalen);
+ stream_pnt(connection->ibuf), expect);
bgp_fsm_notification_exception(connection, notification);
}
@@ -982,7 +1077,7 @@ bgp_msg_notify_send (bgp_connection connection, bgp_session_event_t except,
bgp_nom_code_t code, bgp_nom_subcode_t sub_code)
{
bgp_notify notification;
- notification = bgp_notify_new(code, subcode, 0);
+ notification = bgp_notify_new(code, sub_code, 0);
bgp_fsm_raise_exception(connection, except, notification);
}
@@ -994,7 +1089,7 @@ bgp_msg_notify_send_with_data (bgp_connection connection,
u_char *data, size_t datalen)
{
bgp_notify notification;
- notification = bgp_notify_new(code, subcode, datalen);
+ notification = bgp_notify_new(code, sub_code, datalen);
notification = bgp_notify_append_data(notification, data, datalen);
bgp_fsm_raise_exception(connection, except, notification);
}
diff --git a/bgpd/bgp_msg_write.h b/bgpd/bgp_msg_write.h
index 68891a67..9e24ce6f 100644
--- a/bgpd/bgp_msg_write.h
+++ b/bgpd/bgp_msg_write.h
@@ -52,4 +52,7 @@ bgp_packet_set_marker(struct stream *s, uint8_t type) ;
extern int
bgp_packet_set_size (struct stream *s) ;
+extern int
+bgp_msg_send_end_of_rib(bgp_connection connection, iAFI_t afi, iSAFI_t safi);
+
#endif /* _QUAGGA_BGP_MSG_WRITE_H */
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index 3c1cf753..0f02ae38 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -460,7 +460,7 @@ bgp_accept_action(qps_file qf, void* file_info)
inet_sutop(&su_remote, buf)) ;
/* See if we are ready to accept connections from the connecting party */
- session = bgp_session_lookup(&su_remote, &exists) ;
+ session = bgp_session_index_seek(&su_remote, &exists) ;
if (session != NULL)
{
if (BGP_DEBUG(events, EVENTS))
diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
index 573371ee..ce86db4d 100644
--- a/bgpd/bgp_open.c
+++ b/bgpd/bgp_open.c
@@ -58,8 +58,8 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer)
struct capability_mp_data mpc;
struct capability_header *hdr;
- pnt = peer->notify.data;
- end = pnt + peer->notify.length;
+ pnt = peer->notify->data;
+ end = pnt + peer->notify->length;
while (pnt < end)
{
@@ -119,7 +119,7 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer)
}
}
-static void
+void
bgp_capability_mp_data (struct stream *s, struct capability_mp_data *mpc)
{
mpc->afi = stream_getw (s);
@@ -197,21 +197,21 @@ bgp_capability_orf_not_support (struct peer *peer, afi_t afi, safi_t safi,
peer->host, afi, safi, type, mode);
}
-static const struct message orf_type_str[] =
+const struct message orf_type_str[] =
{
{ ORF_TYPE_PREFIX, "Prefixlist" },
{ ORF_TYPE_PREFIX_OLD, "Prefixlist (old)" },
};
-static const int orf_type_str_max
+const int orf_type_str_max
= sizeof(orf_type_str)/sizeof(orf_type_str[0]);
-static const struct message orf_mode_str[] =
+const struct message orf_mode_str[] =
{
{ ORF_MODE_RECEIVE, "Receive" },
{ ORF_MODE_SEND, "Send" },
{ ORF_MODE_BOTH, "Both" },
};
-static const int orf_mode_str_max
+const int orf_mode_str_max
= sizeof(orf_mode_str)/sizeof(orf_mode_str[0]);
static int
@@ -446,7 +446,7 @@ bgp_capability_as4 (struct peer *peer, struct capability_header *hdr)
return as4;
}
-static const struct message capcode_str[] =
+const struct message capcode_str[] =
{
{ CAPABILITY_CODE_MP, "MultiProtocol Extensions" },
{ CAPABILITY_CODE_REFRESH, "Route Refresh" },
@@ -457,10 +457,10 @@ static const struct message capcode_str[] =
{ CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)" },
{ CAPABILITY_CODE_ORF_OLD, "ORF (Old)" },
};
-static const int capcode_str_max = sizeof(capcode_str)/sizeof(capcode_str[0]);
+const int capcode_str_max = sizeof(capcode_str)/sizeof(capcode_str[0]);
/* Minimum sizes for length field of each cap (so not inc. the header) */
-static const size_t cap_minsizes[] =
+const size_t cap_minsizes[] =
{
[CAPABILITY_CODE_MP] = sizeof (struct capability_mp_data),
[CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN,
diff --git a/bgpd/bgp_open.h b/bgpd/bgp_open.h
index 59265dc9..edd29733 100644
--- a/bgpd/bgp_open.h
+++ b/bgpd/bgp_open.h
@@ -21,6 +21,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#ifndef _QUAGGA_BGP_OPEN_H
#define _QUAGGA_BGP_OPEN_H
+#include "log.h"
+
/* Standard header for capability TLV */
struct capability_header
{
@@ -102,10 +104,21 @@ struct capability_gr
#define RESTART_R_BIT 0x8000
#define RESTART_F_BIT 0x80
+extern const struct message capcode_str[];
+extern const int capcode_str_max;
+extern const size_t cap_minsizes[];
+
+extern const struct message orf_type_str[];
+extern const int orf_type_str_max;
+extern const struct message orf_mode_str[];
+extern const int orf_mode_str_max;
+
extern int bgp_open_option_parse (struct peer *, u_char, int *);
extern void bgp_open_capability (struct stream *, struct peer *);
extern void bgp_capability_vty_out (struct vty *, struct peer *);
extern as_t peek_for_as4_capability (struct peer *, u_char);
+extern void bgp_capability_mp_data (struct stream *s,
+ struct capability_mp_data *mpc);
extern int bgp_afi_safi_valid_indices (afi_t, safi_t *);
#endif /* _QUAGGA_BGP_OPEN_H */
diff --git a/bgpd/bgp_open_state.c b/bgpd/bgp_open_state.c
index b122abfe..ada4ee70 100644
--- a/bgpd/bgp_open_state.c
+++ b/bgpd/bgp_open_state.c
@@ -19,13 +19,17 @@
* Boston, MA 02111-1307, USA.
*/
-#include "bgpd/bgp_open_state.h"
+#include "zebra.h"
+
+#include "bgpd/bgpd.h"
#include "bgpd/bgp_peer.h"
+#include "bgpd/bgp_session.h"
+#include "bgpd/bgp_open_state.h"
#include "lib/memory.h"
+#include "lib/memtypes.h"
-#include "bgpd/bgpd.h"
/*==============================================================================
* BGP Open State.
@@ -75,7 +79,6 @@ 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. */
@@ -92,7 +95,7 @@ bgp_peer_open_state_init_new(bgp_open_state state, bgp_peer peer)
state->holdtime = peer->bgp->default_holdtime ;
/* Set our bgpd_id */
- state->bgp_id = peer->local_id ;
+ state->bgp_id = peer->local_id.s_addr ;
/* Do not send capability. */ /* TODO: can_capability? */
state->can_capability =
@@ -104,8 +107,8 @@ bgp_peer_open_state_init_new(bgp_open_state state, bgp_peer peer)
/* Fill in the supported AFI/SAFI */
- for (afi = qAFI_MIN ; afi <= qAFI_MAX ; ++afi)
- for (safi = qSAFI_MIN ; safi <= qSAFI_MAX ; ++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 |= qafx_bit(qafx_num_from_qAFI_qSAFI(afi, safi)) ;
@@ -115,8 +118,8 @@ bgp_peer_open_state_init_new(bgp_open_state state, bgp_peer peer)
: bgp_cap_form_none ;
/* ORF capability. */
- for (afi = qAFI_MIN ; afi <= qAFI_MAX ; ++afi)
- for (safi = qSAFI_MIN ; safi <= qSAFI_MAX ; ++safi)
+ 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 |=
@@ -183,7 +186,7 @@ bgp_open_state_unknown_add(bgp_open_state state, uint8_t code,
/*------------------------------------------------------------------------------
* Get count of number of unknown capabilities in given open_state.
*/
-extern void
+extern int
bgp_open_state_unknown_count(bgp_open_state state)
{
return vector_end(&state->unknowns) ;
@@ -234,7 +237,7 @@ bgp_peer_open_state_receive(bgp_peer peer)
session->keepalive_timer_interval = peer->v_keepalive ;
/* Set remote router-id */
- peer->remote_id = open_recv->bgp_id;
+ peer->remote_id.s_addr = open_recv->bgp_id;
/* AS4 */
if (open_recv->can_as4)
@@ -244,8 +247,8 @@ bgp_peer_open_state_receive(bgp_peer peer)
/* Ignore capability when override-capability is set. */
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)
+ 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)
@@ -264,8 +267,8 @@ bgp_peer_open_state_receive(bgp_peer peer)
SET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
/* ORF */
- for (afi = qAFI_MIN ; afi <= qAFI_MAX ; ++afi)
- for (safi = qSAFI_MIN ; safi <= qSAFI_MAX ; ++safi)
+ 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_orf_prefix_send)
@@ -295,8 +298,8 @@ bgp_peer_open_state_receive(bgp_peer peer)
SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
/* Graceful restart */
- for (afi = qAFI_MIN ; afi <= qAFI_MAX ; ++afi)
- for (safi = qSAFI_MIN ; safi <= qSAFI_MAX ; ++safi)
+ 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 (peer->afc[afi][safi] && (qb & open_recv->can_preserve))
diff --git a/bgpd/bgp_open_state.h b/bgpd/bgp_open_state.h
index c67e0108..2019941e 100644
--- a/bgpd/bgp_open_state.h
+++ b/bgpd/bgp_open_state.h
@@ -106,7 +106,7 @@ bgp_open_state_free(bgp_open_state state) ;
extern void
bgp_open_state_unknown_add(bgp_open_state state, uint8_t code,
void* value, bgp_size_t length) ;
-extern void
+extern int
bgp_open_state_unknown_count(bgp_open_state state) ;
extern bgp_cap_unknown
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index cfafbdf9..3018daa9 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -838,6 +838,8 @@ void
bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
u_char *data, size_t datalen)
{
+ /* TODO: do we still need this? */
+#if 0
struct stream *s;
int length;
@@ -914,6 +916,7 @@ bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
BGP_WRITE_OFF (peer->t_write);
bgp_write_notify (peer);
+#endif
}
/* Send BGP notify packet. */
@@ -1820,6 +1823,8 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
static void
bgp_notify_receive (struct peer *peer, bgp_size_t size)
{
+ /* TODO: do we still need this? */
+#if 0
struct bgp_notify bgp_notify;
if (peer->notify.data)
@@ -1894,6 +1899,7 @@ bgp_notify_receive (struct peer *peer, bgp_size_t size)
UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
+#endif
}
/* Keepalive treatment function -- get keepalive send keepalive */
diff --git a/bgpd/bgp_peer.c b/bgpd/bgp_peer.c
index 3d686171..9e9f8b06 100644
--- a/bgpd/bgp_peer.c
+++ b/bgpd/bgp_peer.c
@@ -33,9 +33,11 @@
#include "memory.h"
#include "plist.h"
#include "mqueue.h"
+#include "workqueue.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_peer.h"
+#include "bgpd/bgp_peer_index.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_debug.h"
@@ -45,6 +47,7 @@
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_dump.h"
#include "bgpd/bgp_open.h"
+#include "bgpd/bgp_advertise.h"
#include "bgpd/bgp_engine.h"
#include "bgpd/bgp_session.h"
@@ -53,6 +56,21 @@
#include "bgpd/bgp_snmp.h"
#endif /* HAVE_SNMP */
+/* prototypes */
+
+static int
+bgp_session_has_established(bgp_peer peer);
+static int
+bgp_session_has_stopped(bgp_peer peer);
+static void
+bgp_uptime_reset (struct peer *peer);
+static int
+bgp_routeadv_timer (struct thread *thread);
+static int
+bgp_graceful_restart_timer_expire (struct thread *thread);
+static int
+bgp_graceful_stale_timer_expire (struct thread *thread);
+
/*==============================================================================
* This is the high level management of BGP Peers and peering conversations.
*
@@ -78,215 +96,6 @@
*
*/
-
-/*==============================================================================
- * BGP Peer Index
- *
- * When peers are created, they are registered in the bgp_peer_index. When
- * they are destroyed, they are removed. This is done by the Routeing Engine.
- *
- * The peer index is used by the Routeing Engine to lookup peers.
- *
- * The BGP Engine needs to lookup sessions when a listening socket accepts a
- * connection -- first, to decide whether to continue with the connection, and
- * second, to tie the connection to the right session. It uses the peer index
- * to do this.
- *
- * A mutex is used to coordinate access to the index.
- *
- * NB: the bgp_peer points to its bgp_session (if any). The session pointer
- * MUST only be changed while holding the index mutex.
- *
- * See bgp_peer_set_session().
- *
- * NB: to avoid deadlock, MUST NOT do anything using the index while holding
- * any session mutex.
- *
- * But may acquire a session mutex while doing things to the index.
- */
-
-static struct symbol_table bgp_peer_index ;
-static qpt_mutex_t bgp_peer_index_mutex ;
-
-inline static void BGP_PEER_INDEX_LOCK(void)
-{
- qpt_mutex_lock(&bgp_peer_index_mutex) ;
-} ;
-
-inline static void BGP_PEER_INDEX_UNLOCK(void)
-{
- qpt_mutex_unlock(&bgp_peer_index_mutex) ;
-} ;
-
-/*------------------------------------------------------------------------------
- * Initialise the bgp_peer_index.
- *
- * This must be done before any peers are configured !
- */
-void
-bgp_peer_index_init(void* parent)
-{
- symbol_table_init_new(
- &bgp_peer_index,
- parent,
- 10, /* start ready for a few sessions */
- 200, /* allow to be quite dense */
- sockunion_symbol_hash, /* "name" is an IP Address */
- NULL) ; /* no value change call-back */
-}
-
-/*------------------------------------------------------------------------------
- * Initialise the bgp_peer_index_mutex.
- *
- * This must be done before the BGP Engine is started.
- */
-void
-bgp_peer_index_mutex_init(void* parent)
-{
- qpt_mutex_init(&bgp_peer_index_mutex, qpt_mutex_recursive) ;
-}
-
-/*------------------------------------------------------------------------------
- * Lookup a peer -- do nothing if does not exist
- *
- * For use by the Routeing Engine.
- *
- * Returns the bgp_peer -- NULL if not found.
- */
-bgp_peer
-bgp_peer_index_seek(union sockunion* su)
-{
- bgp_peer peer ;
-
- BGP_PEER_INDEX_LOCK() ; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
- peer = symbol_get_value(symbol_seek(&bgp_peer_index, su)) ;
-
- BGP_PEER_INDEX_UNLOCK() ; /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- return peer ;
-}
-
-/*------------------------------------------------------------------------------
- * Register a peer in the peer index.
- *
- * For use by the Routeing Engine.
- *
- * NB: it is a FATAL error to register a peer for an address which is already
- * registered.
- */
-void
-bgp_peer_index_register(bgp_peer peer, union sockunion* su)
-{
- BGP_PEER_INDEX_LOCK() ; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
- peer = symbol_set_value(symbol_find(&bgp_peer_index, su), peer) ;
-
- BGP_PEER_INDEX_UNLOCK() ; /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- passert(peer == NULL) ;
-}
-
-/*------------------------------------------------------------------------------
- * Unregister a peer in the peer index.
- *
- * returns 1 if successfully unregistered
- * returns 0 if wasn't registered
- * FATAL error if a different peer is registered.
- */
-int
-bgp_peer_index_unregister(bgp_peer peer, union sockunion* su)
-{
- int found = 0;
- int right_peer = 1;
- symbol s = NULL;
-
- BGP_PEER_INDEX_LOCK() ; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
- s = symbol_seek(&bgp_peer_index, su);
- found = (s != NULL);
- if (found)
- {
- right_peer = (peer == symbol_get_value(s));
- if (right_peer)
- symbol_delete(s);
- }
-
- BGP_PEER_INDEX_UNLOCK() ; /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- passert(right_peer) ;
- return found;
-}
-
-/*------------------------------------------------------------------------------
- * Lookup a session -- do nothing if does not exist
- *
- * For use by the BGP Engine.
- *
- * Returns the bgp_session, or NULL if not found OR not active
- * Sets *p_found <=> found.
- *
- * NB: the BGP Engine may not access the bgp_session structure if it is not
- * in either of the active states (Enabled or Established).
- *
- * So this function does not return the bgp_session unless it is active.
- *
- * For callers who care, the p_found return indicates whether the session
- * exists, or not.
- */
-extern bgp_session
-bgp_session_index_seek(union sockunion* su, int* p_found)
-{
- bgp_session session ;
- bgp_peer peer ;
-
- BGP_PEER_INDEX_LOCK() ; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
- peer = symbol_get_value(symbol_seek(&bgp_peer_index, su)) ;
- *p_found = (peer != NULL) ;
- if (*p_found && bgp_session_is_active(peer->session))
- /* NULL peer->session is not active */
- session = peer->session ;
- else
- session = NULL ;
-
- BGP_PEER_INDEX_UNLOCK() ; /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- return session ;
-}
-
-/*------------------------------------------------------------------------------
- * Set peer's session pointer.
- *
- * For use by the Routeing Engine. Locks the bgp_peer_index mutex so that the
- * BGP Engine is not fooled when it looks up the session.
- *
- * Returns the old session pointer value.
- *
- * NB: it is a FATAL error to change the pointer if the current session is
- * "active".
- *
- */
-
-bgp_session
-bgp_peer_new_session(bgp_peer peer, bgp_session new_session)
-{
- bgp_session old_session ;
-
- BGP_PEER_INDEX_LOCK() ; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
- old_session = peer->session ;
- peer->session = new_session ;
-
- passert(!bgp_session_is_active(old_session)) ;
-
- BGP_PEER_INDEX_UNLOCK() ; /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- return old_session ;
-}
-
-
-
/*==============================================================================
* Deal with change in session state -- mqueue_action function.
*
@@ -298,44 +107,46 @@ bgp_peer_new_session(bgp_peer peer, bgp_session new_session)
* Established -> Stopped -- for some reason
*
* -- arg0 = session
- * arg1 = new state
+ * args = bgp_session_event_args
*
*/
void
-bgp_peer_new_session_state(mqueue_block mqb, mqb_flag_t flag)
+bgp_session_do_event(mqueue_block mqb, mqb_flag_t flag)
{
- bgp_session session = mqb_get_arg0(mqb) ;
- bgp_session_state_t state = mqb_get_arg1_i(mqb) ;
- bgp_peer peer = session->peer ;
+
+ struct bgp_session_event_args * args = mqb_get_args(mqb) ;
+ bgp_session session = mqb_get_arg0(mqb) ;
+ bgp_peer peer = session->peer ;
if (flag == mqb_action)
{
- bgp_session_lock(session) ;
+ BGP_SESSION_LOCK(session) ;
- switch(new_state)
+ switch(args->state)
{
/* If now Enabled, then the BGP Engine is attempting to connect */
/* (may be waiting for the Idle Hold Time to expire. */
- case bgp_session_Enabled:
- bgp_session_enable(session, peer);
+ case bgp_session_sEnabled:
+ bgp_session_enable(peer);
break ;
/* If now Established, then the BGP Engine has exchanged BGP Open */
/* messages, and received the KeepAlive that acknowledges our Open. */
- case bgp_session_Established:
+ case bgp_session_sEstablished:
bgp_session_has_established(peer);
break ;
/* If now Stopped, then for some reason the BGP Engine has either */
/* stopped trying to connect, or the session has been stopped. */
- case bgp_session_Stopped:
+ case bgp_session_sStopped:
bgp_session_has_stopped(peer);
break ;
default:
+ break;
}
- bgp_session_unlock(session) ;
+ BGP_SESSION_UNLOCK(session) ;
}
mqb_free(mqb) ;
@@ -350,7 +161,6 @@ bgp_peer_new_session_state(mqueue_block mqb, mqb_flag_t flag)
static int
bgp_session_has_established(bgp_peer peer)
{
- struct bgp_notify *notify;
afi_t afi;
safi_t safi;
int nsf_af_count = 0;
@@ -363,10 +173,7 @@ bgp_session_has_established(bgp_peer peer)
SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
/* Clear last notification data. */
- notify = &peer->notify;
- if (notify->data)
- XFREE (MTYPE_TMP, notify->data);
- memset (notify, 0, sizeof (struct bgp_notify));
+ bgp_notify_free(&(peer->notify));
/* Clear start timer value to default. */
peer->v_start = BGP_INIT_START_TIMER;
@@ -603,7 +410,8 @@ bgp_peer_timers_stop(bgp_peer peer)
BGP_TIMER_OFF (peer->t_pmax_restart);
} ;
-void
+/* TODO: bgp_timer_set - kill ? */
+static void
bgp_timer_set (struct peer *peer)
{
int jitter = 0;
@@ -891,7 +699,7 @@ peer_create (union sockunion *su, struct bgp *bgp, as_t local_as,
bgp_timer_set (peer);
/* session */
- peer->session = bgp_session_init_new(NULL);
+ peer->session = bgp_session_init_new(peer->session, peer);
/* register */
bgp_peer_index_register(peer, &peer->su);
@@ -1039,8 +847,7 @@ peer_delete (struct peer *peer)
}
/* unregister */
- if (peer->su)
- bgp_peer_index_unregister(peer, &peer->su);
+ bgp_peer_index_deregister(peer, &peer->su);
peer_unlock (peer); /* initial reference */
diff --git a/bgpd/bgp_peer.h b/bgpd/bgp_peer.h
index 30e02323..43a89e12 100644
--- a/bgpd/bgp_peer.h
+++ b/bgpd/bgp_peer.h
@@ -24,6 +24,7 @@
#include "bgpd/bgp_common.h"
#include "bgpd/bgp_notification.h"
+#include "bgpd/bgp_peer_index.h"
#include "lib/plist.h"
@@ -142,6 +143,14 @@ struct peer
/* Packet receive buffer. */
struct stream *ibuf;
+ /* TODO: kill - kludge to get things to compile */
+#if 1
+ struct stream_fifo *obuf;
+ struct stream *work;
+ int fd;
+ unsigned long packet_size;
+#endif
+
/* Status of the peer. */
int status;
int ostatus;
@@ -151,6 +160,7 @@ struct peer
/* Peer information */
bgp_session session ; /* Current session */
+ bgp_peer_index_entry index_entry ; /* and our index entry */
int ttl; /* TTL of TCP connection to the peer. */
char *desc; /* Description of the peer. */
@@ -329,7 +339,7 @@ struct peer
struct hash *hash[AFI_MAX][SAFI_MAX];
/* Notify data. */
- struct bgp_notify notify;
+ bgp_notify notify;
/* Filter structure. */
struct bgp_filter filter[AFI_MAX][SAFI_MAX];
@@ -446,7 +456,9 @@ struct peer
/* Prototypes. */
extern int bgp_event (struct thread *);
extern int bgp_stop (struct peer *peer);
+#if 0
extern void bgp_timer_set (struct peer *);
+#endif
extern void bgp_fsm_change_status (struct peer *peer, int status);
extern const char *peer_down_str[];
@@ -456,19 +468,7 @@ extern const char *peer_down_str[];
*/
extern void
-bgp_peer_index_init(void* parent) ;
-
-extern void
-bgp_peer_index_mutex_init(void* parent) ;
-
-extern bgp_peer
-bgp_peer_index_seek(union sockunion* su) ;
-
-extern void
-bgp_peer_index_register(bgp_peer peer, union sockunion* su) ;
-
-extern bgp_session
-bgp_session_index_seek(union sockunion* su, int* p_found) ;
+bgp_session_do_event(mqueue_block mqb, mqb_flag_t flag);
extern struct peer *
peer_new (struct bgp *bgp);
diff --git a/bgpd/bgp_peer_index.c b/bgpd/bgp_peer_index.c
index 2967d11f..bad95d95 100644
--- a/bgpd/bgp_peer_index.c
+++ b/bgpd/bgp_peer_index.c
@@ -258,6 +258,37 @@ bgp_session_index_seek(union sockunion* su, int* p_found)
return accept ;
} ;
+/*------------------------------------------------------------------------------
+ * Set peer's session pointer.
+ *
+ * For use by the Routeing Engine. Locks the bgp_peer_index mutex so that the
+ * BGP Engine is not fooled when it looks up the session.
+ *
+ * Returns the old session pointer value.
+ *
+ * NB: it is a FATAL error to change the pointer if the current session is
+ * "active".
+ *
+ */
+
+bgp_session
+bgp_peer_new_session(bgp_peer peer, bgp_session new_session)
+{
+ bgp_session old_session ;
+
+ BGP_PEER_INDEX_LOCK() ; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+
+ old_session = peer->session ;
+ peer->session = new_session ;
+
+ passert(!bgp_session_is_active(old_session)) ;
+
+ BGP_PEER_INDEX_UNLOCK() ; /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
+
+ return old_session ;
+}
+
+
/*==============================================================================
* Extending the bgp_peer_id_table and adding free entries to it.
*/
diff --git a/bgpd/bgp_peer_index.h b/bgpd/bgp_peer_index.h
index ae41de24..355b3654 100644
--- a/bgpd/bgp_peer_index.h
+++ b/bgpd/bgp_peer_index.h
@@ -85,5 +85,8 @@ bgp_peer_index_seek_entry(union sockunion* su) ;
extern bgp_session
bgp_session_index_seek(union sockunion* su, int* p_found) ;
+extern bgp_session
+bgp_peer_new_session(bgp_peer peer, bgp_session new_session);
+
#endif /* _QUAGGA_BGP_PEER_INDEX_H */
diff --git a/bgpd/bgp_session.c b/bgpd/bgp_session.c
index 1f8e06dc..3f6333fa 100644
--- a/bgpd/bgp_session.c
+++ b/bgpd/bgp_session.c
@@ -23,6 +23,8 @@
#include "bgpd/bgp_peer.h"
#include "bgpd/bgp_engine.h"
#include "bgpd/bgp_peer_index.h"
+#include "bgpd/bgp_fsm.h"
+#include "bgpd/bgp_open_state.h"
#include "lib/memory.h"
#include "lib/sockunion.h"
@@ -85,7 +87,7 @@ extern bgp_session
bgp_session_init_new(bgp_session session, bgp_peer peer)
{
assert(peer->session == NULL) ;
- assert(peer->index_entry->session == NULL) ;
+ assert(peer->index_entry->accept == NULL) ;
if (session == NULL)
session = XCALLOC(MTYPE_BGP_SESSION, sizeof(struct bgp_session)) ;
@@ -156,7 +158,7 @@ bgp_session_free(bgp_session session)
qpt_mutex_destroy(&session->mutex, 0) ;
- bgp_notify_free(session->notification);
+ bgp_notify_free(&session->notification);
bgp_open_state_free(session->open_send);
bgp_open_state_free(session->open_recv);
XFREE(MTYPE_BGP_SESSION, session->host);
@@ -169,15 +171,6 @@ bgp_session_free(bgp_session session)
return NULL;
}
-
-/* Look up session
- *
- */
-extern bgp_session
-bgp_session_lookup(union sockunion* su, int* exists) ;
-
-
-
/*==============================================================================
* Enable session for given peer -- allocate session if required.
*
@@ -218,7 +211,7 @@ bgp_session_enable(bgp_peer peer)
session->state = bgp_session_sIdle;
session->made = 0;
session->event = bgp_session_null_event;
- session->notification = bgp_notify_free(session->notification);
+ bgp_notify_free(&session->notification);
session->err = 0;
session->ordinal = 0;
@@ -264,7 +257,7 @@ bgp_session_enable(bgp_peer peer)
confirm(sizeof(struct bgp_session_enable_args) == 0) ;
- bgp_to_engine(mqb) ;
+ bgp_to_bgp_engine(mqb) ;
} ;
/*------------------------------------------------------------------------------
@@ -337,7 +330,7 @@ bgp_session_disable(bgp_peer peer, bgp_notify notification)
confirm(sizeof(struct bgp_session_enable_args) == 0) ;
- bgp_to_engine_priority(mqb) ;
+ bgp_to_bgp_engine_priority(mqb) ;
} ;
/*------------------------------------------------------------------------------
@@ -376,7 +369,7 @@ bgp_session_event(bgp_session session)
args->state = session->state ;
args->ordinal = session->ordinal ;
- bgp_to_peering(mqb) ;
+ bgp_to_peering_engine(mqb) ;
}
/*==============================================================================
@@ -387,6 +380,10 @@ bgp_session_event(bgp_session session)
* The BGP Engine takes care of discarding the stream block once it's been
* dealt with.
*/
+
+static void
+bgp_session_do_update_send(mqueue_block mqb, mqb_flag_t flag);
+
extern void
bgp_session_update_send(bgp_session session, struct stream* upd)
{
@@ -399,7 +396,7 @@ bgp_session_update_send(bgp_session session, struct stream* upd)
args->buf = upd ;
- bgp_to_engine(mqb) ;
+ bgp_to_bgp_engine(mqb) ;
} ;
/*==============================================================================
@@ -410,6 +407,10 @@ bgp_session_update_send(bgp_session session, struct stream* upd)
* The Peering Engine takes care of discarding the stream block once it's been
* dealt with.
*/
+
+static void
+bgp_session_do_update_recv(mqueue_block mqb, mqb_flag_t flag);
+
extern void
bgp_session_update_recv(bgp_session session, struct stream* upd)
{
@@ -422,7 +423,7 @@ bgp_session_update_recv(bgp_session session, struct stream* upd)
args->buf = upd ;
- bgp_to_peering(mqb) ;
+ bgp_to_peering_engine(mqb) ;
} ;
diff --git a/bgpd/bgp_session.h b/bgpd/bgp_session.h
index b84fca04..cd4bf107 100644
--- a/bgpd/bgp_session.h
+++ b/bgpd/bgp_session.h
@@ -246,7 +246,7 @@ extern bgp_session
bgp_session_init_new(bgp_session session, bgp_peer peer) ;
extern bgp_session
-bgp_session_lookup(union sockunion* su, int* exists) ;
+bgp_session_free(bgp_session session);
extern void
bgp_session_enable(bgp_peer peer) ;
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index fd7697ca..dfd9c316 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -7595,21 +7595,23 @@ bgp_show_peer (struct vty *vty, struct peer *p)
#endif /* HAVE_IPV6 */
}
- /* Timer information. */
+ /* TODO: Timer information. */
+#if 0
if (p->t_start)
vty_out (vty, "Next start timer due in %ld seconds%s",
thread_timer_remain_second (p->t_start), VTY_NEWLINE);
if (p->t_connect)
vty_out (vty, "Next connect timer due in %ld seconds%s",
thread_timer_remain_second (p->t_connect), VTY_NEWLINE);
+#endif
vty_out (vty, "Read thread: %s Write thread: %s%s",
p->t_read ? "on" : "off",
p->t_write ? "on" : "off",
VTY_NEWLINE);
- if (p->notify.code == BGP_NOTIFY_OPEN_ERR
- && p->notify.subcode == BGP_NOTIFY_OPEN_UNSUP_CAPBL)
+ if (p->notify->code == BGP_NOTIFY_OPEN_ERR
+ && p->notify->subcode == BGP_NOTIFY_OPEN_UNSUP_CAPBL)
bgp_capability_vty_out (vty, p);
vty_out (vty, "%s", VTY_NEWLINE);
diff --git a/lib/memtypes.c b/lib/memtypes.c
index 96dd8f4a..f8f541de 100644
--- a/lib/memtypes.c
+++ b/lib/memtypes.c
@@ -174,6 +174,7 @@ struct memory_list memory_list_bgp[] =
{ MTYPE_BGP_DAMP_ARRAY, "BGP Dampening array" },
{ MTYPE_BGP_REGEXP, "BGP regexp" },
{ MTYPE_BGP_AGGREGATE, "BGP aggregate" },
+ { MTYPE_BGP_OPEN_STATE, "BGP Open State" },
{ -1, NULL }
};
diff --git a/lib/mqueue.h b/lib/mqueue.h
index b1332e68..a4f5d91d 100644
--- a/lib/mqueue.h
+++ b/lib/mqueue.h
@@ -22,6 +22,8 @@
#ifndef _ZEBRA_MQUEUE_H
#define _ZEBRA_MQUEUE_H
+#include <stddef.h>
+
#include "qpthreads.h"
#include "qtime.h"
diff --git a/lib/plist.h b/lib/plist.h
index 97dab78e..0d9e3ecb 100644
--- a/lib/plist.h
+++ b/lib/plist.h
@@ -26,6 +26,7 @@
#include "prefix.h"
#include "symtab.h"
#include "vector.h"
+#include "vty.h"
#define AFI_ORF_PREFIX 65535