]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Merge branch 'mq-bgp-multilisten' into 299-mq-bgp-async-listen
authorMaria Matejka <mq@ucw.cz>
Thu, 13 Nov 2025 17:13:21 +0000 (18:13 +0100)
committerMaria Matejka <mq@ucw.cz>
Thu, 13 Nov 2025 17:13:21 +0000 (18:13 +0100)
1  2 
doc/bird.sgml
nest/iface.c
nest/iface.h
proto/bgp/bgp.c
proto/bgp/bgp.h
proto/bgp/config.Y

diff --cc doc/bird.sgml
Simple merge
diff --cc nest/iface.c
Simple merge
diff --cc nest/iface.h
Simple merge
diff --cc proto/bgp/bgp.c
index f49a2ab2446a5b688b9c8269e8f068a01d532bf2,0a68acb97343735b4d3e799e51b3c05d06bc56ef..d3d61eafd15a9f3d4171adf735250bff66848551
@@@ -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)
    /* 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;
 -
 -    bgp_sk_delete_ao_key(p, blr->sock->sk, key, NULL, -1, -1, "listening");
+ 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_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);
  }
  
 -  struct iface *iface;
+ static void
+ bgp_if_reload(struct bgp_proto *p, struct iface_patt *patt)
+ {
 -  WALK_LIST(iface, iface_list)
+   struct ifa *a;
++  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);
  
 -  P->if_notify = NULL;
 -  P->ifa_notify = NULL;
+   /* Setup interface notification hooks */
 -      P->if_notify = bgp_if_notify;
++  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->ifa_notify = bgp_ifa_notify;
++      P->iface_sub.if_notify = bgp_if_notify;
+     else
++      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->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;
 +  p->postponed_sk = 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 ? */
    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;
  }
  
diff --cc proto/bgp/bgp.h
Simple merge
Simple merge