summaryrefslogtreecommitdiff
path: root/nest
diff options
context:
space:
mode:
authorMaria Matejka <mq@jmq.cz>2018-11-21 20:37:11 +0100
committerJan Maria Matejka <mq@ucw.cz>2018-12-06 09:55:21 +0100
commit265419a3695b9a5c0a01d9fffc60f66fea8bee13 (patch)
tree069d7d7ba9cc5ef23c8babbcd8947e42448dd724 /nest
parent0642fb4d456fe12e1bbeb2ffc2149433f228c02e (diff)
Custom route attributes
For local route marking purposes, local custom route attributes may be defined. These attributes are seamlessly stripped after export filter to every real protocol like Kernel, BGP or OSPF, they however pass through pipes. We currently allow at most 256 custom attributes. This should be much faster than currently used bgp communities for marking routes.
Diffstat (limited to 'nest')
-rw-r--r--nest/config.Y4
-rw-r--r--nest/route.h9
-rw-r--r--nest/rt-attr.c13
3 files changed, 21 insertions, 5 deletions
diff --git a/nest/config.Y b/nest/config.Y
index 88f74b96..34bde3fa 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -532,6 +532,7 @@ r_args:
$$ = cfg_allocz(sizeof(struct rt_show_data));
init_list(&($$->tables));
$$->filter = FILTER_ACCEPT;
+ $$->running_on_config = new_config->fallback;
}
| r_args net_any {
$$ = $1;
@@ -586,7 +587,6 @@ r_args:
if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
$$->export_mode = $2;
$$->export_protocol = c->proto;
- $$->running_on_config = c->proto->cf->global;
$$->tables_defined_by = RSD_TDB_INDIRECT;
}
| r_args export_mode SYM '.' r_args_channel {
@@ -597,7 +597,6 @@ r_args:
$$->export_mode = $2;
$$->export_channel = proto_find_channel_by_name(c->proto, $5);
if (!$$->export_channel) cf_error("Export channel not found");
- $$->running_on_config = c->proto->cf->global;
$$->tables_defined_by = RSD_TDB_INDIRECT;
}
| r_args PROTOCOL SYM {
@@ -606,7 +605,6 @@ r_args:
if ($$->show_protocol) cf_error("Protocol specified twice");
if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
$$->show_protocol = c->proto;
- $$->running_on_config = c->proto->cf->global;
$$->tables_defined_by = RSD_TDB_INDIRECT;
}
| r_args STATS {
diff --git a/nest/route.h b/nest/route.h
index 080bbf58..2600f087 100644
--- a/nest/route.h
+++ b/nest/route.h
@@ -471,13 +471,20 @@ typedef struct eattr {
} u;
} eattr;
+
#define EA_CODE(proto,id) (((proto) << 8) | (id))
-#define EA_PROTO(ea) ((ea) >> 8)
#define EA_ID(ea) ((ea) & 0xff)
+#define EA_PROTO(ea) ((ea) >> 8)
+#define EA_CUSTOM(id) ((id) | EA_CUSTOM_BIT)
+#define EA_IS_CUSTOM(ea) ((ea) & EA_CUSTOM_BIT)
+#define EA_CUSTOM_ID(ea) ((ea) & ~EA_CUSTOM_BIT)
+
+const char *ea_custom_name(uint ea);
#define EA_GEN_IGP_METRIC EA_CODE(PROTOCOL_NONE, 0)
#define EA_CODE_MASK 0xffff
+#define EA_CUSTOM_BIT 0x8000
#define EA_ALLOW_UNDEF 0x10000 /* ea_find: allow EAF_TYPE_UNDEF */
#define EA_BIT(n) ((n) << 24) /* Used in bitfield accessors */
diff --git a/nest/rt-attr.c b/nest/rt-attr.c
index 7a91a4f6..eeeaaa4c 100644
--- a/nest/rt-attr.c
+++ b/nest/rt-attr.c
@@ -884,7 +884,18 @@ ea_show(struct cli *c, eattr *e)
byte buf[CLI_MSG_SIZE];
byte *pos = buf, *end = buf + sizeof(buf);
- if (p = class_to_protocol[EA_PROTO(e->id)])
+ if (EA_IS_CUSTOM(e->id))
+ {
+ const char *name = ea_custom_name(e->id);
+ if (name)
+ {
+ pos += bsprintf(pos, "%s", name);
+ status = GA_NAME;
+ }
+ else
+ pos += bsprintf(pos, "%02x.", EA_PROTO(e->id));
+ }
+ else if (p = class_to_protocol[EA_PROTO(e->id)])
{
pos += bsprintf(pos, "%s.", p->name);
if (p->get_attr)