]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Merge branch 'mq-bmp-to-merge-to-v3' into thread-next
authorMaria Matejka <mq@ucw.cz>
Wed, 11 Oct 2023 20:06:18 +0000 (22:06 +0200)
committerMaria Matejka <mq@ucw.cz>
Wed, 11 Oct 2023 20:06:18 +0000 (22:06 +0200)
1  2 
NEWS
configure.ac
doc/bird.sgml
filter/test.conf
nest/proto.c
nest/protocol.h
proto/bgp/attrs.c
proto/bgp/bgp.c
proto/bgp/bgp.h
proto/bgp/packets.c

diff --cc NEWS
index 5a344f42d5811e321ed3561ba156be873049e40a,070f8d2f361a7dcab83cff65b8179fee2ce7217e..c0ccaa8e752284d08303d0432b187f4adc5c86ae
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -1,34 -1,23 +1,54 @@@
 +Version 3.0alpha2 (2023-05-11)
 +  o Fixed memory leaks and use-after free bugs
 +  o Simple thread work balancing
 +  o MRT switched off
 +  o Slow kernel route synchronization to be fixed later
 +
 +Version 3.0alpha1 (2023-04-18)
 +  o Worker threads for BGP, Pipe, RPKI and BFD
 +  o Configurable number of threads
 +  o Asynchronous route export
 +  o Flat attribute structure
 +  o Inline import tables
 +  o Export tables merged with BGP prefix / attribute buckets
 +  o Fixed ROA check locking inversion in route table dumps
 +  o MRT switched off
 +
 +Version 3.0-alpha0 (2022-02-07)
 +  o Removal of fixed protocol-specific route attributes
 +  o Asynchronous route export
 +  o Explicit table import / export hooks
 +  o Partially lockless route attribute cache
 +  o Thread-safe resource management
 +  o Thread-safe interface notifications
 +  o Thread-safe protocol API
 +  o Adoption of BFD IO loop for general use
 +  o Parallel Pipe protocol
 +  o Parallel RPKI protocol
 +  o Parallel BGP protocol
 +  o Lots of refactoring
 +  o Bugfixes and improvements as they came along
 +
+ Version 2.13 (2023-04-21)
+   o Babel: IPv4 via IPv6 extension (RFC 9229)
+   o Babel: Improve authentication on lossy networks
+   o BGP: New 'allow bgp_med' option
+   o BSD: Support for IPv4 routes with IPv6 nexthop on FreeBSD
+   o Experimental BMP protocol implementation
+   o Important bugfixes
+   Notes:
+   We changed versioning scheme from <epoch>.<major>.<minor> to more common
+   <major>.<minor>.<patch> . From now on, you may expect that BIRD 2.13.x will be
+   strictly only fixing bugs found in 2.13, whereas BIRD 2.14 will also contain
+   new features.
+   This BIRD version contains an alpha release of BMP protocol implementation.
+   It is not ready for production usage and therefore it is not compiled by
+   default and have to be enabled during installation.
  Version 2.0.12 (2023-01-23)
    o Filter: New 'onlink' route attribute
    o Compile-time option to use 4-way tries instead of 16-way ones
