summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_notification.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_notification.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_notification.c')
-rw-r--r--bgpd/bgp_notification.c102
1 files changed, 85 insertions, 17 deletions
diff --git a/bgpd/bgp_notification.c b/bgpd/bgp_notification.c
index 6676b346..2dc6952e 100644
--- a/bgpd/bgp_notification.c
+++ b/bgpd/bgp_notification.c
@@ -22,11 +22,13 @@
*/
#include <string.h>
+#include <netinet/in.h>
#include "lib/zassert.h"
#include "lib/memory.h"
#include "bgpd/bgp_notification.h"
+#include "bgpd/bgp_open_state.h"
/*==============================================================================
* A bgp_notify structure encapsulates the contents of a BGP NOTIFICATION
@@ -41,9 +43,9 @@
* Rounds up to multiple of 32, such that is always at least 16 bytes available.
*/
static inline bgp_size_t
-bgp_notify_size(bgp_size_t length)
+bgp_notify_size(bgp_size_t size)
{
- return sizeof(struct bgp_notify) + (((length + 32 + 16 - 1) / 32) * 32) ;
+ return (size == 0) ? 0 : ((size + 32 + 16 - 1) / 32) * 32 ;
} ;
/*==============================================================================
@@ -60,15 +62,19 @@ bgp_notify_new(bgp_nom_code_t code, bgp_nom_subcode_t subcode,
bgp_size_t expect)
{
bgp_notify notification ;
- bgp_size_t size = bgp_notify_size(expect) ;
- notification = XCALLOC(MTYPE_BGP_NOTIFY, size) ;
+ notification = XCALLOC(MTYPE_BGP_NOTIFY, sizeof(struct bgp_notify)) ;
notification->code = code ;
notification->subcode = subcode ;
- notification->size = size ;
+ notification->size = bgp_notify_size(expect) ;
notification->length = 0 ;
+ if (notification->size != 0)
+ notification->data = XCALLOC(MTYPE_TMP, notification->size) ;
+ else
+ notification->data = NULL ;
+
return notification ;
} ;
@@ -81,7 +87,11 @@ extern void
bgp_notify_free(bgp_notify notification)
{
if (notification != NULL)
- XFREE(MTYPE_BGP_NOTIFY, notification) ;
+ {
+ if (notification->data != NULL)
+ XFREE(MTYPE_TMP, notification->data) ;
+ XFREE(MTYPE_BGP_NOTIFY, notification) ;
+ } ;
} ;
/*------------------------------------------------------------------------------
@@ -91,16 +101,25 @@ extern bgp_notify
bgp_notify_dup(bgp_notify notification)
{
bgp_notify duplicate ;
- bgp_size_t size ;
if (notification == NULL)
return NULL ;
- size = bgp_notify_size(notification->length) ;
- duplicate = XMALLOC(MTYPE_BGP_NOTIFY, size) ;
+ duplicate = XMALLOC(MTYPE_BGP_NOTIFY, sizeof(struct bgp_notify)) ;
+ *duplicate = *notification ;
- memcpy((void*)duplicate, (void*)notification, size) ;
- duplicate->size = size ;
+ if (notification->length == 0)
+ {
+ duplicate->size = 0 ;
+ duplicate->data = NULL ;
+ }
+ else
+ {
+ bgp_size_t size = bgp_notify_size(duplicate->length) ;
+ duplicate->size = size ;
+ duplicate->data = XCALLOC(MTYPE_TMP, size) ;
+ memcpy(duplicate->data, notification->data, duplicate->length) ;
+ } ;
return duplicate ;
} ;
@@ -113,8 +132,8 @@ bgp_notify_dup(bgp_notify notification)
extern void
bgp_notify_unset(bgp_notify* p_notification)
{
- if (*p_notification != NULL)
- XFREE(MTYPE_BGP_NOTIFY, *p_notification) ; /* sets *p_notification NULL */
+ bgp_notify_free(*p_notification) ; /* free anything that's there */
+ *p_notification = NULL ;
} ;
/*------------------------------------------------------------------------------
@@ -159,22 +178,44 @@ bgp_notify_set_mov(bgp_notify* p_dst, bgp_notify* p_src)
} ;
/*==============================================================================
+ * Set new Code and Subcode and discard and data accumulated so far.
+ */
+extern bgp_notify
+bgp_notify_reset(bgp_notify notification, bgp_nom_code_t code,
+ bgp_nom_subcode_t subcode)
+{
+ if (notification == NULL)
+ return bgp_notify_new(code, subcode, 0) ;
+
+ notification->code = code ;
+ notification->subcode = subcode ;
+ notification->length = 0 ;
+
+ return notification ;
+} ;
+
+/*==============================================================================
* Append data to given notification
*
* Copes with zero length append.
*
* NB: returns possibly NEW ADDRESS of the notification.
*/
-extern bgp_notify
+extern void
bgp_notify_append_data(bgp_notify notification, const void* data,
bgp_size_t len)
{
bgp_size_t new_length = notification->length + len ;
- if ((sizeof(struct bgp_notify) + new_length) > notification->size)
+ if (new_length > notification->size)
{
bgp_size_t size = bgp_notify_size(new_length) ;
- notification = XREALLOC(MTYPE_BGP_NOTIFY, notification, size) ;
+
+ if (notification->size == 0)
+ notification->data = XCALLOC(MTYPE_TMP, size) ;
+ else
+ notification->data = XREALLOC(MTYPE_TMP, notification->data, size) ;
+
memset((char*)notification + notification->size, 0,
size - notification->size) ;
notification->size = size ;
@@ -184,6 +225,33 @@ bgp_notify_append_data(bgp_notify notification, const void* data,
memcpy((char*)(notification->data) + notification->length, data, len) ;
notification->length = new_length ;
+} ;
- return notification ;
+/*------------------------------------------------------------------------------
+ * Append one byte
+ */
+extern void
+bgp_notify_append_b(bgp_notify notification, uint8_t b)
+{
+ bgp_notify_append_data(notification, &b, 1) ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Append one word (uint16_t), in network byte order
+ */
+extern void
+bgp_notify_append_w(bgp_notify notification, uint16_t w)
+{
+ w = htons(w) ;
+ bgp_notify_append_data(notification, &w, 2) ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Append one long (uint32_t), in network byte order
+ */
+extern void
+bgp_notify_append_l(bgp_notify notification, uint32_t l)
+{
+ l = htonl(l) ;
+ bgp_notify_append_data(notification, &l, 4) ;
} ;