From 3e5a31b24ee6a3bdcc478fa9c842c5d1b69cd067 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 9 Aug 2021 23:43:46 -0400 Subject: [PATCH] bgpd: Convert `struct peer_connection` to dynamically allocated As part of the conversion to a `struct peer_connection` it will be desirable to have 2 pointers one for when we open a connection and one for when we receive a connection. Start this actual conversion over to this in `struct peer`. If this sounds confusing take a look at the bgp state machine for connections and how it resolves the processing of this router opening -vs- this router receiving an open. At some point in time the state machine decides that we are keeping one of the two connections. Future commits will allow us to untangle the peer/doppelganger duality with this abstraction. Signed-off-by: Donald Sharp --- bgpd/bgp_bfd.c | 2 +- bgpd/bgp_bmp.c | 6 +- bgpd/bgp_dump.c | 4 +- bgpd/bgp_evpn.c | 2 +- bgpd/bgp_fsm.c | 224 +++++++++++++++++------------------ bgpd/bgp_fsm.h | 4 +- bgpd/bgp_io.c | 6 +- bgpd/bgp_network.c | 53 +++++---- bgpd/bgp_packet.c | 63 +++++----- bgpd/bgp_script.c | 2 +- bgpd/bgp_snmp_bgp4.c | 4 +- bgpd/bgp_snmp_bgp4v2.c | 2 +- bgpd/bgp_vty.c | 63 +++++----- bgpd/bgpd.c | 188 +++++++++++++++-------------- bgpd/bgpd.h | 5 +- bgpd/rfapi/rfapi.c | 4 +- bgpd/rfapi/vnc_zebra.c | 4 +- tests/bgpd/test_aspath.c | 5 +- tests/bgpd/test_capability.c | 3 +- tests/bgpd/test_mp_attr.c | 3 +- tests/bgpd/test_packet.c | 7 +- 21 files changed, 340 insertions(+), 314 deletions(-) diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c index 598368ae66..7f83e97107 100644 --- a/bgpd/bgp_bfd.c +++ b/bgpd/bgp_bfd.c @@ -56,7 +56,7 @@ static void bfd_session_status_update(struct bfd_session_params *bsp, peer->last_reset = PEER_DOWN_BFD_DOWN; /* rfc9384 */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_BFD_DOWN); diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index 4d604addda..04a70aa59f 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -703,7 +703,7 @@ static int bmp_peer_status_changed(struct peer *peer) if (!bmpbgp) return 0; - if (peer->connection.status == Deleted) { + if (peer->connection->status == Deleted) { bbpeer = bmp_bgp_peer_find(peer->qobj_node.nid); if (bbpeer) { XFREE(MTYPE_BMP_OPEN, bbpeer->open_rx); @@ -715,12 +715,12 @@ static int bmp_peer_status_changed(struct peer *peer) } /* Check if this peer just went to Established */ - if ((peer->connection.ostatus != OpenConfirm) || + if ((peer->connection->ostatus != OpenConfirm) || !(peer_established(peer))) return 0; if (peer->doppelganger && - (peer->doppelganger->connection.status != Deleted)) { + (peer->doppelganger->connection->status != Deleted)) { bbpeer = bmp_bgp_peer_get(peer); bbdopp = bmp_bgp_peer_find(peer->doppelganger->qobj_node.nid); if (bbdopp) { diff --git a/bgpd/bgp_dump.c b/bgpd/bgp_dump.c index 489b3c6587..3b5fbf368b 100644 --- a/bgpd/bgp_dump.c +++ b/bgpd/bgp_dump.c @@ -512,8 +512,8 @@ int bgp_dump_state(struct peer *peer) bgp_dump_all.type); bgp_dump_common(obuf, peer, 1); /* force this in as4speak*/ - stream_putw(obuf, peer->connection.ostatus); - stream_putw(obuf, peer->connection.status); + stream_putw(obuf, peer->connection->ostatus); + stream_putw(obuf, peer->connection->status); /* Set length. */ bgp_dump_set_size(obuf, MSG_PROTOCOL_BGP4MP); diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index ef62799940..7457326c1b 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -6462,7 +6462,7 @@ void bgp_reimport_evpn_routes_upon_martian_change( if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) continue; - if (peer->connection.status != Established) + if (peer->connection->status != Established) continue; if (CHECK_FLAG(peer->af_flags[afi][safi], diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 41d386ebaa..ec1387cc96 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -146,13 +146,13 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) if (bgp_debug_neighbor_events(peer)) zlog_debug("%s: peer transfer %p fd %d -> %p fd %d)", - from_peer->host, from_peer, from_peer->connection.fd, - peer, peer->connection.fd); + from_peer->host, from_peer, from_peer->connection->fd, + peer, peer->connection->fd); - bgp_writes_off(&peer->connection); - bgp_reads_off(&peer->connection); - bgp_writes_off(&from_peer->connection); - bgp_reads_off(&from_peer->connection); + bgp_writes_off(peer->connection); + bgp_reads_off(peer->connection); + bgp_writes_off(from_peer->connection); + bgp_reads_off(from_peer->connection); /* * Before exchanging FD remove doppelganger from @@ -172,21 +172,21 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) EVENT_OFF(from_peer->t_delayopen); EVENT_OFF(from_peer->t_connect_check_r); EVENT_OFF(from_peer->t_connect_check_w); - EVENT_OFF(from_peer->connection.t_process_packet); + EVENT_OFF(from_peer->connection->t_process_packet); /* * At this point in time, it is possible that there are packets pending * on various buffers. Those need to be transferred or dropped, * otherwise we'll get spurious failures during session establishment. */ - frr_with_mutex (&peer->connection.io_mtx, - &from_peer->connection.io_mtx) { - fd = peer->connection.fd; - peer->connection.fd = from_peer->connection.fd; - from_peer->connection.fd = fd; + frr_with_mutex (&peer->connection->io_mtx, + &from_peer->connection->io_mtx) { + fd = peer->connection->fd; + peer->connection->fd = from_peer->connection->fd; + from_peer->connection->fd = fd; - stream_fifo_clean(peer->connection.ibuf); - stream_fifo_clean(peer->connection.obuf); + stream_fifo_clean(peer->connection->ibuf); + stream_fifo_clean(peer->connection->obuf); /* * this should never happen, since bgp_process_packet() is the @@ -208,21 +208,21 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) } // copy each packet from old peer's output queue to new peer - while (from_peer->connection.obuf->head) - stream_fifo_push(peer->connection.obuf, + while (from_peer->connection->obuf->head) + stream_fifo_push(peer->connection->obuf, stream_fifo_pop( - from_peer->connection.obuf)); + from_peer->connection->obuf)); // copy each packet from old peer's input queue to new peer - while (from_peer->connection.ibuf->head) - stream_fifo_push(peer->connection.ibuf, + while (from_peer->connection->ibuf->head) + stream_fifo_push(peer->connection->ibuf, stream_fifo_pop( - from_peer->connection.ibuf)); + from_peer->connection->ibuf)); - ringbuf_wipe(peer->connection.ibuf_work); - ringbuf_copy(peer->connection.ibuf_work, - from_peer->connection.ibuf_work, - ringbuf_remain(from_peer->connection.ibuf_work)); + ringbuf_wipe(peer->connection->ibuf_work); + ringbuf_copy(peer->connection->ibuf_work, + from_peer->connection->ibuf_work, + ringbuf_remain(from_peer->connection->ibuf_work)); } peer->as = from_peer->as; @@ -233,16 +233,16 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) peer->v_gr_restart = from_peer->v_gr_restart; peer->cap = from_peer->cap; peer->remote_role = from_peer->remote_role; - status = peer->connection.status; - pstatus = peer->connection.ostatus; + status = peer->connection->status; + pstatus = peer->connection->ostatus; last_evt = peer->last_event; last_maj_evt = peer->last_major_event; - peer->connection.status = from_peer->connection.status; - peer->connection.ostatus = from_peer->connection.ostatus; + peer->connection->status = from_peer->connection->status; + peer->connection->ostatus = from_peer->connection->ostatus; peer->last_event = from_peer->last_event; peer->last_major_event = from_peer->last_major_event; - from_peer->connection.status = status; - from_peer->connection.ostatus = pstatus; + from_peer->connection->status = status; + from_peer->connection->ostatus = pstatus; from_peer->last_event = last_evt; from_peer->last_major_event = last_maj_evt; peer->remote_id = from_peer->remote_id; @@ -304,13 +304,13 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER) ? "accept" : ""), - peer->host, peer->connection.fd, - from_peer->connection.fd); + peer->host, peer->connection->fd, + from_peer->connection->fd); BGP_EVENT_ADD(peer, BGP_Stop); BGP_EVENT_ADD(from_peer, BGP_Stop); return NULL; } - if (from_peer->connection.status > Active) { + if (from_peer->connection->status > Active) { if (bgp_getsockname(from_peer) < 0) { flog_err(EC_LIB_SOCKET, "%%bgp_getsockname() failed for %s from_peer %s fd %d (peer fd %d)", @@ -319,8 +319,8 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) PEER_STATUS_ACCEPT_PEER) ? "accept" : ""), - from_peer->host, from_peer->connection.fd, - peer->connection.fd); + from_peer->host, from_peer->connection->fd, + peer->connection->fd); bgp_stop(from_peer); from_peer = NULL; } @@ -338,10 +338,10 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) if (from_peer) bgp_replace_nexthop_by_peer(from_peer, peer); - bgp_reads_on(&peer->connection); - bgp_writes_on(&peer->connection); - event_add_event(bm->master, bgp_process_packet, &peer->connection, 0, - &peer->connection.t_process_packet); + bgp_reads_on(peer->connection); + bgp_writes_on(peer->connection); + event_add_event(bm->master, bgp_process_packet, peer->connection, 0, + &peer->connection->t_process_packet); return (peer); } @@ -354,7 +354,7 @@ void bgp_timer_set(struct peer *peer) afi_t afi; safi_t safi; - switch (peer->connection.status) { + switch (peer->connection->status) { case Idle: /* First entry point of peer's finite state machine. In Idle status start timer is on unless peer is shutdown or peer is @@ -522,8 +522,8 @@ static void bgp_connect_timer(struct event *thread) /* stop the DelayOpenTimer if it is running */ EVENT_OFF(peer->t_delayopen); - assert(!peer->connection.t_write); - assert(!peer->connection.t_read); + assert(!peer->connection->t_write); + assert(!peer->connection->t_read); if (bgp_debug_neighbor_events(peer)) zlog_debug("%s [FSM] Timer (connect timer expire)", peer->host); @@ -558,7 +558,7 @@ static void bgp_holdtime_timer(struct event *thread) * for systems where we are heavily loaded for one * reason or another. */ - inq_count = atomic_load_explicit(&peer->connection.ibuf->count, + inq_count = atomic_load_explicit(&peer->connection->ibuf->count, memory_order_relaxed); if (inq_count) BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer, @@ -1225,7 +1225,7 @@ static void bgp_update_delay_process_status_change(struct peer *peer) if (CHECK_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV)) bgp_update_restarted_peers(peer); } - if (peer->connection.ostatus == Established && + if (peer->connection->ostatus == Established && bgp_update_delay_active(peer->bgp)) { /* Adjust the update-delay state to account for this flap. NOTE: Intentionally skipping adjusting implicit_eors or @@ -1302,15 +1302,15 @@ void bgp_fsm_change_status(struct peer *peer, enum bgp_fsm_status status) } /* Preserve old status and change into new status. */ - peer->connection.ostatus = peer->connection.status; - peer->connection.status = status; + peer->connection->ostatus = peer->connection->status; + peer->connection->status = status; /* Reset received keepalives counter on every FSM change */ peer->rtt_keepalive_rcv = 0; /* Fire backward transition hook if that's the case */ - if (peer->connection.ostatus == Established && - peer->connection.status != Established) + if (peer->connection->ostatus == Established && + peer->connection->status != Established) hook_call(peer_backward_transition, peer); /* Save event that caused status change. */ @@ -1338,10 +1338,10 @@ void bgp_fsm_change_status(struct peer *peer, enum bgp_fsm_status status) if (bgp_debug_neighbor_events(peer)) zlog_debug("%s fd %d went from %s to %s", peer->host, - peer->connection.fd, - lookup_msg(bgp_status_msg, peer->connection.ostatus, + peer->connection->fd, + lookup_msg(bgp_status_msg, peer->connection->ostatus, NULL), - lookup_msg(bgp_status_msg, peer->connection.status, + lookup_msg(bgp_status_msg, peer->connection->status, NULL)); } @@ -1384,7 +1384,7 @@ enum bgp_fsm_state_progress bgp_stop(struct peer *peer) } /* Can't do this in Clearing; events are used for state transitions */ - if (peer->connection.status != Clearing) { + if (peer->connection->status != Clearing) { /* Delete all existing events of the peer */ BGP_EVENT_FLUSH(peer); } @@ -1503,8 +1503,8 @@ enum bgp_fsm_state_progress bgp_stop(struct peer *peer) bgp_keepalives_off(peer); /* Stop read and write threads. */ - bgp_writes_off(&peer->connection); - bgp_reads_off(&peer->connection); + bgp_writes_off(peer->connection); + bgp_reads_off(peer->connection); EVENT_OFF(peer->t_connect_check_r); EVENT_OFF(peer->t_connect_check_w); @@ -1517,14 +1517,14 @@ enum bgp_fsm_state_progress bgp_stop(struct peer *peer) EVENT_OFF(peer->t_delayopen); /* Clear input and output buffer. */ - frr_with_mutex (&peer->connection.io_mtx) { - if (peer->connection.ibuf) - stream_fifo_clean(peer->connection.ibuf); - if (peer->connection.obuf) - stream_fifo_clean(peer->connection.obuf); + frr_with_mutex (&peer->connection->io_mtx) { + if (peer->connection->ibuf) + stream_fifo_clean(peer->connection->ibuf); + if (peer->connection->obuf) + stream_fifo_clean(peer->connection->obuf); - if (peer->connection.ibuf_work) - ringbuf_wipe(peer->connection.ibuf_work); + if (peer->connection->ibuf_work) + ringbuf_wipe(peer->connection->ibuf_work); if (peer->curr) { stream_free(peer->curr); @@ -1533,9 +1533,9 @@ enum bgp_fsm_state_progress bgp_stop(struct peer *peer) } /* Close of file descriptor. */ - if (peer->connection.fd >= 0) { - close(peer->connection.fd); - peer->connection.fd = -1; + if (peer->connection->fd >= 0) { + close(peer->connection->fd); + peer->connection->fd = -1; } /* Reset capabilities. */ @@ -1559,7 +1559,7 @@ enum bgp_fsm_state_progress bgp_stop(struct peer *peer) /* Received ORF prefix-filter */ peer->orf_plist[afi][safi] = NULL; - if ((peer->connection.status == OpenConfirm) || + if ((peer->connection->status == OpenConfirm) || peer_established(peer)) { /* ORF received prefix-filter pnt */ snprintf(orf_name, sizeof(orf_name), "%s.%d.%d", @@ -1661,19 +1661,19 @@ static void bgp_connect_check(struct event *thread) struct peer *peer; peer = EVENT_ARG(thread); - assert(!CHECK_FLAG(peer->connection.thread_flags, + assert(!CHECK_FLAG(peer->connection->thread_flags, PEER_THREAD_READS_ON)); - assert(!CHECK_FLAG(peer->connection.thread_flags, + assert(!CHECK_FLAG(peer->connection->thread_flags, PEER_THREAD_WRITES_ON)); - assert(!peer->connection.t_read); - assert(!peer->connection.t_write); + assert(!peer->connection->t_read); + assert(!peer->connection->t_write); EVENT_OFF(peer->t_connect_check_r); EVENT_OFF(peer->t_connect_check_w); /* Check file descriptor. */ slen = sizeof(status); - ret = getsockopt(peer->connection.fd, SOL_SOCKET, SO_ERROR, + ret = getsockopt(peer->connection->fd, SOL_SOCKET, SO_ERROR, (void *)&status, &slen); /* If getsockopt is fail, this is fatal error. */ @@ -1704,19 +1704,19 @@ static void bgp_connect_check(struct event *thread) add read thread for reading open message. */ static enum bgp_fsm_state_progress bgp_connect_success(struct peer *peer) { - if (peer->connection.fd < 0) { + if (peer->connection->fd < 0) { flog_err(EC_BGP_CONNECT, "%s peer's fd is negative value %d", - __func__, peer->connection.fd); + __func__, peer->connection->fd); return bgp_stop(peer); } if (bgp_getsockname(peer) < 0) { flog_err_sys(EC_LIB_SOCKET, "%s: bgp_getsockname(): failed for peer %s, fd %d", - __func__, peer->host, peer->connection.fd); + __func__, peer->host, peer->connection->fd); bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, - bgp_fsm_error_subcode(peer->connection.status)); - bgp_writes_on(&peer->connection); + bgp_fsm_error_subcode(peer->connection->status)); + bgp_writes_on(peer->connection); return BGP_FSM_FAILURE; } @@ -1726,7 +1726,7 @@ static enum bgp_fsm_state_progress bgp_connect_success(struct peer *peer) */ bgp_nht_interface_events(peer); - bgp_reads_on(&peer->connection); + bgp_reads_on(peer->connection); if (bgp_debug_neighbor_events(peer)) { if (!CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) @@ -1748,19 +1748,19 @@ static enum bgp_fsm_state_progress bgp_connect_success(struct peer *peer) static enum bgp_fsm_state_progress bgp_connect_success_w_delayopen(struct peer *peer) { - if (peer->connection.fd < 0) { + if (peer->connection->fd < 0) { flog_err(EC_BGP_CONNECT, "%s: peer's fd is negative value %d", - __func__, peer->connection.fd); + __func__, peer->connection->fd); return bgp_stop(peer); } if (bgp_getsockname(peer) < 0) { flog_err_sys(EC_LIB_SOCKET, "%s: bgp_getsockname(): failed for peer %s, fd %d", - __func__, peer->host, peer->connection.fd); + __func__, peer->host, peer->connection->fd); bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, - bgp_fsm_error_subcode(peer->connection.status)); - bgp_writes_on(&peer->connection); + bgp_fsm_error_subcode(peer->connection->status)); + bgp_writes_on(peer->connection); return BGP_FSM_FAILURE; } @@ -1770,7 +1770,7 @@ bgp_connect_success_w_delayopen(struct peer *peer) */ bgp_nht_interface_events(peer); - bgp_reads_on(&peer->connection); + bgp_reads_on(peer->connection); if (bgp_debug_neighbor_events(peer)) { if (!CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) @@ -1900,11 +1900,11 @@ enum bgp_fsm_state_progress bgp_start(struct peer *peer) } } - assert(!peer->connection.t_write); - assert(!peer->connection.t_read); - assert(!CHECK_FLAG(peer->connection.thread_flags, + assert(!peer->connection->t_write); + assert(!peer->connection->t_read); + assert(!CHECK_FLAG(peer->connection->thread_flags, PEER_THREAD_WRITES_ON)); - assert(!CHECK_FLAG(peer->connection.thread_flags, + assert(!CHECK_FLAG(peer->connection->thread_flags, PEER_THREAD_READS_ON)); status = bgp_connect(peer); @@ -1917,7 +1917,7 @@ enum bgp_fsm_state_progress bgp_start(struct peer *peer) case connect_success: if (bgp_debug_neighbor_events(peer)) zlog_debug("%s [FSM] Connect immediately success, fd %d", - peer->host, peer->connection.fd); + peer->host, peer->connection->fd); BGP_EVENT_ADD(peer, TCP_connection_open); break; @@ -1926,10 +1926,10 @@ enum bgp_fsm_state_progress bgp_start(struct peer *peer) readable or writable. */ if (bgp_debug_neighbor_events(peer)) zlog_debug("%s [FSM] Non blocking connect waiting result, fd %d", - peer->host, peer->connection.fd); - if (peer->connection.fd < 0) { + peer->host, peer->connection->fd); + if (peer->connection->fd < 0) { flog_err(EC_BGP_FSM, "%s peer's fd is negative value %d", - __func__, peer->connection.fd); + __func__, peer->connection->fd); return BGP_FSM_FAILURE; } /* @@ -1942,9 +1942,9 @@ enum bgp_fsm_state_progress bgp_start(struct peer *peer) * unused event in that function. */ event_add_read(bm->master, bgp_connect_check, peer, - peer->connection.fd, &peer->t_connect_check_r); + peer->connection->fd, &peer->t_connect_check_r); event_add_write(bm->master, bgp_connect_check, peer, - peer->connection.fd, &peer->t_connect_check_w); + peer->connection->fd, &peer->t_connect_check_w); break; } return BGP_FSM_SUCCESS; @@ -1969,8 +1969,8 @@ static enum bgp_fsm_state_progress bgp_reconnect(struct peer *peer) static enum bgp_fsm_state_progress bgp_fsm_open(struct peer *peer) { /* If DelayOpen is active, we may still need to send an open message */ - if ((peer->connection.status == Connect) || - (peer->connection.status == Active)) + if ((peer->connection->status == Connect) || + (peer->connection->status == Active)) bgp_open_send(peer); /* Send keepalive and make keepalive timer */ @@ -1985,11 +1985,11 @@ static enum bgp_fsm_state_progress bgp_fsm_event_error(struct peer *peer) { flog_err(EC_BGP_FSM, "%s [FSM] unexpected packet received in state %s", peer->host, - lookup_msg(bgp_status_msg, peer->connection.status, NULL)); + lookup_msg(bgp_status_msg, peer->connection->status, NULL)); return bgp_stop_with_notify(peer, BGP_NOTIFY_FSM_ERR, bgp_fsm_error_subcode( - peer->connection.status)); + peer->connection->status)); } /* Hold timer expire. This is error of BGP connection. So cut the @@ -2296,13 +2296,13 @@ static enum bgp_fsm_state_progress bgp_establish(struct peer *peer) } if (peer->doppelganger && - (peer->doppelganger->connection.status != Deleted)) { + (peer->doppelganger->connection->status != Deleted)) { if (bgp_debug_neighbor_events(peer)) zlog_debug( "[Event] Deleting stub connection for peer %s", peer->host); - if (peer->doppelganger->connection.status > Active) + if (peer->doppelganger->connection->status > Active) bgp_notify_send(peer->doppelganger, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION); else @@ -2344,9 +2344,9 @@ static enum bgp_fsm_state_progress bgp_ignore(struct peer *peer) flog_err(EC_BGP_FSM, "%s [FSM] Ignoring event %s in state %s, prior events %s, %s, fd %d", peer->host, bgp_event_str[peer->cur_event], - lookup_msg(bgp_status_msg, peer->connection.status, NULL), + lookup_msg(bgp_status_msg, peer->connection->status, NULL), bgp_event_str[peer->last_event], - bgp_event_str[peer->last_major_event], peer->connection.fd); + bgp_event_str[peer->last_major_event], peer->connection->fd); return BGP_FSM_SUCCESS; } @@ -2356,9 +2356,9 @@ static enum bgp_fsm_state_progress bgp_fsm_exception(struct peer *peer) flog_err(EC_BGP_FSM, "%s [FSM] Unexpected event %s in state %s, prior events %s, %s, fd %d", peer->host, bgp_event_str[peer->cur_event], - lookup_msg(bgp_status_msg, peer->connection.status, NULL), + lookup_msg(bgp_status_msg, peer->connection->status, NULL), bgp_event_str[peer->last_event], - bgp_event_str[peer->last_major_event], peer->connection.fd); + bgp_event_str[peer->last_major_event], peer->connection->fd); return bgp_stop(peer); } @@ -2367,7 +2367,7 @@ void bgp_fsm_nht_update(struct peer *peer, bool has_valid_nexthops) if (!peer) return; - switch (peer->connection.status) { + switch (peer->connection->status) { case Idle: if (has_valid_nexthops) BGP_EVENT_ADD(peer, BGP_Start); @@ -2596,22 +2596,22 @@ int bgp_event_update(struct peer *peer, enum bgp_fsm_events event) dyn_nbr = peer_dynamic_neighbor(peer); /* Logging this event. */ - next = FSM[peer->connection.status - 1][event - 1].next_state; + next = FSM[peer->connection->status - 1][event - 1].next_state; - if (bgp_debug_neighbor_events(peer) && peer->connection.status != next) + if (bgp_debug_neighbor_events(peer) && peer->connection->status != next) zlog_debug("%s [FSM] %s (%s->%s), fd %d", peer->host, bgp_event_str[event], - lookup_msg(bgp_status_msg, peer->connection.status, + lookup_msg(bgp_status_msg, peer->connection->status, NULL), lookup_msg(bgp_status_msg, next, NULL), - peer->connection.fd); + peer->connection->fd); peer->last_event = peer->cur_event; peer->cur_event = event; /* Call function. */ - if (FSM[peer->connection.status - 1][event - 1].func) - ret = (*(FSM[peer->connection.status - 1][event - 1].func))( + if (FSM[peer->connection->status - 1][event - 1].func) + ret = (*(FSM[peer->connection->status - 1][event - 1].func))( peer); if (ret >= BGP_FSM_SUCCESS) { @@ -2625,7 +2625,7 @@ int bgp_event_update(struct peer *peer, enum bgp_fsm_events event) } /* If status is changed. */ - if (next != peer->connection.status) { + if (next != peer->connection->status) { bgp_fsm_change_status(peer, next); /* @@ -2656,10 +2656,10 @@ int bgp_event_update(struct peer *peer, enum bgp_fsm_events event) "%s [FSM] Failure handling event %s in state %s, prior events %s, %s, fd %d, last reset: %s", peer->host, bgp_event_str[peer->cur_event], lookup_msg(bgp_status_msg, - peer->connection.status, NULL), + peer->connection->status, NULL), bgp_event_str[peer->last_event], bgp_event_str[peer->last_major_event], - peer->connection.fd, + peer->connection->fd, peer_down_str[peer->last_reset]); bgp_stop(peer); bgp_fsm_change_status(peer, Idle); diff --git a/bgpd/bgp_fsm.h b/bgpd/bgp_fsm.h index 547897de39..ed66ab9fb1 100644 --- a/bgpd/bgp_fsm.h +++ b/bgpd/bgp_fsm.h @@ -17,13 +17,13 @@ enum bgp_fsm_state_progress { /* Macro for BGP read, write and timer thread. */ #define BGP_TIMER_ON(T, F, V) \ do { \ - if ((peer->connection.status != Deleted)) \ + if ((peer->connection->status != Deleted)) \ event_add_timer(bm->master, (F), peer, (V), &(T)); \ } while (0) #define BGP_EVENT_ADD(P, E) \ do { \ - if ((P)->connection.status != Deleted) \ + if ((P)->connection->status != Deleted) \ event_add_event(bm->master, bgp_event, (P), (E), NULL); \ } while (0) diff --git a/bgpd/bgp_io.c b/bgpd/bgp_io.c index efef773d85..84e428cbc4 100644 --- a/bgpd/bgp_io.c +++ b/bgpd/bgp_io.c @@ -71,7 +71,7 @@ void bgp_writes_off(struct peer_connection *connection) event_cancel_async(fpt->master, &connection->t_write, NULL); EVENT_OFF(peer->t_generate_updgrp_packets); - UNSET_FLAG(peer->connection.thread_flags, PEER_THREAD_WRITES_ON); + UNSET_FLAG(peer->connection->thread_flags, PEER_THREAD_WRITES_ON); } void bgp_reads_on(struct peer_connection *connection) @@ -294,8 +294,8 @@ done: return; } - event_add_read(fpt->master, bgp_process_reads, peer, connection->fd, - &connection->t_read); + event_add_read(fpt->master, bgp_process_reads, connection, + connection->fd, &connection->t_read); if (added_pkt) event_add_event(bm->master, bgp_process_packet, connection, 0, &connection->t_process_packet); diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index 6a3b4e8c87..c5e7f7be63 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -429,7 +429,7 @@ static void bgp_accept(struct event *thread) peer1 = peer_lookup_dynamic_neighbor(bgp, &su); if (peer1) { /* Dynamic neighbor has been created, let it proceed */ - peer1->connection.fd = bgp_sock; + peer1->connection->fd = bgp_sock; /* Set the user configured MSS to TCP socket */ if (CHECK_FLAG(peer1->flags, PEER_FLAG_TCP_MSS)) @@ -482,11 +482,12 @@ static void bgp_accept(struct event *thread) * Established and then the Clearing_Completed event is generated. Also, * block incoming connection in Deleted state. */ - if (peer1->connection.status == Clearing || - peer1->connection.status == Deleted) { + if (peer1->connection->status == Clearing || + peer1->connection->status == Deleted) { if (bgp_debug_neighbor_events(peer1)) zlog_debug("[Event] Closing incoming conn for %s (%p) state %d", - peer1->host, peer1, peer1->connection.status); + peer1->host, peer1, + peer1->connection->status); close(bgp_sock); return; } @@ -523,7 +524,7 @@ static void bgp_accept(struct event *thread) if (bgp_debug_neighbor_events(peer1)) zlog_debug("[Event] connection from %s fd %d, active peer status %d fd %d", inet_sutop(&su, buf), bgp_sock, - peer1->connection.status, peer1->connection.fd); + peer1->connection->status, peer1->connection->fd); if (peer1->doppelganger) { /* We have an existing connection. Kill the existing one and run @@ -562,7 +563,7 @@ static void bgp_accept(struct event *thread) peer->doppelganger = peer1; peer1->doppelganger = peer; - peer->connection.fd = bgp_sock; + peer->connection->fd = bgp_sock; frr_with_privs(&bgpd_privs) { vrf_bind(peer->bgp->vrf_id, bgp_sock, bgp_get_bound_name(peer)); } @@ -683,12 +684,12 @@ static int bgp_update_source(struct peer *peer) if (bgp_update_address(ifp, &peer->su, &addr)) return -1; - ret = sockunion_bind(peer->connection.fd, &addr, 0, &addr); + ret = sockunion_bind(peer->connection->fd, &addr, 0, &addr); } /* Source is specified with IP address. */ if (peer->update_source) - ret = sockunion_bind(peer->connection.fd, peer->update_source, + ret = sockunion_bind(peer->connection->fd, peer->update_source, 0, peer->update_source); return ret; @@ -697,9 +698,9 @@ static int bgp_update_source(struct peer *peer) /* BGP try to connect to the peer. */ int bgp_connect(struct peer *peer) { - assert(!CHECK_FLAG(peer->connection.thread_flags, + assert(!CHECK_FLAG(peer->connection->thread_flags, PEER_THREAD_WRITES_ON)); - assert(!CHECK_FLAG(peer->connection.thread_flags, + assert(!CHECK_FLAG(peer->connection->thread_flags, PEER_THREAD_READS_ON)); ifindex_t ifindex = 0; @@ -710,11 +711,11 @@ int bgp_connect(struct peer *peer) } frr_with_privs(&bgpd_privs) { /* Make socket for the peer. */ - peer->connection.fd = + peer->connection->fd = vrf_sockunion_socket(&peer->su, peer->bgp->vrf_id, bgp_get_bound_name(peer)); } - if (peer->connection.fd < 0) { + if (peer->connection->fd < 0) { peer->last_reset = PEER_DOWN_SOCKET_ERROR; if (bgp_debug_neighbor_events(peer)) zlog_debug("%s: Failure to create socket for connection to %s, error received: %s(%d)", @@ -723,18 +724,18 @@ int bgp_connect(struct peer *peer) return -1; } - set_nonblocking(peer->connection.fd); + set_nonblocking(peer->connection->fd); /* Set the user configured MSS to TCP socket */ if (CHECK_FLAG(peer->flags, PEER_FLAG_TCP_MSS)) - sockopt_tcp_mss_set(peer->connection.fd, peer->tcp_mss); + sockopt_tcp_mss_set(peer->connection->fd, peer->tcp_mss); - bgp_socket_set_buffer_size(peer->connection.fd); + bgp_socket_set_buffer_size(peer->connection->fd); /* Set TCP keepalive when TCP keepalive is enabled */ - bgp_update_setsockopt_tcp_keepalive(peer->bgp, peer->connection.fd); + bgp_update_setsockopt_tcp_keepalive(peer->bgp, peer->connection->fd); - if (bgp_set_socket_ttl(peer, peer->connection.fd) < 0) { + if (bgp_set_socket_ttl(peer, peer->connection->fd) < 0) { peer->last_reset = PEER_DOWN_SOCKET_ERROR; if (bgp_debug_neighbor_events(peer)) zlog_debug("%s: Failure to set socket ttl for connection to %s, error received: %s(%d)", @@ -744,15 +745,15 @@ int bgp_connect(struct peer *peer) return -1; } - sockopt_reuseaddr(peer->connection.fd); - sockopt_reuseport(peer->connection.fd); + sockopt_reuseaddr(peer->connection->fd); + sockopt_reuseport(peer->connection->fd); #ifdef IPTOS_PREC_INTERNETCONTROL frr_with_privs(&bgpd_privs) { if (sockunion_family(&peer->su) == AF_INET) - setsockopt_ipv4_tos(peer->connection.fd, bm->tcp_dscp); + setsockopt_ipv4_tos(peer->connection->fd, bm->tcp_dscp); else if (sockunion_family(&peer->su) == AF_INET6) - setsockopt_ipv6_tclass(peer->connection.fd, + setsockopt_ipv6_tclass(peer->connection->fd, bm->tcp_dscp); } #endif @@ -765,7 +766,7 @@ int bgp_connect(struct peer *peer) if (!BGP_PEER_SU_UNSPEC(peer)) bgp_md5_set(peer); - bgp_md5_set_connect(peer->connection.fd, &peer->su, prefixlen, + bgp_md5_set_connect(peer->connection->fd, &peer->su, prefixlen, peer->password); } @@ -782,10 +783,10 @@ int bgp_connect(struct peer *peer) if (bgp_debug_neighbor_events(peer)) zlog_debug("%s [Event] Connect start to %s fd %d", peer->host, - peer->host, peer->connection.fd); + peer->host, peer->connection->fd); /* Connect to the remote peer. */ - return sockunion_connect(peer->connection.fd, &peer->su, + return sockunion_connect(peer->connection->fd, &peer->su, htons(peer->port), ifindex); } @@ -802,10 +803,10 @@ int bgp_getsockname(struct peer *peer) peer->su_remote = NULL; } - peer->su_local = sockunion_getsockname(peer->connection.fd); + peer->su_local = sockunion_getsockname(peer->connection->fd); if (!peer->su_local) return -1; - peer->su_remote = sockunion_getpeername(peer->connection.fd); + peer->su_remote = sockunion_getpeername(peer->connection->fd); if (!peer->su_remote) return -1; diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 7bee979c68..d8b4bda620 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -111,15 +111,15 @@ static void bgp_packet_add(struct peer *peer, struct stream *s) uint32_t holdtime; intmax_t sendholdtime; - frr_with_mutex (&peer->connection.io_mtx) { + frr_with_mutex (&peer->connection->io_mtx) { /* if the queue is empty, reset the "last OK" timestamp to * now, otherwise if we write another packet immediately * after it'll get confused */ - if (!stream_fifo_count_safe(peer->connection.obuf)) + if (!stream_fifo_count_safe(peer->connection->obuf)) peer->last_sendq_ok = monotime(NULL); - stream_fifo_push(peer->connection.obuf, s); + stream_fifo_push(peer->connection->obuf, s); delta = monotime(NULL) - peer->last_sendq_ok; @@ -477,7 +477,7 @@ void bgp_generate_updgrp_packets(struct event *thread) * let's stop adding to the outq if we are * already at the limit. */ - if (peer->connection.obuf->count >= bm->outq_limit) { + if (peer->connection->obuf->count >= bm->outq_limit) { bgp_write_proceed_actions(peer); return; } @@ -605,10 +605,10 @@ void bgp_generate_updgrp_packets(struct event *thread) bpacket_queue_advance_peer(paf); } } while (s && (++generated < wpq) && - (peer->connection.obuf->count <= bm->outq_limit)); + (peer->connection->obuf->count <= bm->outq_limit)); if (generated) - bgp_writes_on(&peer->connection); + bgp_writes_on(peer->connection); bgp_write_proceed_actions(peer); } @@ -637,7 +637,7 @@ void bgp_keepalive_send(struct peer *peer) /* Add packet to the peer. */ bgp_packet_add(peer, s); - bgp_writes_on(&peer->connection); + bgp_writes_on(peer->connection); } /* @@ -706,18 +706,18 @@ void bgp_open_send(struct peer *peer) /* Add packet to the peer. */ bgp_packet_add(peer, s); - bgp_writes_on(&peer->connection); + bgp_writes_on(peer->connection); } /* * Writes NOTIFICATION message directly to a peer socket without waiting for * the I/O thread. * - * There must be exactly one stream on the peer->connection.obuf FIFO, and the + * There must be exactly one stream on the peer->connection->obuf FIFO, and the * data within this stream must match the format of a BGP NOTIFICATION message. * Transmission is best-effort. * - * @requires peer->connection.io_mtx + * @requires peer->connection->io_mtx * @param peer * @return 0 */ @@ -728,7 +728,7 @@ static void bgp_write_notify(struct peer *peer) struct stream *s; /* There should be at least one packet. */ - s = stream_fifo_pop(peer->connection.obuf); + s = stream_fifo_pop(peer->connection->obuf); if (!s) return; @@ -739,7 +739,7 @@ static void bgp_write_notify(struct peer *peer) * socket is in nonblocking mode, if we can't deliver the NOTIFY, well, * we only care about getting a clean shutdown at this point. */ - ret = write(peer->connection.fd, STREAM_DATA(s), stream_get_endp(s)); + ret = write(peer->connection->fd, STREAM_DATA(s), stream_get_endp(s)); /* * only connection reset/close gets counted as TCP_fatal_error, failure @@ -753,7 +753,7 @@ static void bgp_write_notify(struct peer *peer) /* Disable Nagle, make NOTIFY packet go out right away */ val = 1; - (void)setsockopt(peer->connection.fd, IPPROTO_TCP, TCP_NODELAY, + (void)setsockopt(peer->connection->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); /* Retrieve BGP packet type. */ @@ -910,7 +910,7 @@ static void bgp_notify_send_internal(struct peer *peer, uint8_t code, bool hard_reset = bgp_notify_send_hard_reset(peer, code, sub_code); /* Lock I/O mutex to prevent other threads from pushing packets */ - frr_mutex_lock_autounlock(&peer->connection.io_mtx); + frr_mutex_lock_autounlock(&peer->connection->io_mtx); /* ============================================== */ /* Allocate new stream. */ @@ -943,7 +943,7 @@ static void bgp_notify_send_internal(struct peer *peer, uint8_t code, bgp_packet_set_size(s); /* wipe output buffer */ - stream_fifo_clean(peer->connection.obuf); + stream_fifo_clean(peer->connection->obuf); /* * If possible, store last packet for debugging purposes. This check is @@ -1028,7 +1028,7 @@ static void bgp_notify_send_internal(struct peer *peer, uint8_t code, peer->last_reset = PEER_DOWN_NOTIFY_SEND; /* Add packet to peer's output queue */ - stream_fifo_push(peer->connection.obuf, s); + stream_fifo_push(peer->connection->obuf, s); bgp_peer_gr_flags_update(peer); BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp, @@ -1181,7 +1181,7 @@ void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi, /* Add packet to the peer. */ bgp_packet_add(peer, s); - bgp_writes_on(&peer->connection); + bgp_writes_on(peer->connection); } /* @@ -1299,7 +1299,7 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi, /* Add packet to the peer. */ bgp_packet_add(peer, s); - bgp_writes_on(&peer->connection); + bgp_writes_on(peer->connection); } /* RFC1771 6.8 Connection collision detection. */ @@ -1326,14 +1326,14 @@ static int bgp_collision_detect(struct peer *new, struct in_addr remote_id) * states. Note that a peer GR is handled by closing the existing * connection upon receipt of new one. */ - if (peer_established(peer) || peer->connection.status == Clearing) { + if (peer_established(peer) || peer->connection->status == Clearing) { bgp_notify_send(new, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION); return -1; } - if ((peer->connection.status != OpenConfirm) && - (peer->connection.status != OpenSent)) + if ((peer->connection->status != OpenConfirm) && + (peer->connection->status != OpenSent)) return 0; /* @@ -1414,7 +1414,7 @@ static int bgp_collision_detect(struct peer *new, struct in_addr remote_id) * Side effects * ------------ * - May send NOTIFY messages - * - May not modify peer->connection.status + * - May not modify peer->connection->status * - May not call bgp_event_update() */ @@ -1813,7 +1813,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) return BGP_Stop; } } - peer->rtt = sockopt_tcp_rtt(peer->connection.fd); + peer->rtt = sockopt_tcp_rtt(peer->connection->fd); return Receive_OPEN_message; } @@ -1832,7 +1832,7 @@ static int bgp_keepalive_receive(struct peer *peer, bgp_size_t size) bgp_update_implicit_eors(peer); - peer->rtt = sockopt_tcp_rtt(peer->connection.fd); + peer->rtt = sockopt_tcp_rtt(peer->connection->fd); /* If the peer's RTT is higher than expected, shutdown * the peer automatically. @@ -1922,10 +1922,10 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) flog_err(EC_BGP_INVALID_STATUS, "%s [FSM] Update packet received under status %s", peer->host, - lookup_msg(bgp_status_msg, peer->connection.status, + lookup_msg(bgp_status_msg, peer->connection->status, NULL)); bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, - bgp_fsm_error_subcode(peer->connection.status)); + bgp_fsm_error_subcode(peer->connection->status)); return BGP_Stop; } @@ -2374,10 +2374,10 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) flog_err(EC_BGP_INVALID_STATUS, "%s [Error] Route refresh packet received under status %s", peer->host, - lookup_msg(bgp_status_msg, peer->connection.status, + lookup_msg(bgp_status_msg, peer->connection->status, NULL)); bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, - bgp_fsm_error_subcode(peer->connection.status)); + bgp_fsm_error_subcode(peer->connection->status)); return BGP_Stop; } @@ -2962,10 +2962,10 @@ int bgp_capability_receive(struct peer *peer, bgp_size_t size) flog_err(EC_BGP_NO_CAP, "%s [Error] Dynamic capability packet received under status %s", peer->host, - lookup_msg(bgp_status_msg, peer->connection.status, + lookup_msg(bgp_status_msg, peer->connection->status, NULL)); bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, - bgp_fsm_error_subcode(peer->connection.status)); + bgp_fsm_error_subcode(peer->connection->status)); return BGP_Stop; } @@ -3003,8 +3003,7 @@ void bgp_process_packet(struct event *thread) fsm_update_result = 0; /* Guard against scheduled events that occur after peer deletion. */ - if (peer->connection.status == Deleted || - peer->connection.status == Clearing) + if (connection->status == Deleted || connection->status == Clearing) return; unsigned int processed = 0; diff --git a/bgpd/bgp_script.c b/bgpd/bgp_script.c index fe075f37b0..b37385812e 100644 --- a/bgpd/bgp_script.c +++ b/bgpd/bgp_script.c @@ -26,7 +26,7 @@ void lua_pushpeer(lua_State *L, const struct peer *peer) lua_setfield(L, -2, "remote_id"); lua_pushinaddr(L, &peer->local_id); lua_setfield(L, -2, "local_id"); - lua_pushstring(L, lookup_msg(bgp_status_msg, peer->connection.status, + lua_pushstring(L, lookup_msg(bgp_status_msg, peer->connection->status, NULL)); lua_setfield(L, -2, "state"); lua_pushstring(L, peer->desc ? peer->desc : ""); diff --git a/bgpd/bgp_snmp_bgp4.c b/bgpd/bgp_snmp_bgp4.c index 4f90907d28..8af87ae4b2 100644 --- a/bgpd/bgp_snmp_bgp4.c +++ b/bgpd/bgp_snmp_bgp4.c @@ -251,7 +251,7 @@ static uint8_t *bgpPeerTable(struct variable *v, oid name[], size_t *length, case BGPPEERIDENTIFIER: return SNMP_IPADDRESS(peer->remote_id); case BGPPEERSTATE: - return SNMP_INTEGER(peer->connection.status); + return SNMP_INTEGER(peer->connection->status); case BGPPEERADMINSTATUS: *write_method = write_bgpPeerTable; #define BGP_PeerAdmin_stop 1 @@ -756,7 +756,7 @@ int bgpTrapEstablished(struct peer *peer) oid index[sizeof(oid) * IN_ADDR_SIZE]; /* Check if this peer just went to Established */ - if ((peer->connection.ostatus != OpenConfirm) || + if ((peer->connection->ostatus != OpenConfirm) || !(peer_established(peer))) return 0; diff --git a/bgpd/bgp_snmp_bgp4v2.c b/bgpd/bgp_snmp_bgp4v2.c index 179970af11..5e77a9297b 100644 --- a/bgpd/bgp_snmp_bgp4v2.c +++ b/bgpd/bgp_snmp_bgp4v2.c @@ -265,7 +265,7 @@ static uint8_t *bgpv2PeerTable(struct variable *v, oid name[], size_t *length, else return SNMP_INTEGER(BGP_PEER_ADMIN_STATUS_RUNNING); case BGP4V2_PEER_STATE: - return SNMP_INTEGER(peer->connection.status); + return SNMP_INTEGER(peer->connection->status); case BGP4V2_PEER_DESCRIPTION: if (peer->desc) return SNMP_STRING(peer->desc); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 9086e8af76..445dea92d5 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -2888,7 +2888,7 @@ DEFUN(bgp_reject_as_sets, bgp_reject_as_sets_cmd, * with aspath containing AS_SET or AS_CONFED_SET. */ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { peer->last_reset = PEER_DOWN_AS_SETS_REJECT; bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -2914,7 +2914,7 @@ DEFUN(no_bgp_reject_as_sets, no_bgp_reject_as_sets_cmd, * with aspath containing AS_SET or AS_CONFED_SET. */ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { peer->last_reset = PEER_DOWN_AS_SETS_REJECT; bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -4851,7 +4851,7 @@ static int peer_conf_interface_get(struct vty *vty, const char *conf_if, peer_flag_unset(peer, PEER_FLAG_IFPEER_V6ONLY); /* v6only flag changed. Reset bgp seesion */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { peer->last_reset = PEER_DOWN_V6ONLY_CHANGE; bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -5040,7 +5040,7 @@ DEFUN (no_neighbor, peer_notify_unconfig(peer); peer_delete(peer); - if (other && other->connection.status != Deleted) { + if (other && other->connection->status != Deleted) { peer_notify_unconfig(other); peer_delete(other); } @@ -11750,11 +11750,13 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, atomic_size_t outq_count, inq_count; outq_count = atomic_load_explicit(&peer->connection - .obuf->count, + ->obuf + ->count, memory_order_relaxed); inq_count = atomic_load_explicit(&peer->connection - .ibuf->count, + ->ibuf + ->count, memory_order_relaxed); json_object_int_add( @@ -11791,7 +11793,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, json_object_string_add( json_peer, "state", lookup_msg(bgp_status_msg, - peer->connection.status, + peer->connection->status, NULL)); else if (CHECK_FLAG( peer->sflags, @@ -11803,7 +11805,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, json_object_string_add( json_peer, "state", lookup_msg(bgp_status_msg, - peer->connection.status, + peer->connection->status, NULL)); /* BGP peer state */ @@ -11922,11 +11924,13 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, atomic_size_t outq_count, inq_count; outq_count = atomic_load_explicit(&peer->connection - .obuf->count, + ->obuf + ->count, memory_order_relaxed); inq_count = atomic_load_explicit(&peer->connection - .ibuf->count, + ->ibuf + ->count, memory_order_relaxed); vty_out(vty, "4"); @@ -12000,7 +12004,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, vty_out(vty, " %12s", lookup_msg(bgp_status_msg, peer->connection - .status, + ->status, NULL)); vty_out(vty, " %8u", 0); @@ -13583,7 +13587,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, /* Status. */ json_object_string_add(json_neigh, "bgpState", lookup_msg(bgp_status_msg, - p->connection.status, NULL)); + p->connection->status, NULL)); if (peer_established(p)) { time_t uptime; @@ -13601,7 +13605,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, json_object_int_add(json_neigh, "bgpTimerUpEstablishedEpoch", epoch_tbuf); - } else if (p->connection.status == Active) { + } else if (p->connection->status == Active) { if (CHECK_FLAG(p->flags, PEER_FLAG_PASSIVE)) json_object_string_add(json_neigh, "bgpStateIs", "passive"); @@ -13662,7 +13666,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, /* Configured and Synced tcp-mss value for peer */ if (CHECK_FLAG(p->flags, PEER_FLAG_TCP_MSS)) { - sync_tcp_mss = sockopt_tcp_mss_get(p->connection.fd); + sync_tcp_mss = sockopt_tcp_mss_get(p->connection->fd); json_object_int_add(json_neigh, "bgpTcpMssConfigured", p->tcp_mss); json_object_int_add(json_neigh, "bgpTcpMssSynced", @@ -13707,13 +13711,13 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, /* Status. */ vty_out(vty, " BGP state = %s", - lookup_msg(bgp_status_msg, p->connection.status, NULL)); + lookup_msg(bgp_status_msg, p->connection->status, NULL)); if (peer_established(p)) vty_out(vty, ", up for %8s", peer_uptime(p->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL)); - else if (p->connection.status == Active) { + else if (p->connection->status == Active) { if (CHECK_FLAG(p->flags, PEER_FLAG_PASSIVE)) vty_out(vty, " (passive)"); else if (CHECK_FLAG(p->sflags, PEER_STATUS_NSF_WAIT)) @@ -13748,7 +13752,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, /* Configured and synced tcp-mss value for peer */ if (CHECK_FLAG(p->flags, PEER_FLAG_TCP_MSS)) { - sync_tcp_mss = sockopt_tcp_mss_get(p->connection.fd); + sync_tcp_mss = sockopt_tcp_mss_get(p->connection->fd); vty_out(vty, " Configured tcp-mss is %d", p->tcp_mss); vty_out(vty, ", synced tcp-mss is %d\n", sync_tcp_mss); } @@ -14722,9 +14726,9 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, /* Packet counts. */ atomic_size_t outq_count, inq_count; - outq_count = atomic_load_explicit(&p->connection.obuf->count, + outq_count = atomic_load_explicit(&p->connection->obuf->count, memory_order_relaxed); - inq_count = atomic_load_explicit(&p->connection.ibuf->count, + inq_count = atomic_load_explicit(&p->connection->ibuf->count, memory_order_relaxed); json_object_int_add(json_stat, "depthInq", @@ -14775,9 +14779,9 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, notify_out, notify_in, update_out, update_in, keepalive_out, keepalive_in, refresh_out, refresh_in, dynamic_cap_out, dynamic_cap_in; - outq_count = atomic_load_explicit(&p->connection.obuf->count, + outq_count = atomic_load_explicit(&p->connection->obuf->count, memory_order_relaxed); - inq_count = atomic_load_explicit(&p->connection.ibuf->count, + inq_count = atomic_load_explicit(&p->connection->ibuf->count, memory_order_relaxed); open_out = atomic_load_explicit(&p->open_out, memory_order_relaxed); @@ -15121,12 +15125,12 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, json_object_int_add(json_neigh, "authenticationEnabled", 1); - if (p->connection.t_read) + if (p->connection->t_read) json_object_string_add(json_neigh, "readThread", "on"); else json_object_string_add(json_neigh, "readThread", "off"); - if (CHECK_FLAG(p->connection.thread_flags, + if (CHECK_FLAG(p->connection->thread_flags, PEER_THREAD_WRITES_ON)) json_object_string_add(json_neigh, "writeThread", "on"); else @@ -15158,12 +15162,12 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, vty_out(vty, "Peer Authentication Enabled\n"); vty_out(vty, "Read thread: %s Write thread: %s FD used: %d\n", - p->connection.t_read ? "on" : "off", - CHECK_FLAG(p->connection.thread_flags, + p->connection->t_read ? "on" : "off", + CHECK_FLAG(p->connection->thread_flags, PEER_THREAD_WRITES_ON) ? "on" : "off", - p->connection.fd); + p->connection->fd); } if (p->notify.code == BGP_NOTIFY_OPEN_ERR @@ -16427,9 +16431,10 @@ static int bgp_show_one_peer_group(struct vty *vty, struct peer_group *group, PEER_STATUS_PREFIX_OVERFLOW)) peer_status = "Idle (PfxCt)"; else - peer_status = lookup_msg(bgp_status_msg, - peer->connection.status, - NULL); + peer_status = + lookup_msg(bgp_status_msg, + peer->connection->status, + NULL); dynamic = peer_dynamic_neighbor(peer); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 3b34f12e2a..7def60b4ec 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -135,7 +135,7 @@ static int bgp_check_main_socket(bool create, struct bgp *bgp) void bgp_session_reset(struct peer *peer) { if (peer->doppelganger && - (peer->doppelganger->connection.status != Deleted) && + (peer->doppelganger->connection->status != Deleted) && !(CHECK_FLAG(peer->doppelganger->flags, PEER_FLAG_CONFIG_NODE))) peer_delete(peer->doppelganger); @@ -157,7 +157,7 @@ static void bgp_session_reset_safe(struct peer *peer, struct listnode **nnode) npeer = (n) ? listgetdata(n) : NULL; if (peer->doppelganger && - (peer->doppelganger->connection.status != Deleted) && + (peer->doppelganger->connection->status != Deleted) && !(CHECK_FLAG(peer->doppelganger->flags, PEER_FLAG_CONFIG_NODE))) { if (peer->doppelganger == npeer) /* nnode and *nnode are confirmed to be non-NULL here */ @@ -306,7 +306,7 @@ static int bgp_router_id_set(struct bgp *bgp, const struct in_addr *id, for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { IPV4_ADDR_COPY(&peer->local_id, id); - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { peer->last_reset = PEER_DOWN_RID_CHANGE; bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -485,7 +485,7 @@ void bgp_cluster_id_set(struct bgp *bgp, struct in_addr *cluster_id) if (peer->sort != BGP_PEER_IBGP) continue; - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { peer->last_reset = PEER_DOWN_CLID_CHANGE; bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -509,7 +509,7 @@ void bgp_cluster_id_unset(struct bgp *bgp) if (peer->sort != BGP_PEER_IBGP) continue; - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { peer->last_reset = PEER_DOWN_CLID_CHANGE; bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -582,7 +582,7 @@ void bgp_confederation_id_set(struct bgp *bgp, as_t as, const char *as_str) if (ptype == BGP_PEER_EBGP) { peer->local_as = as; if (BGP_IS_VALID_STATE_FOR_NOTIF( - peer->connection.status)) { + peer->connection->status)) { peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE; bgp_notify_send( @@ -600,7 +600,7 @@ void bgp_confederation_id_set(struct bgp *bgp, as_t as, const char *as_str) if (ptype == BGP_PEER_EBGP) peer->local_as = as; if (BGP_IS_VALID_STATE_FOR_NOTIF( - peer->connection.status)) { + peer->connection->status)) { peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE; bgp_notify_send( @@ -628,7 +628,7 @@ void bgp_confederation_id_unset(struct bgp *bgp) if (peer_sort(peer) != BGP_PEER_IBGP) { peer->local_as = bgp->as; if (BGP_IS_VALID_STATE_FOR_NOTIF( - peer->connection.status)) { + peer->connection->status)) { peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE; bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -682,7 +682,7 @@ void bgp_confederation_peers_add(struct bgp *bgp, as_t as, const char *as_str) peer->local_as = bgp->as; (void)peer_sort(peer); if (BGP_IS_VALID_STATE_FOR_NOTIF( - peer->connection.status)) { + peer->connection->status)) { peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE; bgp_notify_send( @@ -739,7 +739,7 @@ void bgp_confederation_peers_remove(struct bgp *bgp, as_t as) peer->local_as = bgp->confed_id; (void)peer_sort(peer); if (BGP_IS_VALID_STATE_FOR_NOTIF( - peer->connection.status)) { + peer->connection->status)) { peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE; bgp_notify_send( @@ -1140,11 +1140,17 @@ static void bgp_peer_connection_free(struct peer_connection *connection) { bgp_peer_connection_buffers_free(connection); pthread_mutex_destroy(&connection->io_mtx); + + memset(connection, 0, sizeof(struct peer_connection)); + XFREE(MTYPE_BGP_PEER, connection); } -static void bgp_peer_connection_new(struct peer *peer, - struct peer_connection *connection) +struct peer_connection *bgp_peer_connection_new(struct peer *peer) { + struct peer_connection *connection; + + connection = XCALLOC(MTYPE_BGP_PEER, sizeof(struct peer_connection)); + connection->peer = peer; connection->fd = -1; @@ -1166,6 +1172,11 @@ static void bgp_peer_connection_new(struct peer *peer, */ connection->ibuf_work = ringbuf_new(BGP_MAX_PACKET_SIZE * BGP_READ_PACKET_MAX); + + connection->status = Idle; + connection->ostatus = Idle; + + return connection; } static void peer_free(struct peer *peer) @@ -1173,7 +1184,7 @@ static void peer_free(struct peer *peer) afi_t afi; safi_t safi; - assert(peer->connection.status == Deleted); + assert(peer->connection->status == Deleted); QOBJ_UNREG(peer); @@ -1181,17 +1192,15 @@ static void peer_free(struct peer *peer) * but just to be sure.. */ bgp_timer_set(peer); - bgp_reads_off(&peer->connection); - bgp_writes_off(&peer->connection); + bgp_reads_off(peer->connection); + bgp_writes_off(peer->connection); event_cancel_event_ready(bm->master, peer); FOREACH_AFI_SAFI (afi, safi) EVENT_OFF(peer->t_revalidate_all[afi][safi]); - assert(!peer->connection.t_write); - assert(!peer->connection.t_read); + assert(!peer->connection->t_write); + assert(!peer->connection->t_read); BGP_EVENT_FLUSH(peer); - bgp_peer_connection_free(&peer->connection); - /* Free connected nexthop, if present */ if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE) && !peer_dynamic_neighbor(peer)) @@ -1245,6 +1254,8 @@ static void peer_free(struct peer *peer) if (peer->as_pretty) XFREE(MTYPE_BGP, peer->as_pretty); + bgp_peer_connection_free(peer->connection); + bgp_unlock(peer->bgp); stream_free(peer->last_reset_cause); @@ -1426,11 +1437,12 @@ struct peer *peer_new(struct bgp *bgp) /* Allocate new peer. */ peer = XCALLOC(MTYPE_BGP_PEER, sizeof(struct peer)); + /* Create buffers. */ + peer->connection = bgp_peer_connection_new(peer); + /* Set default value. */ peer->v_start = BGP_INIT_START_TIMER; peer->v_connect = bgp->default_connect_retry; - peer->connection.status = Idle; - peer->connection.ostatus = Idle; peer->cur_event = peer->last_event = peer->last_major_event = 0; peer->bgp = bgp_lock(bgp); peer = peer_lock(peer); /* initial reference */ @@ -1468,7 +1480,7 @@ struct peer *peer_new(struct bgp *bgp) bgp_peer_gr_init(peer); /* Create buffers. */ - bgp_peer_connection_new(peer, &peer->connection); + peer->connection = bgp_peer_connection_new(peer); /* Get service port number. */ sp = getservbyname("bgp", "tcp"); @@ -1946,7 +1958,7 @@ void peer_as_change(struct peer *peer, as_t as, int as_specified, /* Stop peer. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { peer->last_reset = PEER_DOWN_REMOTE_AS_CHANGE; bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -2318,8 +2330,8 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi) BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } - if (peer->connection.status == OpenSent || - peer->connection.status == OpenConfirm) { + if (peer->connection->status == OpenSent || + peer->connection->status == OpenConfirm) { peer->last_reset = PEER_DOWN_AF_ACTIVATE; bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -2334,8 +2346,8 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi) * activation. */ other = peer->doppelganger; - if (other && (other->connection.status == OpenSent || - other->connection.status == OpenConfirm)) { + if (other && (other->connection->status == OpenSent || + other->connection->status == OpenConfirm)) { other->last_reset = PEER_DOWN_AF_ACTIVATE; bgp_notify_send(other, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -2556,7 +2568,7 @@ int peer_delete(struct peer *peer) struct listnode *pn; int accept_peer; - assert(peer->connection.status != Deleted); + assert(peer->connection->status != Deleted); bgp = peer->bgp; accept_peer = CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER); @@ -2564,14 +2576,14 @@ int peer_delete(struct peer *peer) bgp_soft_reconfig_table_task_cancel(bgp, NULL, peer); bgp_keepalives_off(peer); - bgp_reads_off(&peer->connection); - bgp_writes_off(&peer->connection); + bgp_reads_off(peer->connection); + bgp_writes_off(peer->connection); event_cancel_event_ready(bm->master, peer); FOREACH_AFI_SAFI (afi, safi) EVENT_OFF(peer->t_revalidate_all[afi][safi]); - assert(!CHECK_FLAG(peer->connection.thread_flags, + assert(!CHECK_FLAG(peer->connection->thread_flags, PEER_THREAD_WRITES_ON)); - assert(!CHECK_FLAG(peer->connection.thread_flags, + assert(!CHECK_FLAG(peer->connection->thread_flags, PEER_THREAD_READS_ON)); assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_KEEPALIVES_ON)); @@ -2894,7 +2906,7 @@ int peer_group_remote_as(struct bgp *bgp, const char *group_name, as_t *as, void peer_notify_unconfig(struct peer *peer) { - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_PEER_UNCONFIG); } @@ -2909,7 +2921,7 @@ static void peer_notify_shutdown(struct peer *peer) return; } - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN); } @@ -2921,7 +2933,7 @@ void peer_group_notify_unconfig(struct peer_group *group) for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) { other = peer->doppelganger; - if (other && other->connection.status != Deleted) { + if (other && other->connection->status != Deleted) { other->group = NULL; peer_notify_unconfig(other); } else @@ -2947,7 +2959,7 @@ int peer_group_delete(struct peer_group *group) bgp_zebra_terminate_radv(bgp, peer); peer_delete(peer); - if (other && other->connection.status != Deleted) { + if (other && other->connection->status != Deleted) { other->group = NULL; peer_delete(other); } @@ -2996,7 +3008,7 @@ int peer_group_remote_as_delete(struct peer_group *group) peer_delete(peer); - if (other && other->connection.status != Deleted) { + if (other && other->connection->status != Deleted) { other->group = NULL; peer_delete(other); } @@ -3176,7 +3188,7 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer, SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE); - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { peer->last_reset = PEER_DOWN_RMAP_BIND; bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -3732,7 +3744,7 @@ void bgp_instance_down(struct bgp *bgp) /* Bring down peers, so corresponding routes are purged. */ for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer)) { - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN); else @@ -4416,7 +4428,7 @@ void peer_change_action(struct peer *peer, afi_t afi, safi_t safi, /* If we're resetting session, we've to delete both peer struct */ if ((peer->doppelganger) && - (peer->doppelganger->connection.status != Deleted) && + (peer->doppelganger->connection->status != Deleted) && (!CHECK_FLAG(peer->doppelganger->flags, PEER_FLAG_CONFIG_NODE))) peer_delete(peer->doppelganger); @@ -4429,7 +4441,7 @@ void peer_change_action(struct peer *peer, afi_t afi, safi_t safi, BGP_ROUTE_REFRESH_NORMAL); else { if ((peer->doppelganger) && - (peer->doppelganger->connection.status != Deleted) && + (peer->doppelganger->connection->status != Deleted) && (!CHECK_FLAG(peer->doppelganger->flags, PEER_FLAG_CONFIG_NODE))) peer_delete(peer->doppelganger); @@ -4588,7 +4600,7 @@ static void peer_flag_modify_action(struct peer *peer, uint64_t flag) } if (BGP_IS_VALID_STATE_FOR_NOTIF( - peer->connection.status)) { + peer->connection->status)) { char *msg = peer->tx_shutdown_message; size_t msglen; uint8_t msgbuf[BGP_ADMIN_SHUTDOWN_MSG_LEN + 1]; @@ -4618,7 +4630,7 @@ static void peer_flag_modify_action(struct peer *peer, uint64_t flag) peer->v_start = BGP_INIT_START_TIMER; BGP_EVENT_ADD(peer, BGP_Stop); } - } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) { + } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { if (flag == PEER_FLAG_DYNAMIC_CAPABILITY) peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE; else if (flag == PEER_FLAG_PASSIVE) @@ -4655,7 +4667,7 @@ void bgp_shutdown_enable(struct bgp *bgp, const char *msg) continue; /* send a RFC 4486 notification message if necessary */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { if (msg) { size_t datalen = strlen(msg); @@ -5077,7 +5089,8 @@ int peer_ebgp_multihop_set(struct peer *peer, int ttl) if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { if (peer->sort != BGP_PEER_IBGP) { - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) + if (BGP_IS_VALID_STATE_FOR_NOTIF( + peer->connection->status)) bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else @@ -5095,7 +5108,8 @@ int peer_ebgp_multihop_set(struct peer *peer, int ttl) peer->ttl = group->conf->ttl; - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) + if (BGP_IS_VALID_STATE_FOR_NOTIF( + peer->connection->status)) bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else @@ -5132,7 +5146,7 @@ int peer_ebgp_multihop_unset(struct peer *peer) peer->ttl = ttl; if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else @@ -5149,9 +5163,9 @@ int peer_ebgp_multihop_unset(struct peer *peer) peer->ttl = BGP_DEFAULT_TTL; - if (peer->connection.fd >= 0) { + if (peer->connection->fd >= 0) { if (BGP_IS_VALID_STATE_FOR_NOTIF( - peer->connection.status)) + peer->connection->status)) bgp_notify_send( peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -5306,7 +5320,7 @@ int peer_update_source_if_set(struct peer *peer, const char *ifname) /* Check if handling a regular peer. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { /* Send notification or reset peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -5344,7 +5358,7 @@ int peer_update_source_if_set(struct peer *peer, const char *ifname) member->update_source = NULL; /* Send notification or reset peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection.status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) { member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; bgp_notify_send(member, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -5377,7 +5391,7 @@ void peer_update_source_addr_set(struct peer *peer, const union sockunion *su) /* Check if handling a regular peer. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { /* Send notification or reset peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -5414,7 +5428,7 @@ void peer_update_source_addr_set(struct peer *peer, const union sockunion *su) XFREE(MTYPE_PEER_UPDATE_SOURCE, member->update_if); /* Send notification or reset peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection.status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) { member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; bgp_notify_send(member, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -5465,7 +5479,7 @@ void peer_update_source_unset(struct peer *peer) /* Check if handling a regular peer. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { /* Send notification or reset peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -5501,7 +5515,7 @@ void peer_update_source_unset(struct peer *peer) XFREE(MTYPE_PEER_UPDATE_SOURCE, member->update_if); /* Send notification or reset peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection.status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) { member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; bgp_notify_send(member, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -6466,7 +6480,7 @@ int peer_local_as_unset(struct peer *peer) /* Check if handling a regular peer. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { /* Send notification or stop peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE; bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -6494,7 +6508,7 @@ int peer_local_as_unset(struct peer *peer) XFREE(MTYPE_BGP, member->change_local_as_pretty); /* Send notification or stop peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection.status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) { member->last_reset = PEER_DOWN_LOCAL_AS_CHANGE; bgp_notify_send(member, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); @@ -6526,7 +6540,7 @@ int peer_password_set(struct peer *peer, const char *password) /* Check if handling a regular peer. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { /* Send notification or reset peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else @@ -6562,7 +6576,7 @@ int peer_password_set(struct peer *peer, const char *password) member->password = XSTRDUP(MTYPE_PEER_PASSWORD, password); /* Send notification or reset peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection.status)) + if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) bgp_notify_send(member, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else @@ -6607,7 +6621,7 @@ int peer_password_unset(struct peer *peer) /* Check if handling a regular peer. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { /* Send notification or reset peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else @@ -6634,7 +6648,7 @@ int peer_password_unset(struct peer *peer) XFREE(MTYPE_PEER_PASSWORD, member->password); /* Send notification or reset peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection.status)) + if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) bgp_notify_send(member, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else @@ -7835,15 +7849,15 @@ int peer_ttl_security_hops_set(struct peer *peer, int gtsm_hops) if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { peer->gtsm_hops = gtsm_hops; - if (peer->connection.fd >= 0) + if (peer->connection->fd >= 0) sockopt_minttl(peer->su.sa.sa_family, - peer->connection.fd, + peer->connection->fd, MAXTTL + 1 - gtsm_hops); - if ((peer->connection.status < Established) && + if ((peer->connection->status < Established) && peer->doppelganger && - (peer->doppelganger->connection.fd >= 0)) + (peer->doppelganger->connection->fd >= 0)) sockopt_minttl(peer->su.sa.sa_family, - peer->doppelganger->connection.fd, + peer->doppelganger->connection->fd, MAXTTL + 1 - gtsm_hops); } else { group = peer->group; @@ -7860,18 +7874,18 @@ int peer_ttl_security_hops_set(struct peer *peer, int gtsm_hops) * no session then do nothing (will get * handled by next connection) */ - if (gpeer->connection.fd >= 0 && + if (gpeer->connection->fd >= 0 && gpeer->gtsm_hops != BGP_GTSM_HOPS_DISABLED) sockopt_minttl(gpeer->su.sa.sa_family, - gpeer->connection.fd, + gpeer->connection->fd, MAXTTL + 1 - gpeer->gtsm_hops); - if ((gpeer->connection.status < Established) && + if ((gpeer->connection->status < Established) && gpeer->doppelganger && - (gpeer->doppelganger->connection.fd >= 0)) + (gpeer->doppelganger->connection->fd >= 0)) sockopt_minttl(gpeer->su.sa.sa_family, gpeer->doppelganger - ->connection.fd, + ->connection->fd, MAXTTL + 1 - gtsm_hops); } } @@ -7904,15 +7918,15 @@ int peer_ttl_security_hops_unset(struct peer *peer) if (peer->sort == BGP_PEER_EBGP) ret = peer_ebgp_multihop_unset(peer); else { - if (peer->connection.fd >= 0) + if (peer->connection->fd >= 0) sockopt_minttl(peer->su.sa.sa_family, - peer->connection.fd, 0); + peer->connection->fd, 0); - if ((peer->connection.status < Established) && + if ((peer->connection->status < Established) && peer->doppelganger && - (peer->doppelganger->connection.fd >= 0)) + (peer->doppelganger->connection->fd >= 0)) sockopt_minttl(peer->su.sa.sa_family, - peer->doppelganger->connection.fd, + peer->doppelganger->connection->fd, 0); } } else { @@ -7922,16 +7936,16 @@ int peer_ttl_security_hops_unset(struct peer *peer) if (peer->sort == BGP_PEER_EBGP) ret = peer_ebgp_multihop_unset(peer); else { - if (peer->connection.fd >= 0) + if (peer->connection->fd >= 0) sockopt_minttl(peer->su.sa.sa_family, - peer->connection.fd, 0); + peer->connection->fd, 0); - if ((peer->connection.status < Established) && + if ((peer->connection->status < Established) && peer->doppelganger && - (peer->doppelganger->connection.fd >= 0)) + (peer->doppelganger->connection->fd >= 0)) sockopt_minttl(peer->su.sa.sa_family, peer->doppelganger - ->connection.fd, + ->connection->fd, 0); } } @@ -7983,7 +7997,7 @@ int peer_clear(struct peer *peer, struct listnode **nnode) return 0; peer->v_start = BGP_INIT_START_TIMER; - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_RESET); else @@ -8003,7 +8017,7 @@ int peer_clear_soft(struct peer *peer, afi_t afi, safi_t safi, if (!peer->afc[afi][safi]) return BGP_ERR_AF_UNCONFIGURED; - peer->rtt = sockopt_tcp_rtt(peer->connection.fd); + peer->rtt = sockopt_tcp_rtt(peer->connection->fd); if (stype == BGP_CLEAR_SOFT_OUT || stype == BGP_CLEAR_SOFT_BOTH) { /* Clear the "neighbor x.x.x.x default-originate" flag */ @@ -8286,8 +8300,9 @@ static int peer_unshut_after_cfg(struct bgp *bgp) peer->host); peer->shut_during_cfg = false; - if (peer_active(peer) && peer->connection.status != Established) { - if (peer->connection.status != Idle) + if (peer_active(peer) && + peer->connection->status != Established) { + if (peer->connection->status != Idle) BGP_EVENT_ADD(peer, BGP_Stop); BGP_EVENT_ADD(peer, BGP_Start); } @@ -8388,7 +8403,8 @@ void bgp_terminate(void) peer); continue; } - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection.status)) + if (BGP_IS_VALID_STATE_FOR_NOTIF( + peer->connection->status)) bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_PEER_UNCONFIG); } diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 196f25a24c..51e0cb3802 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1147,6 +1147,7 @@ struct peer_connection { #define PEER_THREAD_WRITES_ON (1U << 0) #define PEER_THREAD_READS_ON (1U << 1) }; +extern struct peer_connection *bgp_peer_connection_new(struct peer *peer); extern void bgp_peer_connection_buffers_free(struct peer_connection *connection); /* BGP neighbor structure. */ @@ -1213,7 +1214,7 @@ struct peer { * time to consolidate between the two, we'll solidify * into the connection variable being used. */ - struct peer_connection connection; + struct peer_connection *connection; int ttl; /* TTL of TCP connection to the peer. */ int rtt; /* Estimated round-trip-time from TCP_INFO */ @@ -2595,7 +2596,7 @@ static inline char *timestamp_string(time_t ts) static inline bool peer_established(struct peer *peer) { - return peer->connection.status == Established; + return peer->connection->status == Established; } static inline bool peer_dynamic_neighbor(struct peer *peer) diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index 6e99c74bcb..ff7137bdd9 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -1236,9 +1236,9 @@ static int rfapi_open_inner(struct rfapi_descriptor *rfd, struct bgp *bgp, * Fill in BGP peer structure */ rfd->peer = peer_new(bgp); - rfd->peer->connection.status = Established; /* keep bgp core happy */ + rfd->peer->connection->status = Established; /* keep bgp core happy */ - bgp_peer_connection_buffers_free(&rfd->peer->connection); + bgp_peer_connection_buffers_free(rfd->peer->connection); { /* base code assumes have valid host pointer */ char buf[INET6_ADDRSTRLEN]; diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c index 4fd057e848..c886beea91 100644 --- a/bgpd/rfapi/vnc_zebra.c +++ b/bgpd/rfapi/vnc_zebra.c @@ -171,11 +171,11 @@ static void vnc_redistribute_add(struct prefix *p, uint32_t metric, * Same setup as in rfapi_open() */ vncHD1VR.peer = peer_new(bgp); - vncHD1VR.peer->connection.status = + vncHD1VR.peer->connection->status = Established; /* keep bgp core happy */ bgp_peer_connection_buffers_free( - &vncHD1VR.peer->connection); + vncHD1VR.peer->connection); /* base code assumes have valid host pointer */ vncHD1VR.peer->host = diff --git a/tests/bgpd/test_aspath.c b/tests/bgpd/test_aspath.c index 6c52e4d86d..799733b7b5 100644 --- a/tests/bgpd/test_aspath.c +++ b/tests/bgpd/test_aspath.c @@ -1343,10 +1343,11 @@ static int handle_attr_test(struct aspath_tests *t) bgp.asnotation = t->segment->asnotation; peer.curr = stream_new(BGP_MAX_PACKET_SIZE); - peer.connection.obuf = stream_fifo_new(); + peer.connection = bgp_peer_connection_new(&peer); + peer.connection->obuf = stream_fifo_new(); peer.bgp = &bgp; peer.host = (char *)"none"; - peer.connection.fd = -1; + peer.connection->fd = -1; peer.cap = t->cap; peer.max_packet_size = BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE; diff --git a/tests/bgpd/test_capability.c b/tests/bgpd/test_capability.c index 6b6d910715..84c9f53066 100644 --- a/tests/bgpd/test_capability.c +++ b/tests/bgpd/test_capability.c @@ -972,7 +972,8 @@ int main(void) parse_test(peer, &opt_params[i++], OPT_PARAM); SET_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV); - peer->connection.status = Established; + peer->connection = bgp_peer_connection_new(peer); + peer->connection->status = Established; i = 0; while (dynamic_cap_msgs[i].name) diff --git a/tests/bgpd/test_mp_attr.c b/tests/bgpd/test_mp_attr.c index 29c706676c..cebdda9e5c 100644 --- a/tests/bgpd/test_mp_attr.c +++ b/tests/bgpd/test_mp_attr.c @@ -1085,7 +1085,8 @@ int main(void) peer = peer_create_accept(bgp); peer->host = (char *)"foo"; - peer->connection.status = Established; + peer->connection = bgp_peer_connection_new(peer); + peer->connection->status = Established; peer->curr = stream_new(BGP_MAX_PACKET_SIZE); ifp.ifindex = 0; diff --git a/tests/bgpd/test_packet.c b/tests/bgpd/test_packet.c index 638852f37c..a83276be07 100644 --- a/tests/bgpd/test_packet.c +++ b/tests/bgpd/test_packet.c @@ -64,11 +64,12 @@ int main(int argc, char *argv[]) } SET_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV); - peer->connection.status = Established; + peer->connection = bgp_peer_connection_new(peer); + peer->connection->status = Established; - peer->connection.fd = open(argv[1], O_RDONLY | O_NONBLOCK); + peer->connection->fd = open(argv[1], O_RDONLY | O_NONBLOCK); t.arg = peer; - peer->connection.t_read = &t; + peer->connection->t_read = &t; // printf("bgp_read_packet returns: %d\n", bgp_read(&t)); } -- 2.39.5