]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Merge commit '2d0652dd1088395c50df8fe1a99f1111b44688c6' into thread-next
authorOndrej Zajicek <santiago@crfreenet.org>
Mon, 1 Apr 2024 01:00:10 +0000 (03:00 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Mon, 1 Apr 2024 01:00:10 +0000 (03:00 +0200)
1  2 
proto/bgp/attrs.c

index 78acfc69a4fc3a6a11da255d4816ab458b2ac39b,85646647f4b98a183e798dec548b75d8f790a4be..f53456d95853e31d77f6c99bca3d225e8caa8464
   * format - Optional hook that converts eattr to textual representation.
   */
  
 -
 -struct bgp_attr_desc {
 -  const char *name;
 -  uint type;
 -  uint flags;
 -  void (*export)(struct bgp_export_state *s, eattr *a);
 -  int  (*encode)(struct bgp_write_state *s, eattr *a, byte *buf, uint size);
 -  void (*decode)(struct bgp_parse_state *s, uint code, uint flags, byte *data, uint len, ea_list **to);
 -  void (*format)(const eattr *ea, byte *buf, uint size);
 +union bgp_attr_desc {
 +  struct ea_class class;
 +  struct {
 +    EA_CLASS_INSIDE;
 +    void (*export)(struct bgp_export_state *s, eattr *a);
 +    int  (*encode)(struct bgp_write_state *s, eattr *a, byte *buf, uint size);
 +    void (*decode)(struct bgp_parse_state *s, uint code, uint flags, byte *data, uint len, ea_list **to);
 +  };
  };
  
 -static const struct bgp_attr_desc bgp_attr_table[];
 +static union bgp_attr_desc bgp_attr_table[];
 +static inline const union bgp_attr_desc *bgp_find_attr_desc(eattr *a)
 +{
 +  const struct ea_class *class = ea_class_find(a->id);
  
 -static inline int bgp_attr_known(uint code);
 +  if ((class < &bgp_attr_table[0].class) || (class >= &bgp_attr_table[BGP_ATTR_MAX].class))
 +    return NULL;
  
 -eattr *
 -bgp_set_attr(ea_list **attrs, struct linpool *pool, uint code, uint flags, uintptr_t val)
 +  return (const union bgp_attr_desc *) class;
 +}
 +
 +#define BGP_EA_ID(code)       (bgp_attr_table[code].id)
 +#define EA_BGP_ID(code)       (((union bgp_attr_desc *) ea_class_find(code)) - bgp_attr_table)
 +
 +void bgp_set_attr_u32(ea_list **to, uint code, uint flags, u32 val)
  {
 -  ASSERT(bgp_attr_known(code));
 +  const union bgp_attr_desc *desc = &bgp_attr_table[code];
  
 -  return ea_set_attr(
 -      attrs,
 -      pool,
 -      EA_CODE(PROTOCOL_BGP, code),
 -      bgp_attr_table[code].flags | (flags & BAF_PARTIAL),
 -      bgp_attr_table[code].type,
 -      val
 -  );
 +  ea_set_attr(to, EA_LITERAL_EMBEDDED(
 +      &desc->class,
-       flags & ~BAF_EXT_LEN,
++      desc->flags | (flags & BAF_PARTIAL),
 +      val
 +      ));
  }
  
 +void bgp_set_attr_ptr(ea_list **to, uint code, uint flags, const struct adata *ad)
 +{
 +  const union bgp_attr_desc *desc = &bgp_attr_table[code];
  
-       flags & ~BAF_EXT_LEN,
 +  ea_set_attr(to, EA_LITERAL_DIRECT_ADATA(
 +      &desc->class,
-       flags & ~BAF_EXT_LEN,
++      desc->flags | (flags & BAF_PARTIAL),
 +      ad
 +      ));
 +}
 +
 +void
 +bgp_set_attr_data(ea_list **to, uint code, uint flags, void *data, uint len)
 +{
 +  const union bgp_attr_desc *desc = &bgp_attr_table[code];
 +
 +  ea_set_attr(to, EA_LITERAL_STORE_ADATA(
 +      &desc->class,
++      desc->flags | (flags & BAF_PARTIAL),
 +      data,
 +      len
 +      ));
 +}
 +
 +void
 +bgp_unset_attr(ea_list **to, uint code)
 +{
 +  const union bgp_attr_desc *desc = &bgp_attr_table[code];
 +  ea_unset_attr(to, 0, &desc->class);
 +}
  
  #define REPORT(msg, args...) \
    ({ log(L_REMOTE "%s: " msg, s->proto->p.name, ## args); })
@@@ -1250,24 -1166,39 +1250,25 @@@ bgp_find_ea_class_by_id(uint id
  static inline void
  bgp_export_attr(struct bgp_export_state *s, eattr *a, ea_list *to)
  {
 -  if (EA_PROTO(a->id) != PROTOCOL_BGP)
 +  const union bgp_attr_desc *desc = bgp_find_attr_desc(a);
 +  if (!desc)
      return;
  
-   /* The flags might have been zero if the attr was added locally */
 -  uint code = EA_ID(a->id);
 -
 -  if (bgp_attr_known(code))
 -  {
 -    const struct bgp_attr_desc *desc = &bgp_attr_table[code];
 -
 -    /* The flags should be correct, we reset them just to be sure */
 -    ASSERT(!((a->flags ^ desc->flags) & (BAF_OPTIONAL | BAF_TRANSITIVE)));
 -    a->flags = (a->flags & BAF_PARTIAL) | desc->flags;
 -
 -    /* Set partial bit if new opt-trans attribute is attached to non-local route */
 -    if ((s->src != NULL) && (a->originated) &&
 -      (a->flags & BAF_OPTIONAL) && (a->flags & BAF_TRANSITIVE))
 -      a->flags |= BAF_PARTIAL;
++  /* The flags should be correct, we reset them just to be sure */
++  ASSERT(!((a->flags ^ desc->flags) & (BAF_OPTIONAL | BAF_TRANSITIVE)));
 +  a->flags = (a->flags & BAF_PARTIAL) | desc->flags;
  
 -    /* Call specific hook */
 -    CALL(desc->export, s, a);
 +  /* Set partial bit if new opt-trans attribute is attached to non-local route */
 +  if ((s->src != NULL) && (a->originated) &&
 +      (a->flags & BAF_OPTIONAL) && (a->flags & BAF_TRANSITIVE))
 +    a->flags |= BAF_PARTIAL;
  
 -    /* Attribute might become undefined in hook */
 -    if (a->undef)
 -      return;
 -  }
 -  else
 -  {
 -    /* Don't re-export unknown non-transitive attributes */
 -    if (!(a->flags & BAF_TRANSITIVE))
 -      return;
 +  /* Call specific hook */
 +  CALL(desc->export, s, a);
  
 -    a->flags |= BAF_PARTIAL;
 -  }
 +  /* Attribute might become undefined in hook */
 +  if (a->undef)
 +    return;
  
    /* Append updated attribute */
    to->attrs[to->count++] = *a;