summaryrefslogtreecommitdiff
path: root/proto
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2023-10-05 21:29:04 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2023-10-05 21:54:25 +0200
commit57aa077227d1f2440dc1b2bb6cbbebd418a6b898 (patch)
tree6fa256de15ca415262cfaeb7c4e0cc61cca3cdd1 /proto
parentba01a6f2e66d03eb5d9426fdf4973f30e09c5710 (diff)
BGP: Improve custom BGP attributes
- Implement EA_GET for custom BGP attributes - Forbid EA_SET on existing opaque attributes - Forbid redefining existing attributes - Document possible compatibility problems
Diffstat (limited to 'proto')
-rw-r--r--proto/bgp/attrs.c6
-rw-r--r--proto/bgp/bgp.h1
-rw-r--r--proto/bgp/config.Y11
3 files changed, 14 insertions, 4 deletions
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
index 9387ddba..4346cd5d 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -1152,6 +1152,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 1ba3de5e..2e95037c 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 4e7d0329..6981a117 100644
--- a/proto/bgp/config.Y
+++ b/proto/bgp/config.Y
@@ -365,11 +365,14 @@ dynamic_attr: BGP_LARGE_COMMUNITY
dynamic_attr: BGP_OTC
{ $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_CODE(PROTOCOL_BGP, BA_ONLY_TO_CUSTOMER)); } ;
-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;