Author: adrian.chadd
Date: Sun Feb 22 13:21:14 2009
New Revision: 13822
Modified:
playpen/LUSCA_HEAD_bgp/app/bgptest/bgptest.c
playpen/LUSCA_HEAD_bgp/libsqbgp/bgp_core.c
playpen/LUSCA_HEAD_bgp/libsqbgp/bgp_core.h
Log:
Flesh out the bgp core code to handle some of the state and message
processing.
Adapt the test code to call bgp_read() instead of doing its own buffer
handling, etc.
Its obviously incomplete and the keepalive processing needs to be
implemented; this all requires async network IO to be implemented
(soon!)
The next task is to start tracking prefixes and AS paths, hm.
Modified: playpen/LUSCA_HEAD_bgp/app/bgptest/bgptest.c
==============================================================================
--- playpen/LUSCA_HEAD_bgp/app/bgptest/bgptest.c (original)
+++ playpen/LUSCA_HEAD_bgp/app/bgptest/bgptest.c Sun Feb 22 13:21:14 2009
@@ -51,9 +51,7 @@
int fd, r;
struct sockaddr_in sa;
struct in_addr bgp_id;
- char buf[4096];
- int bufofs = 0;
- int i, len;
+ bgp_instance_t bi;
#if 0
if (argc < 4) {
@@ -67,53 +65,34 @@
_db_init("ALL,1 85,99");
_db_set_stderr_debug(99);
+
- fd = socket(AF_INET, SOCK_STREAM, 0);
- assert(fd != -1);
- /* connect to bgp thing */
bzero(&sa, sizeof(sa));
inet_aton("216.12.163.51", &sa.sin_addr);
inet_aton("216.12.163.53", &bgp_id);
sa.sin_port = htons(179);
sa.sin_len = sizeof(struct sockaddr_in);
sa.sin_family = AF_INET;
- r = connect(fd, (struct sockaddr *) &sa, sizeof(sa));
- assert(r > -1);
-
- /* Now, loop over and read messages */
- /* We'll eventually have to uhm, speak BGP.. */
- r = bgp_send_hello(fd, 65535, 120, bgp_id);
-
- printf("ready to read stuff\n");
+
+ bgp_create_instance(&bi);
+ bgp_set_lcl(&bi, bgp_id, 65535, 120);
+ bgp_set_rem(&bi, 38620);
+
+ /* connect to bgp thing */
while (1) {
- bzero(buf + bufofs, sizeof(buf) - bufofs);
- /* XXX should check there's space in the buffer first! */
- debug(85, 1) ("main: space in buf is %d bytes\n", (int)
sizeof(buf) - bufofs);
- len = read(fd, buf + bufofs, sizeof(buf) - bufofs);
- assert(len > 0);
- bufofs += len;
- printf("read: %d bytes; bufsize is now %d\n", len, bufofs);
- i = 0;
-
- /* loop over; try to handle partial messages */
- while (i < len) {
- debug(85, 1) ("looping..\n");
- /* Is there enough data here? */
- if (! bgp_msg_complete(buf + i, bufofs - i)) {
- debug(85, 1) ("main: incomplete packet\n");
- break;
- }
- r = bgp_decode_message(fd, buf + i, bufofs - i);
- assert(r > 0);
- i += r;
- debug(85, 1) ("main: pkt was %d bytes, i is
now %d\n", r, i);
- }
- /* "consume" the rest of the buffer */
- memmove(buf, buf + i, sizeof(buf) - i);
- bufofs -= i;
- debug(85, 1) ("consumed %d bytes; bufsize is now %d\n", i,
bufofs);
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ assert(fd != -1);
+ r = connect(fd, (struct sockaddr *) &sa, sizeof(sa));
+ r = bgp_send_hello(fd, 65535, 120, bgp_id);
+ if (r > 0)
+ while (r > 0)
+ r = bgp_read(&bi, fd);
+ bgp_close(&bi);
+ close(fd);
+ debug(85, 1) ("sleeping for 15 seconds..\n");
+ sleep(15);
}
#if 0
Modified: playpen/LUSCA_HEAD_bgp/libsqbgp/bgp_core.c
==============================================================================
--- playpen/LUSCA_HEAD_bgp/libsqbgp/bgp_core.c (original)
+++ playpen/LUSCA_HEAD_bgp/libsqbgp/bgp_core.c Sun Feb 22 13:21:14 2009
@@ -21,65 +21,100 @@
#include "bgp_core.h"
-#if 0
+void
+bgp_create_instance(bgp_instance_t *bi)
+{
+ bzero(bi, sizeof(*bi));
+ bi->state = BGP_IDLE;
+}
+
+void
+bgp_destroy_instance(bgp_instance_t *bi)
+{
+ /* Free RIB entries and RIB tree */
+ /* Ensure AS path entries are gone, complain for leftovers! */
+ /* Free AS path hash */
+ bzero(bi, sizeof(*bi));
+}
+
+void
+bgp_set_lcl(bgp_instance_t *bi, struct in_addr bgp_id, u_short asn,
u_short hold_time)
+{
+ memcpy(&bi->lcl.bgp_id, &bgp_id, sizeof(bgp_id));
+ bi->lcl.asn = asn;
+ bi->lcl.hold_time = hold_time;
+}
+
+void
+bgp_set_rem(bgp_instance_t *bi, u_short asn)
+{
+ bi->rem.asn = asn;
+ bi->rem.hold_time = -1;
+}
+
+/*
+ * Move to ACTIVE phase. In this phase, BGP is trying to actively
+ * establish a connection.
+ *
+ * This code doesn't do the networking stuff - instead, the owner of this
BGP
+ * connection state will do the networking stuff and call bgp_close() or
+ * bgp_open().
+ */
+void
+bgp_active(bgp_instance_t *bi)
+{
+
+}
+
+/*
+ * Read some data from the given file descriptor (using the read() syscall
for now!)
+ * and update the BGP state machine. The caller should check for retval <=
0 and reset
+ * the socket and FSM as appropriate.
+ */
int
-main(int argc, const char *argv[])
+bgp_read(bgp_instance_t *bi, int fd)
{
- int fd, r;
- struct sockaddr_in sa;
- struct in_addr bgp_id;
- char buf[4096];
- int bufofs = 0;
- int i, len;
-
- fd = socket(AF_INET, SOCK_STREAM, 0);
- assert(fd != -1);
-
- /* connect to bgp thing */
- bzero(&sa, sizeof(sa));
- inet_aton("216.12.163.51", &sa.sin_addr);
- inet_aton("216.12.163.53", &bgp_id);
- sa.sin_port = htons(179);
- sa.sin_len = sizeof(struct sockaddr_in);
- sa.sin_family = AF_INET;
- r = connect(fd, (struct sockaddr *) &sa, sizeof(sa));
- assert(r > -1);
-
- /* Now, loop over and read messages */
- /* We'll eventually have to uhm, speak BGP.. */
- r = bgp_send_hello(fd, 65535, 120, bgp_id);
-
- printf("ready to read stuff\n");
-
- while (1) {
- bzero(buf + bufofs, sizeof(buf) - bufofs);
- /* XXX should check there's space in the buffer first! */
- printf("main: space in buf is %d bytes\n", (int) sizeof(buf) -
bufofs);
- len = read(fd, buf + bufofs, sizeof(buf) - bufofs);
- assert(len > 0);
- bufofs += len;
- printf("read: %d bytes; bufsize is now %d\n", len, bufofs);
- i = 0;
-
- /* loop over; try to handle partial messages */
- while (i < len) {
- printf("looping..\n");
- /* Is there enough data here? */
- if (! bgp_msg_complete(buf + i, bufofs - i)) {
- printf("main: incomplete packet\n");
- break;
- }
- r = bgp_decode_message(fd, buf + i, bufofs - i);
- assert(r > 0);
- i += r;
- printf("main: pkt was %d bytes, i is now %d\n", r, i);
+ int len, i, r;
+
+ /* Append data to buffer */
+ bzero(bi->recv.buf + bi->recv.bufofs, BGP_RECV_BUF - bi->recv.bufofs);
+ debug(85, 1) ("main: space in buf is %d bytes\n", (int) BGP_RECV_BUF -
bi->recv.bufofs);
+
+ len = read(fd, bi->recv.buf + bi->recv.bufofs, BGP_RECV_BUF -
bi->recv.bufofs);
+ if (len <= 0)
+ return len;
+
+ bi->recv.bufofs += len;
+ debug(85, 2) ("read: %d bytes; bufsize is now %d\n", len,
bi->recv.bufofs);
+ i = 0;
+ /* loop over; try to handle partial messages */
+ while (i < len) {
+ debug(85, 1) ("looping..\n");
+ /* Is there enough data here? */
+ if (! bgp_msg_complete(bi->recv.buf + i, bi->recv.bufofs - i)) {
+ debug(85, 1) ("main: incomplete packet\n");
+ break;
}
- /* "consume" the rest of the buffer */
- memmove(buf, buf + i, sizeof(buf) - i);
- bufofs -= i;
- printf("consumed %d bytes; bufsize is now %d\n", i, bufofs);
+ r = bgp_decode_message(fd, bi->recv.buf + i, bi->recv.bufofs -
i);
+ assert(r > 0);
+ i += r;
+ debug(85, 1) ("main: pkt was %d bytes, i is now %d\n", r, i);
}
+ /* "consume" the rest of the buffer */
+ memmove(bi->recv.buf, bi->recv.buf + i, BGP_RECV_BUF - i);
+ bi->recv.bufofs -= i;
+ debug(85, 1) ("consumed %d bytes; bufsize is now %d\n", i,
bi->recv.bufofs);
+ return len;
+}
- exit(0);
+/*
+ * Move connection to IDLE state. Destroy any AS path / prefix entries.
+ */
+void
+bgp_close(bgp_instance_t *bi)
+{
+ bi->state = BGP_IDLE;
+ /* free prefixes */
+ /* ensure no as path entries exist in the hash! */
}
-#endif
+
Modified: playpen/LUSCA_HEAD_bgp/libsqbgp/bgp_core.h
==============================================================================
--- playpen/LUSCA_HEAD_bgp/libsqbgp/bgp_core.h (original)
+++ playpen/LUSCA_HEAD_bgp/libsqbgp/bgp_core.h Sun Feb 22 13:21:14 2009
@@ -3,10 +3,22 @@
#define BGP_RECV_BUF 4096
+typedef enum {
+ BGP_NONE = 0,
+ BGP_IDLE,
+ BGP_CONNECT,
+ BGP_ACTIVE,
+ BGP_OPENSENT,
+ BGP_OPENCONFIRM,
+ BGP_ESTABLISHED,
+} bgp_fsm_t;
+
struct _bgp_instance {
+
+ bgp_fsm_t state;
struct {
char buf[BGP_RECV_BUF];
- int offset;
+ int bufofs;
} recv;
u_short hold_time; /* Calculated from local and remote
hold times */
@@ -14,8 +26,13 @@
struct {
u_short asn;
u_short hold_time;
- sqaddr_t addr;
- } lcl, rem;
+ struct in_addr bgp_id;
+ } lcl;
+
+ struct {
+ u_short asn;
+ u_short hold_time;
+ } rem;
/* The AS path table */
@@ -27,5 +44,11 @@
void bgp_create_instance(bgp_instance_t *bi);
void bgp_destroy_instance(bgp_instance_t *bi);
+void bgp_set_lcl(bgp_instance_t *bi, struct in_addr bgp_id, u_short asn,
u_short hold_time);
+void bgp_set_rem(bgp_instance_t *bi, u_short asn);
+
+void bgp_active(bgp_instance_t *bi);
+int bgp_read(bgp_instance_t *bi, int fd);
+void bgp_close(bgp_instance_t *bi);
#endif
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"lusca-commit" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/lusca-commit?hl=en
-~----------~----~----~----~------~----~------~--~---