]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Merge remote-tracking branch 'origin/master' into thread-next
authorMaria Matejka <mq@ucw.cz>
Fri, 18 Jul 2025 11:17:54 +0000 (13:17 +0200)
committerMaria Matejka <mq@ucw.cz>
Fri, 18 Jul 2025 11:17:54 +0000 (13:17 +0200)
1  2 
conf/cf-lex.l
conf/confbase.Y
doc/bird.sgml
filter/config.Y
filter/data.c
filter/data.h
filter/f-inst.c
filter/test.conf
lib/string.h

diff --cc conf/cf-lex.l
Simple merge
diff --cc conf/confbase.Y
index 00bbabc9f85161d0966b3d8b9b12917d453f4ba3,27c422eabd53d5fd0170deedbc4668134d279928..565646dae82426a46ffa29b9e78d5158177bbeeb
@@@ -164,8 -158,7 +164,8 @@@ CF_DECL
  %nonassoc PREFIX_DUMMY
  %left AND OR
  %nonassoc '=' '<' '>' '~' GEQ LEQ NEQ NMA IMP PO PC
- %left '+' '-'
 +%left '|' '&'
+ %left '+' '-' PP
  %left '*' '/' '%'
  %left '!'
  %nonassoc '.'
diff --cc doc/bird.sgml
Simple merge
diff --cc filter/config.Y
index d2719637be45e5a056e157d8850ad696fad1877a,d4ffa204346e8b892ec176997612e4818ffc130e..585658b400a744190465a210eb1ac83939845450
@@@ -959,18 -945,21 +960,21 @@@ 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); }
+  | APPEND '(' term ',' term ')' { $$ = f_dispatch_method_x("append", $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); }
+  | term PP term { $$ = f_dispatch_method_x("append", $1->type, $1, $3); }
 + | ROA_CHECK '(' rtable ')' { $$ = f_implicit_roa_check($3); }
 + | ROA_CHECK '(' rtable ',' term ',' term ')' { $$ = f_new_inst(FI_ROA_CHECK, $5, $7, $3); }
   | ASPA_CHECK '(' rtable ',' term ',' term ')' { $$ = f_new_inst(FI_ASPA_CHECK_EXPLICIT, $5, $7, $3); }
  
   | FORMAT '(' term ')' {  $$ = f_new_inst(FI_FORMAT, $3); }
diff --cc filter/data.c
index 4dd09d07d48123089789ac88b9a1c18c61b105a9,9b052f894a5d5b95901e22eeac4ed5422c6e5b17..4b34c2c9b874699373c8ce3e9de898d25007d96c
@@@ -743,74 -669,14 +743,86 @@@ val_dump(const struct f_val *v) 
    return val_dump_buffer;
  }
  
 +struct f_val *
 +lp_val_copy(struct linpool *lp, const struct f_val *v)
 +{
 +  switch (v->type)
 +  {
 +    case T_VOID:
 +    case T_BOOL:
 +    case T_INT:
 +    case T_IP:
 +    case T_PAIR:
 +    case T_QUAD:
 +    case T_EC:
 +    case T_LC:
 +    case T_RD:
 +    case T_ENUM:
 +    case T_PATH_MASK_ITEM:
 +      /* These aren't embedded but there is no need to copy them */
 +    case T_SET:
 +    case T_PREFIX_SET:
 +    case T_PATH_MASK:
 +    case T_IFACE:
 +      {
 +      struct f_val *out = lp_alloc(lp, sizeof(*out));
 +      *out = *v;
 +      return out;
 +      }
 +
 +    case T_NET:
 +      {
 +      struct {
 +        struct f_val val;
 +        net_addr net[0];
 +      } *out = lp_alloc(lp, sizeof(*out) + v->val.net->length);
 +      out->val = *v;
 +      out->val.val.net = out->net;
 +      net_copy(out->net, v->val.net);
 +      return &out->val;
 +      }
 +
 +    case T_STRING:
 +      {
 +      uint len = strlen(v->val.s);
 +      struct {
 +        struct f_val val;
 +        char buf[0];
 +      } *out = lp_alloc(lp, sizeof(*out) + len + 1);
 +      out->val = *v;
 +      out->val.val.s = out->buf;
 +      memcpy(out->buf, v->val.s, len+1);
 +      return &out->val;
 +      }
 +
 +    case T_PATH:
 +    case T_CLIST:
 +    case T_ECLIST:
 +    case T_LCLIST:
 +      {
 +      struct {
 +        struct f_val val;
 +        struct adata ad;
 +      } *out = lp_alloc(lp, sizeof(*out) + v->val.ad->length);
 +      out->val = *v;
 +      out->val.val.ad = &out->ad;
 +      memcpy(&out->ad, v->val.ad, v->val.ad->length);
 +      return &out->val;
 +      }
 +
 +    default:
 +      bug("Unknown type in value copy: %d", v->type);
 +  }
 +}
++
+ const struct adata *
+ bytestring_append(struct linpool *pool, const struct adata *v1, const struct adata *v2)
+ {
+   if (!v1 || !v2)
+     return v1 ?: v2;
+   struct adata *res = lp_alloc_adata(pool, v1->length + v2->length);
+   memcpy(res->data, v1->data, v1->length);
+   memcpy(res->data + v1->length, v2->data, v2->length);
+   return res;
+ }
diff --cc filter/data.h
Simple merge
diff --cc filter/f-inst.c
Simple merge
Simple merge
diff --cc lib/string.h
index 7e04919510c1b935cb61ff0345ae243cf2d6659e,0107c5949e5103fb7af00077bb7cef662969f86e..0633a3c47045667f129c7a9c89f8bc8c6d96c430
@@@ -69,17 -66,17 +69,30 @@@ lp_strdup(linpool *lp, const char *c
    return z;
  }
  
 +#define tmp_strdup(x) lp_strdup(tmp_linpool, (x))
 +
 +static inline char *
 +mb_strdup(pool *p, const char *c)
 +{
 +  size_t l = strlen(c) + 1;
 +  char *z = mb_alloc(p, l);
 +  memcpy(z, c, l);
 +  return z;
 +}
 +
+ static inline char *
+ lp_strcat(linpool *lp, const char *s1, const char *s2)
+ {
+   size_t l1 = strlen(s1);
+   size_t l2 = strlen(s2);
+   char *z = lp_allocu(lp, l1 + l2 + 1);
+   memcpy(z, s1, l1);
+   memcpy(z + l1, s2, l2 + 1);
+   return z;
+ }
++#define tmp_strcat(x, y) lp_strcat(tmp_linpool, (x), (y))
++
  static inline void
  memset32(void *D, u32 val, uint n)
  {