diff --cc configure.ac
Simple merge
diff --cc doc/bird.sgml
Simple merge
Simple merge
diff --cc nest/proto.c
index 5b00cc9d9dca012f60f30b194ac046920c8fecd0,a532570575eeb1d12a6aafffb76c0aa7f51d8dc9..b0ca57da53df5d5fd40ede6bf78bc7a6dc3b109c
@@@ -272,10 -177,12 +272,11 @@@ proto_add_channel(struct proto *p, stru
    c->preference = cf->preference;
    c->debug = cf->debug;
    c->merge_limit = cf->merge_limit;
 -  c->in_keep_filtered = cf->in_keep_filtered;
 +  c->in_keep = cf->in_keep;
    c->rpki_reload = cf->rpki_reload;
+   c->bmp_hack = cf->bmp_hack;
  
    c->channel_state = CS_DOWN;
 -  c->export_state = ES_DOWN;
    c->last_state_change = current_time();
    c->reloadable = 1;
  
diff --cc nest/protocol.h
index ca33a7fc5a4b12f6135706b46244492d46a0fd4a,dad0b781bd8c2431fa9a92c5c14eec92ea80c113..70b2022d3fee1770e6567d7f6f6012a2c8fec2e7
@@@ -202,16 -224,20 +202,12 @@@ struct proto 
     *  Routing entry hooks (called only for routes belonging to this protocol):
     *
     *     rte_recalculate Called at the beginning of the best route selection
 -   *     rte_better   Compare two rte's and decide which one is better (1=first, 0=second).
 -   *       rte_same   Compare two rte's and decide whether they are identical (1=yes, 0=no).
     *       rte_mergable       Compare two rte's and decide whether they could be merged (1=yes, 0=no).
--   *     rte_insert   Called whenever a rte is inserted to a routing table.
--   *     rte_remove   Called whenever a rte is removed from the routing table.
     */
  
 -  int (*rte_recalculate)(struct rtable *, struct network *, struct rte *, struct rte *, struct rte *);
 -  int (*rte_better)(struct rte *, struct rte *);
 +  int (*rte_recalculate)(struct rtable_private *, struct network *, struct rte *, struct rte *, struct rte *);
    int (*rte_mergable)(struct rte *, struct rte *);
 -  struct rte * (*rte_modify)(struct rte *, struct linpool *);
--  void (*rte_insert)(struct network *, struct rte *);
--  void (*rte_remove)(struct network *, struct rte *);
 -  u32 (*rte_igp_metric)(struct rte *);
 +  u32 (*rte_igp_metric)(const struct rte *);
  
    /* Hic sunt protocol-specific data */
  };
@@@ -663,9 -619,10 +660,10 @@@ struct channel_config *proto_cf_find_ch
  static inline struct channel_config *proto_cf_main_channel(struct proto_config *pc)
  { return proto_cf_find_channel(pc, pc->net_type); }
  
 -struct channel *proto_find_channel_by_table(struct proto *p, struct rtable *t);
 +struct channel *proto_find_channel_by_table(struct proto *p, rtable *t);
  struct channel *proto_find_channel_by_name(struct proto *p, const char *n);
  struct channel *proto_add_channel(struct proto *p, struct channel_config *cf);
+ void proto_remove_channel(struct proto *p, struct channel *c);
  int proto_configure_channel(struct proto *p, struct channel **c, struct channel_config *cf);
  
  void channel_set_state(struct channel *c, uint state);
index 973e29352f408fc1242004e65a3286d0117369f9,de45cae0e6181d90829f51e423c614795e6bb5c4..6335a1e19051a9e109ab09dd96d1ca6ef24d6898
@@@ -1209,33 -1145,20 +1209,43 @@@ static union bgp_attr_desc bgp_attr_tab
    },
  };
  
 -static inline int
 -bgp_attr_known(uint code)
 +eattr *
 +bgp_find_attr(ea_list *attrs, uint code)
  {
 -  return (code < ARRAY_SIZE(bgp_attr_table)) && bgp_attr_table[code].name;
 +  return ea_find(attrs, BGP_EA_ID(code));
  }
  
 -void bgp_fix_attr_flags(ea_list *attrs)
 +void
 +bgp_register_attrs(void)
 +{
 +  for (uint i=0; i<ARRAY_SIZE(bgp_attr_table); i++)
 +  {
 +    if (!bgp_attr_table[i].name)
 +      bgp_attr_table[i] = (union bgp_attr_desc) {
 +      .name = mb_sprintf(&root_pool, "bgp_unknown_0x%02x", i),
 +      .type = T_OPAQUE,
 +      .flags = BAF_OPTIONAL,
 +      .readonly = 1,
 +      .export = bgp_export_unknown,
 +      .encode = bgp_encode_raw,
 +      .decode = bgp_decode_unknown,
 +      .format = bgp_format_unknown,
 +      };
 +
 +    ea_register_init(&bgp_attr_table[i].class);
 +  }
 +}
 +
++void
++bgp_fix_attr_flags(ea_list *attrs)
+ {
+   for (u8 i = 0; i < attrs->count; i++)
+   {
+     attrs->attrs[i].flags = bgp_attr_table[EA_ID(attrs->attrs[i].id)].flags;
+   }
+ }
++
  /*
   *    Attribute export
   */
diff --cc proto/bgp/bgp.c
index 0de9c603f4d3101a722001b9ebe9b3a72fb9b401,a6e9cf8394d77434e6d55e2db33032756272dbe5..3c7bdab17c102c91009521c0c314261fcdd8d6a2
  #include "lib/string.h"
  
  #include "bgp.h"
