summaryrefslogtreecommitdiff
path: root/nest
diff options
context:
space:
mode:
Diffstat (limited to 'nest')
-rw-r--r--nest/route.h5
-rw-r--r--nest/rt-attr.c29
2 files changed, 33 insertions, 1 deletions
diff --git a/nest/route.h b/nest/route.h
index 5ee04a30..fccc571b 100644
--- a/nest/route.h
+++ b/nest/route.h
@@ -417,13 +417,15 @@ typedef struct eattr {
#define EA_CODE_MASK 0xffff
#define EA_ALLOW_UNDEF 0x10000 /* ea_find: allow EAF_TYPE_UNDEF */
+#define EA_BIT(n) ((n) << 24) /* Used in bitfield accessors */
#define EAF_TYPE_MASK 0x0f /* Mask with this to get type */
-#define EAF_TYPE_INT 0x01 /* 32-bit signed integer number */
+#define EAF_TYPE_INT 0x01 /* 32-bit unsigned integer number */
#define EAF_TYPE_OPAQUE 0x02 /* Opaque byte string (not filterable) */
#define EAF_TYPE_IP_ADDRESS 0x04 /* IP address */
#define EAF_TYPE_ROUTER_ID 0x05 /* Router ID (IPv4 address) */
#define EAF_TYPE_AS_PATH 0x06 /* BGP AS path (encoding per RFC 1771:4.3) */
+#define EAF_TYPE_BITFIELD 0x09 /* 32-bit embedded bitfield */
#define EAF_TYPE_INT_SET 0x0a /* Set of u32's (e.g., a community list) */
#define EAF_TYPE_EC_SET 0x0e /* Set of pairs of u32's - ext. community list */
#define EAF_TYPE_UNDEF 0x0f /* `force undefined' entry */
@@ -469,6 +471,7 @@ void ea_merge(ea_list *from, ea_list *to); /* Merge sub-lists to allocated buffe
int ea_same(ea_list *x, ea_list *y); /* Test whether two ea_lists are identical */
unsigned int ea_hash(ea_list *e); /* Calculate 16-bit hash value */
ea_list *ea_append(ea_list *to, ea_list *what);
+void ea_format_bitfield(struct eattr *a, byte *buf, int bufsize, const char **names, int min, int max);
int mpnh__same(struct mpnh *x, struct mpnh *y); /* Compare multipath nexthops */
static inline int mpnh_same(struct mpnh *x, struct mpnh *y)
diff --git a/nest/rt-attr.c b/nest/rt-attr.c
index 09691bf1..938b2b44 100644
--- a/nest/rt-attr.c
+++ b/nest/rt-attr.c
@@ -563,6 +563,32 @@ get_generic_attr(eattr *a, byte **buf, int buflen UNUSED)
return GA_UNKNOWN;
}
+void
+ea_format_bitfield(struct eattr *a, byte *buf, int bufsize, const char **names, int min, int max)
+{
+ byte *bound = buf + bufsize - 32;
+ u32 data = a->u.data;
+ int i;
+
+ for (i = min; i < max; i++)
+ if ((data & (1u << i)) && names[i])
+ {
+ if (buf > bound)
+ {
+ strcpy(buf, " ...");
+ return;
+ }
+
+ buf += bsprintf(buf, " %s", names[i]);
+ data &= ~(1u << i);
+ }
+
+ if (data)
+ bsprintf(buf, " %08x", data);
+
+ return;
+}
+
static inline void
opaque_format(struct adata *ad, byte *buf, unsigned int size)
{
@@ -665,6 +691,9 @@ ea_show(struct cli *c, eattr *e)
case EAF_TYPE_AS_PATH:
as_path_format(ad, pos, end - pos);
break;
+ case EAF_TYPE_BITFIELD:
+ bsprintf(pos, "%08x", e->u.data);
+ break;
case EAF_TYPE_INT_SET:
ea_show_int_set(c, ad, 1, pos, buf, end);
return;