summaryrefslogtreecommitdiff
path: root/nest
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2022-05-30 15:31:19 +0200
committerMaria Matejka <mq@ucw.cz>2022-05-30 15:31:19 +0200
commitd7b077f5d63625beaca1bcfe971e3b853dbfcc06 (patch)
tree7d0e8d62cca65ae2dd3d5e6231657f1e43630b5a /nest
parentd024f471ea5239a8cb6ce2ccd83b686a1d438aa5 (diff)
parent4a23ede2b056a41456790cc20a0c3d92a7137693 (diff)
Merge commit '4a23ede2b056a41456790cc20a0c3d92a7137693' into haugesund
Diffstat (limited to 'nest')
-rw-r--r--nest/Makefile7
-rw-r--r--nest/a-path.c4
-rw-r--r--nest/proto.c45
-rw-r--r--nest/protocol.h4
-rw-r--r--nest/route.h57
-rw-r--r--nest/rt-attr.c22
-rw-r--r--nest/rt-dev.c6
7 files changed, 76 insertions, 69 deletions
diff --git a/nest/Makefile b/nest/Makefile
index 884d3950..7d451ba4 100644
--- a/nest/Makefile
+++ b/nest/Makefile
@@ -1,7 +1,12 @@
-src := a-path.c a-set.c cli.c cmds.c iface.c locks.c neighbor.c password.c proto.c rt-attr.c rt-dev.c rt-fib.c rt-show.c rt-table.c
+src := a-path.c a-set.c cli.c cmds.c iface.c locks.c neighbor.c password.c proto.c proto-build.c rt-attr.c rt-dev.c rt-fib.c rt-show.c rt-table.c
obj := $(src-o-files)
$(all-daemon)
$(cf-local)
+$(call proto-build,dev_build)
+
+$(proto-build-c): $(lastword $(MAKEFILE_LIST))
+ $(E)echo GEN $@
+ $(Q)echo "$(patsubst %,void %(void); ,$(PROTO_BUILD)) void protos_build_gen(void) { $(patsubst %, %(); ,$(PROTO_BUILD))}" > $@
tests_src := a-set_test.c a-path_test.c
tests_targets := $(tests_targets) $(tests-target-files)
diff --git a/nest/a-path.c b/nest/a-path.c
index 2e34a3d1..badbc911 100644
--- a/nest/a-path.c
+++ b/nest/a-path.c
@@ -591,7 +591,7 @@ as_path_match_set(const struct adata *path, const struct f_tree *set)
p += 2;
for (i=0; i<n; i++)
{
- struct f_val v = {T_INT, .val.i = get_as(p)};
+ struct f_val v = { .type = T_INT, .val.i = get_as(p)};
if (find_tree(set, &v))
return 1;
p += BS;
@@ -631,7 +631,7 @@ as_path_filter(struct linpool *pool, const struct adata *path, const struct f_tr
if (set)
{
- struct f_val v = {T_INT, .val.i = as};
+ struct f_val v = { .type = T_INT, .val.i = as};
match = !!find_tree(set, &v);
}
else
diff --git a/nest/proto.c b/nest/proto.c
index 09582d2e..304451cb 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -23,9 +23,9 @@
#include "filter/f-inst.h"
pool *proto_pool;
-list proto_list;
+list STATIC_LIST_INIT(proto_list);
-static list protocol_list;
+static list STATIC_LIST_INIT(protocol_list);
struct protocol *class_to_protocol[PROTOCOL__MAX];
#define CD(c, msg, args...) ({ if (c->debug & D_STATES) log(L_TRACE "%s.%s: " msg, c->proto->name, c->name ?: "?", ## args); })
@@ -1757,6 +1757,8 @@ proto_build(struct protocol *p)
/* FIXME: convert this call to some protocol hook */
extern void bfd_init_all(void);
+void protos_build_gen(void);
+
/**
* protos_build - build a protocol list
*
@@ -1769,44 +1771,7 @@ extern void bfd_init_all(void);
void
protos_build(void)
{
- init_list(&proto_list);
- init_list(&protocol_list);
-
- proto_build(&proto_device);
-#ifdef CONFIG_RADV
- proto_build(&proto_radv);
-#endif
-#ifdef CONFIG_RIP
- proto_build(&proto_rip);
-#endif
-#ifdef CONFIG_STATIC
- proto_build(&proto_static);
-#endif
-#ifdef CONFIG_MRT
- proto_build(&proto_mrt);
-#endif
-#ifdef CONFIG_OSPF
- proto_build(&proto_ospf);
-#endif
-#ifdef CONFIG_PIPE
- proto_build(&proto_pipe);
-#endif
-#ifdef CONFIG_BGP
- proto_build(&proto_bgp);
-#endif
-#ifdef CONFIG_BFD
- proto_build(&proto_bfd);
- bfd_init_all();
-#endif
-#ifdef CONFIG_BABEL
- proto_build(&proto_babel);
-#endif
-#ifdef CONFIG_RPKI
- proto_build(&proto_rpki);
-#endif
-#ifdef CONFIG_PERF
- proto_build(&proto_perf);
-#endif
+ protos_build_gen();
proto_pool = rp_new(&root_pool, "Protocols");
proto_shutdown_timer = tm_new(proto_pool);
diff --git a/nest/protocol.h b/nest/protocol.h
index 7447cbf0..d813c91e 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -84,8 +84,8 @@ struct protocol {
void (*copy_config)(struct proto_config *, struct proto_config *); /* Copy config from given protocol instance */
};
-void protos_build(void);
-void proto_build(struct protocol *);
+void protos_build(void); /* Called from sysdep to initialize protocols */
+void proto_build(struct protocol *); /* Called from protocol to register itself */
void protos_preconfig(struct config *);
void protos_commit(struct config *new, struct config *old, int force_restart, int type);
struct proto * proto_spawn(struct proto_config *cf, uint disabled);
diff --git a/nest/route.h b/nest/route.h
index 1aba218b..61a5f623 100644
--- a/nest/route.h
+++ b/nest/route.h
@@ -664,7 +664,10 @@ static inline int rte_is_reachable(rte *r)
typedef struct eattr {
word id; /* EA_CODE(PROTOCOL_..., protocol-dependent ID) */
byte flags; /* Protocol-dependent flags */
- byte type; /* Attribute type and several flags (EAF_...) */
+ byte type:5; /* Attribute type */
+ byte originated:1; /* The attribute has originated locally */
+ byte fresh:1; /* An uncached attribute (e.g. modified in export filter) */
+ byte undef:1; /* Explicitly undefined */
union {
uintptr_t data;
const struct adata *ptr; /* Attribute data elsewhere */
@@ -700,11 +703,8 @@ const char *ea_custom_name(uint ea);
#define EAF_TYPE_PTR 0x0d /* Pointer to an object */
#define EAF_TYPE_EC_SET 0x0e /* Set of pairs of u32's - ext. community list */
#define EAF_TYPE_LC_SET 0x12 /* Set of triplets of u32's - large community list */
-#define EAF_TYPE_UNDEF 0x1f /* `force undefined' entry */
#define EAF_EMBEDDED 0x01 /* Data stored in eattr.u.data (part of type spec) */
#define EAF_VAR_LENGTH 0x02 /* Attribute length is variable (part of type spec) */
-#define EAF_ORIGINATED 0x20 /* The attribute has originated locally */
-#define EAF_FRESH 0x40 /* An uncached attribute (e.g. modified in export filter) */
typedef struct adata {
uint length; /* Length of data */
@@ -772,27 +772,50 @@ void ea_format_bitfield(const struct eattr *a, byte *buf, int bufsize, const cha
ea = NULL; \
} while(0) \
+struct ea_one_attr_list {
+ ea_list l;
+ eattr a;
+};
+
static inline eattr *
ea_set_attr(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, uintptr_t val)
{
- ea_list *a = lp_alloc(pool, sizeof(ea_list) + sizeof(eattr));
- eattr *e = &a->attrs[0];
+ struct ea_one_attr_list *ea = lp_alloc(pool, sizeof(*ea));
+ *ea = (struct ea_one_attr_list) {
+ .l.flags = EALF_SORTED,
+ .l.count = 1,
+ .l.next = *to,
- a->flags = EALF_SORTED;
- a->count = 1;
- a->next = *to;
- *to = a;
-
- e->id = id;
- e->type = type;
- e->flags = flags;
+ .a.id = id,
+ .a.type = type,
+ .a.flags = flags,
+ };
if (type & EAF_EMBEDDED)
- e->u.data = (u32) val;
+ ea->a.u.data = val;
else
- e->u.ptr = (struct adata *) val;
+ ea->a.u.ptr = (struct adata *) val;
+
+ *to = &ea->l;
- return e;
+ return &ea->a;
+}
+
+static inline void
+ea_unset_attr(ea_list **to, struct linpool *pool, _Bool local, uint code)
+{
+ struct ea_one_attr_list *ea = lp_alloc(pool, sizeof(*ea));
+ *ea = (struct ea_one_attr_list) {
+ .l.flags = EALF_SORTED,
+ .l.count = 1,
+ .l.next = *to,
+ .a.id = code,
+ .a.fresh = local,
+ .a.originated = local,
+ .a.undef = 1,
+ };
+
+ *to = &ea->l;
}
static inline void
diff --git a/nest/rt-attr.c b/nest/rt-attr.c
index 863d411b..22b45db9 100644
--- a/nest/rt-attr.c
+++ b/nest/rt-attr.c
@@ -448,8 +448,7 @@ ea_find(ea_list *e, unsigned id)
{
eattr *a = ea__find(e, id & EA_CODE_MASK);
- if (a && (a->type & EAF_TYPE_MASK) == EAF_TYPE_UNDEF &&
- !(id & EA_ALLOW_UNDEF))
+ if (a && a->undef && !(id & EA_ALLOW_UNDEF))
return NULL;
return a;
}
@@ -516,7 +515,7 @@ ea_walk(struct ea_walk_state *s, uint id, uint max)
BIT32_SET(s->visited, n);
- if ((a->type & EAF_TYPE_MASK) == EAF_TYPE_UNDEF)
+ if (a->undef)
continue;
s->eattrs = e;
@@ -616,14 +615,17 @@ ea_do_prune(ea_list *e)
/* Now s0 is the most recent version, s[-1] the oldest one */
/* Drop undefs */
- if ((s0->type & EAF_TYPE_MASK) == EAF_TYPE_UNDEF)
+ if (s0->undef)
continue;
/* Copy the newest version to destination */
*d = *s0;
/* Preserve info whether it originated locally */
- d->type = (d->type & ~(EAF_ORIGINATED|EAF_FRESH)) | (s[-1].type & EAF_ORIGINATED);
+ d->originated = s[-1].originated;
+
+ /* Not fresh any more, we prefer surstroemming */
+ d->fresh = 0;
/* Next destination */
d++;
@@ -737,6 +739,9 @@ ea_same(ea_list *x, ea_list *y)
if (a->id != b->id ||
a->flags != b->flags ||
a->type != b->type ||
+ a->originated != b->originated ||
+ a->fresh != b->fresh ||
+ a->undef != b->undef ||
((a->type & EAF_EMBEDDED) ? a->u.data != b->u.data : !adata_same(a->u.ptr, b->u.ptr)))
return 0;
}
@@ -939,6 +944,10 @@ ea_show(struct cli *c, const eattr *e)
{
*pos++ = ':';
*pos++ = ' ';
+
+ if (e->undef)
+ bsprintf(pos, "undefined");
+ else
switch (e->type & EAF_TYPE_MASK)
{
case EAF_TYPE_INT:
@@ -968,7 +977,6 @@ ea_show(struct cli *c, const eattr *e)
case EAF_TYPE_LC_SET:
ea_show_lc_set(c, ad, pos, buf, end);
return;
- case EAF_TYPE_UNDEF:
default:
bsprintf(pos, "<type %02x>", e->type);
}
@@ -1004,7 +1012,7 @@ ea_dump(ea_list *e)
eattr *a = &e->attrs[i];
debug(" %02x:%02x.%02x", EA_PROTO(a->id), EA_ID(a->id), a->flags);
debug("=%c", "?iO?I?P???S?????" [a->type & EAF_TYPE_MASK]);
- if (a->type & EAF_ORIGINATED)
+ if (a->originated)
debug("o");
if (a->type & EAF_EMBEDDED)
debug(":%08x", a->u.data);
diff --git a/nest/rt-dev.c b/nest/rt-dev.c
index 5d1e57b3..129c724f 100644
--- a/nest/rt-dev.c
+++ b/nest/rt-dev.c
@@ -194,3 +194,9 @@ struct protocol proto_device = {
.reconfigure = dev_reconfigure,
.copy_config = dev_copy_config
};
+
+void
+dev_build(void)
+{
+ proto_build(&proto_device);
+}