+ #include "proto/bmp/bmp.h"
  
 +static void bgp_listen_create(void *);
  
  static list STATIC_LIST_INIT(bgp_sockets);            /* Global list of listening sockets */
 +static list STATIC_LIST_INIT(bgp_listen_pending);     /* Global list of listening socket open requests */
 +static event bgp_listen_event = { .hook = bgp_listen_create };
  
 +static DOMAIN(rtable) bgp_listen_domain;
 +static pool *bgp_listen_pool;
  
  static void bgp_connect(struct bgp_proto *p);
  static void bgp_active(struct bgp_proto *p);
@@@ -469,13 -375,18 +470,20 @@@ bgp_close_conn(struct bgp_conn *conn
    conn->keepalive_timer = NULL;
    rfree(conn->hold_timer);
    conn->hold_timer = NULL;
 +
    rfree(conn->tx_ev);
    conn->tx_ev = NULL;
 -  rfree(conn->sk);
 +
 +  sk_close(conn->sk);
    conn->sk = NULL;
  
+   mb_free(conn->local_open_msg);
+   conn->local_open_msg = NULL;
+   mb_free(conn->remote_open_msg);
+   conn->remote_open_msg = NULL;
+   conn->local_open_length = 0;
+   conn->remote_open_length = 0;
    mb_free(conn->local_caps);
    conn->local_caps = NULL;
    mb_free(conn->remote_caps);
@@@ -809,10 -722,10 +826,10 @@@ bgp_conn_enter_close_state(struct bgp_c
    conn->sk->rx_hook = NULL;
  
    /* Timeout for CLOSE state, if we cannot send notification soon then we just hangup */
 -  bgp_start_timer(conn->hold_timer, 10);
 +  bgp_start_timer(p, conn->hold_timer, 10);
  
    if (os == BS_ESTABLISHED)
-     bgp_conn_leave_established_state(p);
+     bgp_conn_leave_established_state(conn, p);
  }
  
  void
@@@ -823,10 -736,10 +840,10 @@@ bgp_conn_enter_idle_state(struct bgp_co
  
    bgp_close_conn(conn);
    bgp_conn_set_state(conn, BS_IDLE);
 -  ev_schedule(p->event);
 +  proto_send_event(&p->p, p->event);
  
    if (os == BS_ESTABLISHED)
-     bgp_conn_leave_established_state(p);
+     bgp_conn_leave_established_state(conn, p);
  }
  
  /**
diff --cc proto/bgp/bgp.h
index bae7055a981cc9af6a905b0b958b89bdd12b30be,324df43c3e24053429609de69e6915b00bf5a3bd..c371307de871969677eb8033fd2ab28f703e3f2c
@@@ -516,9 -500,16 +523,16 @@@ struct bgp_parse_state 
  #define BGP_RX_BUFFER_EXT_SIZE        65535
  #define BGP_TX_BUFFER_EXT_SIZE        65535
  
 -#define BGP_CF_WALK_CHANNELS(P,C) WALK_LIST(C, P->c.channels) if (C->c.channel == &channel_bgp)
 -#define BGP_WALK_CHANNELS(P,C) WALK_LIST(C, P->p.channels) if (C->c.channel == &channel_bgp)
 +#define BGP_CF_WALK_CHANNELS(P,C) WALK_LIST(C, P->c.channels) if (C->c.class == &channel_bgp)
 +#define BGP_WALK_CHANNELS(P,C) WALK_LIST(C, P->p.channels) if (C->c.class == &channel_bgp)
  
+ #define BGP_MSG_HDR_MARKER_SIZE       16
+ #define BGP_MSG_HDR_MARKER_POS        0
+ #define BGP_MSG_HDR_LENGTH_SIZE       2
+ #define BGP_MSG_HDR_LENGTH_POS        BGP_MSG_HDR_MARKER_SIZE
+ #define BGP_MSG_HDR_TYPE_SIZE 1
+ #define BGP_MSG_HDR_TYPE_POS  (BGP_MSG_HDR_MARKER_SIZE + BGP_MSG_HDR_LENGTH_SIZE)
  static inline int bgp_channel_is_ipv4(struct bgp_channel *c)
  { return BGP_AFI(c->afi) == BGP_AFI_IPV4; }
  
@@@ -565,18 -556,14 +579,20 @@@ void bgp_store_error(struct bgp_proto *
  void bgp_stop(struct bgp_proto *p, int subcode, byte *data, uint len);
  const char *bgp_format_role_name(u8 role);
  
+ void bgp_fix_attr_flags(ea_list *attrs);
  static inline int
 -rte_resolvable(rte *rt)
 +rte_resolvable(const rte *rt)
  {
 -  return rt->attrs->dest != RTD_UNREACHABLE;
 +  eattr *nhea = ea_find(rt->attrs, &ea_gen_nexthop);
 +  if (!nhea)
 +    return 0;
 +
 +  struct nexthop_adata *nhad = (void *) nhea->u.ptr;
 +  return NEXTHOP_IS_REACHABLE(nhad) || (nhad->dest != RTD_UNREACHABLE);
  }
  
 +extern struct rte_owner_class bgp_rte_owner_class;
  
  #ifdef LOCAL_DEBUG
  #define BGP_FORCE_DEBUG 1
@@@ -604,34 -612,31 +620,36 @@@ int bgp_encode_mp_reach_mrt(struct bgp_
  
  int bgp_encode_attrs(struct bgp_write_state *s, ea_list *attrs, byte *buf, byte *end);
  ea_list * bgp_decode_attrs(struct bgp_parse_state *s, byte *data, uint len);
 -void bgp_finish_attrs(struct bgp_parse_state *s, rta *a);
 +void bgp_finish_attrs(struct bgp_parse_state *s, ea_list **to);
 +
 +void bgp_setup_out_table(struct bgp_channel *c);
 +
 +void bgp_init_pending_tx(struct bgp_channel *c);
 +void bgp_free_pending_tx(struct bgp_channel *c);
  
 -void bgp_init_bucket_table(struct bgp_channel *c);
 -void bgp_free_bucket_table(struct bgp_channel *c);
 -void bgp_free_bucket(struct bgp_channel *c, struct bgp_bucket *b);
 -void bgp_defer_bucket(struct bgp_channel *c, struct bgp_bucket *b);
  void bgp_withdraw_bucket(struct bgp_channel *c, struct bgp_bucket *b);
 +int bgp_done_bucket(struct bgp_channel *c, struct bgp_bucket *b);
  
 -void bgp_init_prefix_table(struct bgp_channel *c);
 -void bgp_free_prefix_table(struct bgp_channel *c);
 -void bgp_free_prefix(struct bgp_channel *c, struct bgp_prefix *bp);
 +void bgp_done_prefix(struct bgp_channel *c, struct bgp_prefix *px, struct bgp_bucket *buck);
  
 -int bgp_rte_better(struct rte *, struct rte *);
 -int bgp_rte_mergable(rte *pri, rte *sec);
 -int bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best);
 -struct rte *bgp_rte_modify_stale(struct rte *r, struct linpool *pool);
 -u32 bgp_rte_igp_metric(struct rte *);
 -void bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old);
 +int bgp_rte_better(const rte *, const rte *);
 +int bgp_rte_mergable(const rte *pri, const rte *sec);
 +int bgp_rte_recalculate(struct rtable_private *table, net *net, struct rte_storage *new, struct rte_storage *old, struct rte_storage *old_best);
 +void bgp_rte_modify_stale(struct rt_export_request *req, const net_addr *n, struct rt_pending_export *first, struct rt_pending_export *last, const rte **feed, uint count);
 +u32 bgp_rte_igp_metric(const rte *);
 +void bgp_rt_notify(struct proto *P, struct channel *C, const net_addr *n, rte *new, const rte *old);
  int bgp_preexport(struct channel *, struct rte *);
 -int bgp_get_attr(const struct eattr *e, byte *buf, int buflen);
 -void bgp_get_route_info(struct rte *, byte *buf);
 -int bgp_total_aigp_metric_(rte *e, u64 *metric, const struct adata **ad);
 +void bgp_get_route_info(const rte *, byte *);
 +int bgp_total_aigp_metric_(const rte *e, u64 *metric, const struct adata **ad);
 +
 +static inline struct bgp_proto *bgp_rte_proto(const rte *rte)
 +{
 +  return (rte->src->owner->class == &bgp_rte_owner_class) ?
 +    SKIP_BACK(struct bgp_proto, p.sources, rte->src->owner) : NULL;
 +}
  
+ byte * bgp_bmp_encode_rte(struct bgp_channel *c, byte *buf, const net_addr *n, const struct rte *new, const struct rte_src *src);
  #define BGP_AIGP_METRIC               1
  #define BGP_AIGP_MAX          U64(0xffffffffffffffff)
  
Simple merge