summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikael Magnusson <mikma@users.sourceforge.net>2023-11-25 23:44:31 +0100
committerMikael Magnusson <mikma@users.sourceforge.net>2023-11-25 23:44:31 +0100
commit1f37906b6ee33a8c7d0ff1b7ada5eb0dcb005072 (patch)
tree1fa785bfb77db3f1dc94fce8425ecb88649b7972
parent9a54c5affeb836b64a1952d0ef75fd88301ae899 (diff)
parent57aa077227d1f2440dc1b2bb6cbbebd418a6b898 (diff)
Merge commit '57aa0772' into wireguard-next-tmp7-1
-rw-r--r--doc/bird.sgml12
-rw-r--r--filter/f-inst.c11
-rw-r--r--proto/bgp/attrs.c6
-rw-r--r--proto/bgp/bgp.h1
-rw-r--r--proto/bgp/config.Y11
5 files changed, 32 insertions, 9 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml
index a023473f..5e795450 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -3561,10 +3561,14 @@ some of them (marked with `<tt/O/') are optional.
name="local role"> is configured it set automatically.
</descrip>
-<p>For attributes unknown by BIRD, the user can assign a name (on top level)
-to an attribute by its number. This defined name can be used then to both set
-(by a bytestring literal, transitive) or unset the given attribute even though
-BIRD knows nothing about it:
+<p>For attributes unknown by BIRD, the user can assign a name (on top level) to
+an attribute by its number. This defined name can be used then to get, set (as a
+bytestring, transitive) or unset the given attribute even though BIRD knows
+nothing about it.
+
+<p>Note that it is not possible to define an attribute with the same number
+as one known by BIRD, therefore use of this statement carries a risk of
+incompatibility with future BIRD versions.
<tt><label id="bgp-attribute-custom">attribute bgp <m/number/ bytestring <m/name/;</tt>
diff --git a/filter/f-inst.c b/filter/f-inst.c
index 739cbf5d..6eccd86b 100644
--- a/filter/f-inst.c
+++ b/filter/f-inst.c
@@ -838,7 +838,10 @@
RESULT_(T_QUAD, i, e->u.data);
break;
case EAF_TYPE_OPAQUE:
- RESULT_(T_ENUM_EMPTY, i, 0);
+ 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));
@@ -878,6 +881,12 @@
ARG_ANY(1);
DYNAMIC_ATTR;
ARG_TYPE(1, da.f_type);
+
+ FID_NEW_BODY;
+ if (da.f_type == T_ENUM_EMPTY)
+ cf_error("Setting opaque attribute is not allowed");
+
+ FID_INTERPRET_BODY;
{
struct ea_list *l = lp_alloc(fs->pool, sizeof(struct ea_list) + sizeof(eattr));
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
index dc764331..c6d5312c 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -1195,6 +1195,12 @@ bgp_attr_known(uint code)
return (code < ARRAY_SIZE(bgp_attr_table)) && bgp_attr_table[code].name;
}
+const char *
+bgp_attr_name(uint code)
+{
+ return (code < ARRAY_SIZE(bgp_attr_table)) ? bgp_attr_table[code].name : NULL;
+}
+
void bgp_fix_attr_flags(ea_list *attrs)
{
for (u8 i = 0; i < attrs->count; i++)
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index d8baf416..3de9aed5 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -611,6 +611,7 @@ bgp_unset_attr(ea_list **to, struct linpool *pool, uint code)
int bgp_encode_mp_reach_mrt(struct bgp_write_state *s, eattr *a, byte *buf, uint size);
+const char * bgp_attr_name(uint code);
int bgp_encode_attrs(struct bgp_write_state *s, ea_list *attrs, byte *buf, byte *end);
ea_list * bgp_decode_attrs(struct bgp_parse_state *s, byte *data, uint len);
void bgp_finish_attrs(struct bgp_parse_state *s, rta *a);
diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y
index 912ff05f..f0605924 100644
--- a/proto/bgp/config.Y
+++ b/proto/bgp/config.Y
@@ -367,11 +367,14 @@ dynamic_attr: BGP_OTC
dynamic_attr: BGP_TUNNEL_ENCAP
{ $$ = f_new_dynamic_attr(EAF_TYPE_TUNNEL_ENCAP, T_TLVLIST, EA_CODE(PROTOCOL_BGP, BA_TUNNEL_ENCAP)); } ;
-custom_attr: ATTRIBUTE BGP NUM type symbol ';' {
- if($3 > 255 || $3 < 1)
- cf_error("Invalid attribute number. (Given %i, must be 1-255.)", $3);
- if($4 != T_BYTESTRING)
+custom_attr: ATTRIBUTE BGP expr type symbol ';' {
+ if ($3 > 255 || $3 < 1)
+ cf_error("Invalid attribute number (Given %i, must be 1-255)", $3);
+ if ($4 != T_BYTESTRING)
cf_error("Attribute type must be bytestring, not %s", f_type_name($4));
+ if (bgp_attr_name($3))
+ cf_error("Attribute BGP.%d already known as %s", $3, bgp_attr_name($3));
+
struct f_dynamic_attr *a = cfg_alloc(sizeof(struct f_dynamic_attr));
*a = f_new_dynamic_attr(f_type_attr($4), T_BYTESTRING, EA_CODE(PROTOCOL_BGP, $3));
a->flags = BAF_TRANSITIVE | BAF_OPTIONAL;