]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Merge commit '224a152c53f304881f8616a1c9255b467062a069' into thread-next
authorOndrej Zajicek <santiago@crfreenet.org>
Thu, 28 Mar 2024 15:22:23 +0000 (16:22 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Thu, 28 Mar 2024 15:22:23 +0000 (16:22 +0100)
1  2 
filter/config.Y
filter/f-inst.c
nest/rt-attr.c

diff --cc filter/config.Y
index 45444eb2c75a9474a8288a20877eff2d97259885,79786faa42260c2abd88050451203e9097c0acd1..353e27ae4c2bc3adba5b5d75fcbab68517ff65a4
@@@ -941,30 -933,18 +941,18 @@@ term
  
   | term_dot_method
  
 - | '+' EMPTY '+' { $$ = f_new_inst(FI_CONSTANT, val_empty(T_PATH)); }
 - | '-' EMPTY '-' { $$ = f_new_inst(FI_CONSTANT, val_empty(T_CLIST)); }
 - | '-' '-' EMPTY '-' '-' { $$ = f_new_inst(FI_CONSTANT, val_empty(T_ECLIST)); }
 - | '-' '-' '-' EMPTY '-' '-' '-' { $$ = f_new_inst(FI_CONSTANT, val_empty(T_LCLIST)); }
 + | '+' EMPTY '+' { $$ = f_new_inst(FI_CONSTANT, f_get_empty(T_PATH)); }
 + | '-' EMPTY '-' { $$ = f_new_inst(FI_CONSTANT, f_get_empty(T_CLIST)); }
 + | '-' '-' EMPTY '-' '-' { $$ = f_new_inst(FI_CONSTANT, f_get_empty(T_ECLIST)); }
 + | '-' '-' '-' EMPTY '-' '-' '-' { $$ = f_new_inst(FI_CONSTANT, f_get_empty(T_LCLIST)); }
  
-  | PREPEND '(' term ',' term ')' {
-      $$ = f_dispatch_method_x("prepend", $3->type, $3, $5);
-      cf_warn("prepend(x,y) function is deprecated, please use x.prepend(y)");
-    }
-  | ADD '(' term ',' term ')' {
-      $$ = f_dispatch_method_x("add", $3->type, $3, $5);
-      cf_warn("add(x,y) function is deprecated, please use x.add(y)");
-    }
-  | DELETE '(' term ',' term ')' {
-      $$ = f_dispatch_method_x("delete", $3->type, $3, $5);
-      cf_warn("delete(x,y) function is deprecated, please use x.delete(y)");
-    }
-  | FILTER '(' term ',' term ')' {
-      $$ = f_dispatch_method_x("filter", $3->type, $3, $5);
-      cf_warn("filter(x,y) function is deprecated, please use x.filter(y)");
-    }
+  | PREPEND '(' term ',' term ')' { $$ = f_dispatch_method_x("prepend", $3->type, $3, $5); }
+  | ADD '(' term ',' term ')' { $$ = f_dispatch_method_x("add", $3->type, $3, $5); }
+  | DELETE '(' term ',' term ')' { $$ = f_dispatch_method_x("delete", $3->type, $3, $5); }
+  | FILTER '(' term ',' term ')' { $$ = f_dispatch_method_x("filter", $3->type, $3, $5); }
  
 - | ROA_CHECK '(' rtable ')' { $$ = f_new_inst(FI_ROA_CHECK_IMPLICIT, $3); }
 - | ROA_CHECK '(' rtable ',' term ',' term ')' { $$ = f_new_inst(FI_ROA_CHECK_EXPLICIT, $5, $7, $3); }
 + | ROA_CHECK '(' rtable ')' { $$ = f_implicit_roa_check($3); }
 + | ROA_CHECK '(' rtable ',' term ',' term ')' { $$ = f_new_inst(FI_ROA_CHECK, $5, $7, $3); }
  
   | FORMAT '(' term ')' {  $$ = f_new_inst(FI_FORMAT, $3); }
  
diff --cc filter/f-inst.c
index dab6cdfb3a174f6502cb96d11bb7abab3226d2b4,a3f441fccfb7fffe3306c81b650aae7c1728c24f..2a6ef6cf86f6b7034790284860384bbd9cfea2fd
    }
  
    INST(FI_EA_GET, 1, 1) {     /* Access to extended attributes */
 -    ACCESS_RTE;
 -    ACCESS_EATTRS;
      ARG(1, T_ROUTE);
      DYNAMIC_ATTR;
 -    RESULT_TYPE(da.f_type);
 +    RESULT_TYPE(da->type);
      {
 -      struct ea_list *eal = v1.val.rte ? v1.val.rte->attrs->eattrs : *fs->eattrs;
 -      eattr *e = ea_find(eal, da.ea_code);
 +      struct f_val empty;
 +      const eattr *e = ea_find(v1.val.rte->attrs, da->id);
  
 -      if (!e) {
 -      RESULT_VAL(val_empty(da.f_type));
 -      break;
 -      }
 +      if (e)
 +      {
 +      ASSERT_DIE(e->type == da->type);
  
 -      switch (e->type & EAF_TYPE_MASK) {
 -      case EAF_TYPE_INT:
 -      RESULT_(da.f_type, i, e->u.data);
 -      break;
 -      case EAF_TYPE_ROUTER_ID:
 -      RESULT_(T_QUAD, i, e->u.data);
 -      break;
 -      case EAF_TYPE_OPAQUE:
 -      if (da.f_type == T_ENUM_EMPTY)
 -        RESULT_(T_ENUM_EMPTY, i, 0);
 -      else
 -        RESULT_(T_BYTESTRING, ad, e->u.ptr);
 -      break;
 -      case EAF_TYPE_IP_ADDRESS:
 -      RESULT_(T_IP, ip, *((ip_addr *) e->u.ptr->data));
 -      break;
 -      case EAF_TYPE_AS_PATH:
 -      RESULT_(T_PATH, ad, e->u.ptr);
 -      break;
 -      case EAF_TYPE_BITFIELD:
 -      RESULT_(T_BOOL, i, !!(e->u.data & (1u << da.bit)));
 -      break;
 -      case EAF_TYPE_INT_SET:
 -      RESULT_(T_CLIST, ad, e->u.ptr);
 -      break;
 -      case EAF_TYPE_EC_SET:
 -      RESULT_(T_ECLIST, ad, e->u.ptr);
 -      break;
 -      case EAF_TYPE_LC_SET:
 -      RESULT_(T_LCLIST, ad, e->u.ptr);
 -      break;
 -      case EAF_TYPE_STRING:
 -      RESULT_(T_STRING, s, (const char *) e->u.ptr->data);
 -      break;
 -      default:
 -      bug("Unknown dynamic attribute type");
 +      switch (e->type) {
 +        case T_IP:
 +          RESULT_(T_IP, ip, *((const ip_addr *) e->u.ptr->data));
 +          break;
++
++        case T_STRING:
++          RESULT_(T_STRING, s, (const char *) e->u.ptr->data);
++          break;
++
 +        default:
 +          RESULT_VAL([[(struct f_val) {
 +              .type = e->type,
 +              .val.bval = e->u,
 +              }]]);
 +      }
        }
 +      else if ((empty = f_get_empty(da->type)).type != T_VOID)
 +      RESULT_VAL(empty);
 +      else
 +      RESULT_VOID;
      }
    }
  
  
      FID_INTERPRET_BODY;
      {
 -      struct ea_list *l = lp_alloc(fs->pool, sizeof(struct ea_list) + sizeof(eattr));
 -
 -      l->next = NULL;
 -      l->flags = EALF_SORTED;
 -      l->count = 1;
 -      l->attrs[0].id = da.ea_code;
 -      l->attrs[0].flags = da.flags;
 -      l->attrs[0].type = da.type;
 -      l->attrs[0].originated = 1;
 -      l->attrs[0].fresh = 1;
 -      l->attrs[0].undef = 0;
 -
 -      switch (da.type) {
 -      case EAF_TYPE_INT:
 -      case EAF_TYPE_ROUTER_ID:
 -      l->attrs[0].u.data = v1.val.i;
 -      break;
 +      struct eattr *a;
  
 -      case EAF_TYPE_IP_ADDRESS:;
 -      int len = sizeof(ip_addr);
 -      struct adata *ad = lp_alloc(fs->pool, sizeof(struct adata) + len);
 -      ad->length = len;
 -      (* (ip_addr *) ad->data) = v1.val.ip;
 -      l->attrs[0].u.ptr = ad;
 -      break;
 +      if (da->type >= EAF_TYPE__MAX)
 +      bug("Unsupported attribute type");
  
 -      case EAF_TYPE_OPAQUE:
 -      case EAF_TYPE_AS_PATH:
 -      case EAF_TYPE_INT_SET:
 -      case EAF_TYPE_EC_SET:
 -      case EAF_TYPE_LC_SET:
 -      l->attrs[0].u.ptr = v1.val.ad;
 +      switch (da->type) {
 +      case T_IFACE:
 +      case T_OPAQUE:
 +      runtime( "Setting opaque attribute is not allowed" );
        break;
  
 -      case EAF_TYPE_STRING:;
 -      struct adata *d = lp_alloc_adata(fs->pool, strlen(v1.val.s) + 1);
 -      memcpy(d->data, v1.val.s, d->length);
 -      l->attrs[0].u.ptr = d;
 +      case T_IP:
 +      a = ea_set_attr(&fs->rte->attrs,
 +          EA_LITERAL_STORE_ADATA(da, 0, &v1.val.ip, sizeof(ip_addr)));
        break;
  
 -      case EAF_TYPE_BITFIELD:
 -      {
 -        /* First, we have to find the old value */
 -        eattr *e = ea_find(*fs->eattrs, da.ea_code);
 -        u32 data = e ? e->u.data : 0;
 -
 -        if (v1.val.i)
 -          l->attrs[0].u.data = data | (1u << da.bit);
 -        else
 -          l->attrs[0].u.data = data & ~(1u << da.bit);
 -      }
++      case T_STRING:
++      a = ea_set_attr(&fs->rte->attrs,
++          EA_LITERAL_STORE_ADATA(da, 0, &v1.val.s, strlen(v1.val.s) + 1));
+       break;
        default:
 -      bug("Unknown dynamic attribute type");
 +      a = ea_set_attr(&fs->rte->attrs,
 +          EA_LITERAL_GENERIC(da->id, da->type, 0, .u = v1.val.bval));
 +      break;
        }
  
 -      f_rta_cow(fs);
 -      l->next = *fs->eattrs;
 -      *fs->eattrs = l;
 +      a->originated = 1;
 +      a->fresh = 1;
      }
    }
  
diff --cc nest/rt-attr.c
index e29ded29fff2d1a1b686401f934b8dcaa0ed393a,c8ef8e081c69c27802c34a160a275515b67cd936..468b279d114679e9bd21966fc86d926a28beb15a
@@@ -1407,81 -953,78 +1407,84 @@@ ea_show(struct cli *c, const eattr *e
    byte buf[CLI_MSG_SIZE];
    byte *pos = buf, *end = buf + sizeof(buf);
  
 -  if (EA_IS_CUSTOM(e->id))
 -    {
 -      const char *name = ea_custom_name(e->id);
 -      if (name)
 -        {
 -        pos += bsprintf(pos, "%s", name);
 -        status = GA_NAME;
 -      }
 -      else
 -      pos += bsprintf(pos, "%02x.", EA_PROTO(e->id));
 -    }
 -  else if (p = class_to_protocol[EA_PROTO(e->id)])
 -    {
 -      pos += bsprintf(pos, "%s.", p->name);
 -      if (p->get_attr)
 -      status = p->get_attr(e, pos, end - pos);
 -      pos += strlen(pos);
 -    }
 -  else if (EA_PROTO(e->id))
 -    pos += bsprintf(pos, "%02x.", EA_PROTO(e->id));
 -  else
 -    status = get_generic_attr(e, &pos, end - pos);
 +  ASSERT_DIE(e->id < ea_class_max);
  
 -  if (status < GA_NAME)
 -    pos += bsprintf(pos, "%02x", EA_ID(e->id));
 -  if (status < GA_FULL)
 -    {
 -      *pos++ = ':';
 -      *pos++ = ' ';
 +  struct ea_class *cls = ea_class_global[e->id];
 +  ASSERT_DIE(cls);
 +
 +  if (e->undef || cls->hidden)
 +    return;
 +  else if (cls->format)
 +    cls->format(e, buf, end - buf);
 +  else
 +    switch (e->type)
 +      {
 +      case T_INT:
 +        if ((cls == &ea_gen_igp_metric) && e->u.data >= IGP_METRIC_UNKNOWN)
 +          return;
  
 -      if (e->undef)
 -      bsprintf(pos, "undefined");
 -      else
 -      switch (e->type & EAF_TYPE_MASK)
 -      {
 -      case EAF_TYPE_INT:
          bsprintf(pos, "%u", e->u.data);
          break;
 -      case EAF_TYPE_OPAQUE:
 +      case T_OPAQUE:
          opaque_format(ad, pos, end - pos);
          break;
 -      case EAF_TYPE_IP_ADDRESS:
 +      case T_IP:
          bsprintf(pos, "%I", *(ip_addr *) ad->data);
          break;
 -      case EAF_TYPE_ROUTER_ID:
 +      case T_QUAD:
          bsprintf(pos, "%R", e->u.data);
          break;
 -      case EAF_TYPE_AS_PATH:
 +      case T_PATH:
          as_path_format(ad, pos, end - pos);
          break;
 -      case EAF_TYPE_BITFIELD:
 -        bsprintf(pos, "%08x", e->u.data);
 -        break;
 -      case EAF_TYPE_INT_SET:
 -        ea_show_int_set(c, ad, 1, pos, buf, end);
 +      case T_CLIST:
 +        ea_show_int_set(c, cls->name, ad, 1, buf);
          return;
 -      case EAF_TYPE_EC_SET:
 -        ea_show_ec_set(c, ad, pos, buf, end);
 +      case T_ECLIST:
 +        ea_show_ec_set(c, cls->name, ad, buf);
          return;
 -      case EAF_TYPE_LC_SET:
 -        ea_show_lc_set(c, ad, pos, buf, end);
 +      case T_LCLIST:
 +        ea_show_lc_set(c, cls->name, ad, buf);
          return;
 -      case EAF_TYPE_STRING:
++      case T_STRING:
+         bsnprintf(pos, end - pos, "%s", (const char *) ad->data);
+         break;
 +      case T_NEXTHOP_LIST:
 +        ea_show_nexthop_list(c, (struct nexthop_adata *) e->u.ptr);
 +        return;
 +      case T_HOSTENTRY:
 +        ea_show_hostentry(ad, pos, end - pos);
 +        break;
        default:
          bsprintf(pos, "<type %02x>", e->type);
 -      }
 -    }
 +      }
  
 -  if (status != GA_HIDDEN)
 -    cli_printf(c, -1012, "\t%s", buf);
 +  cli_printf(c, -1012, "\t%s: %s", cls->name, buf);
 +}
 +
 +static void
 +nexthop_dump(const struct adata *ad)
 +{
 +  struct nexthop_adata *nhad = (struct nexthop_adata *) ad;
 +
 +  debug(":");
 +
 +  if (!NEXTHOP_IS_REACHABLE(nhad))
 +  {
 +    const char *name = rta_dest_name(nhad->dest);
 +    if (name)
 +      debug(" %s", name);
 +    else
 +      debug(" D%d", nhad->dest);
 +  }
 +  else NEXTHOP_WALK(nh, nhad)
 +    {
 +      if (ipa_nonzero(nh->gw)) debug(" ->%I", nh->gw);
 +      if (nh->labels) debug(" L %d", nh->label[0]);
 +      for (int i=1; i<nh->labels; i++)
 +      debug("/%d", nh->label[i]);
 +      debug(" [%s]", nh->iface ? nh->iface->name : "???");
 +    }
  }
  
  /**