mirror of
				https://gitlab.labs.nic.cz/labs/bird.git
				synced 2024-05-11 16:54:54 +00:00 
			
		
		
		
	Nest: Removing separate tmpa from route propagation
This is a fundamental change of an original (1999) concept of route processing inside BIRD. During import/export, there was a temporary ea_list created which was to be used instead of the another one inside the route itself. This led to some confusion, quirks, and strange filter code that handled extended route attributes. Dropping it now. The protocol interface has changed in an uniform way -- the `struct ea_list *attrs` argument has been removed from store_tmp_attrs(), import_control(), rt_notify() and get_route_info().
This commit is contained in:
		@@ -538,14 +538,23 @@ val_format(struct f_val v, buffer *buf)
 | 
			
		||||
 | 
			
		||||
static struct rte **f_rte;
 | 
			
		||||
static struct rta *f_old_rta;
 | 
			
		||||
static struct ea_list **f_tmp_attrs;
 | 
			
		||||
static struct ea_list **f_eattrs;
 | 
			
		||||
static struct linpool *f_pool;
 | 
			
		||||
static struct buffer f_buf;
 | 
			
		||||
static int f_flags;
 | 
			
		||||
 | 
			
		||||
static inline void f_cache_eattrs(void)
 | 
			
		||||
{
 | 
			
		||||
  f_eattrs = &((*f_rte)->attrs->eattrs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void f_rte_cow(void)
 | 
			
		||||
{
 | 
			
		||||
  *f_rte = rte_cow(*f_rte);
 | 
			
		||||
  if (!((*f_rte)->flags & REF_COW))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  *f_rte = rte_do_cow(*f_rte);
 | 
			
		||||
  f_eattrs = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -570,6 +579,9 @@ f_rta_cow(void)
 | 
			
		||||
   * suppose hostentry is not changed by filters).
 | 
			
		||||
   */
 | 
			
		||||
  (*f_rte)->attrs = rta_do_cow((*f_rte)->attrs, f_pool);
 | 
			
		||||
 | 
			
		||||
  /* Re-cache the ea_list */
 | 
			
		||||
  f_cache_eattrs();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
@@ -603,7 +615,10 @@ static struct tbf rl_runtime_err = TBF_DEFAULT_LOG_LIMITS;
 | 
			
		||||
      return val;
 | 
			
		||||
 | 
			
		||||
#define ACCESS_RTE \
 | 
			
		||||
  do { if (!f_rte) runtime("No route to access"); } while (0)
 | 
			
		||||
  do { if (!f_rte) runtime("No route to access"); else f_cache_eattrs(); } while (0)
 | 
			
		||||
 | 
			
		||||
#define ACCESS_EATTRS \
 | 
			
		||||
  do { if (!f_eattrs) f_cache_eattrs(); } while (0)
 | 
			
		||||
 | 
			
		||||
#define BITFIELD_MASK(what) \
 | 
			
		||||
  (1u << (what->a2.i >> 24))
 | 
			
		||||
@@ -995,17 +1010,11 @@ interpret(struct f_inst *what)
 | 
			
		||||
    break;
 | 
			
		||||
  case FI_EA_GET:	/* Access to extended attributes */
 | 
			
		||||
    ACCESS_RTE;
 | 
			
		||||
    ACCESS_EATTRS;
 | 
			
		||||
    {
 | 
			
		||||
      eattr *e = NULL;
 | 
			
		||||
      u16 code = what->a2.i;
 | 
			
		||||
      int f_type = what->aux >> 8;
 | 
			
		||||
 | 
			
		||||
      if (!(f_flags & FF_FORCE_TMPATTR))
 | 
			
		||||
	e = ea_find((*f_rte)->attrs->eattrs, code);
 | 
			
		||||
      if (!e)
 | 
			
		||||
	e = ea_find((*f_tmp_attrs), code);
 | 
			
		||||
      if ((!e) && (f_flags & FF_FORCE_TMPATTR))
 | 
			
		||||
	e = ea_find((*f_rte)->attrs->eattrs, code);
 | 
			
		||||
      eattr *e = ea_find(*f_eattrs, code);
 | 
			
		||||
 | 
			
		||||
      if (!e) {
 | 
			
		||||
	/* A special case: undefined as_path looks like empty as_path */
 | 
			
		||||
@@ -1089,6 +1098,7 @@ interpret(struct f_inst *what)
 | 
			
		||||
    break;
 | 
			
		||||
  case FI_EA_SET:
 | 
			
		||||
    ACCESS_RTE;
 | 
			
		||||
    ACCESS_EATTRS;
 | 
			
		||||
    ARG_ANY(1);
 | 
			
		||||
    {
 | 
			
		||||
      struct ea_list *l = lp_alloc(f_pool, sizeof(struct ea_list) + sizeof(eattr));
 | 
			
		||||
@@ -1143,13 +1153,7 @@ interpret(struct f_inst *what)
 | 
			
		||||
	  runtime( "Setting bit in bitfield attribute to non-bool value" );
 | 
			
		||||
	{
 | 
			
		||||
	  /* First, we have to find the old value */
 | 
			
		||||
	  eattr *e = NULL;
 | 
			
		||||
	  if (!(f_flags & FF_FORCE_TMPATTR))
 | 
			
		||||
	    e = ea_find((*f_rte)->attrs->eattrs, code);
 | 
			
		||||
	  if (!e)
 | 
			
		||||
	    e = ea_find((*f_tmp_attrs), code);
 | 
			
		||||
	  if ((!e) && (f_flags & FF_FORCE_TMPATTR))
 | 
			
		||||
	    e = ea_find((*f_rte)->attrs->eattrs, code);
 | 
			
		||||
	  eattr *e = ea_find(*f_eattrs, code);
 | 
			
		||||
	  u32 data = e ? e->u.data : 0;
 | 
			
		||||
 | 
			
		||||
	  if (v1.val.i)
 | 
			
		||||
@@ -1181,14 +1185,9 @@ interpret(struct f_inst *what)
 | 
			
		||||
      default: bug("Unknown type in e,S");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (!(what->aux & EAF_TEMP) && (!(f_flags & FF_FORCE_TMPATTR))) {
 | 
			
		||||
	f_rta_cow();
 | 
			
		||||
	l->next = (*f_rte)->attrs->eattrs;
 | 
			
		||||
	(*f_rte)->attrs->eattrs = l;
 | 
			
		||||
      } else {
 | 
			
		||||
	l->next = (*f_tmp_attrs);
 | 
			
		||||
	(*f_tmp_attrs) = l;
 | 
			
		||||
      }
 | 
			
		||||
      f_rta_cow();
 | 
			
		||||
      l->next = *f_eattrs;
 | 
			
		||||
      *f_eattrs = l;
 | 
			
		||||
    }
 | 
			
		||||
    break;
 | 
			
		||||
  case FI_PREF_GET:
 | 
			
		||||
@@ -1518,11 +1517,12 @@ interpret(struct f_inst *what)
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      ACCESS_RTE;
 | 
			
		||||
      ACCESS_EATTRS;
 | 
			
		||||
      v1.val.net = (*f_rte)->net->n.addr;
 | 
			
		||||
 | 
			
		||||
      /* We ignore temporary attributes, probably not a problem here */
 | 
			
		||||
      /* 0x02 is a value of BA_AS_PATH, we don't want to include BGP headers */
 | 
			
		||||
      eattr *e = ea_find((*f_rte)->attrs->eattrs, EA_CODE(PROTOCOL_BGP, 0x02));
 | 
			
		||||
      eattr *e = ea_find(*f_eattrs, EA_CODE(PROTOCOL_BGP, 0x02));
 | 
			
		||||
 | 
			
		||||
      if (!e || e->type != EAF_TYPE_AS_PATH)
 | 
			
		||||
	runtime("Missing AS_PATH attribute");
 | 
			
		||||
@@ -1720,7 +1720,6 @@ i_same(struct f_inst *f1, struct f_inst *f2)
 | 
			
		||||
 * f_run - run a filter for a route
 | 
			
		||||
 * @filter: filter to run
 | 
			
		||||
 * @rte: route being filtered, may be modified
 | 
			
		||||
 * @tmp_attrs: temporary attributes, prepared by caller or generated by f_run()
 | 
			
		||||
 * @tmp_pool: all filter allocations go from this pool
 | 
			
		||||
 * @flags: flags
 | 
			
		||||
 *
 | 
			
		||||
@@ -1742,7 +1741,7 @@ i_same(struct f_inst *f1, struct f_inst *f2)
 | 
			
		||||
 * modified in place, old cached rta is possibly freed.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool, int flags)
 | 
			
		||||
f_run(struct filter *filter, struct rte **rte, struct linpool *tmp_pool, int flags)
 | 
			
		||||
{
 | 
			
		||||
  if (filter == FILTER_ACCEPT)
 | 
			
		||||
    return F_ACCEPT;
 | 
			
		||||
@@ -1755,7 +1754,6 @@ f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struc
 | 
			
		||||
 | 
			
		||||
  f_rte = rte;
 | 
			
		||||
  f_old_rta = NULL;
 | 
			
		||||
  f_tmp_attrs = tmp_attrs;
 | 
			
		||||
  f_pool = tmp_pool;
 | 
			
		||||
  f_flags = flags;
 | 
			
		||||
 | 
			
		||||
@@ -1797,11 +1795,9 @@ f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struc
 | 
			
		||||
struct f_val
 | 
			
		||||
f_eval_rte(struct f_inst *expr, struct rte **rte, struct linpool *tmp_pool)
 | 
			
		||||
{
 | 
			
		||||
  struct ea_list *tmp_attrs = NULL;
 | 
			
		||||
 | 
			
		||||
  f_rte = rte;
 | 
			
		||||
  f_old_rta = NULL;
 | 
			
		||||
  f_tmp_attrs = &tmp_attrs;
 | 
			
		||||
  f_pool = tmp_pool;
 | 
			
		||||
  f_flags = 0;
 | 
			
		||||
 | 
			
		||||
@@ -1810,9 +1806,6 @@ f_eval_rte(struct f_inst *expr, struct rte **rte, struct linpool *tmp_pool)
 | 
			
		||||
  /* Note that in this function we assume that rte->attrs is private / uncached */
 | 
			
		||||
  struct f_val res = interpret(expr);
 | 
			
		||||
 | 
			
		||||
  /* Hack to include EAF_TEMP attributes to the main list */
 | 
			
		||||
  (*rte)->attrs->eattrs = ea_append(tmp_attrs, (*rte)->attrs->eattrs);
 | 
			
		||||
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1820,7 +1813,6 @@ struct f_val
 | 
			
		||||
f_eval(struct f_inst *expr, struct linpool *tmp_pool)
 | 
			
		||||
{
 | 
			
		||||
  f_flags = 0;
 | 
			
		||||
  f_tmp_attrs = NULL;
 | 
			
		||||
  f_rte = NULL;
 | 
			
		||||
  f_pool = tmp_pool;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user