#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
/* 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. */
/* Human readable format string. */
char *str;
+
+ /* Disable IEEE floating-point encoding for extended community */
+ bool disable_ieee_floating;
};
struct ecommunity_as {
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)
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 *);
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 *);
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)
{
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 */