]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_ecommunity.h
zebra: clang-format style fixes
[mirror_frr.git] / bgpd / bgp_ecommunity.h
index 6d0275a0c3bab9a8b94c52207803cf39fd1184c9..4d7d4234a261ff6221c03dfceccce84968c6191b 100644 (file)
@@ -22,6 +22,7 @@
 #define _QUAGGA_BGP_ECOMMUNITY_H
 
 #include "bgpd/bgp_route.h"
+#include "bgpd/bgp_rpki.h"
 #include "bgpd/bgpd.h"
 
 /* Refer to rfc7153 for the IANA registry definitions. These are
@@ -51,6 +52,7 @@
 /* Note: This really depends on the high-order octet. This means that
  * multiple definitions for the same value are possible.
  */
+#define ECOMMUNITY_ORIGIN_VALIDATION_STATE  0x00
 #define ECOMMUNITY_ROUTE_TARGET             0x02
 #define ECOMMUNITY_SITE_ORIGIN              0x03
 #define ECOMMUNITY_LINK_BANDWIDTH           0x04
 #define ECOMMUNITY_SIZE                        8
 #define IPV6_ECOMMUNITY_SIZE                  20
 
+/* Extended Community Origin Validation State */
+enum ecommunity_origin_validation_states {
+       ECOMMUNITY_ORIGIN_VALIDATION_STATE_VALID,
+       ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTFOUND,
+       ECOMMUNITY_ORIGIN_VALIDATION_STATE_INVALID,
+       ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTUSED
+};
+
 /* Extended Communities type flag.  */
 #define ECOMMUNITY_FLAG_NON_TRANSITIVE      0x40
 
+/* Extended Community readable string length */
+#define ECOMMUNITY_STRLEN 64
+
 /* Extended Communities attribute.  */
 struct ecommunity {
        /* Reference counter.  */
@@ -121,6 +134,9 @@ struct ecommunity {
 
        /* Human readable format string.  */
        char *str;
+
+       /* Disable IEEE floating-point encoding for extended community */
+       bool disable_ieee_floating;
 };
 
 struct ecommunity_as {
@@ -195,13 +211,28 @@ static inline void encode_route_target_as4(as_t as, uint16_t val,
        eval->val[7] = val & 0xff;
 }
 
+/* Helper function to convert uint32 to IEEE-754 Floating Point */
+static uint32_t uint32_to_ieee_float_uint32(uint32_t u)
+{
+       union {
+               float r;
+               uint32_t d;
+       } f = {.r = (float)u};
+
+       return f.d;
+}
+
 /*
  * Encode BGP Link Bandwidth extended community
  *  bandwidth (bw) is in bytes-per-sec
  */
 static inline void encode_lb_extcomm(as_t as, uint32_t bw, bool non_trans,
-                                    struct ecommunity_val *eval)
+                                    struct ecommunity_val *eval,
+                                    bool disable_ieee_floating)
 {
+       uint32_t bandwidth =
+               disable_ieee_floating ? bw : uint32_to_ieee_float_uint32(bw);
+
        memset(eval, 0, sizeof(*eval));
        eval->val[0] = ECOMMUNITY_ENCODE_AS;
        if (non_trans)
@@ -209,18 +240,46 @@ static inline void encode_lb_extcomm(as_t as, uint32_t bw, bool non_trans,
        eval->val[1] = ECOMMUNITY_LINK_BANDWIDTH;
        eval->val[2] = (as >> 8) & 0xff;
        eval->val[3] = as & 0xff;
-       eval->val[4] = (bw >> 24) & 0xff;
-       eval->val[5] = (bw >> 16) & 0xff;
-       eval->val[6] = (bw >> 8) & 0xff;
-       eval->val[7] = bw & 0xff;
+       eval->val[4] = (bandwidth >> 24) & 0xff;
+       eval->val[5] = (bandwidth >> 16) & 0xff;
+       eval->val[6] = (bandwidth >> 8) & 0xff;
+       eval->val[7] = bandwidth & 0xff;
+}
+
+static inline void encode_origin_validation_state(enum rpki_states state,
+                                                 struct ecommunity_val *eval)
+{
+       enum ecommunity_origin_validation_states ovs_state =
+               ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTUSED;
+
+       switch (state) {
+       case RPKI_VALID:
+               ovs_state = ECOMMUNITY_ORIGIN_VALIDATION_STATE_VALID;
+               break;
+       case RPKI_NOTFOUND:
+               ovs_state = ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTFOUND;
+               break;
+       case RPKI_INVALID:
+               ovs_state = ECOMMUNITY_ORIGIN_VALIDATION_STATE_INVALID;
+               break;
+       case RPKI_NOT_BEING_USED:
+               break;
+       }
+
+       memset(eval, 0, sizeof(*eval));
+       eval->val[0] = ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS;
+       eval->val[1] = ECOMMUNITY_ORIGIN_VALIDATION_STATE;
+       eval->val[7] = ovs_state;
 }
 
 extern void ecommunity_init(void);
 extern void ecommunity_finish(void);
 extern void ecommunity_free(struct ecommunity **);
-extern struct ecommunity *ecommunity_parse(uint8_t *, unsigned short);
+extern struct ecommunity *ecommunity_parse(uint8_t *, unsigned short,
+                                          bool disable_ieee_floating);
 extern struct ecommunity *ecommunity_parse_ipv6(uint8_t *pnt,
-                                               unsigned short length);
+                                               unsigned short length,
+                                               bool disable_ieee_floating);
 extern struct ecommunity *ecommunity_dup(struct ecommunity *);
 extern struct ecommunity *ecommunity_merge(struct ecommunity *,
                                           struct ecommunity *);
@@ -234,6 +293,7 @@ extern struct ecommunity *ecommunity_str2com_ipv6(const char *str, int type,
                                                  int keyword_included);
 extern char *ecommunity_ecom2str(struct ecommunity *, int, int);
 extern void ecommunity_strfree(char **s);
+extern bool ecommunity_include(struct ecommunity *e1, struct ecommunity *e2);
 extern bool ecommunity_match(const struct ecommunity *,
                             const struct ecommunity *);
 extern char *ecommunity_str(struct ecommunity *);
@@ -278,7 +338,9 @@ extern void bgp_aggr_ecommunity_remove(void *arg);
 extern const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom,
                                                uint32_t *bw);
 extern struct ecommunity *ecommunity_replace_linkbw(as_t as,
-                               struct ecommunity *ecom, uint64_t cum_bw);
+                                                   struct ecommunity *ecom,
+                                                   uint64_t cum_bw,
+                                                   bool disable_ieee_floating);
 
 static inline void ecommunity_strip_rts(struct ecommunity *ecom)
 {
@@ -288,4 +350,7 @@ static inline void ecommunity_strip_rts(struct ecommunity *ecom)
        ecommunity_strip(ecom, ECOMMUNITY_ENCODE_IP, subtype);
        ecommunity_strip(ecom, ECOMMUNITY_ENCODE_AS4, subtype);
 }
+extern struct ecommunity *
+ecommunity_add_origin_validation_state(enum rpki_states rpki_state,
+                                      struct ecommunity *ecom);
 #endif /* _QUAGGA_BGP_ECOMMUNITY_H */