summaryrefslogtreecommitdiffstats
path: root/bgpd
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd')
-rw-r--r--bgpd/bgp_common.h13
-rw-r--r--bgpd/bgp_debug.c9
-rw-r--r--bgpd/bgp_debug.h2
-rw-r--r--bgpd/bgp_fsm.h8
-rw-r--r--bgpd/bgp_main.c28
-rw-r--r--bgpd/bgp_mplsvpn.c2
-rw-r--r--bgpd/bgp_nexthop.c2
-rw-r--r--bgpd/bgp_packet.c90
-rw-r--r--bgpd/bgp_peer.c34
-rw-r--r--bgpd/bgp_peer.h12
-rw-r--r--bgpd/bgp_route.c10
-rw-r--r--bgpd/bgp_session.c79
-rw-r--r--bgpd/bgp_session.h14
-rw-r--r--bgpd/bgp_snmp.c1
-rw-r--r--bgpd/bgp_vty.c14
-rw-r--r--bgpd/bgpd.c95
-rw-r--r--bgpd/bgpd.h2
17 files changed, 297 insertions, 118 deletions
diff --git a/bgpd/bgp_common.h b/bgpd/bgp_common.h
index 703b2ab2..a1821b17 100644
--- a/bgpd/bgp_common.h
+++ b/bgpd/bgp_common.h
@@ -132,6 +132,19 @@ enum bgp_session_events
bgp_session_eDiscard, /* discarded by sibling */
} ;
+typedef enum bgp_peer_states bgp_peer_state_t ;
+enum bgp_peer_states
+{
+ bgp_peer_min_state = 0,
+
+ bgp_peer_sIdle = 1, /* session not yet established */
+ bgp_peer_sEstablished = 2, /* session established */
+ bgp_peer_sClearing = 3, /* Clearing routes */
+ bgp_peer_sDeleted = 4, /* Deleted, linger until lock count == 0 */
+
+ bgp_peer_max_state = 4
+} ;
+
/*==============================================================================
* Other common types and ....
*/
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index 78ac799d..3e3042a7 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -77,6 +77,15 @@ const struct message bgp_status_msg[] =
};
const int bgp_status_msg_max = bgp_fsm_last_state + 1 ;
+const struct message bgp_peer_status_msg[] =
+{
+ { bgp_peer_sIdle, "Idle" },
+ { bgp_peer_sEstablished, "Established" },
+ { bgp_peer_sClearing, "Clearing" },
+ { bgp_peer_sDeleted, "Deleted" },
+};
+const int bgp_peer_status_msg_max = bgp_peer_max_state + 1 ;
+
/* BGP message type string. */
const char *bgp_type_str[] =
{
diff --git a/bgpd/bgp_debug.h b/bgpd/bgp_debug.h
index ce8547b0..9a7d7d80 100644
--- a/bgpd/bgp_debug.h
+++ b/bgpd/bgp_debug.h
@@ -125,4 +125,6 @@ extern void bgp_notify_print (struct peer *, struct bgp_notify *, const char *);
extern const struct message bgp_status_msg[];
extern const int bgp_status_msg_max;
+extern const struct message bgp_peer_status_msg[];
+extern const int bgp_peer_status_msg_max;
#endif /* _QUAGGA_BGP_DEBUG_H */
diff --git a/bgpd/bgp_fsm.h b/bgpd/bgp_fsm.h
index 49a4bef9..57224d33 100644
--- a/bgpd/bgp_fsm.h
+++ b/bgpd/bgp_fsm.h
@@ -72,7 +72,7 @@ bgp_fsm_notification_exception(bgp_connection connection,
/* Macro for BGP read, write and timer thread. */
#define BGP_READ_ON(T,F,V) \
do { \
- if (!(T) && (peer->status != Deleted)) \
+ if (!(T) && (peer->state != bgp_peer_sDeleted)) \
THREAD_READ_ON(master,T,F,peer,V); \
} while (0)
@@ -84,7 +84,7 @@ bgp_fsm_notification_exception(bgp_connection connection,
#define BGP_WRITE_ON(T,F,V) \
do { \
- if (!(T) && (peer->status != Deleted)) \
+ if (!(T) && (peer->state != bgp_peer_sDeleted)) \
THREAD_WRITE_ON(master,(T),(F),peer,(V)); \
} while (0)
@@ -96,7 +96,7 @@ bgp_fsm_notification_exception(bgp_connection connection,
#define BGP_TIMER_ON(T,F,V) \
do { \
- if (!(T) && (peer->status != Deleted)) \
+ if (!(T) && (peer->state != bgp_peer_sDeleted)) \
THREAD_TIMER_ON(master,(T),(F),peer,(V)); \
} while (0)
@@ -108,7 +108,7 @@ bgp_fsm_notification_exception(bgp_connection connection,
#define BGP_EVENT_ADD(P,E) \
do { \
- if ((P)->status != Deleted) \
+ if ((P)->state != bgp_peer_sDeleted) \
thread_add_event (master, bgp_event, (P), (E)); \
} while (0)
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 2916c70f..e98d841e 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -216,25 +216,9 @@ sigint (void)
#endif
zlog_notice ("Terminating on signal");
- if (!retain_mode)
- {
- /* tell the routing engine to send notifies to peers and wait
- * for all sessions to be disabled */
- sigterm_enqueue();
- }
- else
- {
- /* ask remaining pthreads to die */
- if (qpthreads_enabled && routing_nexus != NULL)
- qpn_terminate(routing_nexus);
-
- if (qpthreads_enabled && bgp_nexus != NULL)
- qpn_terminate(bgp_nexus);
-
- if (cli_nexus != NULL)
- qpn_terminate(cli_nexus);
- }
-
+ /* tell the routing engine to send notifies to peers and wait
+ * for all sessions to be disabled */
+ sigterm_enqueue();
}
/* SIGUSR1 handler. */
@@ -648,7 +632,7 @@ sighup_action(mqueue_block mqb, mqb_flag_t flag)
{
if (flag == mqb_action)
{
- bgp_terminate (0); /* send notfies */
+ bgp_terminate (0, 0); /* send notfies */
bgp_reset ();
}
@@ -669,9 +653,9 @@ sigterm_action(mqueue_block mqb, mqb_flag_t flag)
{
if (flag == mqb_action)
{
- /* send notify to all peers, wiat for alll sessions to be disables
+ /* send notify to all peers, wait for all sessions to be disables
* then terminate all pthreads */
- bgp_terminate(1);
+ bgp_terminate(1, retain_mode);
}
mqb_free(mqb);
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 72ad089e..206844f9 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -92,7 +92,7 @@ bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr,
u_char *tagpnt;
/* Check peer status. */
- if (peer->status != Established)
+ if (peer->state != bgp_peer_sEstablished)
return 0;
/* Make prefix_rd */
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index b5b36a79..7a096faa 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -434,7 +434,7 @@ bgp_scan (afi_t afi, safi_t safi)
/* Maximum prefix check */
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{
- if (peer->status != Established)
+ if (peer->state != bgp_peer_sEstablished)
continue;
if (peer->afc[afi][SAFI_UNICAST])
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 8b42de78..4f1b3f04 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -29,7 +29,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "memory.h"
#include "sockunion.h" /* for inet_ntop () */
#include "linklist.h"
-#include "plist.h"
#include "bgpd/bgpd.h"
@@ -50,6 +49,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_advertise.h"
#include "bgpd/bgp_vty.h"
+#include "bgpd/bgp_route_refresh.h"
int stream_put_prefix (struct stream *, struct prefix *);
@@ -860,14 +860,82 @@ bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
/* Send route refresh message to the peer. */
-/* TODO: wire up to bgp_route_refresh structure and send a route_refresh
- * message, rather than a raw "update".
- */
-
void
bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
u_char orf_type, u_char when_to_refresh, int remove)
{
+ bgp_route_refresh rr = NULL;
+ struct bgp_filter *filter = NULL;
+ bgp_session session = peer->session;
+ struct orf_prefix *orfpe = NULL;
+ struct prefix_list *plist = NULL;
+ struct orf_prefix orfp;
+ vector_index i;
+ int orf_refresh = 0;
+ enum prefix_list_type pe_type;
+ bgp_form_t form;
+
+ if (DISABLE_BGP_ANNOUNCE)
+ return;
+
+ filter = &peer->filter[afi][safi];
+
+ /* Adjust safi code. */
+ if (safi == SAFI_MPLS_VPN)
+ safi = BGP_SAFI_VPNV4;
+
+ /* Make BGP update packet. */
+ form = (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
+ ? bgp_form_rfc
+ : bgp_form_pre;
+
+ rr = bgp_route_refresh_new(afi, safi, 1);
+ rr->defer = (when_to_refresh == REFRESH_DEFER);
+
+ if (orf_type == ORF_TYPE_PREFIX
+ || orf_type == ORF_TYPE_PREFIX_OLD)
+ if (remove || filter->plist[FILTER_IN].ref)
+ {
+ orf_refresh = 1;
+ if (remove)
+ {
+ UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
+ bgp_orf_add_remove_all(rr, orf_type, form);
+ if (BGP_DEBUG (normal, NORMAL))
+ zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
+ peer->host, orf_type,
+ (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
+ afi, safi);
+ }
+ else
+ {
+ SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
+ plist = prefix_list_ref_plist(filter->plist[FILTER_IN].ref) ;
+ for (i = 0; prefix_bgp_orf_get(plist, i, &orfp, &pe_type); ++i)
+ {
+ orfpe = bgp_orf_add(rr, orf_type, form, 0, pe_type == PREFIX_DENY);
+ *orfpe = orfp;
+ }
+ if (BGP_DEBUG (normal, NORMAL))
+ zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
+ peer->host, orf_type,
+ (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
+ afi, safi);
+ }
+ }
+
+ if (BGP_DEBUG (normal, NORMAL))
+ {
+ if (! orf_refresh)
+ zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
+ peer->host, afi, safi);
+ }
+
+ bgp_session_route_refresh_send(session, rr);
+
+#if 0
+ /* old code */
+
struct stream *s;
struct stream *packet;
int length;
@@ -957,6 +1025,7 @@ bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
/* Add packet to the peer. */
bgp_packet_add (peer, packet);
bgp_write(peer);
+#endif
}
/* Send capability message to the peer. */
@@ -1450,10 +1519,10 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
char attrstr[BUFSIZ] = "";
/* Status must be Established. */
- if (peer->status != Established)
+ if (peer->state != bgp_peer_sEstablished)
{
zlog_err ("%s [FSM] Update packet received under status %s",
- peer->host, LOOKUP (bgp_status_msg, peer->status));
+ peer->host, LOOKUP (bgp_peer_status_msg, peer->state));
bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
return -1;
}
@@ -1749,7 +1818,7 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
/* If peering is stopped due to some reason, do not generate BGP
event. */
- if (peer->status != Established)
+ if (peer->state != bgp_peer_sEstablished)
return 0;
/* Increment packet counter. */
@@ -2174,10 +2243,11 @@ bgp_capability_receive (struct peer *peer, bgp_size_t size)
}
/* Status must be Established. */
- if (peer->status != Established)
+ if (peer->state != bgp_peer_sEstablished)
{
plog_err (peer->log,
- "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
+ "%s [Error] Dynamic capability packet received under status %s",
+ peer->host, LOOKUP (bgp_status_msg, peer->state));
bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
return -1;
}
diff --git a/bgpd/bgp_peer.c b/bgpd/bgp_peer.c
index aa1c8841..3dec683a 100644
--- a/bgpd/bgp_peer.c
+++ b/bgpd/bgp_peer.c
@@ -320,14 +320,14 @@ bgp_peer_stop (struct peer *peer)
char orf_name[BUFSIZ];
/* Can't do this in Clearing; events are used for state transitions */
- if (peer->status != Clearing)
+ if (peer->state != bgp_peer_sClearing)
{
/* Delete all existing events of the peer */
BGP_EVENT_FLUSH (peer);
}
/* Increment Dropped count. */
- if (peer->status == Established)
+ if (peer->state == bgp_peer_sEstablished)
{
peer->dropped++;
@@ -458,9 +458,9 @@ bgp_peer_timers_stop(bgp_peer peer)
static void
bgp_timer_set (struct peer *peer)
{
- switch (peer->status)
+ switch (peer->state)
{
- case Idle:
+ case bgp_peer_sIdle:
/* First entry point of peer's finite state machine. In Idle
status start timer is on unless peer is shutdown or peer is
inactive. All other timer must be turned off */
@@ -497,18 +497,20 @@ bgp_timer_set (struct peer *peer)
break;
#endif
- case Established:
+ case bgp_peer_sEstablished:
/* In Established status start and connect timer is turned
off. */
BGP_TIMER_OFF (peer->t_asorig);
break;
- case Deleted:
+ case bgp_peer_sDeleted:
BGP_TIMER_OFF (peer->t_gr_restart);
BGP_TIMER_OFF (peer->t_gr_stale);
BGP_TIMER_OFF (peer->t_pmax_restart);
- case Clearing:
+ case bgp_peer_sClearing:
BGP_TIMER_OFF (peer->t_asorig);
BGP_TIMER_OFF (peer->t_routeadv);
+ default:
+ assert(0);
}
}
@@ -661,8 +663,8 @@ peer_new (struct bgp *bgp)
peer->v_start = BGP_INIT_START_TIMER;
peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
peer->v_asorig = BGP_DEFAULT_ASORIGINATE;
- peer->status = Idle;
- peer->ostatus = Idle;
+ peer->state = bgp_peer_sIdle;
+ peer->ostate = bgp_peer_sIdle;
peer->weight = 0;
peer->password = NULL;
peer->bgp = bgp;
@@ -772,7 +774,7 @@ peer_delete (struct peer *peer)
struct bgp_filter *filter;
struct listnode *pn;
- assert (peer->status != Deleted);
+ assert (peer->state != bgp_peer_sDeleted);
bgp = peer->bgp;
@@ -895,7 +897,7 @@ peer_delete (struct peer *peer)
void
peer_free (struct peer *peer)
{
- assert (peer->status == Deleted);
+ assert (peer->state == bgp_peer_sDeleted);
bgp_unlock(peer->bgp);
@@ -1006,7 +1008,7 @@ bgp_peer_disable(bgp_peer peer, bgp_notify notification)
void
peer_change_status (bgp_peer peer, int status)
{
- bgp_dump_state (peer, peer->status, status);
+ bgp_dump_state (peer, peer->state, status);
/* Transition into Clearing or Deleted must /always/ clear all routes..
* (and must do so before actually changing into Deleted..
@@ -1015,12 +1017,12 @@ peer_change_status (bgp_peer peer, int status)
bgp_clear_route_all (peer);
/* Preserve old status and change into new status. */
- peer->ostatus = peer->status;
- peer->status = status;
+ peer->ostate = peer->state;
+ peer->state = status;
if (BGP_DEBUG (normal, NORMAL))
zlog_debug ("%s went from %s to %s",
peer->host,
- LOOKUP (bgp_status_msg, peer->ostatus),
- LOOKUP (bgp_status_msg, peer->status));
+ LOOKUP (bgp_peer_status_msg, peer->ostate),
+ LOOKUP (bgp_peer_status_msg, peer->state));
}
diff --git a/bgpd/bgp_peer.h b/bgpd/bgp_peer.h
index b16543d4..7d0bc76b 100644
--- a/bgpd/bgp_peer.h
+++ b/bgpd/bgp_peer.h
@@ -147,8 +147,8 @@ struct peer
struct stream *work;
/* Status of the peer. */
- int status; /* Current status */
- int ostatus; /* Old status */
+ bgp_peer_state_t state; /* current state */
+ bgp_peer_state_t ostate; /* old state */
/* Peer index, used for dumping TABLE_DUMP_V2 format */
uint16_t table_dump_index;
@@ -402,7 +402,7 @@ struct peer
/* Macro for BGP read, write and timer thread. */
#define BGP_READ_ON(T,F,V) \
do { \
- if (!(T) && (peer->status != Deleted)) \
+ if (!(T) && (peer->state != bgp_peer_sDeleted)) \
THREAD_READ_ON(master,T,F,peer,V); \
} while (0)
@@ -414,7 +414,7 @@ struct peer
#define BGP_WRITE_ON(T,F,V) \
do { \
- if (!(T) && (peer->status != Deleted)) \
+ if (!(T) && (peer->state != bgp_peer_sDeleted)) \
THREAD_WRITE_ON(master,(T),(F),peer,(V)); \
} while (0)
@@ -426,7 +426,7 @@ struct peer
#define BGP_TIMER_ON(T,F,V) \
do { \
- if (!(T) && (peer->status != Deleted)) \
+ if (!(T) && (peer->state != bgp_peer_sDeleted)) \
THREAD_TIMER_ON(master,(T),(F),peer,(V)); \
} while (0)
@@ -438,7 +438,7 @@ struct peer
#define BGP_EVENT_ADD(P,E) \
do { \
- if ((P)->status != Deleted) \
+ if ((P)->state != bgp_peer_sDeleted) \
thread_add_event (master, bgp_event, (P), (E)); \
} while (0)
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 46a8cb12..86432b18 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1411,7 +1411,7 @@ bgp_process_announce_selected (struct peer *peer, struct bgp_info *selected,
p = &rn->p;
/* Announce route to Established peer. */
- if (peer->status != Established)
+ if (peer->state == bgp_peer_sEstablished)
return 0;
/* Address family configuration check. */
@@ -2557,7 +2557,7 @@ bgp_announce_route (struct peer *peer, afi_t afi, safi_t safi)
struct bgp_node *rn;
struct bgp_table *table;
- if (peer->status != Established)
+ if (peer->state != bgp_peer_sEstablished)
return;
if (! peer->afc_nego[afi][safi])
@@ -2659,7 +2659,7 @@ bgp_soft_reconfig_in (struct peer *peer, afi_t afi, safi_t safi)
struct bgp_node *rn;
struct bgp_table *table;
- if (peer->status != Established)
+ if (peer->state != bgp_peer_sEstablished)
return;
if (safi != SAFI_MPLS_VPN)
@@ -2726,7 +2726,7 @@ bgp_clear_node_complete (struct work_queue *wq)
/* Flush the event queue and ensure the peer is shut down */
bgp_peer_stop(peer);
BGP_EVENT_FLUSH (peer);
- if (peer->status == Clearing)
+ if (peer->state == bgp_peer_sClearing)
peer_change_status (peer, Idle);
peer_unlock (peer); /* bgp_clear_route */
@@ -3024,7 +3024,7 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
int ret;
/* Check peer status. */
- if (peer->status != Established)
+ if (peer->state != bgp_peer_sEstablished)
return 0;
pnt = packet->nlri;
diff --git a/bgpd/bgp_session.c b/bgpd/bgp_session.c
index ac737faf..406e5a59 100644
--- a/bgpd/bgp_session.c
+++ b/bgpd/bgp_session.c
@@ -47,6 +47,8 @@ static void bgp_session_do_route_refresh_send(mqueue_block mqb,
static void bgp_session_do_disable(mqueue_block mqb, mqb_flag_t flag) ;
static void bgp_session_XON(bgp_session session);
static void bgp_session_do_XON(mqueue_block mqb, mqb_flag_t flag);
+static void bgp_session_do_set_ttl(mqueue_block mqb, mqb_flag_t flag);
+static void bgp_session_do_route_refresh_recv(mqueue_block mqb, mqb_flag_t flag);
/*==============================================================================
* BGP Session.
@@ -323,7 +325,7 @@ bgp_session_do_enable(mqueue_block mqb, mqb_flag_t flag)
* Passes any bgp_notify to the BGP Engine, which will dispose of it in due
* course.
*
- * If no bgp_notify provided, will send Cease/Administrative Shutdown (2).
+ * If no bgp_notify provided, no notify will be sent.
*
* The BGP Engine will stop the session -- unless it is already stopped due to
* some event in the BGP Engine. In any case, the BGP Engine will respond with
@@ -790,6 +792,47 @@ bgp_session_do_update_recv(mqueue_block mqb, mqb_flag_t flag)
}
/*==============================================================================
+ * BGP Engine: received Route Refresh to peer
+ *
+ * The Peering Engine takes care of discarding the bgp_route_refresh once it's been
+ * dealt with.
+ */
+extern void
+bgp_session_route_refresh_recv(bgp_session session, bgp_route_refresh rr)
+{
+ struct bgp_session_route_refresh_args* args ;
+ mqueue_block mqb ;
+
+ mqb = mqb_init_new(NULL, bgp_session_do_route_refresh_recv, session) ;
+
+ args = mqb_get_args(mqb) ;
+ args->rr = rr ;
+ args->pending = NULL ;
+
+ bgp_to_peering_engine(mqb) ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Peering Engine: receive given BGP route refresh message -- mqb action function.
+ *
+ */
+static void
+bgp_session_do_route_refresh_recv(mqueue_block mqb, mqb_flag_t flag)
+{
+ struct bgp_session_route_refresh_args* args = mqb_get_args(mqb) ;
+ bgp_session session = mqb_get_arg0(mqb) ;
+
+ if (flag == mqb_action)
+ {
+
+ /* TODO pricess route_refresh */
+ } ;
+
+ bgp_route_refresh_free(args->rr) ;
+ mqb_free(mqb) ;
+} ;
+
+/*==============================================================================
* BGP Engine: send XON message to Peering Engine
*
* Can be sent more packets now
@@ -823,6 +866,40 @@ bgp_session_do_XON(mqueue_block mqb, mqb_flag_t flag)
mqb_free(mqb) ;
}
+/*==============================================================================
+ * Routing Engine: send ttl message to Peering Engine
+ *
+ */
+void
+bgp_session_set_ttl(bgp_session session, int ttl)
+{
+ mqueue_block mqb ;
+ struct bgp_session_ttl_args *args;
+
+ mqb = mqb_init_new(NULL, bgp_session_do_set_ttl, session) ;
+
+ args = mqb_get_args(mqb) ;
+ args->ttl = ttl ;
+
+ bgp_to_bgp_engine(mqb) ;
+}
+
+/*------------------------------------------------------------------------------
+ * BGP Engine: process incoming ttl message -- mqb action function.
+ */
+static void
+bgp_session_do_set_ttl(mqueue_block mqb, mqb_flag_t flag)
+{
+
+ if (flag == mqb_action)
+ {
+ bgp_session session = mqb_get_arg0(mqb);
+ struct bgp_session_ttl_args *args = mqb_get_args(mqb);
+ /* TODO ttl */
+ }
+
+ mqb_free(mqb) ;
+}
/*==============================================================================
* Session data access functions.
diff --git a/bgpd/bgp_session.h b/bgpd/bgp_session.h
index 82304916..52f22f49 100644
--- a/bgpd/bgp_session.h
+++ b/bgpd/bgp_session.h
@@ -258,10 +258,15 @@ struct bgp_session_XON_args /* to Routeing Engine */
/* no further arguments */
} ;
MQB_ARGS_SIZE_OK(bgp_session_XON_args) ;
+enum { BGP_XON_THRESHOLD = 7 } ;
+struct bgp_session_ttl_args /* to bgp Engine */
+{
+ int ttl ; /* time to live */
+} ;
+MQB_ARGS_SIZE_OK(bgp_session_ttl_args) ;
-enum { BGP_XON_THRESHOLD = 7 } ;
/*==============================================================================
* Session mutex lock/unlock
@@ -313,9 +318,15 @@ extern void
bgp_session_update_recv(bgp_session session, struct stream* buf,
bgp_size_t size) ;
+extern void
+bgp_session_route_refresh_recv(bgp_session session, bgp_route_refresh rr);
+
extern int
bgp_session_is_XON(bgp_peer peer);
+extern void
+bgp_session_set_ttl(bgp_session session, int ttl);
+
/*==============================================================================
* Session data access functions.
*
@@ -325,5 +336,4 @@ bgp_session_is_XON(bgp_peer peer);
extern int
bgp_session_is_active(bgp_session session) ;
-
#endif /* QUAGGA_BGP_SESSION_H */
diff --git a/bgpd/bgp_snmp.c b/bgpd/bgp_snmp.c
index 1e37f266..0b0ef83b 100644
--- a/bgpd/bgp_snmp.c
+++ b/bgpd/bgp_snmp.c
@@ -413,6 +413,7 @@ write_bgpPeerTable (int action, u_char *var_val,
if (! peer)
return SNMP_ERR_NOSUCHNAME;
+ bgp_session_get_statistics(peer);
printf ("val: %ld\n", intval);
switch (v->magic)
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index b94f4abd..05353bc8 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -6768,7 +6768,7 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi)
vty_out (vty, "%8s",
peer_uptime (peer->uptime, timebuf, BGP_UPTIME_LEN));
- if (peer->status == Established)
+ if (peer->state == bgp_peer_sEstablished)
{
vty_out (vty, " %8ld", peer->pcount[afi][safi]);
}
@@ -6779,7 +6779,7 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi)
else if (CHECK_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
vty_out (vty, " Idle (PfxCt)");
else
- vty_out (vty, " %-11s", LOOKUP(bgp_status_msg, peer->status));
+ vty_out (vty, " %-11s", LOOKUP(bgp_peer_status_msg, peer->state));
}
vty_out (vty, "%s", VTY_NEWLINE);
@@ -7301,8 +7301,8 @@ bgp_show_peer (struct vty *vty, struct peer *p)
/* Status. */
vty_out (vty, " BGP state = %s",
- LOOKUP (bgp_status_msg, p->status));
- if (p->status == Established)
+ LOOKUP (bgp_peer_status_msg, p->state));
+ if (p->state == bgp_peer_sEstablished)
vty_out (vty, ", up for %8s",
peer_uptime (p->uptime, timebuf, BGP_UPTIME_LEN));
/* TODO: what is state "Active" now? sEnabled? */
@@ -7331,7 +7331,7 @@ bgp_show_peer (struct vty *vty, struct peer *p)
}
/* Capability. */
- if (p->status == Established)
+ if (p->state == bgp_peer_sEstablished)
{
if (p->cap
|| p->afc_adv[AFI_IP][SAFI_UNICAST]
@@ -7453,7 +7453,7 @@ bgp_show_peer (struct vty *vty, struct peer *p)
int eor_receive_af_count = 0;
vty_out (vty, " Graceful restart informations:%s", VTY_NEWLINE);
- if (p->status == Established)
+ if (p->state == bgp_peer_sEstablished)
{
vty_out (vty, " End-of-RIB send: ");
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
@@ -8025,7 +8025,7 @@ bgp_write_rsclient_summary (struct vty *vty, struct peer *rsclient,
else if (CHECK_FLAG (rsclient->sflags, PEER_STATUS_PREFIX_OVERFLOW))
vty_out (vty, " Idle (PfxCt)");
else
- vty_out (vty, " %-11s", LOOKUP(bgp_status_msg, rsclient->status));
+ vty_out (vty, " %-11s", LOOKUP(bgp_peer_status_msg, rsclient->state));
vty_out (vty, "%s", VTY_NEWLINE);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 30f32592..a5d73fdd 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -184,7 +184,7 @@ bgp_router_id_set (struct bgp *bgp, struct in_addr *id)
{
IPV4_ADDR_COPY (&peer->local_id, id);
- if (peer->status == Established)
+ if (peer->state == bgp_peer_sEstablished)
{
peer->last_reset = PEER_DOWN_RID_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
@@ -214,7 +214,7 @@ bgp_cluster_id_set (struct bgp *bgp, struct in_addr *cluster_id)
if (peer_sort (peer) != BGP_PEER_IBGP)
continue;
- if (peer->status == Established)
+ if (peer->state == bgp_peer_sEstablished)
{
peer->last_reset = PEER_DOWN_CLID_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
@@ -242,7 +242,7 @@ bgp_cluster_id_unset (struct bgp *bgp)
if (peer_sort (peer) != BGP_PEER_IBGP)
continue;
- if (peer->status == Established)
+ if (peer->state == bgp_peer_sEstablished)
{
peer->last_reset = PEER_DOWN_CLID_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
@@ -934,7 +934,7 @@ peer_deactivate (struct peer *peer, afi_t afi, safi_t safi)
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
- if (peer->status == Established)
+ if (peer->state == bgp_peer_sEstablished)
{
if (CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV))
{
@@ -2193,7 +2193,7 @@ peer_af_flag_modify (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag,
/* Execute action when peer is established. */
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
- && peer->status == Established)
+ && peer->state == bgp_peer_sEstablished)
{
if (! set && flag == PEER_FLAG_SOFT_RECONFIG)
bgp_clear_adj_in (peer, afi, safi);
@@ -2234,7 +2234,7 @@ peer_af_flag_modify (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag,
else
UNSET_FLAG (peer->af_flags[afi][safi], flag);
- if (peer->status == Established)
+ if (peer->state == bgp_peer_sEstablished)
{
if (! set && flag == PEER_FLAG_SOFT_RECONFIG)
bgp_clear_adj_in (peer, afi, safi);
@@ -2273,20 +2273,19 @@ peer_af_flag_unset (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
int
peer_ebgp_multihop_set (struct peer *peer, int ttl)
{
-//struct peer_group *group;
-//struct listnode *node, *nnode;
+ struct peer_group *group;
+ struct listnode *node, *nnode;
+ bgp_session session = peer->session;
if (peer_sort (peer) == BGP_PEER_IBGP)
return 0;
peer->ttl = ttl;
- /* TODO: peer-fd doesn't exist */
-#if 0
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
- if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
- sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
+ if (bgp_session_is_active(session) && peer_sort (peer) != BGP_PEER_IBGP)
+ bgp_session_set_ttl (session, peer->ttl);
}
else
{
@@ -2297,20 +2296,21 @@ peer_ebgp_multihop_set (struct peer *peer, int ttl)
continue;
peer->ttl = group->conf->ttl;
+ session = peer->session;
- if (peer->fd >= 0)
- sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
+ if (bgp_session_is_active(session))
+ bgp_session_set_ttl (session, peer->ttl);
}
}
-#endif
return 0;
}
int
peer_ebgp_multihop_unset (struct peer *peer)
{
-//struct peer_group *group;
-//struct listnode *node, *nnode;
+ struct peer_group *group;
+ struct listnode *node, *nnode;
+ bgp_session session = peer->session;
if (peer_sort (peer) == BGP_PEER_IBGP)
return 0;
@@ -2320,12 +2320,10 @@ peer_ebgp_multihop_unset (struct peer *peer)
else
peer->ttl = 1;
- /* TODO: peer-fd doesn't exist */
-#if 0
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
- if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
- sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
+ if (bgp_session_is_active(session) && peer_sort (peer) != BGP_PEER_IBGP)
+ bgp_session_set_ttl (session, peer->ttl);
}
else
{
@@ -2336,12 +2334,13 @@ peer_ebgp_multihop_unset (struct peer *peer)
continue;
peer->ttl = 1;
+ session = peer->session;
- if (peer->fd >= 0)
- sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
+ if (bgp_session_is_active(session))
+ bgp_session_set_ttl (session, peer->ttl);
}
}
-#endif
+
return 0;
}
@@ -2590,7 +2589,7 @@ peer_default_originate_set (struct peer *peer, afi_t afi, safi_t safi,
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
- if (peer->status == Established && peer->afc_nego[afi][safi])
+ if (peer->state == bgp_peer_sEstablished && peer->afc_nego[afi][safi])
bgp_default_originate (peer, afi, safi, 0);
return 0;
}
@@ -2609,7 +2608,7 @@ peer_default_originate_set (struct peer *peer, afi_t afi, safi_t safi,
peer->default_rmap[afi][safi].map = route_map_lookup_by_name (rmap);
}
- if (peer->status == Established && peer->afc_nego[afi][safi])
+ if (peer->state == bgp_peer_sEstablished && peer->afc_nego[afi][safi])
bgp_default_originate (peer, afi, safi, 0);
}
return 0;
@@ -2641,7 +2640,7 @@ peer_default_originate_unset (struct peer *peer, afi_t afi, safi_t safi)
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
- if (peer->status == Established && peer->afc_nego[afi][safi])
+ if (peer->state == bgp_peer_sEstablished && peer->afc_nego[afi][safi])
bgp_default_originate (peer, afi, safi, 1);
return 0;
}
@@ -2657,7 +2656,7 @@ peer_default_originate_unset (struct peer *peer, afi_t afi, safi_t safi)
peer->default_rmap[afi][safi].name = NULL;
peer->default_rmap[afi][safi].map = NULL;
- if (peer->status == Established && peer->afc_nego[afi][safi])
+ if (peer->state == bgp_peer_sEstablished && peer->afc_nego[afi][safi])
bgp_default_originate (peer, afi, safi, 1);
}
return 0;
@@ -3857,7 +3856,7 @@ int
peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi,
enum bgp_clear_type stype)
{
- if (peer->status != Established)
+ if (peer->state == bgp_peer_sEstablished)
return 0;
if (! peer->afc[afi][safi])
@@ -4696,32 +4695,44 @@ bgp_init (void)
}
void
-bgp_terminate (int terminating)
+bgp_terminate (int terminating, int retain_mode)
{
struct bgp *bgp;
struct peer *peer;
struct listnode *node, *nnode;
struct listnode *mnode, *mnnode;
+ bgp_notify notification = NULL;
+
+ if (!retain_mode)
+ notification = bgp_notify_new(BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN, 0);
program_terminating = terminating;
/* Disable all peers */
for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
- bgp_peer_disable(peer, bgp_notify_new(BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN, 0));
-
- bgp_cleanup_routes ();
+ {
+ if (terminating)
+ bgp_peer_disable(peer, notification);
+ else
+ bgp_peer_reenable(peer, notification);
+ }
- if (bm->process_main_queue)
- {
- work_queue_free (bm->process_main_queue);
- bm->process_main_queue = NULL;
- }
- if (bm->process_rsclient_queue)
+ if (!retain_mode)
{
- work_queue_free (bm->process_rsclient_queue);
- bm->process_rsclient_queue = NULL;
+ bgp_cleanup_routes ();
+
+ if (bm->process_main_queue)
+ {
+ work_queue_free (bm->process_main_queue);
+ bm->process_main_queue = NULL;
+ }
+ if (bm->process_rsclient_queue)
+ {
+ work_queue_free (bm->process_rsclient_queue);
+ bm->process_rsclient_queue = NULL;
+ }
}
/* if no sessions were enabled then need to check here */
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 8cfe65c2..fb97d154 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -406,7 +406,7 @@ extern qpn_nexus bgp_nexus;
extern qpn_nexus routing_nexus;
/* Prototypes. */
-extern void bgp_terminate (int);
+extern void bgp_terminate (int, int);
extern void bgp_reset (void);
extern void bgp_zclient_reset (void); /* See bgp_zebra ! */