Commit 875cc073 authored by Ondrej Zajicek (work)'s avatar Ondrej Zajicek (work)
Browse files

Nest: Update handling of temporary attributes

The temporary atttributes are no longer removed by ea_do_prune(), but
they are undefined by store_tmp_attrs() protocol hooks. This fixes
several bugs where temporary attributes were removed when they should
not or not removed when they should be. The flag EAF_TEMP is no longer
needed and was removed.

Update all protocol make_tmp_attrs() / store_tmp_attrs() hooks to use
helper functions and to handle unset attributes properly.

Also fix some related bugs like improper handling of empty eattr list.
parent 9aa77fcc
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1045,7 +1045,7 @@ cmd:
   }
 | UNSET '(' rtadot dynamic_attr ')' ';' {
     $$ = f_new_inst_da(FI_EA_SET, $4);
     $$->aux = EAF_TYPE_UNDEF | EAF_TEMP;
     $$->aux = EAF_TYPE_UNDEF;
     $$->a1.p = NULL;
   }
 | break_command print_list ';' { $$ = f_new_inst(FI_PRINT_AND_DIE); $$->a1.p = $2; $$->a2.i = $1; }
+4 −16
Original line number Diff line number Diff line
@@ -194,8 +194,8 @@ struct proto {
   *	   ifa_notify	Notify protocol about interface address changes.
   *	   rt_notify	Notify protocol about routing table updates.
   *	   neigh_notify	Notify protocol about neighbor cache events.
   *	   make_tmp_attrs  Construct ea_list from private attrs stored in rta.
   *	   store_tmp_attrs Store private attrs back to rta. The route MUST NOT be cached.
   *	   make_tmp_attrs  Add attributes to rta from from private attrs stored in rte. The route and rta MUST NOT be cached.
   *	   store_tmp_attrs Store private attrs back to rte and undef added attributes. The route and rta MUST NOT be cached.
   *	   preexport  Called as the first step of the route exporting process.
   *			It can construct a new rte, add private attributes and
   *			decide whether the route shall be exported: 1=yes, -1=no,
@@ -211,8 +211,8 @@ struct proto {
  void (*ifa_notify)(struct proto *, unsigned flags, struct ifa *a);
  void (*rt_notify)(struct proto *, struct channel *, struct network *net, struct rte *new, struct rte *old);
  void (*neigh_notify)(struct neighbor *neigh);
  struct ea_list *(*make_tmp_attrs)(struct rte *rt, struct linpool *pool);
  void (*store_tmp_attrs)(struct rte *rt);
  void (*make_tmp_attrs)(struct rte *rt, struct linpool *pool);
  void (*store_tmp_attrs)(struct rte *rt, struct linpool *pool);
  int (*preexport)(struct proto *, struct rte **rt, struct linpool *pool);
  void (*reload_routes)(struct channel *);
  void (*feed_begin)(struct channel *, int initial);
@@ -297,18 +297,6 @@ proto_get_router_id(struct proto_config *pc)
  return pc->router_id ? pc->router_id : pc->global->router_id;
}

static inline void
rte_make_tmp_attrs(struct rte **rt, struct linpool *pool)
{
  struct ea_list *(*mta)(struct rte *rt, struct linpool *pool);
  mta = (*rt)->attrs->src->proto->make_tmp_attrs;
  if (!mta) return;
  *rt = rte_cow_rta(*rt, pool);
  struct ea_list *ea = mta(*rt, pool);
  ea->next = (*rt)->attrs->eattrs;
  (*rt)->attrs->eattrs = ea;
}


extern pool *proto_pool;
extern list proto_list;
+7 −3
Original line number Diff line number Diff line
@@ -308,8 +308,10 @@ void rte_free(rte *);
rte *rte_do_cow(rte *);
static inline rte * rte_cow(rte *r) { return (r->flags & REF_COW) ? rte_do_cow(r) : r; }
rte *rte_cow_rta(rte *r, linpool *lp);
void rte_make_tmp_attr(struct rte *r, struct ea_list *e, uint id, uint type, u32 val);
uint rte_store_tmp_attr(struct rte *r, uint id);
void rte_init_tmp_attrs(struct rte *r, linpool *lp, uint max);
void rte_make_tmp_attr(struct rte *r, uint id, uint type, uintptr_t val);
void rte_make_tmp_attrs(struct rte **r, struct linpool *pool, struct rta **old_attrs);
uintptr_t rte_store_tmp_attr(struct rte *r, uint id);
void rt_dump(rtable *);
void rt_dump_all(void);
int rt_feed_channel(struct channel *c);
@@ -512,7 +514,6 @@ const char *ea_custom_name(uint ea);
#define EAF_VAR_LENGTH 0x02		/* Attribute length is variable (part of type spec) */
#define EAF_ORIGINATED 0x20		/* The attribute has originated locally */
#define EAF_FRESH 0x40			/* An uncached attribute (e.g. modified in export filter) */
#define EAF_TEMP 0x80			/* A temporary attribute (the one stored in the tmp attr list) */

typedef struct adata {
  uint length;				/* Length of data */
@@ -542,6 +543,7 @@ typedef struct ea_list {
#define EALF_SORTED 1			/* Attributes are sorted by code */
#define EALF_BISECT 2			/* Use interval bisection for searching */
#define EALF_CACHED 4			/* Attributes belonging to cached rta */
#define EALF_TEMP 8			/* Temporary ea_list added by make_tmp_attrs hooks */

struct rte_src *rt_find_source(struct proto *p, u32 id);
struct rte_src *rt_get_source(struct proto *p, u32 id);
@@ -574,6 +576,8 @@ void ea_format_bitfield(struct eattr *a, byte *buf, int bufsize, const char **na
    ea = t; \
  } \
  ea_sort(ea); \
  if (ea->count == 0) \
    ea = NULL; \
} while(0) \

static inline eattr *
+2 −8
Original line number Diff line number Diff line
@@ -571,8 +571,8 @@ ea_do_sort(ea_list *e)
}

/**
 * In place discard duplicates, undefs and temporary attributes in sorted
 * ea_list. We use stable sort for this reason.
 * In place discard duplicates and undefs in sorted ea_list. We use stable sort
 * for this reason.
 **/
static inline void
ea_do_prune(ea_list *e)
@@ -596,10 +596,6 @@ ea_do_prune(ea_list *e)
      if ((s0->type & EAF_TYPE_MASK) == EAF_TYPE_UNDEF)
	continue;

      /* Drop temporary attributes */
      if (s0->type & EAF_TEMP)
	continue;

      /* Copy the newest version to destination */
      *d = *s0;

@@ -979,8 +975,6 @@ ea_dump(ea_list *e)
	{
	  eattr *a = &e->attrs[i];
	  debug(" %02x:%02x.%02x", EA_PROTO(a->id), EA_ID(a->id), a->flags);
	  if (a->type & EAF_TEMP)
	    debug("T");
	  debug("=%c", "?iO?I?P???S?????" [a->type & EAF_TYPE_MASK]);
	  if (a->type & EAF_ORIGINATED)
	    debug("o");
+4 −3
Original line number Diff line number Diff line
@@ -45,10 +45,11 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d)
  else
    from[0] = 0;

  get_route_info = a->src->proto->proto->get_route_info;
  /* Need to normalize the extended attributes */
  if ((get_route_info || d->verbose) && !rta_is_cached(a))
  if (d->verbose && !rta_is_cached(a) && a->eattrs)
    ea_normalize(a->eattrs);

  get_route_info = a->src->proto->proto->get_route_info;
  if (get_route_info)
    get_route_info(e, info);
  else
@@ -114,7 +115,7 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
	continue;

      ee = e;
      rte_make_tmp_attrs(&e, c->show_pool);
      rte_make_tmp_attrs(&e, c->show_pool, NULL);

      /* Export channel is down, do not try to export routes to it */
      if (ec && (ec->export_state == ES_DOWN))
Loading