]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BGP: Setting and unsetting unknown attributes kk-bgp-unknown-attributes
authorkaterina.kubecova <katerina.kubecova@nic.cz>
Tue, 19 Sep 2023 09:11:24 +0000 (11:11 +0200)
committerMaria Matejka <mq@ucw.cz>
Wed, 20 Sep 2023 12:15:18 +0000 (14:15 +0200)
All these must be declared as bytestring. Allows operators to delete
unwanted attributes breaking the Internet:

    https://blog.benjojo.co.uk/post/bgp-path-attributes-grave-error-handling

doc/bird.sgml
filter/data.h
filter/f-inst.c
filter/f-inst.h
proto/bgp/config.Y

index 3be266cbf3516f139af6932a52d9e30d99da3efd..366797ba75662e513aa2c0cbf41ef1dadf3f443d 100644 (file)
@@ -3287,6 +3287,13 @@ 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:
+
+<tt><label id="bgp-attribute-custom">attribute bgp <m/number/ bytestring <m/name/;</tt>
+
 <sect1>Example
 <label id="bgp-exam">
 
index 90e779c8c9b7dd210bb7e37b14c11e9eac49af87..3430455a55c5387bebfad646b29fbdb15ed30453 100644 (file)
@@ -99,6 +99,7 @@ struct f_dynamic_attr {
   u8 bit;              /* For bitfield accessors */
   enum f_type f_type;  /* Filter type */
   uint ea_code;                /* EA code */
+  uint flags;
 };
 
 enum f_sa_code {
index 510c431f1752e5639923800610c51e2c3705b280..a7bec81ed758331419f594f565b60deb9c8c86ae 100644 (file)
       l->flags = EALF_SORTED;
       l->count = 1;
       l->attrs[0].id = da.ea_code;
-      l->attrs[0].flags = 0;
+      l->attrs[0].flags = da.flags;
       l->attrs[0].type = da.type;
       l->attrs[0].originated = 1;
       l->attrs[0].fresh = 1;
index 2bde6378c30043c587e779a475cbe1f5e7aad569..955cfbdc76f43e0409ca35a43b76af0d7c04ce02 100644 (file)
@@ -118,6 +118,21 @@ static inline struct f_dynamic_attr f_new_dynamic_attr_bit(u8 bit, enum f_type f
 static inline struct f_static_attr f_new_static_attr(int f_type, int code, int readonly)
 { return (struct f_static_attr) { .f_type = f_type, .sa_code = code, .readonly = readonly }; }
 
+static inline int f_type_attr(int f_type) {
+  switch (f_type) {
+    case T_INT:                return EAF_TYPE_INT;
+    case T_IP:         return EAF_TYPE_IP_ADDRESS;
+    case T_QUAD:       return EAF_TYPE_ROUTER_ID;
+    case T_PATH:       return EAF_TYPE_AS_PATH;
+    case T_CLIST:      return EAF_TYPE_INT_SET;
+    case T_ECLIST:     return EAF_TYPE_EC_SET;
+    case T_LCLIST:     return EAF_TYPE_LC_SET;
+    case T_BYTESTRING: return EAF_TYPE_OPAQUE;
+    default:
+      cf_error("Custom route attribute of unsupported type");
+  }
+}
+
 /* Hook for call bt_assert() function in configuration */
 extern void (*bt_assert_hook)(int result, const struct f_line_item *assert);
 
index a1f1f5ac471f7155f02c95f3c154761c521e4a33..d9ff24d82b71f6ccecaab793a77ada3381ce80f1 100644 (file)
@@ -362,7 +362,16 @@ 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)
+    cf_error("Attribute type must be bytestring, not %s.", f_type_name($4));
+  struct f_dynamic_attr* a = (struct f_dynamic_attr*) malloc(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;
+  cf_define_symbol(new_config, $5, SYM_ATTRIBUTE, attribute, a);
+};
 
 CF_ENUM(T_ENUM_BGP_ORIGIN, ORIGIN_, IGP, EGP, INCOMPLETE)