diff options
Diffstat (limited to 'bgpd')
34 files changed, 1250 insertions, 1139 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 3b2270293..791623344 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1368,7 +1368,8 @@ bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode, /* Only relax error handling for eBGP peers */ if (peer->sort != BGP_PEER_EBGP) { - bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR, subcode, + bgp_notify_send_with_data(peer->connection, + BGP_NOTIFY_UPDATE_ERR, subcode, notify_datap, length); return BGP_ATTR_PARSE_ERROR; } @@ -1412,7 +1413,8 @@ bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode, return BGP_ATTR_PARSE_WITHDRAW; case BGP_ATTR_MP_REACH_NLRI: case BGP_ATTR_MP_UNREACH_NLRI: - bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR, subcode, + bgp_notify_send_with_data(peer->connection, + BGP_NOTIFY_UPDATE_ERR, subcode, notify_datap, length); return BGP_ATTR_PARSE_ERROR; } @@ -1768,7 +1770,8 @@ enum bgp_attr_parse_ret bgp_attr_nexthop_valid(struct peer *peer, data[1] = BGP_ATTR_NEXT_HOP; data[2] = BGP_ATTR_NHLEN_IPV4; memcpy(&data[3], &attr->nexthop.s_addr, BGP_ATTR_NHLEN_IPV4); - bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR, + bgp_notify_send_with_data(peer->connection, + BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_INVAL_NEXT_HOP, data, 7); return BGP_ATTR_PARSE_ERROR; @@ -3487,7 +3490,8 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr, - stream_pnt(BGP_INPUT(peer)))); if (peer->sort != BGP_PEER_EBGP) { - bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, + bgp_notify_send(peer->connection, + BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); ret = BGP_ATTR_PARSE_ERROR; } else { @@ -3516,7 +3520,8 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr, - stream_pnt(BGP_INPUT(peer)))); if (peer->sort != BGP_PEER_EBGP) { - bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, + bgp_notify_send(peer->connection, + BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); ret = BGP_ATTR_PARSE_ERROR; } else { @@ -3581,10 +3586,10 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr, stream_get(&ndata[lfl + 1], BGP_INPUT(peer), ndl); - bgp_notify_send_with_data( - peer, BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, ndata, - ndl + lfl + 1); + bgp_notify_send_with_data(peer->connection, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, + ndata, ndl + lfl + 1); ret = BGP_ATTR_PARSE_ERROR; goto done; @@ -3619,7 +3624,8 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr, "%s: error BGP attribute type %d appears twice in a message", peer->host, type); - bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, + bgp_notify_send(peer->connection, + BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_MAL_ATTR); ret = BGP_ATTR_PARSE_ERROR; goto done; @@ -3747,7 +3753,7 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr, } if (ret == BGP_ATTR_PARSE_ERROR_NOTIFYPLS) { - bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, + bgp_notify_send(peer->connection, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_MAL_ATTR); ret = BGP_ATTR_PARSE_ERROR; goto done; @@ -3777,7 +3783,7 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr, flog_warn(EC_BGP_ATTRIBUTE_FETCH_ERROR, "%s: BGP attribute %s, fetch error", peer->host, lookup_msg(attr_str, type, NULL)); - bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, + bgp_notify_send(peer->connection, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); ret = BGP_ATTR_PARSE_ERROR; goto done; @@ -3800,7 +3806,7 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr, flog_warn(EC_BGP_ATTRIBUTES_MISMATCH, "%s: BGP attribute %s, length mismatch", peer->host, lookup_msg(attr_str, type, NULL)); - bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, + bgp_notify_send(peer->connection, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); ret = BGP_ATTR_PARSE_ERROR; @@ -3852,7 +3858,7 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr, if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS_PATH)) && bgp_attr_munge_as4_attrs(peer, attr, as4_path, as4_aggregator, &as4_aggregator_addr)) { - bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, + bgp_notify_send(peer->connection, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_MAL_ATTR); ret = BGP_ATTR_PARSE_ERROR; goto done; @@ -5145,7 +5151,7 @@ void bgp_path_attribute_discard_vty(struct vty *vty, struct peer *peer, * then flush all. */ if (!discard_attrs) { - for (i = 0; i < BGP_ATTR_MAX; i++) + for (i = 1; i <= BGP_ATTR_MAX; i++) peer->discard_attrs[i] = false; goto discard_soft_clear; } @@ -5154,7 +5160,7 @@ void bgp_path_attribute_discard_vty(struct vty *vty, struct peer *peer, frrstr_split(discard_attrs, " ", &attributes, &num_attributes); if (set) - for (i = 0; i < BGP_ATTR_MAX; i++) + for (i = 1; i <= BGP_ATTR_MAX; i++) peer->discard_attrs[i] = false; for (i = 0; i < num_attributes; i++) { @@ -5214,7 +5220,7 @@ void bgp_path_attribute_withdraw_vty(struct vty *vty, struct peer *peer, * then flush all. */ if (!withdraw_attrs) { - for (i = 0; i < BGP_ATTR_MAX; i++) + for (i = 1; i <= BGP_ATTR_MAX; i++) peer->withdraw_attrs[i] = false; goto withdraw_soft_clear; } @@ -5223,7 +5229,7 @@ void bgp_path_attribute_withdraw_vty(struct vty *vty, struct peer *peer, frrstr_split(withdraw_attrs, " ", &attributes, &num_attributes); if (set) - for (i = 0; i < BGP_ATTR_MAX; i++) + for (i = 1; i <= BGP_ATTR_MAX; i++) peer->withdraw_attrs[i] = false; for (i = 0; i < num_attributes; i++) { diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c index 7f83e9710..21864cf1a 100644 --- a/bgpd/bgp_bfd.c +++ b/bgpd/bgp_bfd.c @@ -57,17 +57,17 @@ static void bfd_session_status_update(struct bfd_session_params *bsp, /* rfc9384 */ if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_BFD_DOWN); - BGP_EVENT_ADD(peer, BGP_Stop); + BGP_EVENT_ADD(peer->connection, BGP_Stop); } - if (bss->state == BSS_UP && bss->previous_state != BSS_UP - && !peer_established(peer)) { + if (bss->state == BSS_UP && bss->previous_state != BSS_UP && + !peer_established(peer->connection)) { if (!BGP_PEER_START_SUPPRESSED(peer)) { - bgp_fsm_nht_update(peer, true); - BGP_EVENT_ADD(peer, BGP_Start); + bgp_fsm_nht_update(peer->connection, peer, true); + BGP_EVENT_ADD(peer->connection, BGP_Start); } } } @@ -163,36 +163,35 @@ void bgp_peer_bfd_update_source(struct peer *p) /* Update peer's source/destination addresses. */ bfd_sess_addresses(session, &family, &src.v6, &dst.v6); if (family == AF_INET) { - if ((source && source->sin.sin_addr.s_addr != src.v4.s_addr) - || p->su.sin.sin_addr.s_addr != dst.v4.s_addr) { + if ((source && source->sin.sin_addr.s_addr != src.v4.s_addr) || + p->connection->su.sin.sin_addr.s_addr != dst.v4.s_addr) { if (BGP_DEBUG(bfd, BFD_LIB)) - zlog_debug( - "%s: address [%pI4->%pI4] to [%pI4->%pI4]", - __func__, &src.v4, &dst.v4, - source ? &source->sin.sin_addr - : &src.v4, - &p->su.sin.sin_addr); - - bfd_sess_set_ipv4_addrs( - session, source ? &source->sin.sin_addr : NULL, - &p->su.sin.sin_addr); + zlog_debug("%s: address [%pI4->%pI4] to [%pI4->%pI4]", + __func__, &src.v4, &dst.v4, + source ? &source->sin.sin_addr + : &src.v4, + &p->connection->su.sin.sin_addr); + + bfd_sess_set_ipv4_addrs(session, + source ? &source->sin.sin_addr + : NULL, + &p->connection->su.sin.sin_addr); changed = true; } } else { - if ((source && memcmp(&source->sin6, &src.v6, sizeof(src.v6))) - || memcmp(&p->su.sin6, &dst.v6, sizeof(dst.v6))) { + if ((source && memcmp(&source->sin6, &src.v6, sizeof(src.v6))) || + memcmp(&p->connection->su.sin6, &dst.v6, sizeof(dst.v6))) { if (BGP_DEBUG(bfd, BFD_LIB)) - zlog_debug( - "%s: address [%pI6->%pI6] to [%pI6->%pI6]", - __func__, &src.v6, &dst.v6, - source ? &source->sin6.sin6_addr - : &src.v6, - &p->su.sin6.sin6_addr); + zlog_debug("%s: address [%pI6->%pI6] to [%pI6->%pI6]", + __func__, &src.v6, &dst.v6, + source ? &source->sin6.sin6_addr + : &src.v6, + &p->connection->su.sin6.sin6_addr); bfd_sess_set_ipv6_addrs(session, source ? &source->sin6.sin6_addr : NULL, - &p->su.sin6.sin6_addr); + &p->connection->su.sin6.sin6_addr); changed = true; } } @@ -284,16 +283,17 @@ void bgp_peer_configure_bfd(struct peer *p, bool manual) bgp_peer_bfd_reset(p); /* Configure session with basic BGP peer data. */ - if (p->su.sa.sa_family == AF_INET) + if (p->connection->su.sa.sa_family == AF_INET) bfd_sess_set_ipv4_addrs(p->bfd_config->session, p->su_local ? &p->su_local->sin.sin_addr : NULL, - &p->su.sin.sin_addr); + &p->connection->su.sin.sin_addr); else - bfd_sess_set_ipv6_addrs( - p->bfd_config->session, - p->su_local ? &p->su_local->sin6.sin6_addr : NULL, - &p->su.sin6.sin6_addr); + bfd_sess_set_ipv6_addrs(p->bfd_config->session, + p->su_local + ? &p->su_local->sin6.sin6_addr + : NULL, + &p->connection->su.sin6.sin6_addr); bfd_sess_set_vrf(p->bfd_config->session, p->bgp->vrf_id); bfd_sess_set_hop_count(p->bfd_config->session, diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index 9821dcf7b..727080291 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -264,7 +264,7 @@ static void bmp_per_peer_hdr(struct stream *s, struct peer *peer, stream_putc(s, BMP_PEER_TYPE_GLOBAL_INSTANCE); /* Peer Flags */ - if (peer->su.sa.sa_family == AF_INET6) + if (peer->connection->su.sa.sa_family == AF_INET6) SET_FLAG(flags, BMP_PEER_FLAG_V); else UNSET_FLAG(flags, BMP_PEER_FLAG_V); @@ -275,13 +275,13 @@ static void bmp_per_peer_hdr(struct stream *s, struct peer *peer, stream_put(s, &peer_distinguisher[0], 8); /* Peer Address */ - if (peer->su.sa.sa_family == AF_INET6) - stream_put(s, &peer->su.sin6.sin6_addr, 16); - else if (peer->su.sa.sa_family == AF_INET) { + if (peer->connection->su.sa.sa_family == AF_INET6) + stream_put(s, &peer->connection->su.sin6.sin6_addr, 16); + else if (peer->connection->su.sa.sa_family == AF_INET) { stream_putl(s, 0); stream_putl(s, 0); stream_putl(s, 0); - stream_put_in_addr(s, &peer->su.sin.sin_addr); + stream_put_in_addr(s, &peer->connection->su.sin.sin_addr); } else { stream_putl(s, 0); stream_putl(s, 0); @@ -370,7 +370,7 @@ static struct stream *bmp_peerstate(struct peer *peer, bool down) #define BGP_BMP_MAX_PACKET_SIZE 1024 s = stream_new(BGP_MAX_PACKET_SIZE); - if (peer_established(peer) && !down) { + if (peer_established(peer->connection) && !down) { struct bmp_bgp_peer *bbpeer; bmp_common_hdr(s, BMP_VERSION_3, @@ -716,7 +716,7 @@ static int bmp_peer_status_changed(struct peer *peer) /* Check if this peer just went to Established */ if ((peer->connection->ostatus != OpenConfirm) || - !(peer_established(peer))) + !(peer_established(peer->connection))) return 0; if (peer->doppelganger && @@ -1170,7 +1170,7 @@ static bool bmp_wrqueue(struct bmp *bmp, struct pullwr *pullwr) zlog_info("bmp: skipping queued item for deleted peer"); goto out; } - if (!peer_established(peer)) + if (!peer_established(peer->connection)) goto out; bool is_vpn = (bqe->afi == AFI_L2VPN && bqe->safi == SAFI_EVPN) || @@ -1355,7 +1355,7 @@ static void bmp_stats(struct event *thread) for (ALL_LIST_ELEMENTS_RO(bt->bgp->peer, node, peer)) { size_t count = 0, count_pos, len; - if (!peer_established(peer)) + if (!peer_established(peer->connection)) continue; s = stream_new(BGP_MAX_PACKET_SIZE); diff --git a/bgpd/bgp_conditional_adv.c b/bgpd/bgp_conditional_adv.c index 53652f7dc..b30052d95 100644 --- a/bgpd/bgp_conditional_adv.c +++ b/bgpd/bgp_conditional_adv.c @@ -194,7 +194,7 @@ static void bgp_conditional_adv_timer(struct event *t) if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) continue; - if (!peer_established(peer)) + if (!peer_established(peer->connection)) continue; FOREACH_AFI_SAFI (afi, safi) { diff --git a/bgpd/bgp_dump.c b/bgpd/bgp_dump.c index 3b5fbf368..529713ee3 100644 --- a/bgpd/bgp_dump.c +++ b/bgpd/bgp_dump.c @@ -246,14 +246,15 @@ static void bgp_dump_routes_index_table(struct bgp *bgp) /* Walk down all peers */ for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) { + int family = sockunion_family(&peer->connection->su); /* Peer's type */ - if (sockunion_family(&peer->su) == AF_INET) { + if (family == AF_INET) { stream_putc( obuf, TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4 + TABLE_DUMP_V2_PEER_INDEX_TABLE_IP); - } else if (sockunion_family(&peer->su) == AF_INET6) { + } else if (family == AF_INET6) { stream_putc( obuf, TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4 @@ -264,10 +265,13 @@ static void bgp_dump_routes_index_table(struct bgp *bgp) stream_put_in_addr(obuf, &peer->remote_id); /* Peer's IP address */ - if (sockunion_family(&peer->su) == AF_INET) { - stream_put_in_addr(obuf, &peer->su.sin.sin_addr); - } else if (sockunion_family(&peer->su) == AF_INET6) { - stream_write(obuf, (uint8_t *)&peer->su.sin6.sin6_addr, + if (family == AF_INET) { + stream_put_in_addr(obuf, + &peer->connection->su.sin.sin_addr); + } else if (family == AF_INET6) { + stream_write(obuf, + (uint8_t *)&peer->connection->su.sin6 + .sin6_addr, IPV6_MAX_BYTELEN); } @@ -468,24 +472,26 @@ static void bgp_dump_common(struct stream *obuf, struct peer *peer, stream_putw(obuf, peer->local_as); } - if (peer->su.sa.sa_family == AF_INET) { + if (peer->connection->su.sa.sa_family == AF_INET) { stream_putw(obuf, peer->ifp ? peer->ifp->ifindex : 0); stream_putw(obuf, AFI_IP); - stream_put(obuf, &peer->su.sin.sin_addr, IPV4_MAX_BYTELEN); + stream_put(obuf, &peer->connection->su.sin.sin_addr, + IPV4_MAX_BYTELEN); if (peer->su_local) stream_put(obuf, &peer->su_local->sin.sin_addr, IPV4_MAX_BYTELEN); else stream_put(obuf, empty, IPV4_MAX_BYTELEN); - } else if (peer->su.sa.sa_family == AF_INET6) { + } else if (peer->connection->su.sa.sa_family == AF_INET6) { /* Interface Index and Address family. */ stream_putw(obuf, peer->ifp ? peer->ifp->ifindex : 0); stream_putw(obuf, AFI_IP6); /* Source IP Address and Destination IP Address. */ - stream_put(obuf, &peer->su.sin6.sin6_addr, IPV6_MAX_BYTELEN); + stream_put(obuf, &peer->connection->su.sin6.sin6_addr, + IPV6_MAX_BYTELEN); if (peer->su_local) stream_put(obuf, &peer->su_local->sin6.sin6_addr, @@ -532,10 +538,10 @@ static void bgp_dump_packet_func(struct bgp_dump *bgp_dump, struct peer *peer, /* If dump file pointer is disabled return immediately. */ if (bgp_dump->fp == NULL) return; - if (peer->su.sa.sa_family == AF_INET) { + if (peer->connection->su.sa.sa_family == AF_INET) { addpath_capable = bgp_addpath_encode_rx(peer, AFI_IP, SAFI_UNICAST); - } else if (peer->su.sa.sa_family == AF_INET6) { + } else if (peer->connection->su.sa.sa_family == AF_INET6) { addpath_capable = bgp_addpath_encode_rx(peer, AFI_IP6, SAFI_UNICAST); } diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 786e95384..a84ddae01 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -93,9 +93,11 @@ int bgp_peer_reg_with_nht(struct peer *peer) && !CHECK_FLAG(peer->bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK)) connected = 1; - return bgp_find_or_add_nexthop( - peer->bgp, peer->bgp, family2afi(peer->su.sa.sa_family), - SAFI_UNICAST, NULL, peer, connected, NULL); + return bgp_find_or_add_nexthop(peer->bgp, peer->bgp, + family2afi( + peer->connection->su.sa.sa_family), + SAFI_UNICAST, NULL, peer, connected, + NULL); } static void peer_xfer_stats(struct peer *peer_dst, struct peer *peer_src) @@ -116,18 +118,30 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) struct peer *peer; afi_t afi; safi_t safi; - int fd; - enum bgp_fsm_status status, pstatus; enum bgp_fsm_events last_evt, last_maj_evt; + struct peer_connection *keeper, *going_away; assert(from_peer != NULL); + /* + * Keeper is the connection that is staying around + */ + keeper = from_peer->connection; peer = from_peer->doppelganger; if (!peer || !CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) return from_peer; /* + * from_peer is pointing at the non config node and + * at this point peer is pointing at the CONFIG node + * peer ( non incoming connection ). The going_away pointer + * is the connection that is being placed on to + * the non Config node for deletion. + */ + going_away = peer->connection; + + /* * Let's check that we are not going to loose known configuration * state based upon doppelganger rules. */ @@ -146,10 +160,10 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) 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(going_away); + bgp_reads_off(going_away); + bgp_writes_off(keeper); + bgp_reads_off(keeper); /* * Before exchanging FD remove doppelganger from @@ -157,70 +171,29 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) * fd is set to -1. If blocked on lock then keepalive * thread can access peer pointer with fd -1. */ - bgp_keepalives_off(from_peer); - - EVENT_OFF(peer->t_routeadv); - EVENT_OFF(peer->t_connect); - EVENT_OFF(peer->t_delayopen); - EVENT_OFF(peer->t_connect_check_r); - EVENT_OFF(peer->t_connect_check_w); - EVENT_OFF(from_peer->t_routeadv); - EVENT_OFF(from_peer->t_connect); - 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); + bgp_keepalives_off(keeper); + + EVENT_OFF(going_away->t_routeadv); + EVENT_OFF(going_away->t_connect); + EVENT_OFF(going_away->t_delayopen); + EVENT_OFF(going_away->t_connect_check_r); + EVENT_OFF(going_away->t_connect_check_w); + EVENT_OFF(keeper->t_routeadv); + EVENT_OFF(keeper->t_connect); + EVENT_OFF(keeper->t_delayopen); + EVENT_OFF(keeper->t_connect_check_r); + EVENT_OFF(keeper->t_connect_check_w); + EVENT_OFF(keeper->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; - - stream_fifo_clean(peer->connection->ibuf); - stream_fifo_clean(peer->connection->obuf); - - /* - * this should never happen, since bgp_process_packet() is the - * only task that sets and unsets the current packet and it - * runs in our pthread. - */ - if (peer->curr) { - flog_err( - EC_BGP_PKT_PROCESS, - "[%s] Dropping pending packet on connection transfer:", - peer->host); - /* there used to be a bgp_packet_dump call here, but - * that's extremely confusing since there's no way to - * identify the packet in MRT dumps or BMP as dropped - * due to connection transfer. - */ - stream_free(peer->curr); - peer->curr = NULL; - } - - // copy each packet from old peer's output queue to new peer - while (from_peer->connection->obuf->head) - stream_fifo_push(peer->connection->obuf, - stream_fifo_pop( - 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, - stream_fifo_pop( - 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)); - } + peer->connection = keeper; + keeper->peer = peer; + from_peer->connection = going_away; + going_away->peer = from_peer; peer->as = from_peer->as; peer->v_holdtime = from_peer->v_holdtime; @@ -230,16 +203,10 @@ 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; 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->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->last_event = last_evt; from_peer->last_major_event = last_maj_evt; peer->remote_id = from_peer->remote_id; @@ -301,13 +268,12 @@ 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); - BGP_EVENT_ADD(peer, BGP_Stop); - BGP_EVENT_ADD(from_peer, BGP_Stop); + peer->host, going_away->fd, keeper->fd); + BGP_EVENT_ADD(going_away, BGP_Stop); + BGP_EVENT_ADD(keeper, BGP_Stop); return NULL; } - if (from_peer->connection->status > Active) { + if (going_away->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)", @@ -316,9 +282,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); - bgp_stop(from_peer->connection); + from_peer->host, going_away->fd, keeper->fd); + bgp_stop(going_away); from_peer = NULL; } } @@ -335,10 +300,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(keeper); + bgp_writes_on(keeper); + event_add_event(bm->master, bgp_process_packet, keeper, 0, + &keeper->t_process_packet); return (peer); } @@ -346,88 +311,90 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) /* Hook function called after bgp event is occered. And vty's neighbor command invoke this function after making neighbor structure. */ -void bgp_timer_set(struct peer *peer) +void bgp_timer_set(struct peer_connection *connection) { afi_t afi; safi_t safi; + struct peer *peer = connection->peer; - switch (peer->connection->status) { + switch (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 inactive. All other timer must be turned off */ if (BGP_PEER_START_SUPPRESSED(peer) || !peer_active(peer) || peer->bgp->vrf_id == VRF_UNKNOWN) { - EVENT_OFF(peer->t_start); + EVENT_OFF(connection->t_start); } else { - BGP_TIMER_ON(peer->t_start, bgp_start_timer, + BGP_TIMER_ON(connection->t_start, bgp_start_timer, peer->v_start); } - EVENT_OFF(peer->t_connect); - EVENT_OFF(peer->t_holdtime); - bgp_keepalives_off(peer); - EVENT_OFF(peer->t_routeadv); - EVENT_OFF(peer->t_delayopen); + EVENT_OFF(connection->t_connect); + EVENT_OFF(connection->t_holdtime); + bgp_keepalives_off(connection); + EVENT_OFF(connection->t_routeadv); + EVENT_OFF(connection->t_delayopen); break; case Connect: /* After start timer is expired, the peer moves to Connect status. Make sure start timer is off and connect timer is on. */ - EVENT_OFF(peer->t_start); + EVENT_OFF(connection->t_start); if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN)) - BGP_TIMER_ON(peer->t_connect, bgp_connect_timer, + BGP_TIMER_ON(connection->t_connect, bgp_connect_timer, (peer->v_delayopen + peer->v_connect)); else - BGP_TIMER_ON(peer->t_connect, bgp_connect_timer, + BGP_TIMER_ON(connection->t_connect, bgp_connect_timer, peer->v_connect); - EVENT_OFF(peer->t_holdtime); - bgp_keepalives_off(peer); - EVENT_OFF(peer->t_routeadv); + EVENT_OFF(connection->t_holdtime); + bgp_keepalives_off(connection); + EVENT_OFF(connection->t_routeadv); break; case Active: /* Active is waiting connection from remote peer. And if connect timer is expired, change status to Connect. */ - EVENT_OFF(peer->t_start); + EVENT_OFF(connection->t_start); /* If peer is passive mode, do not set connect timer. */ if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSIVE) || CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) { - EVENT_OFF(peer->t_connect); + EVENT_OFF(connection->t_connect); } else { if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN)) - BGP_TIMER_ON( - peer->t_connect, bgp_connect_timer, - (peer->v_delayopen + peer->v_connect)); + BGP_TIMER_ON(connection->t_connect, + bgp_connect_timer, + (peer->v_delayopen + + peer->v_connect)); else - BGP_TIMER_ON(peer->t_connect, bgp_connect_timer, - peer->v_connect); + BGP_TIMER_ON(connection->t_connect, + bgp_connect_timer, peer->v_connect); } - EVENT_OFF(peer->t_holdtime); - bgp_keepalives_off(peer); - EVENT_OFF(peer->t_routeadv); + EVENT_OFF(connection->t_holdtime); + bgp_keepalives_off(connection); + EVENT_OFF(connection->t_routeadv); break; case OpenSent: /* OpenSent status. */ - EVENT_OFF(peer->t_start); - EVENT_OFF(peer->t_connect); + EVENT_OFF(connection->t_start); + EVENT_OFF(connection->t_connect); if (peer->v_holdtime != 0) { - BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer, + BGP_TIMER_ON(connection->t_holdtime, bgp_holdtime_timer, peer->v_holdtime); } else { - EVENT_OFF(peer->t_holdtime); + EVENT_OFF(connection->t_holdtime); } - bgp_keepalives_off(peer); - EVENT_OFF(peer->t_routeadv); - EVENT_OFF(peer->t_delayopen); + bgp_keepalives_off(connection); + EVENT_OFF(connection->t_routeadv); + EVENT_OFF(connection->t_delayopen); break; case OpenConfirm: /* OpenConfirm status. */ - EVENT_OFF(peer->t_start); - EVENT_OFF(peer->t_connect); + EVENT_OFF(connection->t_start); + EVENT_OFF(connection->t_connect); /* * If the negotiated Hold Time value is zero, then the Hold Time @@ -435,24 +402,24 @@ void bgp_timer_set(struct peer *peer) * Additionally if a different hold timer has been negotiated * than we must stop then start the timer again */ - EVENT_OFF(peer->t_holdtime); + EVENT_OFF(connection->t_holdtime); if (peer->v_holdtime == 0) - bgp_keepalives_off(peer); + bgp_keepalives_off(connection); else { - BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer, + BGP_TIMER_ON(connection->t_holdtime, bgp_holdtime_timer, peer->v_holdtime); - bgp_keepalives_on(peer); + bgp_keepalives_on(connection); } - EVENT_OFF(peer->t_routeadv); - EVENT_OFF(peer->t_delayopen); + EVENT_OFF(connection->t_routeadv); + EVENT_OFF(connection->t_delayopen); break; case Established: /* In Established status start and connect timer is turned off. */ - EVENT_OFF(peer->t_start); - EVENT_OFF(peer->t_connect); - EVENT_OFF(peer->t_delayopen); + EVENT_OFF(connection->t_start); + EVENT_OFF(connection->t_connect); + EVENT_OFF(connection->t_delayopen); /* * Same as OpenConfirm, if holdtime is zero then both holdtime @@ -460,32 +427,32 @@ void bgp_timer_set(struct peer *peer) * Additionally if a different hold timer has been negotiated * then we must stop then start the timer again */ - EVENT_OFF(peer->t_holdtime); + EVENT_OFF(connection->t_holdtime); if (peer->v_holdtime == 0) - bgp_keepalives_off(peer); + bgp_keepalives_off(connection); else { - BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer, + BGP_TIMER_ON(connection->t_holdtime, bgp_holdtime_timer, peer->v_holdtime); - bgp_keepalives_on(peer); + bgp_keepalives_on(connection); } break; case Deleted: - EVENT_OFF(peer->t_gr_restart); - EVENT_OFF(peer->t_gr_stale); + EVENT_OFF(peer->connection->t_gr_restart); + EVENT_OFF(peer->connection->t_gr_stale); FOREACH_AFI_SAFI (afi, safi) EVENT_OFF(peer->t_llgr_stale[afi][safi]); - EVENT_OFF(peer->t_pmax_restart); + EVENT_OFF(peer->connection->t_pmax_restart); EVENT_OFF(peer->t_refresh_stalepath); /* fallthru */ case Clearing: - EVENT_OFF(peer->t_start); - EVENT_OFF(peer->t_connect); - EVENT_OFF(peer->t_holdtime); - bgp_keepalives_off(peer); - EVENT_OFF(peer->t_routeadv); - EVENT_OFF(peer->t_delayopen); + EVENT_OFF(connection->t_start); + EVENT_OFF(connection->t_connect); + EVENT_OFF(connection->t_holdtime); + bgp_keepalives_off(connection); + EVENT_OFF(connection->t_routeadv); + EVENT_OFF(connection->t_delayopen); break; case BGP_STATUS_MAX: flog_err(EC_LIB_DEVELOPMENT, @@ -498,9 +465,8 @@ void bgp_timer_set(struct peer *peer) and process event. */ static void bgp_start_timer(struct event *thread) { - struct peer *peer; - - peer = EVENT_ARG(thread); + struct peer_connection *connection = EVENT_ARG(thread); + struct peer *peer = connection->peer; if (bgp_debug_neighbor_events(peer)) zlog_debug("%s [FSM] Timer (start timer expire).", peer->host); @@ -512,21 +478,20 @@ static void bgp_start_timer(struct event *thread) /* BGP connect retry timer. */ static void bgp_connect_timer(struct event *thread) { - struct peer *peer; - - peer = EVENT_ARG(thread); + struct peer_connection *connection = EVENT_ARG(thread); + struct peer *peer = connection->peer; /* stop the DelayOpenTimer if it is running */ - EVENT_OFF(peer->t_delayopen); + EVENT_OFF(connection->t_delayopen); - assert(!peer->connection->t_write); - assert(!peer->connection->t_read); + assert(!connection->t_write); + assert(!connection->t_read); if (bgp_debug_neighbor_events(peer)) zlog_debug("%s [FSM] Timer (connect timer expire)", peer->host); if (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) - bgp_stop(peer->connection); + bgp_stop(connection); else { EVENT_VAL(thread) = ConnectRetry_timer_expired; bgp_event(thread); /* bgp_event unlocks peer */ @@ -537,9 +502,8 @@ static void bgp_connect_timer(struct event *thread) static void bgp_holdtime_timer(struct event *thread) { atomic_size_t inq_count; - struct peer *peer; - - peer = EVENT_ARG(thread); + struct peer_connection *connection = EVENT_ARG(thread); + struct peer *peer = connection->peer; if (bgp_debug_neighbor_events(peer)) zlog_debug("%s [FSM] Timer (holdtime timer expire)", @@ -555,10 +519,10 @@ 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(&connection->ibuf->count, memory_order_relaxed); if (inq_count) - BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer, + BGP_TIMER_ON(connection->t_holdtime, bgp_holdtime_timer, peer->v_holdtime); EVENT_VAL(thread) = Hold_Timer_expired; @@ -567,18 +531,16 @@ static void bgp_holdtime_timer(struct event *thread) void bgp_routeadv_timer(struct event *thread) { - struct peer *peer; - - peer = EVENT_ARG(thread); + struct peer_connection *connection = EVENT_ARG(thread); + struct peer *peer = connection->peer; if (bgp_debug_neighbor_events(peer)) - zlog_debug("%s [FSM] Timer (routeadv timer expire)", - peer->host); + zlog_debug("%s [FSM] Timer (routeadv timer expire)", peer->host); peer->synctime = monotime(NULL); - event_add_timer_msec(bm->master, bgp_generate_updgrp_packets, peer, 0, - &peer->t_generate_updgrp_packets); + event_add_timer_msec(bm->master, bgp_generate_updgrp_packets, connection, + 0, &connection->t_generate_updgrp_packets); /* MRAI timer will be started again when FIFO is built, no need to * do it here. @@ -588,9 +550,8 @@ void bgp_routeadv_timer(struct event *thread) /* RFC 4271 DelayOpenTimer */ void bgp_delayopen_timer(struct event *thread) { - struct peer *peer; - - peer = EVENT_ARG(thread); + struct peer_connection *connection = EVENT_ARG(thread); + struct peer *peer = connection->peer; if (bgp_debug_neighbor_events(peer)) zlog_debug("%s [FSM] Timer (DelayOpentimer expire)", @@ -638,7 +599,8 @@ const char *const peer_down_str[] = {"", "Socket Error", "Admin. shutdown (RTT)"}; -static void bgp_graceful_restart_timer_off(struct peer *peer) +static void bgp_graceful_restart_timer_off(struct peer_connection *connection, + struct peer *peer) { afi_t afi; safi_t safi; @@ -649,7 +611,7 @@ static void bgp_graceful_restart_timer_off(struct peer *peer) return; UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT); - EVENT_OFF(peer->t_gr_stale); + EVENT_OFF(connection->t_gr_stale); if (peer_dynamic_neighbor(peer) && !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) { @@ -659,7 +621,7 @@ static void bgp_graceful_restart_timer_off(struct peer *peer) peer_delete(peer); } - bgp_timer_set(peer); + bgp_timer_set(connection); } static void bgp_llgr_stale_timer_expire(struct event *thread) @@ -687,7 +649,7 @@ static void bgp_llgr_stale_timer_expire(struct event *thread) bgp_clear_stale_route(peer, afi, safi); - bgp_graceful_restart_timer_off(peer); + bgp_graceful_restart_timer_off(peer->connection, peer); } static void bgp_set_llgr_stale(struct peer *peer, afi_t afi, safi_t safi) @@ -766,14 +728,14 @@ static void bgp_set_llgr_stale(struct peer *peer, afi_t afi, safi_t safi) static void bgp_graceful_restart_timer_expire(struct event *thread) { - struct peer *peer, *tmp_peer; + struct peer_connection *connection = EVENT_ARG(thread); + struct peer *peer = connection->peer; + struct peer *tmp_peer; struct listnode *node, *nnode; struct peer_af *paf; afi_t afi; safi_t safi; - peer = EVENT_ARG(thread); - if (bgp_debug_neighbor_events(peer)) { zlog_debug("%pBP graceful restart timer expired", peer); zlog_debug("%pBP graceful restart stalepath timer stopped", @@ -826,17 +788,16 @@ static void bgp_graceful_restart_timer_expire(struct event *thread) } } - bgp_graceful_restart_timer_off(peer); + bgp_graceful_restart_timer_off(connection, peer); } static void bgp_graceful_stale_timer_expire(struct event *thread) { - struct peer *peer; + struct peer_connection *connection = EVENT_ARG(thread); + struct peer *peer = connection->peer; afi_t afi; safi_t safi; - peer = EVENT_ARG(thread); - if (bgp_debug_neighbor_events(peer)) zlog_debug("%pBP graceful restart stalepath timer expired", peer); @@ -964,10 +925,13 @@ void bgp_start_routeadv(struct bgp *bgp) sizeof(bgp->update_delay_peers_resume_time)); for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - if (!peer_established(peer)) + struct peer_connection *connection = peer->connection; + + if (!peer_established(connection)) continue; - EVENT_OFF(peer->t_routeadv); - BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0); + + EVENT_OFF(connection->t_routeadv); + BGP_TIMER_ON(connection->t_routeadv, bgp_routeadv_timer, 0); } } @@ -979,6 +943,7 @@ void bgp_adjust_routeadv(struct peer *peer) time_t nowtime = monotime(NULL); double diff; unsigned long remain; + struct peer_connection *connection = peer->connection; /* Bypass checks for special case of MRAI being 0 */ if (peer->v_routeadv == 0) { @@ -986,7 +951,7 @@ void bgp_adjust_routeadv(struct peer *peer) * different * duration and schedule write thread immediately. */ - EVENT_OFF(peer->t_routeadv); + EVENT_OFF(connection->t_routeadv); peer->synctime = monotime(NULL); /* If suppress fib pending is enabled, route is advertised to @@ -994,7 +959,7 @@ void bgp_adjust_routeadv(struct peer *peer) * is added to update group packet generate which will allow * more routes to be sent in the update message */ - BGP_UPDATE_GROUP_TIMER_ON(&peer->t_generate_updgrp_packets, + BGP_UPDATE_GROUP_TIMER_ON(&connection->t_generate_updgrp_packets, bgp_generate_updgrp_packets); return; } @@ -1018,8 +983,8 @@ void bgp_adjust_routeadv(struct peer *peer) */ diff = difftime(nowtime, peer->last_update); if (diff > (double)peer->v_routeadv) { - EVENT_OFF(peer->t_routeadv); - BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0); + EVENT_OFF(connection->t_routeadv); + BGP_TIMER_ON(connection->t_routeadv, bgp_routeadv_timer, 0); return; } @@ -1039,14 +1004,14 @@ void bgp_adjust_routeadv(struct peer *peer) * * (MRAI - m) < r */ - if (peer->t_routeadv) - remain = event_timer_remain_second(peer->t_routeadv); + if (connection->t_routeadv) + remain = event_timer_remain_second(connection->t_routeadv); else remain = peer->v_routeadv; diff = peer->v_routeadv - diff; if (diff <= (double)remain) { - EVENT_OFF(peer->t_routeadv); - BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, diff); + EVENT_OFF(connection->t_routeadv); + BGP_TIMER_ON(connection->t_routeadv, bgp_routeadv_timer, diff); } } @@ -1154,7 +1119,7 @@ static void bgp_maxmed_onstartup_begin(struct bgp *bgp) static void bgp_maxmed_onstartup_process_status_change(struct peer *peer) { - if (peer_established(peer) && !peer->bgp->established) { + if (peer_established(peer->connection) && !peer->bgp->established) { bgp_maxmed_onstartup_begin(peer->bgp); } } @@ -1212,7 +1177,7 @@ static void bgp_update_delay_begin(struct bgp *bgp) static void bgp_update_delay_process_status_change(struct peer *peer) { - if (peer_established(peer)) { + if (peer_established(peer->connection)) { if (!peer->bgp->established++) { bgp_update_delay_begin(peer->bgp); zlog_info( @@ -1238,17 +1203,18 @@ static void bgp_update_delay_process_status_change(struct peer *peer) /* Called after event occurred, this function change status and reset read/write and timer thread. */ -void bgp_fsm_change_status(struct peer *peer, enum bgp_fsm_status status) +void bgp_fsm_change_status(struct peer_connection *connection, + enum bgp_fsm_status status) { - struct bgp *bgp; + struct peer *peer = connection->peer; + struct bgp *bgp = peer->bgp; uint32_t peer_count; - bgp = peer->bgp; peer_count = bgp->established_peers; if (status == Established) bgp->established_peers++; - else if ((peer_established(peer)) && (status != Established)) + else if ((peer_established(connection)) && (status != Established)) bgp->established_peers--; if (bgp_debug_neighbor_events(peer)) { @@ -1295,19 +1261,19 @@ void bgp_fsm_change_status(struct peer *peer, enum bgp_fsm_status status) */ if (!work_queue_is_scheduled(peer->clear_node_queue) && status != Deleted) - BGP_EVENT_ADD(peer, Clearing_Completed); + BGP_EVENT_ADD(connection, Clearing_Completed); } /* Preserve old status and change into new status. */ - peer->connection->ostatus = peer->connection->status; - peer->connection->status = status; + connection->ostatus = connection->status; + 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 (connection->ostatus == Established && + connection->status != Established) hook_call(peer_backward_transition, peer); /* Save event that caused status change. */ @@ -1335,23 +1301,19 @@ 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, - NULL), - lookup_msg(bgp_status_msg, peer->connection->status, - NULL)); + connection->fd, + lookup_msg(bgp_status_msg, connection->ostatus, NULL), + lookup_msg(bgp_status_msg, connection->status, NULL)); } /* Flush the event queue and ensure the peer is shut down */ static enum bgp_fsm_state_progress bgp_clearing_completed(struct peer_connection *connection) { - struct peer *peer = connection->peer; - enum bgp_fsm_state_progress rc = bgp_stop(connection); if (rc >= BGP_FSM_SUCCESS) - BGP_EVENT_FLUSH(peer); + event_cancel_event_ready(bm->master, connection); return rc; } @@ -1387,11 +1349,11 @@ enum bgp_fsm_state_progress bgp_stop(struct peer_connection *connection) /* Can't do this in Clearing; events are used for state transitions */ if (connection->status != Clearing) { /* Delete all existing events of the peer */ - BGP_EVENT_FLUSH(peer); + event_cancel_event_ready(bm->master, connection); } /* Increment Dropped count. */ - if (peer_established(peer)) { + if (peer_established(connection)) { peer->dropped++; /* Notify BGP conditional advertisement process */ @@ -1413,8 +1375,8 @@ enum bgp_fsm_state_progress bgp_stop(struct peer_connection *connection) } /* graceful restart */ - if (peer->t_gr_stale) { - EVENT_OFF(peer->t_gr_stale); + if (connection->t_gr_stale) { + EVENT_OFF(connection->t_gr_stale); if (bgp_debug_neighbor_events(peer)) zlog_debug( "%pBP graceful restart stalepath timer stopped", @@ -1429,10 +1391,10 @@ enum bgp_fsm_state_progress bgp_stop(struct peer_connection *connection) "%pBP graceful restart stalepath timer started for %d sec", peer, peer->bgp->stalepath_time); } - BGP_TIMER_ON(peer->t_gr_restart, + BGP_TIMER_ON(connection->t_gr_restart, bgp_graceful_restart_timer_expire, peer->v_gr_restart); - BGP_TIMER_ON(peer->t_gr_stale, + BGP_TIMER_ON(connection->t_gr_stale, bgp_graceful_stale_timer_expire, peer->bgp->stalepath_time); } else { @@ -1501,21 +1463,21 @@ enum bgp_fsm_state_progress bgp_stop(struct peer_connection *connection) } /* stop keepalives */ - bgp_keepalives_off(peer); + bgp_keepalives_off(connection); /* Stop read and write threads. */ bgp_writes_off(connection); bgp_reads_off(connection); - EVENT_OFF(peer->t_connect_check_r); - EVENT_OFF(peer->t_connect_check_w); + EVENT_OFF(connection->t_connect_check_r); + EVENT_OFF(connection->t_connect_check_w); /* Stop all timers. */ - EVENT_OFF(peer->t_start); - EVENT_OFF(peer->t_connect); - EVENT_OFF(peer->t_holdtime); - EVENT_OFF(peer->t_routeadv); - EVENT_OFF(peer->t_delayopen); + EVENT_OFF(connection->t_start); + EVENT_OFF(connection->t_connect); + EVENT_OFF(connection->t_holdtime); + EVENT_OFF(connection->t_routeadv); + EVENT_OFF(peer->connection->t_delayopen); /* Clear input and output buffer. */ frr_with_mutex (&connection->io_mtx) { @@ -1561,7 +1523,7 @@ enum bgp_fsm_state_progress bgp_stop(struct peer_connection *connection) peer->orf_plist[afi][safi] = NULL; if ((connection->status == OpenConfirm) || - peer_established(peer)) { + peer_established(connection)) { /* ORF received prefix-filter pnt */ snprintf(orf_name, sizeof(orf_name), "%s.%d.%d", peer->host, afi, safi); @@ -1591,7 +1553,7 @@ enum bgp_fsm_state_progress bgp_stop(struct peer_connection *connection) peer_delete(peer); ret = BGP_FSM_FAILURE_AND_DELETE; } else { - bgp_peer_conf_if_to_su_update(peer); + bgp_peer_conf_if_to_su_update(connection); } return ret; } @@ -1623,10 +1585,13 @@ bgp_stop_with_error(struct peer_connection *connection) /* something went wrong, send notify and tear down */ static enum bgp_fsm_state_progress -bgp_stop_with_notify(struct peer *peer, uint8_t code, uint8_t sub_code) +bgp_stop_with_notify(struct peer_connection *connection, uint8_t code, + uint8_t sub_code) { + struct peer *peer = connection->peer; + /* Send notify to remote peer */ - bgp_notify_send(peer, code, sub_code); + bgp_notify_send(connection, code, sub_code); if (peer_dynamic_neighbor_no_nsf(peer)) { if (bgp_debug_neighbor_events(peer)) @@ -1639,7 +1604,7 @@ bgp_stop_with_notify(struct peer *peer, uint8_t code, uint8_t sub_code) /* Clear start timer value to default. */ peer->v_start = BGP_INIT_START_TIMER; - return bgp_stop(peer->connection); + return bgp_stop(connection); } /** @@ -1662,44 +1627,43 @@ static void bgp_connect_check(struct event *thread) int status; socklen_t slen; int ret; - struct peer *peer; + struct peer_connection *connection = EVENT_ARG(thread); + struct peer *peer = connection->peer; - peer = EVENT_ARG(thread); - assert(!CHECK_FLAG(peer->connection->thread_flags, - PEER_THREAD_READS_ON)); - assert(!CHECK_FLAG(peer->connection->thread_flags, - PEER_THREAD_WRITES_ON)); - assert(!peer->connection->t_read); - assert(!peer->connection->t_write); + assert(!CHECK_FLAG(connection->thread_flags, PEER_THREAD_READS_ON)); + assert(!CHECK_FLAG(connection->thread_flags, PEER_THREAD_WRITES_ON)); + assert(!connection->t_read); + assert(!connection->t_write); - EVENT_OFF(peer->t_connect_check_r); - EVENT_OFF(peer->t_connect_check_w); + EVENT_OFF(connection->t_connect_check_r); + EVENT_OFF(connection->t_connect_check_w); /* Check file descriptor. */ slen = sizeof(status); - ret = getsockopt(peer->connection->fd, SOL_SOCKET, SO_ERROR, - (void *)&status, &slen); + ret = getsockopt(connection->fd, SOL_SOCKET, SO_ERROR, (void *)&status, + &slen); /* If getsockopt is fail, this is fatal error. */ if (ret < 0) { zlog_err("can't get sockopt for nonblocking connect: %d(%s)", errno, safe_strerror(errno)); - BGP_EVENT_ADD(peer, TCP_fatal_error); + BGP_EVENT_ADD(connection, TCP_fatal_error); return; } /* When status is 0 then TCP connection is established. */ if (status == 0) { if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN)) - BGP_EVENT_ADD(peer, TCP_connection_open_w_delay); + BGP_EVENT_ADD(connection, + TCP_connection_open_w_delay); else - BGP_EVENT_ADD(peer, TCP_connection_open); + BGP_EVENT_ADD(connection, TCP_connection_open); return; } else { if (bgp_debug_neighbor_events(peer)) zlog_debug("%s [Event] Connect failed %d(%s)", peer->host, status, safe_strerror(status)); - BGP_EVENT_ADD(peer, TCP_connection_open_failed); + BGP_EVENT_ADD(connection, TCP_connection_open_failed); return; } } @@ -1721,7 +1685,7 @@ bgp_connect_success(struct peer_connection *connection) flog_err_sys(EC_LIB_SOCKET, "%s: bgp_getsockname(): failed for peer %s, fd %d", __func__, peer->host, connection->fd); - bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, + bgp_notify_send(peer->connection, BGP_NOTIFY_FSM_ERR, bgp_fsm_error_subcode(connection->status)); bgp_writes_on(connection); return BGP_FSM_FAILURE; @@ -1744,7 +1708,7 @@ bgp_connect_success(struct peer_connection *connection) } /* Send an open message */ - bgp_open_send(peer); + bgp_open_send(connection); return BGP_FSM_SUCCESS; } @@ -1767,7 +1731,7 @@ bgp_connect_success_w_delayopen(struct peer_connection *connection) flog_err_sys(EC_LIB_SOCKET, "%s: bgp_getsockname(): failed for peer %s, fd %d", __func__, peer->host, connection->fd); - bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, + bgp_notify_send(peer->connection, BGP_NOTIFY_FSM_ERR, bgp_fsm_error_subcode(connection->status)); bgp_writes_on(connection); return BGP_FSM_FAILURE; @@ -1793,8 +1757,8 @@ bgp_connect_success_w_delayopen(struct peer_connection *connection) peer->v_delayopen = peer->delayopen; /* Start the DelayOpenTimer if it is not already running */ - if (!peer->t_delayopen) - BGP_TIMER_ON(peer->t_delayopen, bgp_delayopen_timer, + if (!peer->connection->t_delayopen) + BGP_TIMER_ON(peer->connection->t_delayopen, bgp_delayopen_timer, peer->v_delayopen); if (bgp_debug_neighbor_events(peer)) @@ -1835,9 +1799,9 @@ static enum bgp_fsm_state_progress bgp_start(struct peer_connection *connection) struct peer *peer = connection->peer; int status; - bgp_peer_conf_if_to_su_update(peer); + bgp_peer_conf_if_to_su_update(connection); - if (peer->su.sa.sa_family == AF_UNSPEC) { + if (connection->su.sa.sa_family == AF_UNSPEC) { if (bgp_debug_neighbor_events(peer)) zlog_debug( "%s [FSM] Unable to get neighbor's IP address, waiting...", @@ -1862,20 +1826,6 @@ static enum bgp_fsm_state_progress bgp_start(struct peer_connection *connection) return BGP_FSM_FAILURE; } - /* Scrub some information that might be left over from a previous, - * session - */ - /* Connection information. */ - if (peer->su_local) { - sockunion_free(peer->su_local); - peer->su_local = NULL; - } - - if (peer->su_remote) { - sockunion_free(peer->su_remote); - peer->su_remote = NULL; - } - /* Clear remote router-id. */ peer->remote_id.s_addr = INADDR_ANY; @@ -1884,7 +1834,7 @@ static enum bgp_fsm_state_progress bgp_start(struct peer_connection *connection) /* If the peer is passive mode, force to move to Active mode. */ if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSIVE)) { - BGP_EVENT_ADD(peer, TCP_connection_open_failed); + BGP_EVENT_ADD(connection, TCP_connection_open_failed); return BGP_FSM_SUCCESS; } @@ -1908,7 +1858,7 @@ static enum bgp_fsm_state_progress bgp_start(struct peer_connection *connection) "%s [FSM] Waiting for NHT, no path to neighbor present", peer->host); peer->last_reset = PEER_DOWN_WAITING_NHT; - BGP_EVENT_ADD(peer, TCP_connection_open_failed); + BGP_EVENT_ADD(connection, TCP_connection_open_failed); return BGP_FSM_SUCCESS; } } @@ -1917,20 +1867,20 @@ static enum bgp_fsm_state_progress bgp_start(struct peer_connection *connection) assert(!connection->t_read); assert(!CHECK_FLAG(connection->thread_flags, PEER_THREAD_WRITES_ON)); assert(!CHECK_FLAG(connection->thread_flags, PEER_THREAD_READS_ON)); - status = bgp_connect(peer); + status = bgp_connect(connection); switch (status) { case connect_error: if (bgp_debug_neighbor_events(peer)) zlog_debug("%s [FSM] Connect error", peer->host); - BGP_EVENT_ADD(peer, TCP_connection_open_failed); + BGP_EVENT_ADD(connection, TCP_connection_open_failed); break; case connect_success: if (bgp_debug_neighbor_events(peer)) zlog_debug("%s [FSM] Connect immediately success, fd %d", peer->host, connection->fd); - BGP_EVENT_ADD(peer, TCP_connection_open); + BGP_EVENT_ADD(connection, TCP_connection_open); break; case connect_in_progress: /* To check nonblocking connect, we wait until socket is @@ -1952,10 +1902,10 @@ static enum bgp_fsm_state_progress bgp_start(struct peer_connection *connection) * bgp_connect_check() as the handler for each and cancel the * unused event in that function. */ - event_add_read(bm->master, bgp_connect_check, peer, - 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); + event_add_read(bm->master, bgp_connect_check, connection, + connection->fd, &connection->t_connect_check_r); + event_add_write(bm->master, bgp_connect_check, connection, + connection->fd, &connection->t_connect_check_w); break; } return BGP_FSM_SUCCESS; @@ -1986,7 +1936,7 @@ bgp_fsm_open(struct peer_connection *connection) /* If DelayOpen is active, we may still need to send an open message */ if ((connection->status == Connect) || (connection->status == Active)) - bgp_open_send(peer); + bgp_open_send(connection); /* Send keepalive and make keepalive timer */ bgp_keepalive_send(peer); @@ -2005,7 +1955,7 @@ bgp_fsm_event_error(struct peer_connection *connection) peer->host, lookup_msg(bgp_status_msg, connection->status, NULL)); - return bgp_stop_with_notify(peer, BGP_NOTIFY_FSM_ERR, + return bgp_stop_with_notify(connection, BGP_NOTIFY_FSM_ERR, bgp_fsm_error_subcode(connection->status)); } @@ -2023,28 +1973,26 @@ bgp_fsm_holdtime_expire(struct peer_connection *connection) * the Graceful Restart procedures to be performed when the BGP * speaker receives a BGP NOTIFICATION message or the Hold Time expires. */ - if (peer_established(peer) && + if (peer_established(connection) && bgp_has_graceful_restart_notification(peer)) if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE)) SET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT); - return bgp_stop_with_notify(peer, BGP_NOTIFY_HOLD_ERR, 0); + return bgp_stop_with_notify(connection, BGP_NOTIFY_HOLD_ERR, 0); } /* RFC 4271 DelayOpenTimer_Expires event */ static enum bgp_fsm_state_progress bgp_fsm_delayopen_timer_expire(struct peer_connection *connection) { - struct peer *peer = connection->peer; - /* Stop the DelayOpenTimer */ - EVENT_OFF(peer->t_delayopen); + EVENT_OFF(connection->t_delayopen); /* Send open message to peer */ - bgp_open_send(peer); + bgp_open_send(connection); /* Set the HoldTimer to a large value (4 minutes) */ - peer->v_holdtime = 245; + connection->peer->v_holdtime = 245; return BGP_FSM_SUCCESS; } @@ -2160,6 +2108,11 @@ bgp_establish(struct peer_connection *connection) hash_alloc_intern); return BGP_FSM_FAILURE; } + /* + * At this point the connections have been possibly swapped + * let's reset it. + */ + connection = peer->connection; if (other == peer) ret = BGP_FSM_SUCCESS_STATE_TRANSFER; @@ -2173,7 +2126,7 @@ bgp_establish(struct peer_connection *connection) /* Increment established count. */ peer->established++; - bgp_fsm_change_status(peer, Established); + bgp_fsm_change_status(connection, Established); /* bgp log-neighbor-changes of neighbor Up */ if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) { @@ -2264,8 +2217,8 @@ bgp_establish(struct peer_connection *connection) SET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE); else { UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE); - if (peer->t_gr_stale) { - EVENT_OFF(peer->t_gr_stale); + if (connection->t_gr_stale) { + EVENT_OFF(connection->t_gr_stale); if (bgp_debug_neighbor_events(peer)) zlog_debug( "%pBP graceful restart stalepath timer stopped", @@ -2273,15 +2226,15 @@ bgp_establish(struct peer_connection *connection) } } - if (peer->t_gr_restart) { - EVENT_OFF(peer->t_gr_restart); + if (connection->t_gr_restart) { + EVENT_OFF(connection->t_gr_restart); if (bgp_debug_neighbor_events(peer)) zlog_debug("%pBP graceful restart timer stopped", peer); } /* Reset uptime, turn on keepalives, send current table. */ if (!peer->v_holdtime) - bgp_keepalives_on(peer); + bgp_keepalives_on(connection); peer->uptime = monotime(NULL); @@ -2327,8 +2280,9 @@ bgp_establish(struct peer_connection *connection) * of read-only mode. */ if (!bgp_update_delay_active(peer->bgp)) { - EVENT_OFF(peer->t_routeadv); - BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0); + EVENT_OFF(peer->connection->t_routeadv); + BGP_TIMER_ON(peer->connection->t_routeadv, bgp_routeadv_timer, + 0); } if (peer->doppelganger && @@ -2339,7 +2293,8 @@ bgp_establish(struct peer_connection *connection) peer->host); if (peer->doppelganger->connection->status > Active) - bgp_notify_send(peer->doppelganger, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->doppelganger->connection, + BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION); else peer_delete(peer->doppelganger); @@ -2364,7 +2319,7 @@ bgp_establish(struct peer_connection *connection) static enum bgp_fsm_state_progress bgp_fsm_keepalive(struct peer_connection *connection) { - EVENT_OFF(connection->peer->t_holdtime); + EVENT_OFF(connection->t_holdtime); return BGP_FSM_SUCCESS; } @@ -2372,7 +2327,7 @@ bgp_fsm_keepalive(struct peer_connection *connection) static enum bgp_fsm_state_progress bgp_fsm_update(struct peer_connection *connection) { - EVENT_OFF(connection->peer->t_holdtime); + EVENT_OFF(connection->t_holdtime); return BGP_FSM_SUCCESS; } @@ -2405,26 +2360,27 @@ bgp_fsm_exception(struct peer_connection *connection) return bgp_stop(connection); } -void bgp_fsm_nht_update(struct peer *peer, bool has_valid_nexthops) +void bgp_fsm_nht_update(struct peer_connection *connection, struct peer *peer, + bool has_valid_nexthops) { if (!peer) return; - switch (peer->connection->status) { + switch (connection->status) { case Idle: if (has_valid_nexthops) - BGP_EVENT_ADD(peer, BGP_Start); + BGP_EVENT_ADD(connection, BGP_Start); break; case Connect: if (!has_valid_nexthops) { - EVENT_OFF(peer->t_connect); - BGP_EVENT_ADD(peer, TCP_fatal_error); + EVENT_OFF(connection->t_connect); + BGP_EVENT_ADD(connection, TCP_fatal_error); } break; case Active: if (has_valid_nexthops) { - EVENT_OFF(peer->t_connect); - BGP_EVENT_ADD(peer, ConnectRetry_timer_expired); + EVENT_OFF(connection->t_connect); + BGP_EVENT_ADD(connection, ConnectRetry_timer_expired); } break; case OpenSent: @@ -2433,7 +2389,7 @@ void bgp_fsm_nht_update(struct peer *peer, bool has_valid_nexthops) if (!has_valid_nexthops && (peer->gtsm_hops == BGP_GTSM_HOPS_CONNECTED || peer->bgp->fast_convergence)) - BGP_EVENT_ADD(peer, TCP_fatal_error); + BGP_EVENT_ADD(connection, TCP_fatal_error); case Clearing: case Deleted: case BGP_STATUS_MAX: @@ -2611,50 +2567,48 @@ static const struct { /* Execute event process. */ void bgp_event(struct event *thread) { + struct peer_connection *connection = EVENT_ARG(thread); enum bgp_fsm_events event; - struct peer *peer; + struct peer *peer = connection->peer; - peer = EVENT_ARG(thread); event = EVENT_VAL(thread); peer_lock(peer); - bgp_event_update(peer, event); + bgp_event_update(connection, event); peer_unlock(peer); } -int bgp_event_update(struct peer *peer, enum bgp_fsm_events event) +int bgp_event_update(struct peer_connection *connection, + enum bgp_fsm_events event) { enum bgp_fsm_status next; enum bgp_fsm_state_progress ret = 0; int fsm_result = FSM_PEER_NOOP; - struct peer *other; int passive_conn = 0; int dyn_nbr; - struct peer_connection *connection = peer->connection; + struct peer *peer = connection->peer; - other = peer->doppelganger; passive_conn = (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) ? 1 : 0; dyn_nbr = peer_dynamic_neighbor(peer); /* Logging this event. */ - next = FSM[peer->connection->status - 1][event - 1].next_state; + next = FSM[connection->status - 1][event - 1].next_state; - if (bgp_debug_neighbor_events(peer) && peer->connection->status != next) + if (bgp_debug_neighbor_events(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, - NULL), + lookup_msg(bgp_status_msg, connection->status, NULL), lookup_msg(bgp_status_msg, next, NULL), - peer->connection->fd); + 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))( - peer->connection); + if (FSM[connection->status - 1][event - 1].func) + ret = (*(FSM[connection->status - 1][event - 1].func))( + connection); switch (ret) { case BGP_FSM_SUCCESS: @@ -2665,12 +2619,11 @@ int bgp_event_update(struct peer *peer, enum bgp_fsm_events event) bgp_establish. Update the peer pointer accordingly */ fsm_result = FSM_PEER_TRANSFERRED; - peer = other; } /* If status is changed. */ - if (next != peer->connection->status) { - bgp_fsm_change_status(peer, next); + if (next != connection->status) { + bgp_fsm_change_status(connection, next); /* * If we're going to ESTABLISHED then we executed a @@ -2684,7 +2637,7 @@ int bgp_event_update(struct peer *peer, enum bgp_fsm_events event) } /* Make sure timer is set. */ - bgp_timer_set(peer); + bgp_timer_set(connection); break; case BGP_FSM_FAILURE: /* @@ -2706,8 +2659,8 @@ int bgp_event_update(struct peer *peer, enum bgp_fsm_events event) connection->fd, peer_down_str[peer->last_reset]); bgp_stop(connection); - bgp_fsm_change_status(peer, Idle); - bgp_timer_set(peer); + bgp_fsm_change_status(connection, Idle); + bgp_timer_set(connection); } fsm_result = FSM_PEER_STOPPED; break; diff --git a/bgpd/bgp_fsm.h b/bgpd/bgp_fsm.h index 1f53ac611..fd46b7994 100644 --- a/bgpd/bgp_fsm.h +++ b/bgpd/bgp_fsm.h @@ -17,33 +17,28 @@ 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)) \ - event_add_timer(bm->master, (F), peer, (V), &(T)); \ + if ((connection->status != Deleted)) \ + event_add_timer(bm->master, (F), connection, (V), \ + &(T)); \ } while (0) -#define BGP_EVENT_ADD(P, E) \ +#define BGP_EVENT_ADD(C, E) \ do { \ - if ((P)->connection->status != Deleted) \ - event_add_event(bm->master, bgp_event, (P), (E), NULL); \ + if ((C)->status != Deleted) \ + event_add_event(bm->master, bgp_event, (C), (E), NULL); \ } while (0) -#define BGP_EVENT_FLUSH(P) \ - do { \ - assert(peer); \ - event_cancel_event_ready(bm->master, (P)); \ - } while (0) - -#define BGP_UPDATE_GROUP_TIMER_ON(T, F) \ - do { \ - if (BGP_SUPPRESS_FIB_ENABLED(peer->bgp) && \ - PEER_ROUTE_ADV_DELAY(peer)) \ - event_add_timer_msec( \ - bm->master, (F), peer, \ - (BGP_DEFAULT_UPDATE_ADVERTISEMENT_TIME * \ - 1000), \ - (T)); \ - else \ - event_add_timer_msec(bm->master, (F), peer, 0, (T)); \ +#define BGP_UPDATE_GROUP_TIMER_ON(T, F) \ + do { \ + if (BGP_SUPPRESS_FIB_ENABLED(peer->bgp) && \ + PEER_ROUTE_ADV_DELAY(peer)) \ + event_add_timer_msec(bm->master, (F), connection, \ + (BGP_DEFAULT_UPDATE_ADVERTISEMENT_TIME * \ + 1000), \ + (T)); \ + else \ + event_add_timer_msec(bm->master, (F), connection, 0, \ + (T)); \ } while (0) #define BGP_MSEC_JITTER 10 @@ -111,13 +106,15 @@ enum bgp_fsm_state_progress { /* * Update FSM for peer based on whether we have valid nexthops or not. */ -extern void bgp_fsm_nht_update(struct peer *peer, bool has_valid_nexthops); +extern void bgp_fsm_nht_update(struct peer_connection *connection, + struct peer *peer, bool has_valid_nexthops); extern void bgp_event(struct event *event); -extern int bgp_event_update(struct peer *, enum bgp_fsm_events event); +extern int bgp_event_update(struct peer_connection *connection, + enum bgp_fsm_events event); extern enum bgp_fsm_state_progress bgp_stop(struct peer_connection *connection); -extern void bgp_timer_set(struct peer *); +extern void bgp_timer_set(struct peer_connection *connection); extern void bgp_routeadv_timer(struct event *event); -extern void bgp_fsm_change_status(struct peer *peer, +extern void bgp_fsm_change_status(struct peer_connection *connection, enum bgp_fsm_status status); extern const char *const peer_down_str[]; extern void bgp_update_delay_end(struct bgp *); diff --git a/bgpd/bgp_io.c b/bgpd/bgp_io.c index 84e428cbc..b07e69ac3 100644 --- a/bgpd/bgp_io.c +++ b/bgpd/bgp_io.c @@ -45,7 +45,6 @@ static bool validate_header(struct peer_connection *connection); void bgp_writes_on(struct peer_connection *connection) { struct frr_pthread *fpt = bgp_pth_io; - struct peer *peer = connection->peer; assert(fpt->running); @@ -53,8 +52,8 @@ void bgp_writes_on(struct peer_connection *connection) assert(connection->obuf); assert(connection->ibuf); assert(connection->ibuf_work); - assert(!peer->t_connect_check_r); - assert(!peer->t_connect_check_w); + assert(!connection->t_connect_check_r); + assert(!connection->t_connect_check_w); assert(connection->fd); event_add_write(fpt->master, bgp_process_writes, connection, @@ -69,14 +68,13 @@ void bgp_writes_off(struct peer_connection *connection) assert(fpt->running); event_cancel_async(fpt->master, &connection->t_write, NULL); - EVENT_OFF(peer->t_generate_updgrp_packets); + EVENT_OFF(connection->t_generate_updgrp_packets); UNSET_FLAG(peer->connection->thread_flags, PEER_THREAD_WRITES_ON); } void bgp_reads_on(struct peer_connection *connection) { - struct peer *peer = connection->peer; struct frr_pthread *fpt = bgp_pth_io; assert(fpt->running); @@ -85,8 +83,8 @@ void bgp_reads_on(struct peer_connection *connection) assert(connection->fd); assert(connection->ibuf_work); assert(connection->obuf); - assert(!peer->t_connect_check_r); - assert(!peer->t_connect_check_w); + assert(!connection->t_connect_check_r); + assert(!connection->t_connect_check_w); assert(connection->fd); event_add_read(fpt->master, bgp_process_reads, connection, @@ -151,7 +149,7 @@ static void bgp_process_writes(struct event *thread) event_add_write(fpt->master, bgp_process_writes, connection, connection->fd, &connection->t_write); } else if (!fatal) { - BGP_UPDATE_GROUP_TIMER_ON(&peer->t_generate_updgrp_packets, + BGP_UPDATE_GROUP_TIMER_ON(&connection->t_generate_updgrp_packets, bgp_generate_updgrp_packets); } } @@ -362,7 +360,7 @@ static uint16_t bgp_write(struct peer_connection *connection) if (num < 0) { if (!ERRNO_IO_RETRY(errno)) { - BGP_EVENT_ADD(peer, TCP_fatal_error); + BGP_EVENT_ADD(connection, TCP_fatal_error); SET_FLAG(status, BGP_IO_FATAL_ERR); } else { SET_FLAG(status, BGP_IO_TRANS_ERR); @@ -439,7 +437,7 @@ static uint16_t bgp_write(struct peer_connection *connection) * Handle Graceful Restart case where the state changes * to Connect instead of Idle. */ - BGP_EVENT_ADD(peer, BGP_Stop); + BGP_EVENT_ADD(connection, BGP_Stop); goto done; case BGP_MSG_KEEPALIVE: diff --git a/bgpd/bgp_keepalives.c b/bgpd/bgp_keepalives.c index 48bde1220..92123c2cd 100644 --- a/bgpd/bgp_keepalives.c +++ b/bgpd/bgp_keepalives.c @@ -229,8 +229,10 @@ void *bgp_keepalives_start(void *arg) /* --- thread external functions ------------------------------------------- */ -void bgp_keepalives_on(struct peer *peer) +void bgp_keepalives_on(struct peer_connection *connection) { + struct peer *peer = connection->peer; + if (CHECK_FLAG(peer->thread_flags, PEER_THREAD_KEEPALIVES_ON)) return; @@ -258,8 +260,10 @@ void bgp_keepalives_on(struct peer *peer) } } -void bgp_keepalives_off(struct peer *peer) +void bgp_keepalives_off(struct peer_connection *connection) { + struct peer *peer = connection->peer; + if (!CHECK_FLAG(peer->thread_flags, PEER_THREAD_KEEPALIVES_ON)) return; diff --git a/bgpd/bgp_keepalives.h b/bgpd/bgp_keepalives.h index 2b4389cac..33e574da1 100644 --- a/bgpd/bgp_keepalives.h +++ b/bgpd/bgp_keepalives.h @@ -27,7 +27,7 @@ * If the peer is already registered for keepalives via this function, nothing * happens. */ -extern void bgp_keepalives_on(struct peer *); +extern void bgp_keepalives_on(struct peer_connection *connection); /** * Turns off keepalives for a peer. @@ -36,7 +36,7 @@ extern void bgp_keepalives_on(struct peer *); * * If the peer is already unregistered for keepalives, nothing happens. */ -extern void bgp_keepalives_off(struct peer *); +extern void bgp_keepalives_off(struct peer_connection *connection); /** * Pre-run initialization function for keepalives pthread. diff --git a/bgpd/bgp_mac.c b/bgpd/bgp_mac.c index 0398e4e8c..e629732c7 100644 --- a/bgpd/bgp_mac.c +++ b/bgpd/bgp_mac.c @@ -219,7 +219,7 @@ static void bgp_mac_rescan_evpn_table(struct bgp *bgp, struct ethaddr *macaddr) if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) continue; - if (!peer_established(peer)) + if (!peer_established(peer->connection)) continue; if (bgp_debug_update(peer, NULL, NULL, 1)) diff --git a/bgpd/bgp_memory.c b/bgpd/bgp_memory.c index edaaef602..5c3067f96 100644 --- a/bgpd/bgp_memory.c +++ b/bgpd/bgp_memory.c @@ -17,6 +17,7 @@ DEFINE_MGROUP(BGPD, "bgpd"); DEFINE_MTYPE(BGPD, BGP, "BGP instance"); DEFINE_MTYPE(BGPD, BGP_LISTENER, "BGP listen socket details"); DEFINE_MTYPE(BGPD, BGP_PEER, "BGP peer"); +DEFINE_MTYPE(BGPD, BGP_PEER_CONNECTION, "BGP peer connection"); DEFINE_MTYPE(BGPD, BGP_PEER_HOST, "BGP peer hostname"); DEFINE_MTYPE(BGPD, BGP_PEER_IFNAME, "BGP peer ifname"); DEFINE_MTYPE(BGPD, PEER_GROUP, "Peer group"); diff --git a/bgpd/bgp_memory.h b/bgpd/bgp_memory.h index 1256eafd0..7acb41eeb 100644 --- a/bgpd/bgp_memory.h +++ b/bgpd/bgp_memory.h @@ -13,6 +13,7 @@ DECLARE_MGROUP(BGPD); DECLARE_MTYPE(BGP); DECLARE_MTYPE(BGP_LISTENER); DECLARE_MTYPE(BGP_PEER); +DECLARE_MTYPE(BGP_PEER_CONNECTION); DECLARE_MTYPE(BGP_PEER_HOST); DECLARE_MTYPE(BGP_PEER_IFNAME); DECLARE_MTYPE(PEER_GROUP); diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index 62748a9e5..19b6f4eb7 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -245,8 +245,7 @@ static inline void vpn_leak_postchange(enum vpn_policy_direction direction, if (!CHECK_FLAG(bgp_vpn->af_flags[afi][SAFI_MPLS_VPN], BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL)) bgp_clear_soft_in(bgp_vpn, afi, SAFI_MPLS_VPN); - else - vpn_leak_to_vrf_update_all(bgp_vrf, bgp_vpn, afi); + vpn_leak_to_vrf_update_all(bgp_vrf, bgp_vpn, afi); } if (direction == BGP_VPN_POLICY_DIR_TOVPN) { diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index c5e7f7be6..3e252a06f 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -35,7 +35,7 @@ extern struct zebra_privs_t bgpd_privs; -static char *bgp_get_bound_name(struct peer *peer); +static char *bgp_get_bound_name(struct peer_connection *connection); void bgp_dump_listener_info(struct vty *vty) { @@ -117,11 +117,13 @@ static int bgp_md5_set_connect(int socket, union sockunion *su, return ret; } -static int bgp_md5_set_password(struct peer *peer, const char *password) +static int bgp_md5_set_password(struct peer_connection *connection, + const char *password) { struct listnode *node; int ret = 0; struct bgp_listener *listener; + struct peer *peer = connection->peer; /* * Set or unset the password on the listen socket(s). Outbound @@ -130,9 +132,9 @@ static int bgp_md5_set_password(struct peer *peer, const char *password) frr_with_privs(&bgpd_privs) { for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener)) if (listener->su.sa.sa_family == - peer->su.sa.sa_family) { + connection->su.sa.sa_family) { uint16_t prefixlen = - peer->su.sa.sa_family == AF_INET + connection->su.sa.sa_family == AF_INET ? IPV4_MAX_BITLEN : IPV6_MAX_BITLEN; @@ -149,8 +151,8 @@ static int bgp_md5_set_password(struct peer *peer, const char *password) continue; ret = bgp_md5_set_socket(listener->fd, - &peer->su, prefixlen, - password); + &connection->su, + prefixlen, password); break; } } @@ -186,10 +188,10 @@ int bgp_md5_unset_prefix(struct bgp *bgp, struct prefix *p) return bgp_md5_set_prefix(bgp, p, NULL); } -int bgp_md5_set(struct peer *peer) +int bgp_md5_set(struct peer_connection *connection) { /* Set the password from listen socket. */ - return bgp_md5_set_password(peer, peer->password); + return bgp_md5_set_password(connection, connection->peer->password); } static void bgp_update_setsockopt_tcp_keepalive(struct bgp *bgp, int fd) @@ -211,18 +213,20 @@ static void bgp_update_setsockopt_tcp_keepalive(struct bgp *bgp, int fd) } } -int bgp_md5_unset(struct peer *peer) +int bgp_md5_unset(struct peer_connection *connection) { /* Unset the password from listen socket. */ - return bgp_md5_set_password(peer, NULL); + return bgp_md5_set_password(connection, NULL); } -int bgp_set_socket_ttl(struct peer *peer, int bgp_sock) +int bgp_set_socket_ttl(struct peer_connection *connection) { int ret = 0; + struct peer *peer = connection->peer; if (!peer->gtsm_hops) { - ret = sockopt_ttl(peer->su.sa.sa_family, bgp_sock, peer->ttl); + ret = sockopt_ttl(connection->su.sa.sa_family, connection->fd, + peer->ttl); if (ret) { flog_err( EC_LIB_SOCKET, @@ -235,7 +239,8 @@ int bgp_set_socket_ttl(struct peer *peer, int bgp_sock) with the outgoing ttl. Therefore setting both. */ - ret = sockopt_ttl(peer->su.sa.sa_family, bgp_sock, MAXTTL); + ret = sockopt_ttl(connection->su.sa.sa_family, connection->fd, + MAXTTL); if (ret) { flog_err( EC_LIB_SOCKET, @@ -243,7 +248,7 @@ int bgp_set_socket_ttl(struct peer *peer, int bgp_sock) __func__, &peer->remote_id, errno); return ret; } - ret = sockopt_minttl(peer->su.sa.sa_family, bgp_sock, + ret = sockopt_minttl(connection->su.sa.sa_family, connection->fd, MAXTTL + 1 - peer->gtsm_hops); if (ret) { flog_err( @@ -344,8 +349,8 @@ static void bgp_accept(struct event *thread) int accept_sock; union sockunion su; struct bgp_listener *listener = EVENT_ARG(thread); - struct peer *peer; - struct peer *peer1; + struct peer *peer, *peer1; + struct peer_connection *connection, *connection1; char buf[SU_ADDRSTRLEN]; struct bgp *bgp = NULL; @@ -428,25 +433,24 @@ static void bgp_accept(struct event *thread) if (!peer1) { peer1 = peer_lookup_dynamic_neighbor(bgp, &su); if (peer1) { + connection1 = peer1->connection; /* Dynamic neighbor has been created, let it proceed */ - peer1->connection->fd = bgp_sock; + connection1->fd = bgp_sock; /* Set the user configured MSS to TCP socket */ if (CHECK_FLAG(peer1->flags, PEER_FLAG_TCP_MSS)) sockopt_tcp_mss_set(bgp_sock, peer1->tcp_mss); - bgp_fsm_change_status(peer1, Active); - EVENT_OFF( - peer1->t_start); /* created in peer_create() */ + bgp_fsm_change_status(connection1, Active); + EVENT_OFF(connection1->t_start); if (peer_active(peer1)) { if (CHECK_FLAG(peer1->flags, PEER_FLAG_TIMER_DELAYOPEN)) - BGP_EVENT_ADD( - peer1, - TCP_connection_open_w_delay); + BGP_EVENT_ADD(connection1, + TCP_connection_open_w_delay); else - BGP_EVENT_ADD(peer1, + BGP_EVENT_ADD(connection1, TCP_connection_open); } @@ -465,6 +469,7 @@ static void bgp_accept(struct event *thread) return; } + connection1 = peer1->connection; if (CHECK_FLAG(peer1->flags, PEER_FLAG_SHUTDOWN) || CHECK_FLAG(peer1->bgp->flags, BGP_FLAG_SHUTDOWN)) { if (bgp_debug_neighbor_events(peer1)) @@ -482,8 +487,7 @@ 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 (connection1->status == Clearing || connection1->status == Deleted) { if (bgp_debug_neighbor_events(peer1)) zlog_debug("[Event] Closing incoming conn for %s (%p) state %d", peer1->host, peer1, @@ -523,8 +527,8 @@ 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); + inet_sutop(&su, buf), bgp_sock, connection1->status, + connection1->fd); if (peer1->doppelganger) { /* We have an existing connection. Kill the existing one and run @@ -537,7 +541,7 @@ static void bgp_accept(struct event *thread) peer_delete(peer1->doppelganger); } - if (bgp_set_socket_ttl(peer1, bgp_sock) < 0) + if (bgp_set_socket_ttl(peer1->connection) < 0) if (bgp_debug_neighbor_events(peer1)) zlog_debug( "[Event] Unable to set min/max TTL on peer %s, Continuing", @@ -546,6 +550,8 @@ static void bgp_accept(struct event *thread) peer = peer_create(&su, peer1->conf_if, peer1->bgp, peer1->local_as, peer1->as, peer1->as_type, NULL, false, NULL); + connection = peer->connection; + peer_xfer_config(peer, peer1); bgp_peer_gr_flags_update(peer); @@ -563,18 +569,19 @@ static void bgp_accept(struct event *thread) peer->doppelganger = peer1; peer1->doppelganger = peer; - peer->connection->fd = bgp_sock; + connection->fd = bgp_sock; frr_with_privs(&bgpd_privs) { - vrf_bind(peer->bgp->vrf_id, bgp_sock, bgp_get_bound_name(peer)); + vrf_bind(peer->bgp->vrf_id, bgp_sock, + bgp_get_bound_name(peer->connection)); } bgp_peer_reg_with_nht(peer); - bgp_fsm_change_status(peer, Active); - EVENT_OFF(peer->t_start); /* created in peer_create() */ + bgp_fsm_change_status(connection, Active); + EVENT_OFF(connection->t_start); /* created in peer_create() */ SET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER); /* Make dummy peer until read Open packet. */ - if (peer_established(peer1) - && CHECK_FLAG(peer1->sflags, PEER_STATUS_NSF_MODE)) { + if (peer_established(connection1) && + CHECK_FLAG(peer1->sflags, PEER_STATUS_NSF_MODE)) { /* If we have an existing established connection with graceful * restart * capability announced with one or more address families, then @@ -588,14 +595,14 @@ static void bgp_accept(struct event *thread) PEER_FLAG_GRACEFUL_RESTART_HELPER)) SET_FLAG(peer1->sflags, PEER_STATUS_NSF_WAIT); - bgp_event_update(peer1, TCP_connection_closed); + bgp_event_update(connection1, TCP_connection_closed); } if (peer_active(peer)) { if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN)) - BGP_EVENT_ADD(peer, TCP_connection_open_w_delay); + BGP_EVENT_ADD(connection, TCP_connection_open_w_delay); else - BGP_EVENT_ADD(peer, TCP_connection_open); + BGP_EVENT_ADD(connection, TCP_connection_open); } /* @@ -606,24 +613,23 @@ static void bgp_accept(struct event *thread) } /* BGP socket bind. */ -static char *bgp_get_bound_name(struct peer *peer) +static char *bgp_get_bound_name(struct peer_connection *connection) { - if (!peer) - return NULL; + struct peer *peer = connection->peer; if ((peer->bgp->vrf_id == VRF_DEFAULT) && !peer->ifname && !peer->conf_if) return NULL; - if (peer->su.sa.sa_family != AF_INET - && peer->su.sa.sa_family != AF_INET6) + if (connection->su.sa.sa_family != AF_INET && + connection->su.sa.sa_family != AF_INET6) return NULL; // unexpected /* For IPv6 peering, interface (unnumbered or link-local with interface) * takes precedence over VRF. For IPv4 peering, explicit interface or * VRF are the situations to bind. */ - if (peer->su.sa.sa_family == AF_INET6 && peer->conf_if) + if (connection->su.sa.sa_family == AF_INET6 && peer->conf_if) return peer->conf_if; if (peer->ifname) @@ -667,11 +673,12 @@ int bgp_update_address(struct interface *ifp, const union sockunion *dst, } /* Update source selection. */ -static int bgp_update_source(struct peer *peer) +static int bgp_update_source(struct peer_connection *connection) { struct interface *ifp; union sockunion addr; int ret = 0; + struct peer *peer = connection->peer; sockunion_init(&addr); @@ -681,41 +688,41 @@ static int bgp_update_source(struct peer *peer) if (!ifp) return -1; - if (bgp_update_address(ifp, &peer->su, &addr)) + if (bgp_update_address(ifp, &connection->su, &addr)) return -1; - ret = sockunion_bind(peer->connection->fd, &addr, 0, &addr); + ret = sockunion_bind(connection->fd, &addr, 0, &addr); } /* Source is specified with IP address. */ if (peer->update_source) - ret = sockunion_bind(peer->connection->fd, peer->update_source, - 0, peer->update_source); + ret = sockunion_bind(connection->fd, peer->update_source, 0, + peer->update_source); return ret; } /* BGP try to connect to the peer. */ -int bgp_connect(struct peer *peer) +int bgp_connect(struct peer_connection *connection) { - assert(!CHECK_FLAG(peer->connection->thread_flags, - PEER_THREAD_WRITES_ON)); - assert(!CHECK_FLAG(peer->connection->thread_flags, - PEER_THREAD_READS_ON)); + struct peer *peer = connection->peer; + + assert(!CHECK_FLAG(connection->thread_flags, PEER_THREAD_WRITES_ON)); + assert(!CHECK_FLAG(connection->thread_flags, PEER_THREAD_READS_ON)); ifindex_t ifindex = 0; - if (peer->conf_if && BGP_PEER_SU_UNSPEC(peer)) { + if (peer->conf_if && BGP_CONNECTION_SU_UNSPEC(connection)) { if (bgp_debug_neighbor_events(peer)) zlog_debug("Peer address not learnt: Returning from connect"); return 0; } frr_with_privs(&bgpd_privs) { /* Make socket for the peer. */ - peer->connection->fd = - vrf_sockunion_socket(&peer->su, peer->bgp->vrf_id, - bgp_get_bound_name(peer)); + connection->fd = + vrf_sockunion_socket(&connection->su, peer->bgp->vrf_id, + bgp_get_bound_name(connection)); } - if (peer->connection->fd < 0) { + if (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)", @@ -724,18 +731,18 @@ int bgp_connect(struct peer *peer) return -1; } - set_nonblocking(peer->connection->fd); + set_nonblocking(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(connection->fd, peer->tcp_mss); - bgp_socket_set_buffer_size(peer->connection->fd); + bgp_socket_set_buffer_size(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, connection->fd); - if (bgp_set_socket_ttl(peer, peer->connection->fd) < 0) { + if (bgp_set_socket_ttl(peer->connection) < 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)", @@ -745,33 +752,32 @@ int bgp_connect(struct peer *peer) return -1; } - sockopt_reuseaddr(peer->connection->fd); - sockopt_reuseport(peer->connection->fd); + sockopt_reuseaddr(connection->fd); + sockopt_reuseport(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); - else if (sockunion_family(&peer->su) == AF_INET6) - setsockopt_ipv6_tclass(peer->connection->fd, - bm->tcp_dscp); + if (sockunion_family(&connection->su) == AF_INET) + setsockopt_ipv4_tos(connection->fd, bm->tcp_dscp); + else if (sockunion_family(&connection->su) == AF_INET6) + setsockopt_ipv6_tclass(connection->fd, bm->tcp_dscp); } #endif if (peer->password) { - uint16_t prefixlen = peer->su.sa.sa_family == AF_INET + uint16_t prefixlen = peer->connection->su.sa.sa_family == AF_INET ? IPV4_MAX_BITLEN : IPV6_MAX_BITLEN; - if (!BGP_PEER_SU_UNSPEC(peer)) - bgp_md5_set(peer); + if (!BGP_CONNECTION_SU_UNSPEC(connection)) + bgp_md5_set(connection); - bgp_md5_set_connect(peer->connection->fd, &peer->su, prefixlen, + bgp_md5_set_connect(connection->fd, &connection->su, prefixlen, peer->password); } /* Update source bind. */ - if (bgp_update_source(peer) < 0) { + if (bgp_update_source(connection) < 0) { peer->last_reset = PEER_DOWN_SOCKET_ERROR; return connect_error; } @@ -783,10 +789,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, connection->fd); /* Connect to the remote peer. */ - return sockunion_connect(peer->connection->fd, &peer->su, + return sockunion_connect(connection->fd, &connection->su, htons(peer->port), ifindex); } diff --git a/bgpd/bgp_network.h b/bgpd/bgp_network.h index cf0b4362c..f26d64f1f 100644 --- a/bgpd/bgp_network.h +++ b/bgpd/bgp_network.h @@ -21,15 +21,15 @@ extern int bgp_socket(struct bgp *bgp, unsigned short port, const char *address); extern void bgp_close_vrf_socket(struct bgp *bgp); extern void bgp_close(void); -extern int bgp_connect(struct peer *); -extern int bgp_getsockname(struct peer *); +extern int bgp_connect(struct peer_connection *connection); +extern int bgp_getsockname(struct peer *peer); extern int bgp_md5_set_prefix(struct bgp *bgp, struct prefix *p, const char *password); extern int bgp_md5_unset_prefix(struct bgp *bgp, struct prefix *p); -extern int bgp_md5_set(struct peer *); -extern int bgp_md5_unset(struct peer *); -extern int bgp_set_socket_ttl(struct peer *, int fd); +extern int bgp_md5_set(struct peer_connection *connection); +extern int bgp_md5_unset(struct peer_connection *connection); +extern int bgp_set_socket_ttl(struct peer_connection *connection); extern int bgp_update_address(struct interface *ifp, const union sockunion *dst, union sockunion *addr); diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 367c7056f..7f1a6e73e 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -385,6 +385,7 @@ void bgp_connected_add(struct bgp *bgp, struct connected *ifc) struct bgp_connected_ref *bc; struct listnode *node, *nnode; struct peer *peer; + struct peer_connection *connection; addr = ifc->address; @@ -409,14 +410,14 @@ void bgp_connected_add(struct bgp *bgp, struct connected *ifc) } for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - if (peer->conf_if - && (strcmp(peer->conf_if, ifc->ifp->name) == 0) - && !peer_established(peer) - && !CHECK_FLAG(peer->flags, - PEER_FLAG_IFPEER_V6ONLY)) { + if (peer->conf_if && + (strcmp(peer->conf_if, ifc->ifp->name) == 0) && + !peer_established(peer->connection) && + !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) { + connection = peer->connection; if (peer_active(peer)) - BGP_EVENT_ADD(peer, BGP_Stop); - BGP_EVENT_ADD(peer, BGP_Start); + BGP_EVENT_ADD(connection, BGP_Stop); + BGP_EVENT_ADD(connection, BGP_Start); } } } else if (addr->family == AF_INET6) { @@ -596,7 +597,7 @@ bool bgp_multiaccess_check_v4(struct in_addr nexthop, struct peer *peer) p.family = AF_INET; p.prefixlen = IPV4_MAX_BITLEN; - p.u.prefix4 = peer->su.sin.sin_addr; + p.u.prefix4 = peer->connection->su.sin.sin_addr; dest2 = bgp_node_match(peer->bgp->connected_table[AFI_IP], &p); if (!dest2) { @@ -629,7 +630,7 @@ bool bgp_multiaccess_check_v6(struct in6_addr nexthop, struct peer *peer) p.family = AF_INET6; p.prefixlen = IPV6_MAX_BITLEN; - p.u.prefix6 = peer->su.sin6.sin6_addr; + p.u.prefix6 = peer->connection->su.sin6.sin6_addr; dest2 = bgp_node_match(peer->bgp->connected_table[AFI_IP6], &p); if (!dest2) { @@ -671,7 +672,7 @@ bool bgp_subgrp_multiaccess_check_v6(struct in6_addr nexthop, if (paf->peer == exclude) continue; - p.u.prefix6 = paf->peer->su.sin6.sin6_addr; + p.u.prefix6 = paf->peer->connection->su.sin6.sin6_addr; dest2 = bgp_node_match(bgp->connected_table[AFI_IP6], &p); if (dest1 == dest2) { bgp_dest_unlock_node(dest1); @@ -713,7 +714,7 @@ bool bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop, if (paf->peer == exclude) continue; - p.u.prefix4 = paf->peer->su.sin.sin_addr; + p.u.prefix4 = paf->peer->connection->su.sin.sin_addr; dest2 = bgp_node_match(bgp->connected_table[AFI_IP], &p); if (dest1 == dest2) { diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 3bf7ac91b..60d6f74e1 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -173,20 +173,21 @@ void bgp_replace_nexthop_by_peer(struct peer *from, struct peer *to) afi_t afi; ifindex_t ifindex = 0; - if (!sockunion2hostprefix(&from->su, &pp)) + if (!sockunion2hostprefix(&from->connection->su, &pp)) return; /* * Gather the ifindex for if up/down events to be * tagged into this fun */ - if (from->conf_if && IN6_IS_ADDR_LINKLOCAL(&from->su.sin6.sin6_addr)) - ifindex = from->su.sin6.sin6_scope_id; + if (from->conf_if && + IN6_IS_ADDR_LINKLOCAL(&from->connection->su.sin6.sin6_addr)) + ifindex = from->connection->su.sin6.sin6_scope_id; afi = family2afi(pp.family); bncp = bnc_find(&from->bgp->nexthop_cache_table[afi], &pp, 0, ifindex); - if (!sockunion2hostprefix(&to->su, &pt)) + if (!sockunion2hostprefix(&to->connection->su, &pt)) return; /* @@ -194,8 +195,9 @@ void bgp_replace_nexthop_by_peer(struct peer *from, struct peer *to) * tagged into this fun */ ifindex = 0; - if (to->conf_if && IN6_IS_ADDR_LINKLOCAL(&to->su.sin6.sin6_addr)) - ifindex = to->su.sin6.sin6_scope_id; + if (to->conf_if && + IN6_IS_ADDR_LINKLOCAL(&to->connection->su.sin6.sin6_addr)) + ifindex = to->connection->su.sin6.sin6_scope_id; bnct = bnc_find(&to->bgp->nexthop_cache_table[afi], &pt, 0, ifindex); if (bnct != bncp) @@ -240,10 +242,10 @@ void bgp_unlink_nexthop_by_peer(struct peer *peer) { struct prefix p; struct bgp_nexthop_cache *bnc; - afi_t afi = family2afi(peer->su.sa.sa_family); + afi_t afi = family2afi(peer->connection->su.sa.sa_family); ifindex_t ifindex = 0; - if (!sockunion2hostprefix(&peer->su, &p)) { + if (!sockunion2hostprefix(&peer->connection->su, &p)) { /* * In scenarios where unnumbered BGP session is brought * down by shutting down the interface before unconfiguring @@ -261,8 +263,8 @@ void bgp_unlink_nexthop_by_peer(struct peer *peer) * tagged into this fun */ if (afi == AFI_IP6 && - IN6_IS_ADDR_LINKLOCAL(&peer->su.sin6.sin6_addr)) - ifindex = peer->su.sin6.sin6_scope_id; + IN6_IS_ADDR_LINKLOCAL(&peer->connection->su.sin6.sin6_addr)) + ifindex = peer->connection->su.sin6.sin6_scope_id; bnc = bnc_find(&peer->bgp->nexthop_cache_table[afi], &p, 0, ifindex); } @@ -327,9 +329,11 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, * the ifindex. */ if (afi == AFI_IP6 && - IN6_IS_ADDR_LINKLOCAL(&pi->peer->su.sin6.sin6_addr) && - IPV6_ADDR_SAME(&pi->peer->su.sin6.sin6_addr, &p.u.prefix6)) - ifindex = pi->peer->su.sin6.sin6_scope_id; + IN6_IS_ADDR_LINKLOCAL( + &pi->peer->connection->su.sin6.sin6_addr) && + IPV6_ADDR_SAME(&pi->peer->connection->su.sin6.sin6_addr, + &p.u.prefix6)) + ifindex = pi->peer->connection->su.sin6.sin6_scope_id; if (!is_bgp_static_route && orig_prefix && prefix_same(&p, orig_prefix)) { @@ -351,8 +355,8 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, * tagged into this fun */ if (afi == AFI_IP6 && peer->conf_if && - IN6_IS_ADDR_LINKLOCAL(&peer->su.sin6.sin6_addr)) { - ifindex = peer->su.sin6.sin6_scope_id; + IN6_IS_ADDR_LINKLOCAL(&peer->connection->su.sin6.sin6_addr)) { + ifindex = peer->connection->su.sin6.sin6_scope_id; if (ifindex == 0) { if (BGP_DEBUG(nht, NHT)) { zlog_debug( @@ -363,7 +367,7 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, } } - if (!sockunion2hostprefix(&peer->su, &p)) { + if (!sockunion2hostprefix(&peer->connection->su, &p)) { if (BGP_DEBUG(nht, NHT)) { zlog_debug( "%s: Attempting to register with unknown AFI %d (not %d or %d)", @@ -519,14 +523,15 @@ void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer) * nodes of V6 nexthop cache to find the bnc, it is * currently not being called here. */ - if (!sockunion2hostprefix(&peer->su, &p)) + if (!sockunion2hostprefix(&peer->connection->su, &p)) return; /* * Gather the ifindex for if up/down events to be * tagged into this fun */ - if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&peer->su.sin6.sin6_addr)) - ifindex = peer->su.sin6.sin6_scope_id; + if (afi == AFI_IP6 && + IN6_IS_ADDR_LINKLOCAL(&peer->connection->su.sin6.sin6_addr)) + ifindex = peer->connection->su.sin6.sin6_scope_id; bnc = bnc_find(&peer->bgp->nexthop_cache_table[family2afi(p.family)], &p, 0, ifindex); if (!bnc) { @@ -869,17 +874,18 @@ void bgp_nht_interface_events(struct peer *peer) struct prefix p; ifindex_t ifindex = 0; - if (!IN6_IS_ADDR_LINKLOCAL(&peer->su.sin6.sin6_addr)) + if (!IN6_IS_ADDR_LINKLOCAL(&peer->connection->su.sin6.sin6_addr)) return; - if (!sockunion2hostprefix(&peer->su, &p)) + if (!sockunion2hostprefix(&peer->connection->su, &p)) return; /* * Gather the ifindex for if up/down events to be * tagged into this fun */ - if (peer->conf_if && IN6_IS_ADDR_LINKLOCAL(&peer->su.sin6.sin6_addr)) - ifindex = peer->su.sin6.sin6_scope_id; + if (peer->conf_if && + IN6_IS_ADDR_LINKLOCAL(&peer->connection->su.sin6.sin6_addr)) + ifindex = peer->connection->su.sin6.sin6_scope_id; table = &bgp->nexthop_cache_table[AFI_IP6]; bnc = bnc_find(table, &p, 0, ifindex); @@ -1407,7 +1413,8 @@ void evaluate_paths(struct bgp_nexthop_cache *bnc) __func__, peer->host, peer->bgp->name_pretty, !!valid_nexthops); - bgp_fsm_nht_update(peer, !!valid_nexthops); + bgp_fsm_nht_update(peer->connection, peer, + !!valid_nexthops); SET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED); } } @@ -1468,7 +1475,7 @@ void bgp_nht_reg_enhe_cap_intfs(struct peer *peer) return; bgp = peer->bgp; - if (!sockunion2hostprefix(&peer->su, &p)) { + if (!sockunion2hostprefix(&peer->connection->su, &p)) { zlog_warn("%s: Unable to convert sockunion to prefix for %s", __func__, peer->host); return; @@ -1480,8 +1487,9 @@ void bgp_nht_reg_enhe_cap_intfs(struct peer *peer) * Gather the ifindex for if up/down events to be * tagged into this fun */ - if (peer->conf_if && IN6_IS_ADDR_LINKLOCAL(&peer->su.sin6.sin6_addr)) - ifindex = peer->su.sin6.sin6_scope_id; + if (peer->conf_if && + IN6_IS_ADDR_LINKLOCAL(&peer->connection->su.sin6.sin6_addr)) + ifindex = peer->connection->su.sin6.sin6_scope_id; bnc = bnc_find(&bgp->nexthop_cache_table[AFI_IP6], &p, 0, ifindex); if (!bnc) @@ -1517,7 +1525,7 @@ void bgp_nht_dereg_enhe_cap_intfs(struct peer *peer) bgp = peer->bgp; - if (!sockunion2hostprefix(&peer->su, &p)) { + if (!sockunion2hostprefix(&peer->connection->su, &p)) { zlog_warn("%s: Unable to convert sockunion to prefix for %s", __func__, peer->host); return; @@ -1529,8 +1537,9 @@ void bgp_nht_dereg_enhe_cap_intfs(struct peer *peer) * Gather the ifindex for if up/down events to be * tagged into this fun */ - if (peer->conf_if && IN6_IS_ADDR_LINKLOCAL(&peer->su.sin6.sin6_addr)) - ifindex = peer->su.sin6.sin6_scope_id; + if (peer->conf_if && + IN6_IS_ADDR_LINKLOCAL(&peer->connection->su.sin6.sin6_addr)) + ifindex = peer->connection->su.sin6.sin6_scope_id; bnc = bnc_find(&bgp->nexthop_cache_table[AFI_IP6], &p, 0, ifindex); if (!bnc) diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index c7c91da74..da70f67c1 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -392,7 +392,7 @@ static int bgp_capability_orf_entry(struct peer *peer, zlog_info( "%s ORF Capability entry length error, Cap length %u, num %u", peer->host, hdr->length, num); - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send(peer->connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_MALFORMED_ATTR); return -1; } @@ -965,7 +965,7 @@ static int bgp_capability_parse(struct peer *peer, size_t length, if (stream_get_getp(s) + 2 > end) { zlog_info("%s Capability length error (< header)", peer->host); - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send(peer->connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_MALFORMED_ATTR); return -1; } @@ -978,7 +978,7 @@ static int bgp_capability_parse(struct peer *peer, size_t length, if (start + caphdr.length > end) { zlog_info("%s Capability length error (< length)", peer->host); - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send(peer->connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_MALFORMED_ATTR); return -1; } @@ -1013,7 +1013,8 @@ static int bgp_capability_parse(struct peer *peer, size_t length, NULL), caphdr.length, (unsigned)cap_minsizes[caphdr.code]); - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send(peer->connection, + BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_MALFORMED_ATTR); return -1; } @@ -1026,7 +1027,8 @@ static int bgp_capability_parse(struct peer *peer, size_t length, NULL), caphdr.length, (unsigned)cap_modsizes[caphdr.code]); - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send(peer->connection, + BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_MALFORMED_ATTR); return -1; } @@ -1122,7 +1124,7 @@ static int bgp_capability_parse(struct peer *peer, size_t length, } if (ret < 0) { - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send(peer->connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_MALFORMED_ATTR); return -1; } @@ -1170,7 +1172,7 @@ static bool bgp_role_violation(struct peer *peer) (local_role == ROLE_RS_SERVER && remote_role == ROLE_RS_CLIENT) || (local_role == ROLE_RS_CLIENT && remote_role == ROLE_RS_SERVER))) { - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send(peer->connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_ROLE_MISMATCH); return true; } @@ -1178,7 +1180,7 @@ static bool bgp_role_violation(struct peer *peer) CHECK_FLAG(peer->flags, PEER_FLAG_ROLE_STRICT_MODE)) { const char *err_msg = "Strict mode. Please set the role on your side."; - bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send_with_data(peer->connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_ROLE_MISMATCH, (uint8_t *)err_msg, strlen(err_msg)); return true; @@ -1306,7 +1308,7 @@ int bgp_open_option_parse(struct peer *peer, uint16_t length, */ if (STREAM_READABLE(s) < 1) { zlog_info("%s Option length error", peer->host); - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send(peer->connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_MALFORMED_ATTR); return -1; } @@ -1319,7 +1321,8 @@ int bgp_open_option_parse(struct peer *peer, uint16_t length, if (BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)) { if (STREAM_READABLE(s) < 2) { zlog_info("%s Option length error", peer->host); - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send(peer->connection, + BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_MALFORMED_ATTR); return -1; } @@ -1328,7 +1331,8 @@ int bgp_open_option_parse(struct peer *peer, uint16_t length, } else { if (STREAM_READABLE(s) < 1) { zlog_info("%s Option length error", peer->host); - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send(peer->connection, + BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_MALFORMED_ATTR); return -1; } @@ -1340,7 +1344,7 @@ int bgp_open_option_parse(struct peer *peer, uint16_t length, if (STREAM_READABLE(s) < opt_length) { zlog_info("%s Option length error (%d)", peer->host, opt_length); - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send(peer->connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_MALFORMED_ATTR); return -1; } @@ -1359,7 +1363,7 @@ int bgp_open_option_parse(struct peer *peer, uint16_t length, mp_capability, &error); break; default: - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send(peer->connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNSUP_PARAM); ret = -1; break; @@ -1378,7 +1382,8 @@ int bgp_open_option_parse(struct peer *peer, uint16_t length, if (CHECK_FLAG(peer->flags, PEER_FLAG_STRICT_CAP_MATCH)) { /* If Unsupported Capability exists. */ if (error != error_data) { - bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send_with_data(peer->connection, + BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNSUP_CAPBL, error_data, error - error_data); @@ -1388,7 +1393,7 @@ int bgp_open_option_parse(struct peer *peer, uint16_t length, /* Check local capability does not negotiated with remote peer. */ if (!strict_capability_same(peer)) { - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send(peer->connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNSUP_CAPBL); return -1; } @@ -1427,12 +1432,14 @@ int bgp_open_option_parse(struct peer *peer, uint16_t length, peer->host); if (error != error_data) - bgp_notify_send_with_data( - peer, BGP_NOTIFY_OPEN_ERR, - BGP_NOTIFY_OPEN_UNSUP_CAPBL, error_data, - error - error_data); + bgp_notify_send_with_data(peer->connection, + BGP_NOTIFY_OPEN_ERR, + BGP_NOTIFY_OPEN_UNSUP_CAPBL, + error_data, + error - error_data); else - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send(peer->connection, + BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNSUP_CAPBL); return -1; } @@ -1705,11 +1712,11 @@ uint16_t bgp_open_capability(struct stream *s, struct peer *peer, * supporting RFC-5549 for * Link-Local peering only */ - if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE) - && peer->su.sa.sa_family == AF_INET6 - && afi == AFI_IP - && (safi == SAFI_UNICAST || safi == SAFI_MPLS_VPN - || safi == SAFI_LABELED_UNICAST)) { + if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE) && + peer->connection->su.sa.sa_family == AF_INET6 && + afi == AFI_IP && + (safi == SAFI_UNICAST || safi == SAFI_MPLS_VPN || + safi == SAFI_LABELED_UNICAST)) { /* RFC 5549 Extended Next Hop Encoding */ SET_FLAG(peer->cap, PEER_CAP_ENHE_ADV); diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 0b9cfc8d0..6ae418b98 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -105,21 +105,22 @@ void bgp_packet_set_size(struct stream *s) * Push a packet onto the beginning of the peer's output queue. * This function acquires the peer's write mutex before proceeding. */ -static void bgp_packet_add(struct peer *peer, struct stream *s) +static void bgp_packet_add(struct peer_connection *connection, + struct peer *peer, struct stream *s) { intmax_t delta; uint32_t holdtime; intmax_t sendholdtime; - frr_with_mutex (&peer->connection->io_mtx) { + frr_with_mutex (&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(connection->obuf)) peer->last_sendq_ok = monotime(NULL); - stream_fifo_push(peer->connection->obuf, s); + stream_fifo_push(connection->obuf, s); delta = monotime(NULL) - peer->last_sendq_ok; @@ -146,7 +147,7 @@ static void bgp_packet_add(struct peer *peer, struct stream *s) EC_BGP_SENDQ_STUCK_PROPER, "%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session", peer, sendholdtime); - BGP_EVENT_ADD(peer, TCP_fatal_error); + BGP_EVENT_ADD(connection, TCP_fatal_error); } else if (delta > (intmax_t)holdtime && monotime(NULL) - peer->last_sendq_warn > 5) { flog_warn( @@ -260,7 +261,7 @@ void bgp_update_restarted_peers(struct peer *peer) if (bgp_debug_neighbor_events(peer)) zlog_debug("Peer %s: Checking restarted", peer->host); - if (peer_established(peer)) { + if (peer_established(peer->connection)) { peer->update_delay_over = 1; peer->bgp->restarted_peers++; bgp_check_update_delay(peer->bgp); @@ -283,7 +284,7 @@ void bgp_update_implicit_eors(struct peer *peer) if (bgp_debug_neighbor_events(peer)) zlog_debug("Peer %s: Checking implicit EORs", peer->host); - if (peer_established(peer)) { + if (peer_established(peer->connection)) { peer->update_delay_over = 1; peer->bgp->implicit_eors++; bgp_check_update_delay(peer->bgp); @@ -391,6 +392,7 @@ static void bgp_write_proceed_actions(struct peer *peer) struct bpacket *next_pkt; struct update_subgroup *subgrp; enum bgp_af_index index; + struct peer_connection *connection = peer->connection; for (index = BGP_AF_START; index < BGP_AF_MAX; index++) { paf = peer->peer_af_array[index]; @@ -403,7 +405,7 @@ static void bgp_write_proceed_actions(struct peer *peer) next_pkt = paf->next_pkt_to_send; if (next_pkt && next_pkt->buffer) { - BGP_TIMER_ON(peer->t_generate_updgrp_packets, + BGP_TIMER_ON(connection->t_generate_updgrp_packets, bgp_generate_updgrp_packets, 0); return; } @@ -414,7 +416,7 @@ static void bgp_write_proceed_actions(struct peer *peer) if (bpacket_queue_is_full(SUBGRP_INST(subgrp), SUBGRP_PKTQ(subgrp)) || subgroup_packets_to_build(subgrp)) { - BGP_TIMER_ON(peer->t_generate_updgrp_packets, + BGP_TIMER_ON(connection->t_generate_updgrp_packets, bgp_generate_updgrp_packets, 0); return; } @@ -429,7 +431,7 @@ static void bgp_write_proceed_actions(struct peer *peer) && !CHECK_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND) && safi != SAFI_MPLS_VPN) { - BGP_TIMER_ON(peer->t_generate_updgrp_packets, + BGP_TIMER_ON(connection->t_generate_updgrp_packets, bgp_generate_updgrp_packets, 0); return; } @@ -444,8 +446,8 @@ static void bgp_write_proceed_actions(struct peer *peer) */ void bgp_generate_updgrp_packets(struct event *thread) { - struct peer *peer = EVENT_ARG(thread); - + struct peer_connection *connection = EVENT_ARG(thread); + struct peer *peer = connection->peer; struct stream *s; struct peer_af *paf; struct bpacket *next_pkt; @@ -462,14 +464,14 @@ void bgp_generate_updgrp_packets(struct event *thread) * if peer is Established and updates are not on hold (as part of * update-delay processing). */ - if (!peer_established(peer)) + if (!peer_established(peer->connection)) return; if ((peer->bgp->main_peers_update_hold) || bgp_update_delay_active(peer->bgp)) return; - if (peer->t_routeadv) + if (peer->connection->t_routeadv) return; /* @@ -477,7 +479,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 (connection->obuf->count >= bm->outq_limit) { bgp_write_proceed_actions(peer); return; } @@ -601,14 +603,14 @@ void bgp_generate_updgrp_packets(struct event *thread) * packet with appropriate attributes from peer * and advance peer */ s = bpacket_reformat_for_peer(next_pkt, paf); - bgp_packet_add(peer, s); + bgp_packet_add(connection, peer, s); bpacket_queue_advance_peer(paf); } } while (s && (++generated < wpq) && - (peer->connection->obuf->count <= bm->outq_limit)); + (connection->obuf->count <= bm->outq_limit)); if (generated) - bgp_writes_on(peer->connection); + bgp_writes_on(connection); bgp_write_proceed_actions(peer); } @@ -635,7 +637,7 @@ void bgp_keepalive_send(struct peer *peer) zlog_debug("%s sending KEEPALIVE", peer->host); /* Add packet to the peer. */ - bgp_packet_add(peer, s); + bgp_packet_add(peer->connection, peer, s); bgp_writes_on(peer->connection); } @@ -644,11 +646,12 @@ void bgp_keepalive_send(struct peer *peer) * Creates a BGP Open packet and appends it to the peer's output queue. * Sets capabilities as necessary. */ -void bgp_open_send(struct peer *peer) +void bgp_open_send(struct peer_connection *connection) { struct stream *s; uint16_t send_holdtime; as_t local_as; + struct peer *peer = connection->peer; if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER)) send_holdtime = peer->holdtime; @@ -704,9 +707,9 @@ void bgp_open_send(struct peer *peer) hook_call(bgp_packet_send, peer, BGP_MSG_OPEN, stream_get_endp(s), s); /* Add packet to the peer. */ - bgp_packet_add(peer, s); + bgp_packet_add(connection, peer, s); - bgp_writes_on(peer->connection); + bgp_writes_on(connection); } /* @@ -721,14 +724,15 @@ void bgp_open_send(struct peer *peer) * @param peer * @return 0 */ -static void bgp_write_notify(struct peer *peer) +static void bgp_write_notify(struct peer_connection *connection, + struct peer *peer) { int ret, val; uint8_t type; struct stream *s; /* There should be at least one packet. */ - s = stream_fifo_pop(peer->connection->obuf); + s = stream_fifo_pop(connection->obuf); if (!s) return; @@ -739,7 +743,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(connection->fd, STREAM_DATA(s), stream_get_endp(s)); /* * only connection reset/close gets counted as TCP_fatal_error, failure @@ -747,14 +751,14 @@ static void bgp_write_notify(struct peer *peer) */ if (ret <= 0) { stream_free(s); - BGP_EVENT_ADD(peer, TCP_fatal_error); + BGP_EVENT_ADD(connection, TCP_fatal_error); return; } /* Disable Nagle, make NOTIFY packet go out right away */ val = 1; - (void)setsockopt(peer->connection->fd, IPPROTO_TCP, TCP_NODELAY, - (char *)&val, sizeof(val)); + (void)setsockopt(connection->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, + sizeof(val)); /* Retrieve BGP packet type. */ stream_set_getp(s, BGP_MARKER_SIZE + 2); @@ -776,7 +780,7 @@ static void bgp_write_notify(struct peer *peer) * Handle Graceful Restart case where the state changes to * Connect instead of Idle */ - BGP_EVENT_ADD(peer, BGP_Stop); + BGP_EVENT_ADD(connection, BGP_Stop); stream_free(s); } @@ -902,15 +906,17 @@ bool bgp_notify_received_hard_reset(struct peer *peer, uint8_t code, * @param data Data portion * @param datalen length of data portion */ -static void bgp_notify_send_internal(struct peer *peer, uint8_t code, - uint8_t sub_code, uint8_t *data, - size_t datalen, bool use_curr) +static void bgp_notify_send_internal(struct peer_connection *connection, + uint8_t code, uint8_t sub_code, + uint8_t *data, size_t datalen, + bool use_curr) { struct stream *s; + struct peer *peer = connection->peer; 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(&connection->io_mtx); /* ============================================== */ /* Allocate new stream. */ @@ -943,7 +949,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(connection->obuf); /* * If possible, store last packet for debugging purposes. This check is @@ -1028,13 +1034,13 @@ 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(connection->obuf, s); bgp_peer_gr_flags_update(peer); BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp, peer->bgp->peer); - bgp_write_notify(peer); + bgp_write_notify(connection, peer); } /* @@ -1047,18 +1053,20 @@ static void bgp_notify_send_internal(struct peer *peer, uint8_t code, * @param code BGP error code * @param sub_code BGP error subcode */ -void bgp_notify_send(struct peer *peer, uint8_t code, uint8_t sub_code) +void bgp_notify_send(struct peer_connection *connection, uint8_t code, + uint8_t sub_code) { - bgp_notify_send_internal(peer, code, sub_code, NULL, 0, true); + bgp_notify_send_internal(connection, code, sub_code, NULL, 0, true); } /* * Enqueue notification; called from the main pthread, peer object access is ok. */ -void bgp_notify_send_with_data(struct peer *peer, uint8_t code, +void bgp_notify_send_with_data(struct peer_connection *connection, uint8_t code, uint8_t sub_code, uint8_t *data, size_t datalen) { - bgp_notify_send_internal(peer, code, sub_code, data, datalen, true); + bgp_notify_send_internal(connection, code, sub_code, data, datalen, + true); } /* @@ -1069,7 +1077,8 @@ void bgp_notify_io_invalid(struct peer *peer, uint8_t code, uint8_t sub_code, uint8_t *data, size_t datalen) { /* Avoid touching the peer object */ - bgp_notify_send_internal(peer, code, sub_code, data, datalen, false); + bgp_notify_send_internal(peer->connection, code, sub_code, data, + datalen, false); } /* @@ -1179,7 +1188,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_packet_add(peer->connection, peer, s); bgp_writes_on(peer->connection); } @@ -1203,7 +1212,7 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi, uint16_t len; uint32_t gr_restart_time; - if (!peer_established(peer)) + if (!peer_established(peer->connection)) return; if (!CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_RCV) && @@ -1353,15 +1362,17 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi, bgp_packet_set_size(s); /* Add packet to the peer. */ - bgp_packet_add(peer, s); + bgp_packet_add(peer->connection, peer, s); bgp_writes_on(peer->connection); } /* RFC1771 6.8 Connection collision detection. */ -static int bgp_collision_detect(struct peer *new, struct in_addr remote_id) +static int bgp_collision_detect(struct peer_connection *connection, + struct peer *new, struct in_addr remote_id) { struct peer *peer; + struct peer_connection *other; /* * Upon receipt of an OPEN message, the local system must examine @@ -1377,19 +1388,22 @@ static int bgp_collision_detect(struct peer *new, struct in_addr remote_id) if (peer == NULL) return 0; + other = peer->connection; + /* * Do not accept the new connection in Established or Clearing * 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) { - bgp_notify_send(new, BGP_NOTIFY_CEASE, + if (peer_established(other) || + other->status == Clearing) { + bgp_notify_send(connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION); return -1; } - if ((peer->connection->status != OpenConfirm) && - (peer->connection->status != OpenSent)) + if ((other->status != OpenConfirm) && + (other->status != OpenSent)) return 0; /* @@ -1416,11 +1430,11 @@ static int bgp_collision_detect(struct peer *new, struct in_addr remote_id) * and accepts BGP connection initiated by * the remote system. */ - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(other, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION); return 1; } else { - bgp_notify_send(new, BGP_NOTIFY_CEASE, + bgp_notify_send(connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION); return -1; } @@ -1439,11 +1453,11 @@ static int bgp_collision_detect(struct peer *new, struct in_addr remote_id) * OpenConfirm state). */ if (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) { - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(other, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION); return 1; } else { - bgp_notify_send(new, BGP_NOTIFY_CEASE, + bgp_notify_send(connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION); return -1; } @@ -1486,7 +1500,8 @@ static int bgp_collision_detect(struct peer *new, struct in_addr remote_id) * @param size size of the packet * @return as in summary */ -static int bgp_open_receive(struct peer *peer, bgp_size_t size) +static int bgp_open_receive(struct peer_connection *connection, + struct peer *peer, bgp_size_t size) { int ret; uint8_t version; @@ -1525,7 +1540,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) EC_BGP_PKT_OPEN, "%s: stream does not have enough bytes for extended optional parameters", peer->host); - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send(connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_MALFORMED_ATTR); return BGP_Stop; } @@ -1537,7 +1552,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) EC_BGP_PKT_OPEN, "%s: stream does not have enough bytes to read the extended optional parameters optlen", peer->host); - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send(connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_MALFORMED_ATTR); return BGP_Stop; } @@ -1564,7 +1579,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) flog_err(EC_BGP_PKT_OPEN, "%s: stream has not enough bytes (%u)", peer->host, optlen); - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send(connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_MALFORMED_ATTR); return BGP_Stop; } @@ -1586,7 +1601,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) flog_err(EC_BGP_PKT_OPEN, "%s bad OPEN, got AS4 capability, but AS4 set to 0", peer->host); - bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send_with_data(connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_BAD_PEER_AS, notify_data_remote_as4, 4); return BGP_Stop; @@ -1596,7 +1611,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) if (remote_as == BGP_AS_ZERO) { flog_err(EC_BGP_PKT_OPEN, "%s bad OPEN, got AS set to 0", peer->host); - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send(connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_BAD_PEER_AS); return BGP_Stop; } @@ -1611,7 +1626,8 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) EC_BGP_PKT_OPEN, "%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed", peer->host); - bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send_with_data(connection, + BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_BAD_PEER_AS, notify_data_remote_as4, 4); return BGP_Stop; @@ -1639,7 +1655,8 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) EC_BGP_PKT_OPEN, "%s bad OPEN, got AS4 capability, but remote_as %u mismatch with 16bit 'myasn' %u in open", peer->host, as4, remote_as); - bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send_with_data(connection, + BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_BAD_PEER_AS, notify_data_remote_as4, 4); return BGP_Stop; @@ -1659,7 +1676,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) if (bgp_debug_neighbor_events(peer)) zlog_debug("%s bad OPEN, wrong router identifier %pI4", peer->host, &remote_id); - bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send_with_data(connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_BAD_BGP_IDENT, notify_data_remote_id, 4); return BGP_Stop; @@ -1674,7 +1691,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) "%s bad protocol version, remote requested %d, local request %d", peer->host, version, BGP_VERSION_4); /* Data must be in network byte order here */ - bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send_with_data(connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNSUP_VERSION, (uint8_t *)&maxver, 2); return BGP_Stop; @@ -1686,7 +1703,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) zlog_debug( "%s bad OPEN, remote AS is unspecified currently", peer->host); - bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send_with_data(connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_BAD_PEER_AS, notify_data_remote_as, 2); return BGP_Stop; @@ -1696,7 +1713,8 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) zlog_debug( "%s bad OPEN, remote AS is %u, internal specified", peer->host, remote_as); - bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send_with_data(connection, + BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_BAD_PEER_AS, notify_data_remote_as, 2); return BGP_Stop; @@ -1708,7 +1726,8 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) zlog_debug( "%s bad OPEN, remote AS is %u, external specified", peer->host, remote_as); - bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send_with_data(connection, + BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_BAD_PEER_AS, notify_data_remote_as, 2); return BGP_Stop; @@ -1718,7 +1737,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) if (bgp_debug_neighbor_events(peer)) zlog_debug("%s bad OPEN, remote AS is %u, expected %u", peer->host, remote_as, peer->as); - bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send_with_data(connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_BAD_PEER_AS, notify_data_remote_as, 2); return BGP_Stop; @@ -1728,7 +1747,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) * When collision is detected and this peer is closed. * Return immediately. */ - ret = bgp_collision_detect(peer, remote_id); + ret = bgp_collision_detect(connection, peer, remote_id); if (ret < 0) return BGP_Stop; @@ -1751,7 +1770,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) */ if (holdtime < 3 && holdtime != 0) { - bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send_with_data(connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNACEP_HOLDTIME, (uint8_t *)holdtime_ptr, 2); return BGP_Stop; @@ -1761,7 +1780,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) * is smaller than configured minimum Hold Time. */ if (holdtime < peer->bgp->default_min_holdtime && peer->bgp->default_min_holdtime != 0) { - bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR, + bgp_notify_send_with_data(connection, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNACEP_HOLDTIME, (uint8_t *)holdtime_ptr, 2); return BGP_Stop; @@ -1864,12 +1883,12 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) flog_err(EC_BGP_SND_FAIL, "%s: No local IPv6 address, and zebra does not support V6 routing with v4 nexthops, BGP routing for V6 will not work", peer->host); - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_SUBCODE_UNSPECIFIC); return BGP_Stop; } } - peer->rtt = sockopt_tcp_rtt(peer->connection->fd); + peer->rtt = sockopt_tcp_rtt(connection->fd); return Receive_OPEN_message; } @@ -1881,14 +1900,15 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) * @param size size of the packet * @return as in summary */ -static int bgp_keepalive_receive(struct peer *peer, bgp_size_t size) +static int bgp_keepalive_receive(struct peer_connection *connection, + struct peer *peer, bgp_size_t size) { if (bgp_debug_keepalive(peer)) zlog_debug("%s KEEPALIVE rcvd", peer->host); bgp_update_implicit_eors(peer); - peer->rtt = sockopt_tcp_rtt(peer->connection->fd); + peer->rtt = sockopt_tcp_rtt(connection->fd); /* If the peer's RTT is higher than expected, shutdown * the peer automatically. @@ -1941,7 +1961,7 @@ static void bgp_refresh_stalepath_timer_expire(struct event *thread) "%pBP route-refresh (BoRR) timer expired for afi/safi: %d/%d", peer, afi, safi); - bgp_timer_set(peer); + bgp_timer_set(peer->connection); } /** @@ -1953,7 +1973,8 @@ static void bgp_refresh_stalepath_timer_expire(struct event *thread) * @param size size of the packet * @return as in summary */ -static int bgp_update_receive(struct peer *peer, bgp_size_t size) +static int bgp_update_receive(struct peer_connection *connection, + struct peer *peer, bgp_size_t size) { int ret, nlri_ret; uint8_t *end; @@ -1974,13 +1995,13 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) struct bgp_nlri nlris[NLRI_TYPE_MAX]; /* Status must be Established. */ - if (!peer_established(peer)) { + if (!peer_established(connection)) { flog_err(EC_BGP_INVALID_STATUS, "%s [FSM] Update packet received under status %s", peer->host, lookup_msg(bgp_status_msg, peer->connection->status, NULL)); - bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, + bgp_notify_send(connection, BGP_NOTIFY_FSM_ERR, bgp_fsm_error_subcode(peer->connection->status)); return BGP_Stop; } @@ -2004,7 +2025,7 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) flog_err(EC_BGP_UPDATE_RCV, "%s [Error] Update packet error (packet length is short for unfeasible length)", peer->host); - bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, + bgp_notify_send(connection, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_MAL_ATTR); return BGP_Stop; } @@ -2017,7 +2038,7 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) flog_err(EC_BGP_UPDATE_RCV, "%s [Error] Update packet error (packet unfeasible length overflow %d)", peer->host, withdraw_len); - bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, + bgp_notify_send(connection, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_MAL_ATTR); return BGP_Stop; } @@ -2037,7 +2058,7 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) EC_BGP_UPDATE_PACKET_SHORT, "%s [Error] Packet Error (update packet is short for attribute length)", peer->host); - bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, + bgp_notify_send(peer->connection, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_MAL_ATTR); return BGP_Stop; } @@ -2051,7 +2072,7 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) EC_BGP_UPDATE_PACKET_LONG, "%s [Error] Packet Error (update packet attribute length overflow %d)", peer->host, attribute_len); - bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR, + bgp_notify_send(connection, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_MAL_ATTR); return BGP_Stop; } @@ -2166,12 +2187,12 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) && nlri_ret != BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW) { flog_err(EC_BGP_UPDATE_RCV, "%s [Error] Error parsing NLRI", peer->host); - if (peer_established(peer)) - bgp_notify_send( - peer, BGP_NOTIFY_UPDATE_ERR, - i <= NLRI_WITHDRAW - ? BGP_NOTIFY_UPDATE_INVAL_NETWORK - : BGP_NOTIFY_UPDATE_OPT_ATTR_ERR); + if (peer_established(connection)) + bgp_notify_send(connection, + BGP_NOTIFY_UPDATE_ERR, + i <= NLRI_WITHDRAW + ? BGP_NOTIFY_UPDATE_INVAL_NETWORK + : BGP_NOTIFY_UPDATE_OPT_ATTR_ERR); bgp_attr_unintern_sub(&attr); return BGP_Stop; } @@ -2279,7 +2300,8 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) * @param size size of the packet * @return as in summary */ -static int bgp_notify_receive(struct peer *peer, bgp_size_t size) +static int bgp_notify_receive(struct peer_connection *connection, + struct peer *peer, bgp_size_t size) { struct bgp_notify outer = {}; struct bgp_notify inner = {}; @@ -2400,7 +2422,8 @@ static int bgp_notify_receive(struct peer *peer, bgp_size_t size) * @param size size of the packet * @return as in summary */ -static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) +static int bgp_route_refresh_receive(struct peer_connection *connection, + struct peer *peer, bgp_size_t size) { iana_afi_t pkt_afi; afi_t afi; @@ -2420,19 +2443,19 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) flog_err(EC_BGP_NO_CAP, "%s [Error] BGP route refresh is not enabled", peer->host); - bgp_notify_send(peer, BGP_NOTIFY_HEADER_ERR, + bgp_notify_send(connection, BGP_NOTIFY_HEADER_ERR, BGP_NOTIFY_HEADER_BAD_MESTYPE); return BGP_Stop; } /* Status must be Established. */ - if (!peer_established(peer)) { + if (!peer_established(connection)) { 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, NULL)); - bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, + bgp_notify_send(connection, BGP_NOTIFY_FSM_ERR, bgp_fsm_error_subcode(peer->connection->status)); return BGP_Stop; } @@ -2471,9 +2494,9 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) zlog_err( "%s Enhanced Route Refresh message length error", peer->host); - bgp_notify_send( - peer, BGP_NOTIFY_ROUTE_REFRESH_ERR, - BGP_NOTIFY_ROUTE_REFRESH_INVALID_MSG_LEN); + bgp_notify_send(connection, + BGP_NOTIFY_ROUTE_REFRESH_ERR, + BGP_NOTIFY_ROUTE_REFRESH_INVALID_MSG_LEN); } /* When the BGP speaker receives a ROUTE-REFRESH message @@ -2489,7 +2512,7 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) if (msg_length < 5) { zlog_info("%s ORF route refresh length error", peer->host); - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_SUBCODE_UNSPECIFIC); return BGP_Stop; } @@ -2724,7 +2747,7 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) bgp_set_stale_route(peer, afi, safi); } - if (peer_established(peer)) + if (peer_established(peer->connection)) event_add_timer(bm->master, bgp_refresh_stalepath_timer_expire, paf, peer->bgp->stalepath_time, @@ -2924,7 +2947,7 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt, * length. */ if (pnt + 3 > end) { zlog_err("%pBP: Capability length error", peer); - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_SUBCODE_UNSPECIFIC); return BGP_Stop; } @@ -2936,7 +2959,7 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt, && action != CAPABILITY_ACTION_UNSET) { zlog_err("%pBP: Capability Action Value error %d", peer, action); - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_SUBCODE_UNSPECIFIC); return BGP_Stop; } @@ -2948,7 +2971,7 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt, /* Capability length check. */ if ((pnt + hdr->length + 3) > end) { zlog_err("%pBP: Capability length error", peer); - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_SUBCODE_UNSPECIFIC); return BGP_Stop; } @@ -3033,7 +3056,8 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt, if ((hdr->length - 2) % 4) { zlog_err("%pBP: Received invalid Graceful-Restart capability length %d", peer, hdr->length); - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, + BGP_NOTIFY_CEASE, BGP_NOTIFY_SUBCODE_UNSPECIFIC); return BGP_Stop; } @@ -3056,7 +3080,8 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt, if (hdr->length != CAPABILITY_CODE_ROLE_LEN) { zlog_err("%pBP: Capability (%s) length error", peer, capability); - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, + BGP_NOTIFY_CEASE, BGP_NOTIFY_SUBCODE_UNSPECIFIC); return BGP_Stop; } @@ -3096,7 +3121,8 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt, * @param size size of the packet * @return as in summary */ -int bgp_capability_receive(struct peer *peer, bgp_size_t size) +int bgp_capability_receive(struct peer_connection *connection, + struct peer *peer, bgp_size_t size) { uint8_t *pnt; @@ -3111,20 +3137,19 @@ int bgp_capability_receive(struct peer *peer, bgp_size_t size) flog_err(EC_BGP_NO_CAP, "%s [Error] BGP dynamic capability is not enabled", peer->host); - bgp_notify_send(peer, BGP_NOTIFY_HEADER_ERR, + bgp_notify_send(connection, BGP_NOTIFY_HEADER_ERR, BGP_NOTIFY_HEADER_BAD_MESTYPE); return BGP_Stop; } /* Status must be Established. */ - if (!peer_established(peer)) { + if (!peer_established(connection)) { 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, - NULL)); - bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, - bgp_fsm_error_subcode(peer->connection->status)); + lookup_msg(bgp_status_msg, connection->status, NULL)); + bgp_notify_send(connection, BGP_NOTIFY_FSM_ERR, + bgp_fsm_error_subcode(connection->status)); return BGP_Stop; } @@ -3199,7 +3224,7 @@ void bgp_process_packet(struct event *thread) frrtrace(2, frr_bgp, open_process, peer, size); atomic_fetch_add_explicit(&peer->open_in, 1, memory_order_relaxed); - mprc = bgp_open_receive(peer, size); + mprc = bgp_open_receive(connection, peer, size); if (mprc == BGP_Stop) flog_err( EC_BGP_PKT_OPEN, @@ -3211,7 +3236,7 @@ void bgp_process_packet(struct event *thread) atomic_fetch_add_explicit(&peer->update_in, 1, memory_order_relaxed); peer->readtime = monotime(NULL); - mprc = bgp_update_receive(peer, size); + mprc = bgp_update_receive(connection, peer, size); if (mprc == BGP_Stop) flog_err( EC_BGP_UPDATE_RCV, @@ -3222,7 +3247,7 @@ void bgp_process_packet(struct event *thread) frrtrace(2, frr_bgp, notification_process, peer, size); atomic_fetch_add_explicit(&peer->notify_in, 1, memory_order_relaxed); - mprc = bgp_notify_receive(peer, size); + mprc = bgp_notify_receive(connection, peer, size); if (mprc == BGP_Stop) flog_err( EC_BGP_NOTIFY_RCV, @@ -3234,7 +3259,7 @@ void bgp_process_packet(struct event *thread) peer->readtime = monotime(NULL); atomic_fetch_add_explicit(&peer->keepalive_in, 1, memory_order_relaxed); - mprc = bgp_keepalive_receive(peer, size); + mprc = bgp_keepalive_receive(connection, peer, size); if (mprc == BGP_Stop) flog_err( EC_BGP_KEEP_RCV, @@ -3246,7 +3271,7 @@ void bgp_process_packet(struct event *thread) frrtrace(2, frr_bgp, refresh_process, peer, size); atomic_fetch_add_explicit(&peer->refresh_in, 1, memory_order_relaxed); - mprc = bgp_route_refresh_receive(peer, size); + mprc = bgp_route_refresh_receive(connection, peer, size); if (mprc == BGP_Stop) flog_err( EC_BGP_RFSH_RCV, @@ -3257,7 +3282,7 @@ void bgp_process_packet(struct event *thread) frrtrace(2, frr_bgp, capability_process, peer, size); atomic_fetch_add_explicit(&peer->dynamic_cap_in, 1, memory_order_relaxed); - mprc = bgp_capability_receive(peer, size); + mprc = bgp_capability_receive(connection, peer, size); if (mprc == BGP_Stop) flog_err( EC_BGP_CAP_RCV, @@ -3284,7 +3309,7 @@ void bgp_process_packet(struct event *thread) /* Update FSM */ if (mprc != BGP_PACKET_NOOP) - fsm_update_result = bgp_event_update(peer, mprc); + fsm_update_result = bgp_event_update(connection, mprc); else continue; @@ -3340,7 +3365,7 @@ void bgp_packet_process_error(struct event *thread) connection->fd); /* Closed connection or error on the socket */ - if (peer_established(peer)) { + if (peer_established(connection)) { if ((CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART) || CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER)) @@ -3351,5 +3376,5 @@ void bgp_packet_process_error(struct event *thread) peer->last_reset = PEER_DOWN_CLOSE_SESSION; } - bgp_event_update(peer, code); + bgp_event_update(connection, code); } diff --git a/bgpd/bgp_packet.h b/bgpd/bgp_packet.h index 04bdb8184..b67acf205 100644 --- a/bgpd/bgp_packet.h +++ b/bgpd/bgp_packet.h @@ -37,17 +37,18 @@ DECLARE_HOOK(bgp_packet_send, do { \ _s = bgp_update_packet_eor(_peer, _afi, _safi); \ if (_s) { \ - bgp_packet_add(_peer, _s); \ + bgp_packet_add(_peer->connection, _peer, _s); \ } \ } while (0) /* Packet send and receive function prototypes. */ extern void bgp_keepalive_send(struct peer *peer); -extern void bgp_open_send(struct peer *peer); -extern void bgp_notify_send(struct peer *peer, uint8_t code, uint8_t sub_code); -extern void bgp_notify_send_with_data(struct peer *peer, uint8_t code, - uint8_t sub_code, uint8_t *data, - size_t datalen); +extern void bgp_open_send(struct peer_connection *connection); +extern void bgp_notify_send(struct peer_connection *connection, uint8_t code, + uint8_t sub_code); +extern void bgp_notify_send_with_data(struct peer_connection *connection, + uint8_t code, uint8_t sub_code, + uint8_t *data, size_t datalen); void bgp_notify_io_invalid(struct peer *peer, uint8_t code, uint8_t sub_code, uint8_t *data, size_t datalen); extern void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi, @@ -56,8 +57,8 @@ extern void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi, extern void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi, int capabilty_code, int action); -extern int bgp_capability_receive(struct peer *peer, bgp_size_t length); - +extern int bgp_capability_receive(struct peer_connection *connection, + struct peer *peer, bgp_size_t length); extern int bgp_nlri_parse(struct peer *peer, struct attr *attr, struct bgp_nlri *nlri, bool mp_withdraw); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 8c8087a2f..227a68ee5 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -598,7 +598,7 @@ struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info) */ int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, struct bgp_path_info *exist, int *paths_eq, - struct bgp_maxpaths_cfg *mpath_cfg, int debug, + struct bgp_maxpaths_cfg *mpath_cfg, bool debug, char *pfx_buf, afi_t afi, safi_t safi, enum bgp_path_selection_reason *reason) { @@ -719,16 +719,6 @@ int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, * sticky flag. */ if (newattr->sticky != existattr->sticky) { - if (!debug) { - prefix2str(new_p, pfx_buf, - sizeof(*pfx_buf) - * PREFIX2STR_BUFFER); - bgp_path_info_path_with_addpath_rx_str( - new, new_buf, sizeof(new_buf)); - bgp_path_info_path_with_addpath_rx_str( - exist, exist_buf, sizeof(exist_buf)); - } - if (newattr->sticky && !existattr->sticky) { *reason = bgp_path_selection_evpn_sticky_mac; if (debug) @@ -1507,9 +1497,14 @@ int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, { enum bgp_path_selection_reason reason; char pfx_buf[PREFIX2STR_BUFFER] = {}; + bool debug = false; + + if (debug) + prefix2str(bgp_dest_get_prefix(new->net), pfx_buf, + sizeof(pfx_buf)); - return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf, - AFI_L2VPN, SAFI_EVPN, &reason); + return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, debug, + pfx_buf, AFI_L2VPN, SAFI_EVPN, &reason); } /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist @@ -1523,8 +1518,10 @@ int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new, { int paths_eq; int ret; - ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf, - afi, safi, reason); + bool debug = false; + + ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, debug, + pfx_buf, afi, safi, reason); if (paths_eq) ret = 0; @@ -2712,7 +2709,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest, struct bgp_path_info *pi1; struct bgp_path_info *pi2; struct bgp_path_info *nextpi = NULL; - int paths_eq, do_mpath, debug; + int paths_eq, do_mpath; + bool debug; struct list mp_list; char pfx_buf[PREFIX2STR_BUFFER] = {}; char path_buf[PATH_ADDPATH_STR_BUFFER]; @@ -2746,7 +2744,7 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest, if (pi1->peer != bgp->peer_self && !CHECK_FLAG(pi1->peer->sflags, PEER_STATUS_NSF_WAIT)) { - if (!peer_established(pi1->peer)) + if (!peer_established(pi1->peer->connection)) continue; } @@ -2761,7 +2759,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest, if (pi2->peer != bgp->peer_self && !CHECK_FLAG(pi2->peer->sflags, PEER_STATUS_NSF_WAIT) && - !peer_established(pi2->peer)) + !peer_established( + pi2->peer->connection)) continue; if (!aspath_cmp_left(pi1->attr->aspath, @@ -2834,8 +2833,7 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest, if (pi->peer && pi->peer != bgp->peer_self && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT)) - if (!peer_established(pi->peer)) { - + if (!peer_established(pi->peer->connection)) { if (debug) zlog_debug( "%s: %pBD(%s) non self peer %s not estab state", @@ -2909,7 +2907,7 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest, if (pi->peer && pi->peer != bgp->peer_self && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT)) - if (!peer_established(pi->peer)) + if (!peer_established(pi->peer->connection)) continue; if (!bgp_path_info_nexthop_cmp(pi, new_select)) { @@ -3731,10 +3729,8 @@ void bgp_add_eoiu_mark(struct bgp *bgp) static void bgp_maximum_prefix_restart_timer(struct event *thread) { - struct peer *peer; - - peer = EVENT_ARG(thread); - peer->t_pmax_restart = NULL; + struct peer_connection *connection = EVENT_ARG(thread); + struct peer *peer = connection->peer; if (bgp_debug_neighbor_events(peer)) zlog_debug( @@ -3792,6 +3788,7 @@ bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi, ? bgp_filtered_routes_count(peer, afi, safi) + peer->pcount[afi][safi] : peer->pcount[afi][safi]; + struct peer_connection *connection = peer->connection; if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX)) return false; @@ -3827,7 +3824,7 @@ bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi, ndata[6] = (peer->pmax[afi][safi]); SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW); - bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE, + bgp_notify_send_with_data(connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_MAX_PREFIX, ndata, 7); } @@ -3846,7 +3843,7 @@ bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi, "%pBP Maximum-prefix restart timer started for %d secs", peer, peer->v_pmax_restart); - BGP_TIMER_ON(peer->t_pmax_restart, + BGP_TIMER_ON(connection->t_pmax_restart, bgp_maximum_prefix_restart_timer, peer->v_pmax_restart); } @@ -5182,7 +5179,7 @@ static void bgp_announce_route_timer_expired(struct event *t) paf = EVENT_ARG(t); peer = paf->peer; - if (!peer_established(peer)) + if (!peer_established(peer->connection)) return; if (!peer->afc_nego[paf->afi][paf->safi]) @@ -5598,7 +5595,7 @@ static void bgp_clear_node_complete(struct work_queue *wq) struct peer *peer = wq->spec.data; /* Tickle FSM to start moving again */ - BGP_EVENT_ADD(peer, Clearing_Completed); + BGP_EVENT_ADD(peer->connection, Clearing_Completed); peer_unlock(peer); /* bgp_clear_route */ } @@ -9368,7 +9365,7 @@ void route_vty_out(struct vty *vty, const struct prefix *p, if (json_paths) json_object_string_addf(json_path, "peerId", "%pSU", - &path->peer->su); + &path->peer->connection->su); /* Print aspath */ if (attr->aspath) { @@ -9988,7 +9985,7 @@ static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer, json_peer); else json_object_object_addf(json_adv_to, json_peer, "%pSU", - &peer->su); + &peer->connection->su); } else { if (*first) { vty_out(vty, "%s", header); @@ -10002,12 +9999,12 @@ static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer, peer->conf_if); else vty_out(vty, " %s(%pSU)", peer->hostname, - &peer->su); + &peer->connection->su); } else { if (peer->conf_if) vty_out(vty, " %s", peer->conf_if); else - vty_out(vty, " %pSU", &peer->su); + vty_out(vty, " %pSU", &peer->connection->su); } } } @@ -10433,7 +10430,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, if (json_paths) { json_object_string_addf(json_peer, "peerId", "%pSU", - &path->peer->su); + &path->peer->connection->su); json_object_string_addf(json_peer, "routerId", "%pI4", &path->peer->remote_id); @@ -10468,7 +10465,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, path->peer->host); else vty_out(vty, " from %pSU", - &path->peer->su); + &path->peer->connection->su); } if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) @@ -11009,10 +11006,10 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, str, label2vni(&attr->label)); } - if (path->peer->t_gr_restart && + if (path->peer->connection->t_gr_restart && CHECK_FLAG(path->flags, BGP_PATH_STALE)) { - unsigned long gr_remaining = - event_timer_remain_second(path->peer->t_gr_restart); + unsigned long gr_remaining = event_timer_remain_second( + path->peer->connection->t_gr_restart); if (json_paths) { json_object_int_add(json_path, @@ -14822,8 +14819,8 @@ static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer, if (safi == SAFI_LABELED_UNICAST) safi = SAFI_UNICAST; - return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags, - RPKI_NOT_BEING_USED); + return bgp_show(vty, peer->bgp, afi, safi, type, &peer->connection->su, + show_flags, RPKI_NOT_BEING_USED); } /* @@ -15099,8 +15096,8 @@ uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo, /* Check source address. * Note: for aggregate route, peer can have unspec af type. */ - if (pinfo->sub_type != BGP_ROUTE_AGGREGATE - && !sockunion2hostprefix(&peer->su, &q)) + if (pinfo->sub_type != BGP_ROUTE_AGGREGATE && + !sockunion2hostprefix(&peer->connection->su, &q)) return 0; dest = bgp_node_match(bgp_distance_table[afi][safi], &q); @@ -15576,7 +15573,7 @@ static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg) struct vty *vty = arg; struct peer *peer = bucket->data; - vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su); + vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->connection->su); } DEFUN (show_bgp_listeners, diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index cc13500fa..7470954bf 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -915,7 +915,7 @@ extern void bgp_path_info_add_with_caller(const char *caller, extern void bgp_aggregate_free(struct bgp_aggregate *aggregate); extern int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, struct bgp_path_info *exist, int *paths_eq, - struct bgp_maxpaths_cfg *mpath_cfg, int debug, + struct bgp_maxpaths_cfg *mpath_cfg, bool debug, char *pfx_buf, afi_t afi, safi_t safi, enum bgp_path_selection_reason *reason); #define bgp_path_info_add(A, B) \ diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 9e851c5bc..274df5197 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -282,14 +282,14 @@ route_match_peer(void *rule, const struct prefix *prefix, void *object) } if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { - if (sockunion_same(su, &peer->su)) + if (sockunion_same(su, &peer->connection->su)) return RMAP_MATCH; return RMAP_NOMATCH; } else { group = peer->group; for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) { - if (sockunion_same(su, &peer->su)) + if (sockunion_same(su, &peer->connection->su)) return RMAP_MATCH; } return RMAP_NOMATCH; @@ -574,11 +574,11 @@ route_match_ip_route_source(void *rule, const struct prefix *pfx, void *object) path = object; peer = path->peer; - if (!peer || sockunion_family(&peer->su) != AF_INET) + if (!peer || sockunion_family(&peer->connection->su) != AF_INET) return RMAP_NOMATCH; p.family = AF_INET; - p.prefix = peer->su.sin.sin_addr; + p.prefix = peer->connection->su.sin.sin_addr; p.prefixlen = IPV4_MAX_BITLEN; alist = access_list_lookup(AFI_IP, (char *)rule); @@ -927,11 +927,11 @@ route_match_ip_route_source_prefix_list(void *rule, const struct prefix *prefix, path = object; peer = path->peer; - if (!peer || sockunion_family(&peer->su) != AF_INET) + if (!peer || sockunion_family(&peer->connection->su) != AF_INET) return RMAP_NOMATCH; p.family = AF_INET; - p.prefix = peer->su.sin.sin_addr; + p.prefix = peer->connection->su.sin.sin_addr; p.prefixlen = IPV4_MAX_BITLEN; plist = prefix_list_lookup(AFI_IP, (char *)rule); @@ -4340,7 +4340,7 @@ static void bgp_route_map_process_peer(const char *rmap_name, && (strcmp(rmap_name, filter->map[RMAP_IN].name) == 0)) { filter->map[RMAP_IN].map = map; - if (route_update && peer_established(peer)) { + if (route_update && peer_established(peer->connection)) { if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)) { if (bgp_debug_update(peer, NULL, NULL, 1)) diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index c6e3131e0..f0b2ffdee 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -520,7 +520,7 @@ static void revalidate_all_routes(void) if (!bgp->rib[afi][safi]) continue; - if (!peer_established(peer)) + if (!peer_established(peer->connection)) continue; rvp = XCALLOC(MTYPE_BGP_RPKI_REVALIDATE, diff --git a/bgpd/bgp_snmp_bgp4.c b/bgpd/bgp_snmp_bgp4.c index 8af87ae4b..0c391b621 100644 --- a/bgpd/bgp_snmp_bgp4.c +++ b/bgpd/bgp_snmp_bgp4.c @@ -83,10 +83,10 @@ static struct peer *peer_lookup_addr_ipv4(struct in_addr *src) for (ALL_LIST_ELEMENTS_RO(bm->bgp, bgpnode, bgp)) { for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) { - if (sockunion_family(&peer->su) != AF_INET) + if (sockunion_family(&peer->connection->su) != AF_INET) continue; - if (sockunion2ip(&peer->su) == src->s_addr) + if (sockunion2ip(&peer->connection->su) == src->s_addr) return peer; } } @@ -104,22 +104,22 @@ static struct peer *bgp_peer_lookup_next(struct in_addr *src) for (ALL_LIST_ELEMENTS_RO(bm->bgp, bgpnode, bgp)) { for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) { - if (sockunion_family(&peer->su) != AF_INET) + if (sockunion_family(&peer->connection->su) != AF_INET) continue; - if (ntohl(sockunion2ip(&peer->su)) <= + if (ntohl(sockunion2ip(&peer->connection->su)) <= ntohl(src->s_addr)) continue; if (!next_peer || - ntohl(sockunion2ip(&next_peer->su)) > - ntohl(sockunion2ip(&peer->su))) { + ntohl(sockunion2ip(&next_peer->connection->su)) > + ntohl(sockunion2ip(&peer->connection->su))) { next_peer = peer; } } } if (next_peer) { - src->s_addr = sockunion2ip(&next_peer->su); + src->s_addr = sockunion2ip(&next_peer->connection->su); return next_peer; } @@ -173,6 +173,7 @@ static int write_bgpPeerTable(int action, uint8_t *var_val, { struct in_addr addr; struct peer *peer; + struct peer_connection *connection; long intval; if (var_val_type != ASN_INTEGER) { @@ -190,6 +191,8 @@ static int write_bgpPeerTable(int action, uint8_t *var_val, if (!peer) return SNMP_ERR_NOSUCHNAME; + connection = peer->connection; + if (action != SNMP_MSG_INTERNAL_SET_COMMIT) return SNMP_ERR_NOERROR; @@ -202,7 +205,7 @@ static int write_bgpPeerTable(int action, uint8_t *var_val, #define BGP_PeerAdmin_start 2 /* When the peer is established, */ if (intval == BGP_PeerAdmin_stop) - BGP_EVENT_ADD(peer, BGP_Stop); + BGP_EVENT_ADD(connection, BGP_Stop); else if (intval == BGP_PeerAdmin_start) ; /* Do nothing. */ else @@ -414,7 +417,8 @@ static struct bgp_path_info *bgp4PathAttrLookup(struct variable *v, oid name[], if (dest) { for (path = bgp_dest_get_bgp_path_info(dest); path; path = path->next) - if (sockunion_same(&path->peer->su, &su)) + if (sockunion_same(&path->peer->connection->su, + &su)) return path; bgp_dest_unlock_node(dest); @@ -464,15 +468,18 @@ static struct bgp_path_info *bgp4PathAttrLookup(struct variable *v, oid name[], for (path = bgp_dest_get_bgp_path_info(dest); path; path = path->next) { - if (path->peer->su.sin.sin_family == AF_INET && + if (path->peer->connection->su.sin.sin_family == + AF_INET && ntohl(paddr.s_addr) < - ntohl(path->peer->su.sin.sin_addr - .s_addr)) { + ntohl(path->peer->connection->su.sin + .sin_addr.s_addr)) { if (min) { - if (ntohl(path->peer->su.sin + if (ntohl(path->peer->connection + ->su.sin .sin_addr .s_addr) < - ntohl(min->peer->su.sin + ntohl(min->peer->connection + ->su.sin .sin_addr .s_addr)) min = path; @@ -494,7 +501,8 @@ static struct bgp_path_info *bgp4PathAttrLookup(struct variable *v, oid name[], *offset = rn_p->prefixlen; offset++; oid_copy_in_addr(offset, - &min->peer->su.sin.sin_addr); + &min->peer->connection->su.sin + .sin_addr); addr->prefix = rn_p->u.prefix4; addr->prefixlen = rn_p->prefixlen; @@ -532,7 +540,7 @@ static uint8_t *bgp4PathAttrTable(struct variable *v, oid name[], switch (v->magic) { case BGP4PATHATTRPEER: /* 1 */ - return SNMP_IPADDRESS(path->peer->su.sin.sin_addr); + return SNMP_IPADDRESS(path->peer->connection->su.sin.sin_addr); case BGP4PATHATTRIPADDRPREFIXLEN: /* 2 */ return SNMP_INTEGER(addr.prefixlen); case BGP4PATHATTRIPADDRPREFIX: /* 3 */ @@ -754,10 +762,11 @@ int bgpTrapEstablished(struct peer *peer) int ret; struct in_addr addr; oid index[sizeof(oid) * IN_ADDR_SIZE]; + struct peer_connection *connection = peer->connection; /* Check if this peer just went to Established */ - if ((peer->connection->ostatus != OpenConfirm) || - !(peer_established(peer))) + if ((connection->ostatus != OpenConfirm) || + !(peer_established(connection))) return 0; ret = inet_aton(peer->host, &addr); diff --git a/bgpd/bgp_snmp_bgp4v2.c b/bgpd/bgp_snmp_bgp4v2.c index 5e77a9297..cfafae55d 100644 --- a/bgpd/bgp_snmp_bgp4v2.c +++ b/bgpd/bgp_snmp_bgp4v2.c @@ -43,14 +43,16 @@ static struct peer *peer_lookup_all_vrf(struct ipaddr *addr) for (ALL_LIST_ELEMENTS_RO(bm->bgp, bgpnode, bgp)) { for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) { - switch (sockunion_family(&peer->su)) { + switch (sockunion_family(&peer->connection->su)) { case AF_INET: - if (IPV4_ADDR_SAME(&peer->su.sin.sin_addr, + if (IPV4_ADDR_SAME(&peer->connection->su.sin + .sin_addr, &addr->ip._v4_addr)) return peer; break; case AF_INET6: - if (IPV6_ADDR_SAME(&peer->su.sin6.sin6_addr, + if (IPV6_ADDR_SAME(&peer->connection->su.sin6 + .sin6_addr, &addr->ip._v6_addr)) return peer; break; @@ -74,38 +76,47 @@ static struct peer *peer_lookup_all_vrf_next(struct ipaddr *addr, oid *offset, for (ALL_LIST_ELEMENTS_RO(bm->bgp, bgpnode, bgp)) { for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) { - sa_family_t peer_family = sockunion_family(&peer->su); + sa_family_t peer_family = + sockunion_family(&peer->connection->su); if (peer_family != family) continue; - switch (sockunion_family(&peer->su)) { + switch (peer_family) { case AF_INET: oid2in_addr(offset, IN_ADDR_SIZE, &addr->ip._v4_addr); - if (IPV4_ADDR_CMP(&peer->su.sin.sin_addr, + if (IPV4_ADDR_CMP(&peer->connection->su.sin + .sin_addr, &addr->ip._v4_addr) < 0 || - IPV4_ADDR_SAME(&peer->su.sin.sin_addr, + IPV4_ADDR_SAME(&peer->connection->su.sin + .sin_addr, &addr->ip._v4_addr)) continue; if (!next_peer || - IPV4_ADDR_CMP(&next_peer->su.sin.sin_addr, - &peer->su.sin.sin_addr) > 0) + IPV4_ADDR_CMP(&next_peer->connection->su.sin + .sin_addr, + &peer->connection->su.sin + .sin_addr) > 0) next_peer = peer; break; case AF_INET6: oid2in6_addr(offset, &addr->ip._v6_addr); - if (IPV6_ADDR_CMP(&peer->su.sin6.sin6_addr, + if (IPV6_ADDR_CMP(&peer->connection->su.sin6 + .sin6_addr, &addr->ip._v6_addr) < 0 || - IPV6_ADDR_SAME(&peer->su.sin6.sin6_addr, + IPV6_ADDR_SAME(&peer->connection->su.sin6 + .sin6_addr, &addr->ip._v6_addr)) continue; if (!next_peer || - IPV6_ADDR_CMP(&next_peer->su.sin6.sin6_addr, - &peer->su.sin6.sin6_addr) > 0) + IPV6_ADDR_CMP(&next_peer->connection->su + .sin6.sin6_addr, + &peer->connection->su.sin6 + .sin6_addr) > 0) next_peer = peer; break; @@ -158,13 +169,15 @@ static struct peer *bgpv2PeerTable_lookup(struct variable *v, oid name[], if (peer == NULL) return NULL; - switch (sockunion_family(&peer->su)) { + switch (sockunion_family(&peer->connection->su)) { case AF_INET: - oid_copy_in_addr(offset, &peer->su.sin.sin_addr); + oid_copy_in_addr(offset, + &peer->connection->su.sin.sin_addr); *length = afi_len + namelen; return peer; case AF_INET6: - oid_copy_in6_addr(offset, &peer->su.sin6.sin6_addr); + oid_copy_in6_addr(offset, + &peer->connection->su.sin6.sin6_addr); *length = afi_len + namelen; return peer; default: @@ -467,7 +480,8 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length, if (dest) { for (path = bgp_dest_get_bgp_path_info(dest); path; path = path->next) - if (sockunion_same(&path->peer->su, &su)) + if (sockunion_same(&path->peer->connection->su, + &su)) return path; bgp_dest_unlock_node(dest); @@ -532,27 +546,29 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length, for (path = bgp_dest_get_bgp_path_info(dest); path; path = path->next) { sa_family_t path_family = - sockunion_family(&path->peer->su); + sockunion_family(&path->peer->connection->su); if (path_family == AF_INET && IPV4_ADDR_CMP(&paddr.ip._v4_addr, - &path->peer->su.sin.sin_addr) < 0) { + &path->peer->connection->su.sin + .sin_addr) < 0) { if (!min || (min && - IPV4_ADDR_CMP( - &path->peer->su.sin.sin_addr, - &min->peer->su.sin.sin_addr) < 0)) + IPV4_ADDR_CMP(&path->peer->connection->su + .sin.sin_addr, + &min->peer->connection->su + .sin.sin_addr) < 0)) min = path; } else if (path_family == AF_INET6 && - IPV6_ADDR_CMP( - &paddr.ip._v6_addr, - &path->peer->su.sin6.sin6_addr) < - 0) { + IPV6_ADDR_CMP(&paddr.ip._v6_addr, + &path->peer->connection->su + .sin6.sin6_addr) < 0) { if (!min || (min && - IPV6_ADDR_CMP( - &path->peer->su.sin6.sin6_addr, - &min->peer->su.sin6.sin6_addr) < + IPV6_ADDR_CMP(&path->peer->connection->su + .sin6.sin6_addr, + &min->peer->connection->su + .sin6.sin6_addr) < 0)) min = path; } @@ -578,11 +594,13 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length, /* Encode peer's IP into OID */ if (family == AF_INET) { oid_copy_in_addr(offset, - &min->peer->su.sin.sin_addr); + &min->peer->connection->su.sin + .sin_addr); addr->u.prefix4 = rn_p->u.prefix4; } else { - oid_copy_in6_addr( - offset, &min->peer->su.sin6.sin6_addr); + oid_copy_in6_addr(offset, + &min->peer->connection->su + .sin6.sin6_addr); addr->u.prefix6 = rn_p->u.prefix6; } diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c index a55e48d8e..e47ea8aa8 100644 --- a/bgpd/bgp_updgrp.c +++ b/bgpd/bgp_updgrp.c @@ -279,6 +279,8 @@ static void *updgrp_hash_alloc(void *p) updgrp = XCALLOC(MTYPE_BGP_UPDGRP, sizeof(struct update_group)); memcpy(updgrp, in, sizeof(struct update_group)); updgrp->conf = XCALLOC(MTYPE_BGP_PEER, sizeof(struct peer)); + updgrp->conf->connection = XCALLOC(MTYPE_BGP_PEER_CONNECTION, + sizeof(struct peer_connection)); conf_copy(updgrp->conf, in->conf, in->afi, in->safi); return updgrp; } @@ -634,7 +636,7 @@ static bool updgrp_hash_cmp(const void *p1, const void *p2) if ((CHECK_FLAG(pe1->flags, PEER_FLAG_LONESOUL) || CHECK_FLAG(pe1->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)) && - !sockunion_same(&pe1->su, &pe2->su)) + !sockunion_same(&pe1->connection->su, &pe2->connection->su)) return false; return true; @@ -987,13 +989,18 @@ static struct update_group *update_group_find(struct peer_af *paf) struct update_group *updgrp; struct update_group tmp; struct peer tmp_conf; + struct peer_connection tmp_connection; - if (!peer_established(PAF_PEER(paf))) + if (!peer_established((PAF_PEER(paf))->connection)) return NULL; memset(&tmp, 0, sizeof(tmp)); memset(&tmp_conf, 0, sizeof(tmp_conf)); + memset(&tmp_connection, 0, sizeof(struct peer_connection)); + tmp.conf = &tmp_conf; + tmp_conf.connection = &tmp_connection; + peer2_updgrp_copy(&tmp, paf); updgrp = hash_lookup(paf->peer->bgp->update_groups[paf->afid], &tmp); @@ -1006,10 +1013,14 @@ static struct update_group *update_group_create(struct peer_af *paf) struct update_group *updgrp; struct update_group tmp; struct peer tmp_conf; + struct peer_connection tmp_connection; memset(&tmp, 0, sizeof(tmp)); memset(&tmp_conf, 0, sizeof(tmp_conf)); + memset(&tmp_connection, 0, sizeof(tmp_connection)); + tmp.conf = &tmp_conf; + tmp_conf.connection = &tmp_connection; peer2_updgrp_copy(&tmp, paf); updgrp = hash_get(paf->peer->bgp->update_groups[paf->afid], &tmp, @@ -1039,6 +1050,7 @@ static void update_group_delete(struct update_group *updgrp) XFREE(MTYPE_BGP_PEER_IFNAME, updgrp->conf->ifname); + XFREE(MTYPE_BGP_PEER_CONNECTION, updgrp->conf->connection); XFREE(MTYPE_BGP_PEER, updgrp->conf); XFREE(MTYPE_BGP_UPDGRP, updgrp); } @@ -1251,7 +1263,7 @@ static struct update_subgroup *update_subgroup_find(struct update_group *updgrp, } else version = 0; - if (!peer_established(PAF_PEER(paf))) + if (!peer_established(PAF_PEER(paf)->connection)) return NULL; UPDGRP_FOREACH_SUBGRP (updgrp, subgrp) { @@ -1945,7 +1957,7 @@ void update_group_adjust_peer(struct peer_af *paf) return; peer = PAF_PEER(paf); - if (!peer_established(peer)) { + if (!peer_established(peer->connection)) { return; } @@ -2000,13 +2012,13 @@ int update_group_adjust_soloness(struct peer *peer, int set) if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { peer_lonesoul_or_not(peer, set); - if (peer_established(peer)) + if (peer_established(peer->connection)) bgp_announce_route_all(peer); } else { group = peer->group; for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) { peer_lonesoul_or_not(peer, set); - if (peer_established(peer)) + if (peer_established(peer->connection)) bgp_announce_route_all(peer); } } @@ -2199,12 +2211,15 @@ void subgroup_trigger_write(struct update_subgroup *subgrp) * the subgroup output queue into their own output queue. This action * will trigger a write job on the I/O thread. */ - SUBGRP_FOREACH_PEER (subgrp, paf) - if (peer_established(paf->peer)) - event_add_timer_msec( - bm->master, bgp_generate_updgrp_packets, - paf->peer, 0, - &paf->peer->t_generate_updgrp_packets); + SUBGRP_FOREACH_PEER (subgrp, paf) { + struct peer_connection *connection = paf->peer->connection; + + if (peer_established(connection)) + event_add_timer_msec(bm->master, + bgp_generate_updgrp_packets, + connection, 0, + &connection->t_generate_updgrp_packets); + } } int update_group_clear_update_dbg(struct update_group *updgrp, void *arg) diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index 68fd11a04..ccbb23ebb 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -384,8 +384,11 @@ static void subgroup_coalesce_timer(struct event *thread) SUBGRP_FOREACH_PEER (subgrp, paf) { peer = PAF_PEER(paf); - EVENT_OFF(peer->t_routeadv); - BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0); + struct peer_connection *connection = peer->connection; + + EVENT_OFF(connection->t_routeadv); + BGP_TIMER_ON(connection->t_routeadv, bgp_routeadv_timer, + 0); } } } diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index e0f5b7847..f6db3fb36 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -2890,7 +2890,7 @@ DEFUN(bgp_reject_as_sets, bgp_reject_as_sets_cmd, for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { 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_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } @@ -2916,7 +2916,7 @@ DEFUN(no_bgp_reject_as_sets, no_bgp_reject_as_sets_cmd, for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { 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_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } @@ -4876,7 +4876,7 @@ static int peer_conf_interface_get(struct vty *vty, const char *conf_if, /* v6only flag changed. Reset bgp seesion */ 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_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else bgp_session_reset(peer); @@ -10722,7 +10722,7 @@ static inline void calc_peers_cfgd_estbd(struct bgp *bgp, int *peers_cfgd, if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) continue; (*peers_cfgd)++; - if (peer_established(peer)) + if (peer_established(peer->connection)) (*peers_estbd)++; } } @@ -11246,7 +11246,8 @@ static void bgp_show_peer_reset(struct vty * vty, struct peer *peer, static inline bool bgp_has_peer_failed(struct peer *peer, afi_t afi, safi_t safi) { - return ((!peer_established(peer)) || !peer->afc_recv[afi][safi]); + return ((!peer_established(peer->connection)) || + !peer->afc_recv[afi][safi]); } static void bgp_show_failed_summary(struct vty *vty, struct bgp *bgp, @@ -11273,7 +11274,7 @@ static void bgp_show_failed_summary(struct vty *vty, struct bgp *bgp, peer->dropped); peer_uptime(peer->uptime, timebuf, BGP_UPTIME_LEN, use_json, json_peer); - if (peer_established(peer)) + if (peer_established(peer->connection)) json_object_string_add(json_peer, "lastResetDueTo", "AFI/SAFI Not Negotiated"); else @@ -11296,7 +11297,7 @@ static void bgp_show_failed_summary(struct vty *vty, struct bgp *bgp, peer->dropped, peer_uptime(peer->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL)); - if (peer_established(peer)) + if (peer_established(peer->connection)) vty_out(vty, " AFI/SAFI Not Negotiated\n"); else bgp_show_peer_reset(vty, peer, NULL, @@ -11883,10 +11884,10 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, if (peer->conf_if) json_object_string_add(json_peer, "idType", "interface"); - else if (peer->su.sa.sa_family == AF_INET) + else if (peer->connection->su.sa.sa_family == AF_INET) json_object_string_add(json_peer, "idType", "ipv4"); - else if (peer->su.sa.sa_family == AF_INET6) + else if (peer->connection->su.sa.sa_family == AF_INET6) json_object_string_add(json_peer, "idType", "ipv6"); json_object_object_add(json_peers, peer->host, @@ -11977,7 +11978,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, peer_uptime(peer->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL)); - if (peer_established(peer)) { + if (peer_established(peer->connection)) { if (peer->afc_recv[afi][safi]) { if (CHECK_FLAG( bgp->flags, @@ -12433,9 +12434,9 @@ static void bgp_show_neighnor_graceful_restart_flags(struct vty *vty, bool rbit = false; bool nbit = false; - if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_ADV) - && (CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV)) - && (peer_established(p))) { + if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_ADV) && + (CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV)) && + (peer_established(p->connection))) { rbit = CHECK_FLAG(p->cap, PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV); nbit = CHECK_FLAG(p->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_RCV); } @@ -12458,9 +12459,8 @@ static void bgp_show_neighbor_graceful_restart_remote_mode(struct vty *vty, if (!json) vty_out(vty, "\n Remote GR Mode: "); - if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV) - && (peer_established(peer))) { - + if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV) && + (peer_established(peer->connection))) { if ((peer->nsf_af_count == 0) && !CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) { @@ -12623,11 +12623,12 @@ static void bgp_show_neighbor_graceful_restart_capability_per_afi_safi( json_object_int_add(json_timer, "stalePathTimer", peer->bgp->stalepath_time); - if (peer->t_gr_stale != NULL) { + if (peer->connection->t_gr_stale != NULL) { json_object_int_add(json_timer, "stalePathTimerRemaining", event_timer_remain_second( - peer->t_gr_stale)); + peer->connection + ->t_gr_stale)); } /* Display Configured Selection @@ -12657,11 +12658,11 @@ static void bgp_show_neighbor_graceful_restart_capability_per_afi_safi( " Configured Stale Path Time(sec): %u\n", peer->bgp->stalepath_time); - if (peer->t_gr_stale != NULL) + if (peer->connection->t_gr_stale != NULL) vty_out(vty, " Stale Path Remaining(sec): %ld\n", event_timer_remain_second( - peer->t_gr_stale)); + peer->connection->t_gr_stale)); /* Display Configured Selection * Deferral only when when * Gr mode is enabled. @@ -12706,10 +12707,10 @@ static void bgp_show_neighbor_graceful_restart_time(struct vty *vty, json_object_int_add(json_timer, "receivedRestartTimer", p->v_gr_restart); - if (p->t_gr_restart != NULL) - json_object_int_add( - json_timer, "restartTimerRemaining", - event_timer_remain_second(p->t_gr_restart)); + if (p->connection->t_gr_restart != NULL) + json_object_int_add(json_timer, "restartTimerRemaining", + event_timer_remain_second( + p->connection->t_gr_restart)); json_object_object_add(json, "timers", json_timer); } else { @@ -12720,12 +12721,14 @@ static void bgp_show_neighbor_graceful_restart_time(struct vty *vty, vty_out(vty, " Received Restart Time(sec): %u\n", p->v_gr_restart); - if (p->t_gr_restart != NULL) + if (p->connection->t_gr_restart != NULL) vty_out(vty, " Restart Time Remaining(sec): %ld\n", - event_timer_remain_second(p->t_gr_restart)); - if (p->t_gr_restart != NULL) { + event_timer_remain_second( + p->connection->t_gr_restart)); + if (p->connection->t_gr_restart != NULL) { vty_out(vty, " Restart Time Remaining(sec): %ld\n", - event_timer_remain_second(p->t_gr_restart)); + event_timer_remain_second( + p->connection->t_gr_restart)); } } } @@ -12743,10 +12746,10 @@ static void bgp_show_peer_gr_status(struct vty *vty, struct peer *p, if (p->conf_if) { if (json) json_object_string_addf(json, "neighborAddr", "%pSU", - &p->su); + &p->connection->su); else vty_out(vty, "BGP neighbor on %s: %pSU\n", p->conf_if, - &p->su); + &p->connection->su); } else { snprintf(neighborAddr, sizeof(neighborAddr), "%s%s", dn_flag, p->host); @@ -13414,19 +13417,19 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, if (!use_json) { if (p->conf_if) /* Configured interface name. */ vty_out(vty, "BGP neighbor on %s: %pSU, ", p->conf_if, - &p->su); + &p->connection->su); else /* Configured IP address. */ vty_out(vty, "BGP neighbor is %s%s, ", dn_flag, p->host); } if (use_json) { - if (p->conf_if && BGP_PEER_SU_UNSPEC(p)) + if (p->conf_if && BGP_CONNECTION_SU_UNSPEC(p->connection)) json_object_string_add(json_neigh, "bgpNeighborAddr", "none"); - else if (p->conf_if && !BGP_PEER_SU_UNSPEC(p)) + else if (p->conf_if && !BGP_CONNECTION_SU_UNSPEC(p->connection)) json_object_string_addf(json_neigh, "bgpNeighborAddr", - "%pSU", &p->su); + "%pSU", &p->connection->su); asn_asn2json(json_neigh, "remoteAs", p->as, bgp->asnotation); @@ -13555,7 +13558,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, if (dn_flag[0]) { struct prefix prefix, *range = NULL; - if (sockunion2hostprefix(&(p->su), &prefix)) + if (sockunion2hostprefix(&p->connection->su, + &prefix)) range = peer_group_lookup_dynamic_neighbor_range( p->group, &prefix); @@ -13574,7 +13578,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, if (dn_flag[0]) { struct prefix prefix, *range = NULL; - if (sockunion2hostprefix(&(p->su), &prefix)) + if (sockunion2hostprefix(&p->connection->su, + &prefix)) range = peer_group_lookup_dynamic_neighbor_range( p->group, &prefix); @@ -13612,7 +13617,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, lookup_msg(bgp_status_msg, p->connection->status, NULL)); - if (peer_established(p)) { + if (peer_established(p->connection)) { time_t uptime; uptime = monotime(NULL); @@ -13736,7 +13741,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, vty_out(vty, " BGP state = %s", lookup_msg(bgp_status_msg, p->connection->status, NULL)); - if (peer_established(p)) + if (peer_established(p->connection)) vty_out(vty, ", up for %8s", peer_uptime(p->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL)); @@ -13796,7 +13801,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, bgp->t_condition_check)); } /* Capability. */ - if (peer_established(p) && + if (peer_established(p->connection) && (p->cap || peer_afc_advertised(p) || peer_afc_received(p))) { if (use_json) { json_object *json_cap = NULL; @@ -14653,7 +14658,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, json_grace_send = json_object_new_object(); json_grace_recv = json_object_new_object(); - if ((peer_established(p)) && + if ((peer_established(p->connection)) && CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV)) { FOREACH_AFI_SAFI (afi, safi) { if (CHECK_FLAG(p->af_sflags[afi][safi], @@ -14682,26 +14687,27 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, json_grace_recv); - if (p->t_gr_restart) - json_object_int_add( - json_grace, "gracefulRestartTimerMsecs", - event_timer_remain_second(p->t_gr_restart) * - 1000); + if (p->connection->t_gr_restart) + json_object_int_add(json_grace, + "gracefulRestartTimerMsecs", + event_timer_remain_second( + p->connection->t_gr_restart) * + 1000); - if (p->t_gr_stale) - json_object_int_add( - json_grace, "gracefulStalepathTimerMsecs", - event_timer_remain_second(p->t_gr_stale) * - 1000); + if (p->connection->t_gr_stale) + json_object_int_add(json_grace, + "gracefulStalepathTimerMsecs", + event_timer_remain_second( + p->connection->t_gr_stale) * + 1000); /* more gr info in new format */ BGP_SHOW_PEER_GR_CAPABILITY(vty, p, json_grace); json_object_object_add(json_neigh, "gracefulRestartInfo", json_grace); } else { vty_out(vty, " Graceful restart information:\n"); - if ((peer_established(p)) && + if ((peer_established(p->connection)) && CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV)) { - vty_out(vty, " End-of-RIB send: "); FOREACH_AFI_SAFI (afi, safi) { if (CHECK_FLAG(p->af_sflags[afi][safi], @@ -14729,15 +14735,17 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, vty_out(vty, "\n"); } - if (p->t_gr_restart) + if (p->connection->t_gr_restart) vty_out(vty, " The remaining time of restart timer is %ld\n", - event_timer_remain_second(p->t_gr_restart)); + event_timer_remain_second( + p->connection->t_gr_restart)); - if (p->t_gr_stale) + if (p->connection->t_gr_stale) vty_out(vty, " The remaining time of stalepath timer is %ld\n", - event_timer_remain_second(p->t_gr_stale)); + event_timer_remain_second( + p->connection->t_gr_stale)); /* more gr info in new format */ BGP_SHOW_PEER_GR_CAPABILITY(vty, p, NULL); @@ -14965,21 +14973,22 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, vty_out(vty, " Peer had exceeded the max. no. of prefixes configured.\n"); - if (p->t_pmax_restart) { + if (p->connection->t_pmax_restart) { if (use_json) { json_object_boolean_true_add( json_neigh, "reducePrefixNumFrom"); json_object_int_add(json_neigh, "restartInTimerMsec", event_timer_remain_second( - p->t_pmax_restart) * + p->connection + ->t_pmax_restart) * 1000); } else vty_out(vty, " Reduce the no. of prefix from %s, will restart in %ld seconds\n", p->host, event_timer_remain_second( - p->t_pmax_restart)); + p->connection->t_pmax_restart)); } else { if (use_json) json_object_boolean_true_add( @@ -15116,7 +15125,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, if (use_json) { json_object_int_add(json_neigh, "connectRetryTimer", p->v_connect); - if (peer_established(p)) { + if (peer_established(p->connection)) { json_object_int_add(json_neigh, "estimatedRttInMsecs", p->rtt); if (CHECK_FLAG(p->flags, PEER_FLAG_RTT_SHUTDOWN)) { @@ -15128,21 +15137,25 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, p->rtt_keepalive_rcv); } } - if (p->t_start) - json_object_int_add( - json_neigh, "nextStartTimerDueInMsecs", - event_timer_remain_second(p->t_start) * 1000); - if (p->t_connect) - json_object_int_add( - json_neigh, "nextConnectTimerDueInMsecs", - event_timer_remain_second(p->t_connect) * 1000); - if (p->t_routeadv) { + if (p->connection->t_start) + json_object_int_add(json_neigh, + "nextStartTimerDueInMsecs", + event_timer_remain_second( + p->connection->t_start) * + 1000); + if (p->connection->t_connect) + json_object_int_add(json_neigh, + "nextConnectTimerDueInMsecs", + event_timer_remain_second( + p->connection->t_connect) * + 1000); + if (p->connection->t_routeadv) { json_object_int_add(json_neigh, "mraiInterval", p->v_routeadv); - json_object_int_add( - json_neigh, "mraiTimerExpireInMsecs", - event_timer_remain_second(p->t_routeadv) * - 1000); + json_object_int_add(json_neigh, "mraiTimerExpireInMsecs", + event_timer_remain_second( + p->connection->t_routeadv) * + 1000); } if (p->password) json_object_int_add(json_neigh, "authenticationEnabled", @@ -15162,7 +15175,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, } else { vty_out(vty, "BGP Connect Retry Timer in Seconds: %d\n", p->v_connect); - if (peer_established(p)) { + if (peer_established(p->connection)) { vty_out(vty, "Estimated round trip time: %d ms\n", p->rtt); if (CHECK_FLAG(p->flags, PEER_FLAG_RTT_SHUTDOWN)) @@ -15170,17 +15183,20 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, "Shutdown when RTT > %dms, count > %u\n", p->rtt_expected, p->rtt_keepalive_rcv); } - if (p->t_start) + if (p->connection->t_start) vty_out(vty, "Next start timer due in %ld seconds\n", - event_timer_remain_second(p->t_start)); - if (p->t_connect) + event_timer_remain_second( + p->connection->t_start)); + if (p->connection->t_connect) vty_out(vty, "Next connect timer due in %ld seconds\n", - event_timer_remain_second(p->t_connect)); - if (p->t_routeadv) + event_timer_remain_second( + p->connection->t_connect)); + if (p->connection->t_routeadv) vty_out(vty, "MRAI (interval %u) timer expires in %ld seconds\n", p->v_routeadv, - event_timer_remain_second(p->t_routeadv)); + event_timer_remain_second( + p->connection->t_routeadv)); if (p->password) vty_out(vty, "Peer Authentication Enabled\n"); @@ -15253,7 +15269,7 @@ static int bgp_show_neighbor_graceful_restart(struct vty *vty, struct bgp *bgp, json_neighbor); } } else { - if (sockunion_same(&peer->su, su)) { + if (sockunion_same(&peer->connection->su, su)) { found = true; bgp_show_peer_gr_status(vty, peer, json_neighbor); @@ -15323,7 +15339,7 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp, json); } } else { - if (sockunion_same(&peer->su, su)) { + if (sockunion_same(&peer->connection->su, su)) { find = 1; bgp_show_peer(vty, peer, use_json, json); @@ -15345,7 +15361,9 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp, break; } } else { - if (sockunion_same(&peer->su, su)) { + if (sockunion_same(&peer->connection + ->su, + su)) { find = 1; bgp_show_peer(vty, peer, use_json, json); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 105c1080b..3d993e12c 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -140,11 +140,11 @@ static void bgp_start_interface_nbrs(struct bgp *bgp, struct interface *ifp) struct peer *peer; for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - if (peer->conf_if && (strcmp(peer->conf_if, ifp->name) == 0) - && !peer_established(peer)) { + if (peer->conf_if && (strcmp(peer->conf_if, ifp->name) == 0) && + !peer_established(peer->connection)) { if (peer_active(peer)) - BGP_EVENT_ADD(peer, BGP_Stop); - BGP_EVENT_ADD(peer, BGP_Start); + BGP_EVENT_ADD(peer->connection, BGP_Stop); + BGP_EVENT_ADD(peer->connection, BGP_Start); } } } @@ -183,7 +183,7 @@ static void bgp_nbr_connected_delete(struct bgp *bgp, struct nbr_connected *ifc, if (peer->conf_if && (strcmp(peer->conf_if, ifc->ifp->name) == 0)) { peer->last_reset = PEER_DOWN_NBR_ADDR_DEL; - BGP_EVENT_ADD(peer, BGP_Stop); + BGP_EVENT_ADD(peer->connection, BGP_Stop); } } /* Free neighbor also, if we're asked to. */ @@ -279,7 +279,7 @@ static int bgp_ifp_down(struct interface *ifp) continue; if (ifp == peer->nexthop.ifp) { - BGP_EVENT_ADD(peer, BGP_Stop); + BGP_EVENT_ADD(peer->connection, BGP_Stop); peer->last_reset = PEER_DOWN_IF_DOWN; } } @@ -515,7 +515,8 @@ static int bgp_interface_vrf_update(ZAPI_CALLBACK_ARGS) continue; if (ifp == peer->nexthop.ifp) - BGP_EVENT_ADD(peer, BGP_Stop); + BGP_EVENT_ADD(peer->connection, + BGP_Stop); } } } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 60b394b69..895f36f99 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -80,7 +80,6 @@ #include "bgp_trace.h" DEFINE_MTYPE_STATIC(BGPD, PEER_TX_SHUTDOWN_MSG, "Peer shutdown message (TX)"); -DEFINE_MTYPE_STATIC(BGPD, BGP_PEER_CONNECTION, "BGP Connection information"); DEFINE_QOBJ_TYPE(bgp_master); DEFINE_QOBJ_TYPE(bgp); DEFINE_QOBJ_TYPE(peer); @@ -140,7 +139,7 @@ void bgp_session_reset(struct peer *peer) !(CHECK_FLAG(peer->doppelganger->flags, PEER_FLAG_CONFIG_NODE))) peer_delete(peer->doppelganger); - BGP_EVENT_ADD(peer, BGP_Stop); + BGP_EVENT_ADD(peer->connection, BGP_Stop); } /* @@ -166,7 +165,7 @@ static void bgp_session_reset_safe(struct peer *peer, struct listnode **nnode) peer_delete(peer->doppelganger); } - BGP_EVENT_ADD(peer, BGP_Stop); + BGP_EVENT_ADD(peer->connection, BGP_Stop); } /* BGP global flag manipulation. */ @@ -309,7 +308,7 @@ static int bgp_router_id_set(struct bgp *bgp, const struct in_addr *id, 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_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } @@ -488,7 +487,7 @@ void bgp_cluster_id_set(struct bgp *bgp, struct in_addr *cluster_id) 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_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } @@ -512,7 +511,7 @@ void bgp_cluster_id_unset(struct bgp *bgp) 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_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } @@ -597,9 +596,9 @@ void bgp_confederation_id_set(struct bgp *bgp, as_t as, const char *as_str) peer->connection->status)) { peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE; - bgp_notify_send( - peer, BGP_NOTIFY_CEASE, - BGP_NOTIFY_CEASE_CONFIG_CHANGE); + bgp_notify_send(peer->connection, + BGP_NOTIFY_CEASE, + BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else bgp_session_reset_safe(peer, &nnode); } @@ -615,9 +614,9 @@ void bgp_confederation_id_set(struct bgp *bgp, as_t as, const char *as_str) peer->connection->status)) { peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE; - bgp_notify_send( - peer, BGP_NOTIFY_CEASE, - BGP_NOTIFY_CEASE_CONFIG_CHANGE); + bgp_notify_send(peer->connection, + BGP_NOTIFY_CEASE, + BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else bgp_session_reset_safe(peer, &nnode); } @@ -642,7 +641,8 @@ void bgp_confederation_id_unset(struct bgp *bgp) if (BGP_IS_VALID_STATE_FOR_NOTIF( peer->connection->status)) { peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE; - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, + BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } @@ -697,9 +697,9 @@ void bgp_confederation_peers_add(struct bgp *bgp, as_t as, const char *as_str) peer->connection->status)) { peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE; - bgp_notify_send( - peer, BGP_NOTIFY_CEASE, - BGP_NOTIFY_CEASE_CONFIG_CHANGE); + bgp_notify_send(peer->connection, + BGP_NOTIFY_CEASE, + BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else bgp_session_reset_safe(peer, &nnode); } @@ -754,9 +754,9 @@ void bgp_confederation_peers_remove(struct bgp *bgp, as_t as) peer->connection->status)) { peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE; - bgp_notify_send( - peer, BGP_NOTIFY_CEASE, - BGP_NOTIFY_CEASE_CONFIG_CHANGE); + bgp_notify_send(peer->connection, + BGP_NOTIFY_CEASE, + BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else bgp_session_reset_safe(peer, &nnode); } @@ -947,13 +947,13 @@ int peer_cmp(struct peer *p1, struct peer *p2) } else return strcmp(p1->group->name, p2->group->name); - return sockunion_cmp(&p1->su, &p2->su); + return sockunion_cmp(&p1->connection->su, &p2->connection->su); } static unsigned int peer_hash_key_make(const void *p) { const struct peer *peer = p; - return sockunion_hash(&peer->su); + return sockunion_hash(&peer->connection->su); } static bool peer_hash_same(const void *p1, const void *p2) @@ -961,9 +961,9 @@ static bool peer_hash_same(const void *p1, const void *p2) const struct peer *peer1 = p1; const struct peer *peer2 = p2; - return (sockunion_same(&peer1->su, &peer2->su) - && CHECK_FLAG(peer1->flags, PEER_FLAG_CONFIG_NODE) - == CHECK_FLAG(peer2->flags, PEER_FLAG_CONFIG_NODE)); + return (sockunion_same(&peer1->connection->su, &peer2->connection->su) && + CHECK_FLAG(peer1->flags, PEER_FLAG_CONFIG_NODE) == + CHECK_FLAG(peer2->flags, PEER_FLAG_CONFIG_NODE)); } void peer_flag_inherit(struct peer *peer, uint64_t flag) @@ -1148,13 +1148,15 @@ void bgp_peer_connection_buffers_free(struct peer_connection *connection) } } -static void bgp_peer_connection_free(struct peer_connection *connection) +void bgp_peer_connection_free(struct peer_connection **connection) { - bgp_peer_connection_buffers_free(connection); - pthread_mutex_destroy(&connection->io_mtx); + bgp_peer_connection_buffers_free(*connection); + pthread_mutex_destroy(&(*connection)->io_mtx); - memset(connection, 0, sizeof(struct peer_connection)); - XFREE(MTYPE_BGP_PEER_CONNECTION, connection); + memset(*connection, 0, sizeof(struct peer_connection)); + XFREE(MTYPE_BGP_PEER_CONNECTION, *connection); + + connection = NULL; } struct peer_connection *bgp_peer_connection_new(struct peer *peer) @@ -1204,20 +1206,21 @@ static void peer_free(struct peer *peer) /* this /ought/ to have been done already through bgp_stop earlier, * but just to be sure.. */ - bgp_timer_set(peer); + bgp_timer_set(peer->connection); bgp_reads_off(peer->connection); bgp_writes_off(peer->connection); - event_cancel_event_ready(bm->master, peer); + event_cancel_event_ready(bm->master, peer->connection); FOREACH_AFI_SAFI (afi, safi) EVENT_OFF(peer->t_revalidate_all[afi][safi]); assert(!peer->connection->t_write); assert(!peer->connection->t_read); - BGP_EVENT_FLUSH(peer); + event_cancel_event_ready(bm->master, peer->connection); /* Free connected nexthop, if present */ if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE) && !peer_dynamic_neighbor(peer)) - bgp_delete_connected_nexthop(family2afi(peer->su.sa.sa_family), + bgp_delete_connected_nexthop(family2afi(peer->connection->su.sa + .sa_family), peer); FOREACH_AFI_SAFI (afi, safi) { @@ -1267,7 +1270,7 @@ static void peer_free(struct peer *peer) if (peer->as_pretty) XFREE(MTYPE_BGP, peer->as_pretty); - bgp_peer_connection_free(peer->connection); + bgp_peer_connection_free(&peer->connection); bgp_unlock(peer->bgp); @@ -1602,7 +1605,7 @@ void peer_xfer_config(struct peer *peer_dst, struct peer *peer_src) peer_dst->ttl = peer_src->ttl; } -static int bgp_peer_conf_if_to_su_update_v4(struct peer *peer, +static int bgp_peer_conf_if_to_su_update_v4(struct peer_connection *connection, struct interface *ifp) { struct connected *ifc; @@ -1617,44 +1620,43 @@ static int bgp_peer_conf_if_to_su_update_v4(struct peer *peer, if (ifc->address && (ifc->address->family == AF_INET)) { prefix_copy(&p, CONNECTED_PREFIX(ifc)); if (p.prefixlen == 30) { - peer->su.sa.sa_family = AF_INET; + connection->su.sa.sa_family = AF_INET; addr = ntohl(p.u.prefix4.s_addr); if (addr % 4 == 1) - peer->su.sin.sin_addr.s_addr = + connection->su.sin.sin_addr.s_addr = htonl(addr + 1); else if (addr % 4 == 2) - peer->su.sin.sin_addr.s_addr = + connection->su.sin.sin_addr.s_addr = htonl(addr - 1); #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - peer->su.sin.sin_len = + connection->su.sin.sin_len = sizeof(struct sockaddr_in); #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ return 1; } else if (p.prefixlen == 31) { - peer->su.sa.sa_family = AF_INET; + connection->su.sa.sa_family = AF_INET; addr = ntohl(p.u.prefix4.s_addr); if (addr % 2 == 0) - peer->su.sin.sin_addr.s_addr = + connection->su.sin.sin_addr.s_addr = htonl(addr + 1); else - peer->su.sin.sin_addr.s_addr = + connection->su.sin.sin_addr.s_addr = htonl(addr - 1); #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - peer->su.sin.sin_len = + connection->su.sin.sin_len = sizeof(struct sockaddr_in); #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ return 1; - } else if (bgp_debug_neighbor_events(peer)) - zlog_debug( - "%s: IPv4 interface address is not /30 or /31, v4 session not started", - peer->conf_if); + } else if (bgp_debug_neighbor_events(connection->peer)) + zlog_debug("%s: IPv4 interface address is not /30 or /31, v4 session not started", + connection->peer->conf_if); } } return 0; } -static bool bgp_peer_conf_if_to_su_update_v6(struct peer *peer, +static bool bgp_peer_conf_if_to_su_update_v6(struct peer_connection *connection, struct interface *ifp) { struct nbr_connected *ifc_nbr; @@ -1662,13 +1664,13 @@ static bool bgp_peer_conf_if_to_su_update_v6(struct peer *peer, /* Have we learnt the peer's IPv6 link-local address? */ if (ifp->nbr_connected && (ifc_nbr = listnode_head(ifp->nbr_connected))) { - peer->su.sa.sa_family = AF_INET6; - memcpy(&peer->su.sin6.sin6_addr, &ifc_nbr->address->u.prefix, - sizeof(struct in6_addr)); + connection->su.sa.sa_family = AF_INET6; + memcpy(&connection->su.sin6.sin6_addr, + &ifc_nbr->address->u.prefix, sizeof(struct in6_addr)); #ifdef SIN6_LEN - peer->su.sin6.sin6_len = sizeof(struct sockaddr_in6); + connection->su.sin6.sin6_len = sizeof(struct sockaddr_in6); #endif - peer->su.sin6.sin6_scope_id = ifp->ifindex; + connection->su.sin6.sin6_scope_id = ifp->ifindex; return true; } @@ -1680,13 +1682,14 @@ static bool bgp_peer_conf_if_to_su_update_v6(struct peer *peer, * learnt/derived peer address. If the address has changed, update the * password on the listen socket, if needed. */ -void bgp_peer_conf_if_to_su_update(struct peer *peer) +void bgp_peer_conf_if_to_su_update(struct peer_connection *connection) { struct interface *ifp; int prev_family; int peer_addr_updated = 0; struct listnode *node; union sockunion old_su; + struct peer *peer = connection->peer; /* * This function is only ever needed when FRR an interface @@ -1696,9 +1699,9 @@ void bgp_peer_conf_if_to_su_update(struct peer *peer) if (!peer->conf_if) return; - old_su = peer->su; + old_su = connection->su; - prev_family = peer->su.sa.sa_family; + prev_family = connection->su.sa.sa_family; if ((ifp = if_lookup_by_name(peer->conf_if, peer->bgp->vrf_id))) { peer->ifp = ifp; /* If BGP unnumbered is not "v6only", we first see if we can @@ -1707,7 +1710,8 @@ void bgp_peer_conf_if_to_su_update(struct peer *peer) */ if (!CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) peer_addr_updated = - bgp_peer_conf_if_to_su_update_v4(peer, ifp); + bgp_peer_conf_if_to_su_update_v4(connection, + ifp); /* If "v6only" or we can't derive peer's IPv4 address, see if * we've @@ -1717,7 +1721,8 @@ void bgp_peer_conf_if_to_su_update(struct peer *peer) */ if (!peer_addr_updated) peer_addr_updated = - bgp_peer_conf_if_to_su_update_v6(peer, ifp); + bgp_peer_conf_if_to_su_update_v6(connection, + ifp); } /* If we could derive the peer address, we may need to install the * password @@ -1729,20 +1734,21 @@ void bgp_peer_conf_if_to_su_update(struct peer *peer) if (peer_addr_updated) { if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSWORD) && prev_family == AF_UNSPEC) - bgp_md5_set(peer); + bgp_md5_set(connection); } else { if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSWORD) && prev_family != AF_UNSPEC) - bgp_md5_unset(peer); - peer->su.sa.sa_family = AF_UNSPEC; - memset(&peer->su.sin6.sin6_addr, 0, sizeof(struct in6_addr)); + bgp_md5_unset(connection); + connection->su.sa.sa_family = AF_UNSPEC; + memset(&connection->su.sin6.sin6_addr, 0, + sizeof(struct in6_addr)); } /* * If they are the same, nothing to do here, move along */ - if (!sockunion_same(&old_su, &peer->su)) { - union sockunion new_su = peer->su; + if (!sockunion_same(&old_su, &connection->su)) { + union sockunion new_su = connection->su; struct bgp *bgp = peer->bgp; /* @@ -1771,11 +1777,11 @@ void bgp_peer_conf_if_to_su_update(struct peer *peer) * scan through looking for a matching * su if needed. */ - peer->su = old_su; + connection->su = old_su; hash_release(peer->bgp->peerhash, peer); listnode_delete(peer->bgp->peer, peer); - peer->su = new_su; + connection->su = new_su; (void)hash_get(peer->bgp->peerhash, peer, hash_alloc_intern); listnode_add_sort(peer->bgp->peer, peer); @@ -1842,13 +1848,13 @@ struct peer *peer_create(union sockunion *su, const char *conf_if, if (conf_if) { peer->conf_if = XSTRDUP(MTYPE_PEER_CONF_IF, conf_if); if (su) - peer->su = *su; + peer->connection->su = *su; else - bgp_peer_conf_if_to_su_update(peer); + bgp_peer_conf_if_to_su_update(peer->connection); XFREE(MTYPE_BGP_PEER_HOST, peer->host); peer->host = XSTRDUP(MTYPE_BGP_PEER_HOST, conf_if); } else if (su) { - peer->su = *su; + peer->connection->su = *su; sockunion2str(su, buf, SU_ADDRSTRLEN); XFREE(MTYPE_BGP_PEER_HOST, peer->host); peer->host = XSTRDUP(MTYPE_BGP_PEER_HOST, buf); @@ -1887,7 +1893,7 @@ struct peer *peer_create(union sockunion *su, const char *conf_if, active = peer_active(peer); if (!active) { - if (peer->su.sa.sa_family == AF_UNSPEC) + if (peer->connection->su.sa.sa_family == AF_UNSPEC) peer->last_reset = PEER_DOWN_NBR_ADDR; else peer->last_reset = PEER_DOWN_NOAFI_ACTIVATED; @@ -1919,7 +1925,7 @@ struct peer *peer_create(union sockunion *su, const char *conf_if, peer_flag_set(peer, PEER_FLAG_SHUTDOWN); /* Set up peer's events and timers. */ else if (!active && peer_active(peer)) - bgp_timer_set(peer); + bgp_timer_set(peer->connection); bgp_peer_gr_flags_update(peer); BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp, bgp->peer); @@ -1970,7 +1976,7 @@ void peer_as_change(struct peer *peer, as_t as, int as_specified, if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { 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_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else bgp_session_reset(peer); @@ -2321,9 +2327,9 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi) peer_group2peer_config_copy_af(peer->group, peer, afi, safi); if (!active && peer_active(peer)) { - bgp_timer_set(peer); + bgp_timer_set(peer->connection); } else { - if (peer_established(peer)) { + if (peer_established(peer->connection)) { if (CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_RCV)) { peer->afc_adv[afi][safi] = 1; bgp_capability_send(peer, afi, safi, @@ -2336,14 +2342,15 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi) } } else { peer->last_reset = PEER_DOWN_AF_ACTIVATE; - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, + BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } 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_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } /* @@ -2359,7 +2366,7 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi) 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_send(other->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } @@ -2454,7 +2461,7 @@ static bool non_peergroup_deactivate_af(struct peer *peer, afi_t afi, return true; } - if (peer_established(peer)) { + if (peer_established(peer->connection)) { if (CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_RCV)) { peer->afc_adv[afi][safi] = 0; peer->afc_nego[afi][safi] = 0; @@ -2467,12 +2474,13 @@ static bool non_peergroup_deactivate_af(struct peer *peer, afi_t afi, peer->pcount[afi][safi] = 0; } else { peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE; - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, + BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } else { peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE; - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } @@ -2542,13 +2550,13 @@ void peer_nsf_stop(struct peer *peer) EVENT_OFF(peer->t_llgr_stale[afi][safi]); } - if (peer->t_gr_restart) { - EVENT_OFF(peer->t_gr_restart); + if (peer->connection->t_gr_restart) { + EVENT_OFF(peer->connection->t_gr_restart); if (bgp_debug_neighbor_events(peer)) zlog_debug("%pBP graceful restart timer stopped", peer); } - if (peer->t_gr_stale) { - EVENT_OFF(peer->t_gr_stale); + if (peer->connection->t_gr_stale) { + EVENT_OFF(peer->connection->t_gr_stale); if (bgp_debug_neighbor_events(peer)) zlog_debug( "%pBP graceful restart stalepath timer stopped", @@ -2585,10 +2593,10 @@ int peer_delete(struct peer *peer) bgp_soft_reconfig_table_task_cancel(bgp, NULL, peer); - bgp_keepalives_off(peer); + bgp_keepalives_off(peer->connection); bgp_reads_off(peer->connection); bgp_writes_off(peer->connection); - event_cancel_event_ready(bm->master, peer); + event_cancel_event_ready(bm->master, peer->connection); FOREACH_AFI_SAFI (afi, safi) EVENT_OFF(peer->t_revalidate_all[afi][safi]); assert(!CHECK_FLAG(peer->connection->thread_flags, @@ -2634,7 +2642,7 @@ int peer_delete(struct peer *peer) } UNSET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER); - bgp_fsm_change_status(peer, Deleted); + bgp_fsm_change_status(peer->connection, Deleted); /* Remove from NHT */ if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) @@ -2643,13 +2651,14 @@ int peer_delete(struct peer *peer) /* Password configuration */ if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSWORD)) { XFREE(MTYPE_PEER_PASSWORD, peer->password); - if (!accept_peer && !BGP_PEER_SU_UNSPEC(peer) - && !CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP) - && !CHECK_FLAG(peer->flags, PEER_FLAG_DYNAMIC_NEIGHBOR)) - bgp_md5_unset(peer); + if (!accept_peer && + !BGP_CONNECTION_SU_UNSPEC(peer->connection) && + !CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP) && + !CHECK_FLAG(peer->flags, PEER_FLAG_DYNAMIC_NEIGHBOR)) + bgp_md5_unset(peer->connection); } - bgp_timer_set(peer); /* stops all timers for Deleted */ + bgp_timer_set(peer->connection); /* stops all timers for Deleted */ /* Delete from all peer list. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP) @@ -2857,8 +2866,8 @@ static void peer_group2peer_config_copy(struct peer_group *group, PEER_STR_ATTR_INHERIT(peer, group, password, MTYPE_PEER_PASSWORD); - if (!BGP_PEER_SU_UNSPEC(peer)) - bgp_md5_set(peer); + if (!BGP_CONNECTION_SU_UNSPEC(peer->connection)) + bgp_md5_set(peer->connection); /* update-source apply */ if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_UPDATE_SOURCE)) { @@ -2917,7 +2926,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)) - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_PEER_UNCONFIG); } @@ -2932,7 +2941,7 @@ static void peer_notify_shutdown(struct peer *peer) } if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN); } @@ -3084,8 +3093,8 @@ int peer_group_listen_range_del(struct peer_group *group, struct prefix *range) if (!peer_dynamic_neighbor(peer)) continue; - if (sockunion2hostprefix(&peer->su, &prefix2) - && prefix_match(prefix, &prefix2)) { + if (sockunion2hostprefix(&peer->connection->su, &prefix2) && + prefix_match(prefix, &prefix2)) { if (bgp_debug_neighbor_events(peer)) zlog_debug( "Deleting dynamic neighbor %s group %s upon delete of listen range %pFX", @@ -3200,7 +3209,7 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer, 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_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else { bgp_session_reset(peer); @@ -3239,7 +3248,7 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer, /* Set up peer's events and timers. */ if (peer_active(peer)) - bgp_timer_set(peer); + bgp_timer_set(peer->connection); } return 0; @@ -3731,7 +3740,7 @@ void bgp_instance_up(struct bgp *bgp) /* Kick off any peers that may have been configured. */ for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer)) { if (!BGP_PEER_START_SUPPRESSED(peer)) - BGP_EVENT_ADD(peer, BGP_Start); + BGP_EVENT_ADD(peer->connection, BGP_Start); } /* Process any networks that have been configured. */ @@ -3755,7 +3764,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)) - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN); else bgp_session_reset(peer); @@ -4116,8 +4125,11 @@ struct peer *peer_lookup(struct bgp *bgp, union sockunion *su) { struct peer *peer = NULL; struct peer tmp_peer; + struct peer_connection connection; + memset(&connection, 0, sizeof(struct peer_connection)); memset(&tmp_peer, 0, sizeof(struct peer)); + tmp_peer.connection = &connection; /* * We do not want to find the doppelganger peer so search for the peer @@ -4126,7 +4138,7 @@ struct peer *peer_lookup(struct bgp *bgp, union sockunion *su) */ SET_FLAG(tmp_peer.flags, PEER_FLAG_CONFIG_NODE); - tmp_peer.su = *su; + connection.su = *su; if (bgp != NULL) { peer = hash_lookup(bgp->peerhash, &tmp_peer); @@ -4325,7 +4337,7 @@ bool bgp_path_attribute_discard(struct peer *peer, char *buf, size_t size) buf[0] = '\0'; - for (unsigned int i = 0; i < BGP_ATTR_MAX; i++) { + for (unsigned int i = 1; i <= BGP_ATTR_MAX; i++) { if (peer->discard_attrs[i]) snprintf(buf + strlen(buf), size - strlen(buf), "%s%d", (strlen(buf) > 0) ? " " : "", i); @@ -4345,7 +4357,7 @@ bool bgp_path_attribute_treat_as_withdraw(struct peer *peer, char *buf, buf[0] = '\0'; - for (unsigned int i = 0; i < BGP_ATTR_MAX; i++) { + for (unsigned int i = 1; i <= BGP_ATTR_MAX; i++) { if (peer->withdraw_attrs[i]) snprintf(buf + strlen(buf), size - strlen(buf), "%s%d", (strlen(buf) > 0) ? " " : "", i); @@ -4360,7 +4372,7 @@ bool bgp_path_attribute_treat_as_withdraw(struct peer *peer, char *buf, /* If peer is configured at least one address family return 1. */ bool peer_active(struct peer *peer) { - if (BGP_PEER_SU_UNSPEC(peer)) + if (BGP_CONNECTION_SU_UNSPEC(peer->connection)) return false; if (peer->afc[AFI_IP][SAFI_UNICAST] || peer->afc[AFI_IP][SAFI_MULTICAST] || peer->afc[AFI_IP][SAFI_LABELED_UNICAST] @@ -4431,7 +4443,7 @@ void peer_change_action(struct peer *peer, afi_t afi, safi_t safi, if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) return; - if (!peer_established(peer)) + if (!peer_established(peer->connection)) return; if (type == peer_change_reset) { @@ -4443,7 +4455,7 @@ void peer_change_action(struct peer *peer, afi_t afi, safi_t safi, PEER_FLAG_CONFIG_NODE))) peer_delete(peer->doppelganger); - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else if (type == peer_change_reset_in) { if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_RCV)) @@ -4456,7 +4468,7 @@ void peer_change_action(struct peer *peer, afi_t afi, safi_t safi, PEER_FLAG_CONFIG_NODE))) peer_delete(peer->doppelganger); - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } else if (type == peer_change_reset_out) { @@ -4601,8 +4613,8 @@ static void peer_flag_modify_action(struct peer *peer, uint64_t flag) UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW); - if (peer->t_pmax_restart) { - EVENT_OFF(peer->t_pmax_restart); + if (peer->connection->t_pmax_restart) { + EVENT_OFF(peer->connection->t_pmax_restart); if (bgp_debug_neighbor_events(peer)) zlog_debug( "%pBP Maximum-prefix restart timer canceled", @@ -4627,18 +4639,19 @@ static void peer_flag_modify_action(struct peer *peer, uint64_t flag) memcpy(msgbuf + 1, msg, msglen); bgp_notify_send_with_data( - peer, BGP_NOTIFY_CEASE, + peer->connection, + BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN, msgbuf, msglen + 1); } else - bgp_notify_send( - peer, BGP_NOTIFY_CEASE, - BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN); + bgp_notify_send(peer->connection, + BGP_NOTIFY_CEASE, + BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN); } else bgp_session_reset(peer); } else { peer->v_start = BGP_INIT_START_TIMER; - BGP_EVENT_ADD(peer, BGP_Stop); + BGP_EVENT_ADD(peer->connection, BGP_Stop); } } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { if (flag == PEER_FLAG_DYNAMIC_CAPABILITY) @@ -4648,7 +4661,7 @@ static void peer_flag_modify_action(struct peer *peer, uint64_t flag) else if (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK) peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE; - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else bgp_session_reset(peer); @@ -4687,14 +4700,14 @@ void bgp_shutdown_enable(struct bgp *bgp, const char *msg) data[0] = datalen; memcpy(data + 1, msg, datalen); - bgp_notify_send_with_data( - peer, BGP_NOTIFY_CEASE, - BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN, data, - datalen + 1); + bgp_notify_send_with_data(peer->connection, + BGP_NOTIFY_CEASE, + BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN, + data, datalen + 1); } else { - bgp_notify_send( - peer, BGP_NOTIFY_CEASE, - BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN); + bgp_notify_send(peer->connection, + BGP_NOTIFY_CEASE, + BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN); } } @@ -4702,7 +4715,7 @@ void bgp_shutdown_enable(struct bgp *bgp, const char *msg) peer->v_start = BGP_INIT_START_TIMER; /* trigger a RFC 4271 ManualStop event */ - BGP_EVENT_ADD(peer, BGP_Stop); + BGP_EVENT_ADD(peer->connection, BGP_Stop); } /* set the BGP instances shutdown flag */ @@ -4727,7 +4740,7 @@ void bgp_shutdown_disable(struct bgp *bgp) UNSET_FLAG(bgp->flags, BGP_FLAG_SHUTDOWN); for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) - bgp_timer_set(peer); + bgp_timer_set(peer->connection); } /* Change specified peer flag. */ @@ -4952,8 +4965,8 @@ static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi, COND_FLAG(peer->af_flags[afi][safi], flag, set); /* Execute action when peer is established. */ - if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP) - && peer_established(peer)) { + if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP) && + peer_established(peer->connection)) { if (!set && flag == PEER_FLAG_SOFT_RECONFIG) bgp_clear_adj_in(peer, afi, safi); else { @@ -5006,7 +5019,7 @@ static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi, set != member_invert); /* Execute flag action on peer-group member. */ - if (peer_established(member)) { + if (peer_established(member->connection)) { if (!set && flag == PEER_FLAG_SOFT_RECONFIG) bgp_clear_adj_in(member, afi, safi); else { @@ -5101,7 +5114,8 @@ int peer_ebgp_multihop_set(struct peer *peer, int ttl) if (peer->sort != BGP_PEER_IBGP) { if (BGP_IS_VALID_STATE_FOR_NOTIF( peer->connection->status)) - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, + BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else bgp_session_reset(peer); @@ -5120,7 +5134,8 @@ int peer_ebgp_multihop_set(struct peer *peer, int ttl) if (BGP_IS_VALID_STATE_FOR_NOTIF( peer->connection->status)) - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, + BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else bgp_session_reset(peer); @@ -5157,7 +5172,7 @@ int peer_ebgp_multihop_unset(struct peer *peer) if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else bgp_session_reset(peer); @@ -5176,9 +5191,9 @@ int peer_ebgp_multihop_unset(struct peer *peer) if (peer->connection->fd >= 0) { if (BGP_IS_VALID_STATE_FOR_NOTIF( peer->connection->status)) - bgp_notify_send( - peer, BGP_NOTIFY_CEASE, - BGP_NOTIFY_CEASE_CONFIG_CHANGE); + bgp_notify_send(peer->connection, + BGP_NOTIFY_CEASE, + BGP_NOTIFY_CEASE_CONFIG_CHANGE); else bgp_session_reset(peer); } @@ -5332,7 +5347,7 @@ int peer_update_source_if_set(struct peer *peer, const char *ifname) /* Send notification or reset peer depending on state. */ 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_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else bgp_session_reset(peer); @@ -5370,7 +5385,7 @@ int peer_update_source_if_set(struct peer *peer, const char *ifname) /* Send notification or reset peer depending on state. */ 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_send(member->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else bgp_session_reset(member); @@ -5403,7 +5418,7 @@ void peer_update_source_addr_set(struct peer *peer, const union sockunion *su) /* Send notification or reset peer depending on state. */ 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_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else bgp_session_reset(peer); @@ -5440,7 +5455,7 @@ void peer_update_source_addr_set(struct peer *peer, const union sockunion *su) /* Send notification or reset peer depending on state. */ 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_send(member->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else bgp_session_reset(member); @@ -5491,7 +5506,7 @@ void peer_update_source_unset(struct peer *peer) /* Send notification or reset peer depending on state. */ 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_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else bgp_session_reset(peer); @@ -5527,7 +5542,7 @@ void peer_update_source_unset(struct peer *peer) /* Send notification or reset peer depending on state. */ 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_send(member->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else bgp_session_reset(member); @@ -5606,7 +5621,8 @@ int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi, /* Check if handling a regular peer. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { /* Update peer route announcements. */ - if (peer_established(peer) && peer->afc_nego[afi][safi]) { + if (peer_established(peer->connection) && + peer->afc_nego[afi][safi]) { update_group_adjust_peer(peer_af_find(peer, afi, safi)); bgp_default_originate(peer, afi, safi, 0); bgp_announce_route(peer, afi, safi, false); @@ -5647,7 +5663,8 @@ int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi, } /* Update peer route announcements. */ - if (peer_established(member) && member->afc_nego[afi][safi]) { + if (peer_established(member->connection) && + member->afc_nego[afi][safi]) { update_group_adjust_peer( peer_af_find(member, afi, safi)); bgp_default_originate(member, afi, safi, 0); @@ -5692,7 +5709,8 @@ int peer_default_originate_unset(struct peer *peer, afi_t afi, safi_t safi) /* Check if handling a regular peer. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { /* Update peer route announcements. */ - if (peer_established(peer) && peer->afc_nego[afi][safi]) { + if (peer_established(peer->connection) && + peer->afc_nego[afi][safi]) { update_group_adjust_peer(peer_af_find(peer, afi, safi)); bgp_default_originate(peer, afi, safi, 1); bgp_announce_route(peer, afi, safi, false); @@ -5730,7 +5748,8 @@ int peer_default_originate_unset(struct peer *peer, afi_t afi, safi_t safi) member->default_rmap[afi][safi].map = NULL; /* Update peer route announcements. */ - if (peer_established(member) && member->afc_nego[afi][safi]) { + if (peer_established(member->connection) && + member->afc_nego[afi][safi]) { update_group_adjust_peer(peer_af_find(member, afi, safi)); bgp_default_originate(member, afi, safi, 1); bgp_announce_route(member, afi, safi, false); @@ -5782,10 +5801,10 @@ void peer_on_policy_change(struct peer *peer, afi_t afi, safi_t safi, { if (outbound) { update_group_adjust_peer(peer_af_find(peer, afi, safi)); - if (peer_established(peer)) + if (peer_established(peer->connection)) bgp_announce_route(peer, afi, safi, false); } else { - if (!peer_established(peer)) + if (!peer_established(peer->connection)) return; if (bgp_soft_reconfig_in(peer, afi, safi)) @@ -5980,10 +5999,10 @@ int peer_timers_connect_set(struct peer *peer, uint32_t connect) /* Skip peer-group mechanics for regular peers. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { - if (!peer_established(peer)) { + if (!peer_established(peer->connection)) { if (peer_active(peer)) - BGP_EVENT_ADD(peer, BGP_Stop); - BGP_EVENT_ADD(peer, BGP_Start); + BGP_EVENT_ADD(peer->connection, BGP_Stop); + BGP_EVENT_ADD(peer->connection, BGP_Start); } return 0; } @@ -6001,10 +6020,10 @@ int peer_timers_connect_set(struct peer *peer, uint32_t connect) member->connect = connect; member->v_connect = connect; - if (!peer_established(member)) { + if (!peer_established(member->connection)) { if (peer_active(member)) - BGP_EVENT_ADD(member, BGP_Stop); - BGP_EVENT_ADD(member, BGP_Start); + BGP_EVENT_ADD(member->connection, BGP_Stop); + BGP_EVENT_ADD(member->connection, BGP_Start); } } @@ -6034,10 +6053,10 @@ int peer_timers_connect_unset(struct peer *peer) /* Skip peer-group mechanics for regular peers. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { - if (!peer_established(peer)) { + if (!peer_established(peer->connection)) { if (peer_active(peer)) - BGP_EVENT_ADD(peer, BGP_Stop); - BGP_EVENT_ADD(peer, BGP_Start); + BGP_EVENT_ADD(peer->connection, BGP_Stop); + BGP_EVENT_ADD(peer->connection, BGP_Start); } return 0; } @@ -6055,10 +6074,10 @@ int peer_timers_connect_unset(struct peer *peer) member->connect = 0; member->v_connect = peer->bgp->default_connect_retry; - if (!peer_established(member)) { + if (!peer_established(member->connection)) { if (peer_active(member)) - BGP_EVENT_ADD(member, BGP_Stop); - BGP_EVENT_ADD(member, BGP_Start); + BGP_EVENT_ADD(member->connection, BGP_Stop); + BGP_EVENT_ADD(member->connection, BGP_Start); } } @@ -6082,7 +6101,7 @@ int peer_advertise_interval_set(struct peer *peer, uint32_t routeadv) if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { /* Update peer route announcements. */ update_group_adjust_peer_afs(peer); - if (peer_established(peer)) + if (peer_established(peer->connection)) bgp_announce_route_all(peer); /* Skip peer-group mechanics for regular peers. */ @@ -6105,7 +6124,7 @@ int peer_advertise_interval_set(struct peer *peer, uint32_t routeadv) /* Update peer route announcements. */ update_group_adjust_peer_afs(member); - if (peer_established(member)) + if (peer_established(member->connection)) bgp_announce_route_all(member); } @@ -6139,7 +6158,7 @@ int peer_advertise_interval_unset(struct peer *peer) if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { /* Update peer route announcements. */ update_group_adjust_peer_afs(peer); - if (peer_established(peer)) + if (peer_established(peer->connection)) bgp_announce_route_all(peer); /* Skip peer-group mechanics for regular peers. */ @@ -6164,7 +6183,7 @@ int peer_advertise_interval_unset(struct peer *peer) /* Update peer route announcements. */ update_group_adjust_peer_afs(member); - if (peer_established(member)) + if (peer_established(member->connection)) bgp_announce_route_all(member); } @@ -6492,10 +6511,10 @@ int peer_local_as_unset(struct peer *peer) /* Send notification or stop peer depending on state. */ 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_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else - BGP_EVENT_ADD(peer, BGP_Stop); + BGP_EVENT_ADD(peer->connection, BGP_Stop); /* Skip peer-group mechanics for regular peers. */ return 0; @@ -6520,7 +6539,7 @@ int peer_local_as_unset(struct peer *peer) /* Send notification or stop peer depending on state. */ 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_send(member->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else bgp_session_reset(member); @@ -6551,7 +6570,7 @@ int peer_password_set(struct peer *peer, const char *password) 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)) - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else bgp_session_reset(peer); @@ -6560,10 +6579,11 @@ int peer_password_set(struct peer *peer, const char *password) * Attempt to install password on socket and skip peer-group * mechanics. */ - if (BGP_PEER_SU_UNSPEC(peer)) + if (BGP_CONNECTION_SU_UNSPEC(peer->connection)) return BGP_SUCCESS; - return (bgp_md5_set(peer) >= 0) ? BGP_SUCCESS - : BGP_ERR_TCPSIG_FAILED; + return (bgp_md5_set(peer->connection) >= 0) + ? BGP_SUCCESS + : BGP_ERR_TCPSIG_FAILED; } /* @@ -6587,13 +6607,14 @@ int peer_password_set(struct peer *peer, const char *password) /* Send notification or reset peer depending on state. */ if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) - bgp_notify_send(member, BGP_NOTIFY_CEASE, + bgp_notify_send(member->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else bgp_session_reset(member); /* Attempt to install password on socket. */ - if (!BGP_PEER_SU_UNSPEC(member) && bgp_md5_set(member) < 0) + if (!BGP_CONNECTION_SU_UNSPEC(member->connection) && + bgp_md5_set(member->connection) < 0) ret = BGP_ERR_TCPSIG_FAILED; } @@ -6632,14 +6653,14 @@ int peer_password_unset(struct peer *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)) - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else bgp_session_reset(peer); /* Attempt to uninstall password on socket. */ - if (!BGP_PEER_SU_UNSPEC(peer)) - bgp_md5_unset(peer); + if (!BGP_CONNECTION_SU_UNSPEC(peer->connection)) + bgp_md5_unset(peer->connection); /* Skip peer-group mechanics for regular peers. */ return 0; } @@ -6659,14 +6680,14 @@ int peer_password_unset(struct peer *peer) /* Send notification or reset peer depending on state. */ if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) - bgp_notify_send(member, BGP_NOTIFY_CEASE, + bgp_notify_send(member->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else bgp_session_reset(member); /* Attempt to uninstall password on socket. */ - if (!BGP_PEER_SU_UNSPEC(member)) - bgp_md5_unset(member); + if (!BGP_CONNECTION_SU_UNSPEC(member->connection)) + bgp_md5_unset(member->connection); } /* Set flag and configuration on all peer-group listen ranges */ @@ -7537,14 +7558,14 @@ static bool peer_maximum_prefix_clear_overflow(struct peer *peer) return false; UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW); - if (peer->t_pmax_restart) { - EVENT_OFF(peer->t_pmax_restart); + if (peer->connection->t_pmax_restart) { + EVENT_OFF(peer->connection->t_pmax_restart); if (bgp_debug_neighbor_events(peer)) zlog_debug( "%pBP Maximum-prefix restart timer cancelled", peer); } - BGP_EVENT_ADD(peer, BGP_Start); + BGP_EVENT_ADD(peer->connection, BGP_Start); return true; } @@ -7576,7 +7597,8 @@ int peer_maximum_prefix_set(struct peer *peer, afi_t afi, safi_t safi, /* Check if handling a regular peer. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { /* Re-check if peer violates maximum-prefix. */ - if ((peer_established(peer)) && (peer->afc[afi][safi])) + if ((peer_established(peer->connection)) && + (peer->afc[afi][safi])) bgp_maximum_prefix_overflow(peer, afi, safi, 1); /* Skip peer-group mechanics for regular peers. */ @@ -7613,7 +7635,8 @@ int peer_maximum_prefix_set(struct peer *peer, afi_t afi, safi_t safi, PEER_FLAG_MAX_PREFIX_WARNING); /* Re-check if peer violates maximum-prefix. */ - if ((peer_established(member)) && (member->afc[afi][safi])) + if ((peer_established(member->connection)) && + (member->afc[afi][safi])) bgp_maximum_prefix_overflow(member, afi, safi, 1); } @@ -7684,7 +7707,7 @@ void peer_maximum_prefix_out_refresh_routes(struct peer *peer, afi_t afi, { update_group_adjust_peer(peer_af_find(peer, afi, safi)); - if (peer_established(peer)) + if (peer_established(peer->connection)) bgp_announce_route(peer, afi, safi, false); } @@ -7860,13 +7883,13 @@ int peer_ttl_security_hops_set(struct peer *peer, int gtsm_hops) peer->gtsm_hops = gtsm_hops; if (peer->connection->fd >= 0) - sockopt_minttl(peer->su.sa.sa_family, + sockopt_minttl(peer->connection->su.sa.sa_family, peer->connection->fd, MAXTTL + 1 - gtsm_hops); if ((peer->connection->status < Established) && peer->doppelganger && (peer->doppelganger->connection->fd >= 0)) - sockopt_minttl(peer->su.sa.sa_family, + sockopt_minttl(peer->connection->su.sa.sa_family, peer->doppelganger->connection->fd, MAXTTL + 1 - gtsm_hops); } else { @@ -7874,6 +7897,8 @@ int peer_ttl_security_hops_set(struct peer *peer, int gtsm_hops) group->conf->gtsm_hops = gtsm_hops; for (ALL_LIST_ELEMENTS(group->peer, node, nnode, gpeer)) { + struct peer_connection *connection = + gpeer->connection; gpeer->gtsm_hops = group->conf->gtsm_hops; /* Change setting of existing peer @@ -7884,16 +7909,16 @@ 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 (connection->fd >= 0 && gpeer->gtsm_hops != BGP_GTSM_HOPS_DISABLED) - sockopt_minttl(gpeer->su.sa.sa_family, - gpeer->connection->fd, + sockopt_minttl(connection->su.sa.sa_family, + connection->fd, MAXTTL + 1 - gpeer->gtsm_hops); - if ((gpeer->connection->status < Established) && + if ((connection->status < Established) && gpeer->doppelganger && (gpeer->doppelganger->connection->fd >= 0)) - sockopt_minttl(gpeer->su.sa.sa_family, + sockopt_minttl(connection->su.sa.sa_family, gpeer->doppelganger ->connection->fd, MAXTTL + 1 - gtsm_hops); @@ -7929,13 +7954,13 @@ int peer_ttl_security_hops_unset(struct peer *peer) ret = peer_ebgp_multihop_unset(peer); else { if (peer->connection->fd >= 0) - sockopt_minttl(peer->su.sa.sa_family, + sockopt_minttl(peer->connection->su.sa.sa_family, peer->connection->fd, 0); if ((peer->connection->status < Established) && peer->doppelganger && (peer->doppelganger->connection->fd >= 0)) - sockopt_minttl(peer->su.sa.sa_family, + sockopt_minttl(peer->connection->su.sa.sa_family, peer->doppelganger->connection->fd, 0); } @@ -7947,13 +7972,15 @@ int peer_ttl_security_hops_unset(struct peer *peer) ret = peer_ebgp_multihop_unset(peer); else { if (peer->connection->fd >= 0) - sockopt_minttl(peer->su.sa.sa_family, + sockopt_minttl(peer->connection->su.sa + .sa_family, peer->connection->fd, 0); if ((peer->connection->status < Established) && peer->doppelganger && (peer->doppelganger->connection->fd >= 0)) - sockopt_minttl(peer->su.sa.sa_family, + sockopt_minttl(peer->connection->su.sa + .sa_family, peer->doppelganger ->connection->fd, 0); @@ -8008,7 +8035,7 @@ int peer_clear(struct peer *peer, struct listnode **nnode) peer->v_start = BGP_INIT_START_TIMER; if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_RESET); else bgp_session_reset_safe(peer, nnode); @@ -8021,7 +8048,7 @@ int peer_clear_soft(struct peer *peer, afi_t afi, safi_t safi, { struct peer_af *paf; - if (!peer_established(peer)) + if (!peer_established(peer->connection)) return 0; if (!peer->afc[afi][safi]) @@ -8313,8 +8340,8 @@ static int peer_unshut_after_cfg(struct bgp *bgp) 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); + BGP_EVENT_ADD(peer->connection, BGP_Stop); + BGP_EVENT_ADD(peer->connection, BGP_Start); } } @@ -8415,7 +8442,8 @@ void bgp_terminate(void) } if (BGP_IS_VALID_STATE_FOR_NOTIF( peer->connection->status)) - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, + BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_PEER_UNCONFIG); } } diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index dd8096c57..c3e55b711 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1138,16 +1138,35 @@ struct peer_connection { struct event *t_read; struct event *t_write; + struct event *t_connect; + struct event *t_delayopen; + struct event *t_start; + struct event *t_holdtime; + + struct event *t_connect_check_r; + struct event *t_connect_check_w; + struct event *t_gr_restart; + struct event *t_gr_stale; + + struct event *t_generate_updgrp_packets; + struct event *t_pmax_restart; + + struct event *t_routeadv; struct event *t_process_packet; struct event *t_process_packet_error; + union sockunion su; +#define BGP_CONNECTION_SU_UNSPEC(connection) \ + (connection->su.sa.sa_family == AF_UNSPEC) + /* Thread flags */ _Atomic uint32_t thread_flags; #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_free(struct peer_connection **connection); extern void bgp_peer_connection_buffers_free(struct peer_connection *connection); /* BGP neighbor structure. */ @@ -1225,8 +1244,7 @@ struct peer { char *desc; /* Description of the peer. */ unsigned short port; /* Destination port for peer */ char *host; /* Printable address of the peer. */ - union sockunion su; /* Sockunion address of the peer. */ -#define BGP_PEER_SU_UNSPEC(peer) (peer->su.sa.sa_family == AF_UNSPEC) + time_t uptime; /* Last Up/Down time */ time_t readtime; /* Last read time */ time_t resettime; /* Last reset time */ @@ -1548,19 +1566,8 @@ struct peer { _Atomic uint32_t v_gr_restart; /* Threads. */ - struct event *t_start; - struct event *t_connect_check_r; - struct event *t_connect_check_w; - struct event *t_connect; - struct event *t_holdtime; - struct event *t_routeadv; - struct event *t_delayopen; - struct event *t_pmax_restart; - struct event *t_gr_restart; - struct event *t_gr_stale; struct event *t_llgr_stale[AFI_MAX][SAFI_MAX]; struct event *t_revalidate_all[AFI_MAX][SAFI_MAX]; - struct event *t_generate_updgrp_packets; struct event *t_refresh_stalepath; /* Thread flags. */ @@ -1802,10 +1809,10 @@ struct peer { #define BGP_ATTR_MAX 255 /* Path attributes discard */ - bool discard_attrs[BGP_ATTR_MAX]; + bool discard_attrs[BGP_ATTR_MAX + 1]; /* Path attributes treat-as-withdraw */ - bool withdraw_attrs[BGP_ATTR_MAX]; + bool withdraw_attrs[BGP_ATTR_MAX + 1]; /* BGP Software Version Capability */ #define BGP_MAX_SOFT_VERSION 64 @@ -2164,7 +2171,7 @@ extern void bgp_set_evpn(struct bgp *bgp); extern struct peer *peer_lookup(struct bgp *, union sockunion *); extern struct peer *peer_lookup_by_conf_if(struct bgp *, const char *); extern struct peer *peer_lookup_by_hostname(struct bgp *, const char *); -extern void bgp_peer_conf_if_to_su_update(struct peer *); +extern void bgp_peer_conf_if_to_su_update(struct peer_connection *connection); extern int peer_group_listen_range_del(struct peer_group *, struct prefix *); extern struct peer_group *peer_group_lookup(struct bgp *, const char *); extern struct peer_group *peer_group_get(struct bgp *, const char *); @@ -2595,9 +2602,9 @@ static inline char *timestamp_string(time_t ts) return ctime(&tbuf); } -static inline bool peer_established(struct peer *peer) +static inline bool peer_established(struct peer_connection *connection) { - return peer->connection->status == Established; + return connection->status == Established; } static inline bool peer_dynamic_neighbor(struct peer *peer) diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index 27f7c88d7..a93e186f8 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -3729,8 +3729,9 @@ void rfapiBgpInfoFilteredImportVPN( prefix_same(&pfx_un, &un_prefix)) { /* compare */ un_match = 1; } - if (!RFAPI_LOCAL_BI(bpi) && !RFAPI_LOCAL_BI(info_new) - && sockunion_same(&bpi->peer->su, &info_new->peer->su)) { + if (!RFAPI_LOCAL_BI(bpi) && !RFAPI_LOCAL_BI(info_new) && + sockunion_same(&bpi->peer->connection->su, + &info_new->peer->connection->su)) { /* old & new are both remote, same peer */ remote_peer_match = 1; } |