diff options
Diffstat (limited to 'bgpd')
-rw-r--r-- | bgpd/bgp_common.h | 13 | ||||
-rw-r--r-- | bgpd/bgp_debug.c | 9 | ||||
-rw-r--r-- | bgpd/bgp_debug.h | 2 | ||||
-rw-r--r-- | bgpd/bgp_fsm.h | 8 | ||||
-rw-r--r-- | bgpd/bgp_main.c | 28 | ||||
-rw-r--r-- | bgpd/bgp_mplsvpn.c | 2 | ||||
-rw-r--r-- | bgpd/bgp_nexthop.c | 2 | ||||
-rw-r--r-- | bgpd/bgp_packet.c | 90 | ||||
-rw-r--r-- | bgpd/bgp_peer.c | 34 | ||||
-rw-r--r-- | bgpd/bgp_peer.h | 12 | ||||
-rw-r--r-- | bgpd/bgp_route.c | 10 | ||||
-rw-r--r-- | bgpd/bgp_session.c | 79 | ||||
-rw-r--r-- | bgpd/bgp_session.h | 14 | ||||
-rw-r--r-- | bgpd/bgp_snmp.c | 1 | ||||
-rw-r--r-- | bgpd/bgp_vty.c | 14 | ||||
-rw-r--r-- | bgpd/bgpd.c | 95 | ||||
-rw-r--r-- | bgpd/bgpd.h | 2 |
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 ! */ |