From: Maria Matejka Date: Thu, 13 Nov 2025 17:13:21 +0000 (+0100) Subject: Merge branch 'mq-bgp-multilisten' into 299-mq-bgp-async-listen X-Git-Tag: v3.2.0~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=695f59fa09cc3d63ca4f10e7b2f35431ad55c141;p=thirdparty%2Fbird.git Merge branch 'mq-bgp-multilisten' into 299-mq-bgp-async-listen --- 695f59fa09cc3d63ca4f10e7b2f35431ad55c141 diff --cc proto/bgp/bgp.c index f49a2ab24,0a68acb97..d3d61eafd --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@@ -467,17 -365,14 +473,15 @@@ bgp_enable_ao_key(struct bgp_proto *p, BGP_TRACE(D_EVENTS, "Adding TCP-AO key %d/%d", key->key.send_id, key->key.recv_id); /* Handle listening sockets */ - struct bgp_listen_request *blr; node *nxt; + struct bgp_listen_request *blr, *failed = NULL; node *nxt; WALK_LIST2(blr, nxt, p->listen, pn) - if (bgp_sk_add_ao_key(p, blr->sock->sk, key, "listening") < 0) + BGP_SOCKET_LOCKED(blr->sock, bs) + if (bgp_sk_add_ao_key(p, bs->sk, key, "listening") < 0) { - key->failed = 1; - return -1; + failed = blr; + goto failA; } - key->active = 1; - /* Handle incoming socket */ if (p->incoming_conn.sk) if (bgp_sk_add_ao_key(p, p->incoming_conn.sk, key, "session (in)") < 0) @@@ -486,9 -381,29 +490,29 @@@ /* Handle outgoing socket */ if (p->outgoing_conn.sk) if (bgp_sk_add_ao_key(p, p->outgoing_conn.sk, key, "session (out)") < 0) - return -1; + goto failB; + key->active = 1; return 0; + + failB: + /* Cleanup incoming socket */ + if (p->incoming_conn.sk) + bgp_sk_delete_ao_key(p, p->incoming_conn.sk, key, NULL, -1, -1, "session (in)"); + + failA: + /* Cleanup listening sockets */ + WALK_LIST2(blr, nxt, p->listen, pn) + { + if (blr == failed) + break; - - bgp_sk_delete_ao_key(p, blr->sock->sk, key, NULL, -1, -1, "listening"); ++ BGP_SOCKET_LOCKED(blr->sock, bs) ++ bgp_sk_delete_ao_key(p, bs->sk, key, NULL, -1, -1, "listening"); + } + + /* Mark as failed */ + key->failed = 1; + return -1; } struct bgp_active_keys { @@@ -544,9 -462,8 +571,9 @@@ bgp_disable_ao_key(struct bgp_proto *p /* Handle listening socket */ struct bgp_listen_request *blr; node *nxt; WALK_LIST2(blr, nxt, p->listen, pn) - if (bgp_sk_delete_ao_key(p, blr->sock->sk, key, NULL, -1, -1, "listening") < 0) + BGP_SOCKET_LOCKED(blr->sock, bs) + if (bgp_sk_delete_ao_key(p, bs->sk, key, NULL, -1, -1, "listening") < 0) - return -1; + rv = -1; key->active = 0; @@@ -2244,12 -1986,18 +2269,18 @@@ bgp_iface_match(struct bgp_proto *p, st ASSERT_DIE(p->cf->ipatt); ASSERT_DIE(p->cf->strict_bind); - if ((ps == PS_DOWN) || (ps == PS_STOP)) + if ((ps == PS_DOWN_XX) || (ps == PS_FLUSH) || (ps == PS_STOP)) - return; + return false; if (!iface_patt_match(p->cf->ipatt, i, NULL)) - return; + return false; + + return true; + } + static void + bgp_iface_update(struct bgp_proto *p, uint flags, struct iface *i) + { struct bgp_socket_params params = { .iface = i, .vrf = p->p.vrf, @@@ -2296,6 -2045,29 +2328,28 @@@ bgp_ifa_notify(struct proto *P, uint fl bgp_iface_update(p, flags, i->iface); } + static void + bgp_if_reload(struct bgp_proto *p, struct iface_patt *patt) + { - struct iface *iface; + struct ifa *a; + - WALK_LIST(iface, iface_list) ++ IFACE_WALK(iface) + { + bool old = iface_patt_match(p->cf->ipatt, iface, NULL); + bool new = iface_patt_match(patt, iface, NULL); + + if (old == new) + continue; + + if (ipa_zero(p->cf->local_ip) || p->cf->free_bind) + bgp_iface_update(p, old ? IF_CHANGE_DOWN : IF_CHANGE_UP, iface); + else + WALK_LIST(a, iface->addrs) + if (ipa_equal(a->ip, p->cf->local_ip)) + bgp_iface_update(p, old ? IF_CHANGE_DOWN : IF_CHANGE_UP, iface); + } + } + static void bgp_neigh_notify(neighbor *n) { @@@ -2681,6 -2346,16 +2735,16 @@@ bgp_start(struct proto *P /* Initialize listening socket list */ init_list(&p->listen); + /* Setup interface notification hooks */ - P->if_notify = NULL; - P->ifa_notify = NULL; ++ P->iface_sub.if_notify = NULL; ++ P->iface_sub.ifa_notify = NULL; + if (cf->ipatt) { + if (ipa_zero(cf->local_ip) || cf->free_bind) - P->if_notify = bgp_if_notify; ++ P->iface_sub.if_notify = bgp_if_notify; + else - P->ifa_notify = bgp_ifa_notify; ++ P->iface_sub.ifa_notify = bgp_ifa_notify; + } + /* Initialize TCP-AO keys */ init_list(&p->ao.keys); if (cf->auth_type == BGP_AUTH_AO) @@@ -2866,11 -2515,6 +2930,8 @@@ bgp_init(struct proto_config *CF p->remote_ip = cf->remote_ip; p->remote_as = cf->remote_as; + p->postponed_sk = NULL; + - P->iface_sub.if_notify = (cf->ipatt && ipa_zero(cf->local_ip)) ? bgp_if_notify : NULL; - P->iface_sub.ifa_notify = (cf->ipatt && !ipa_zero(cf->local_ip)) ? bgp_ifa_notify : NULL; - /* Hack: We use cf->remote_ip just to pass remote_ip from bgp_spawn() */ if (cf->c.parent) cf->remote_ip = IPA_NONE; @@@ -3383,7 -3039,19 +3469,19 @@@ bgp_reconfigure(struct proto *P, struc && !bstrcmp(old->dynamic_name, new->dynamic_name) && (old->dynamic_name_digits == new->dynamic_name_digits); - /* Reconfigure TCP-AP */ + /* Reconfigure interface notification hooks */ - same = same && (!P->if_notify == !(new->ipatt && ipa_zero(new->local_ip))); - same = same && (!P->ifa_notify == !(new->ipatt && !ipa_zero(new->local_ip))); ++ same = same && (!P->iface_sub.if_notify == !(new->ipatt && ipa_zero(new->local_ip))); ++ same = same && (!P->iface_sub.ifa_notify == !(new->ipatt && !ipa_zero(new->local_ip))); + + /* Differing pattern lists cause an update of the listening sockets + * and also if the connection is up, then active sockets. */ + bool need_if_reload = same && new->ipatt && old->ipatt && !iface_plists_equal(new->ipatt, old->ipatt); + if (need_if_reload && !bgp_is_dynamic(p) && ( + p->incoming_conn.sk && !iface_patt_match(new->ipatt, p->incoming_conn.sk->iface, NULL) || + p->outgoing_conn.sk && !iface_patt_match(new->ipatt, p->outgoing_conn.sk->iface, NULL))) + same = 0; + + /* Reconfigure TCP-AO */ same = same && bgp_reconfigure_ao_keys(p, new); /* FIXME: Move channel reconfiguration to generic protocol code ? */ @@@ -3431,9 -3094,14 +3529,12 @@@ if (((co->state == BS_OPENCONFIRM) || (co->state == BS_ESTABLISHED)) && !bgp_check_capabilities(co)) return 0; - proto_setup_mpls_map(P, RTS_BGP, 1); - - if (p->start_state > BSS_PREPARE) + if (bgp_start_state(p) > BSS_PREPARE) bgp_update_bfd(p, new->bfd); + if (need_if_reload) + bgp_if_reload(p, new->ipatt); + return 1; }