diff options
Diffstat (limited to 'nest')
-rw-r--r-- | nest/Makefile | 7 | ||||
-rw-r--r-- | nest/a-path.c | 4 | ||||
-rw-r--r-- | nest/proto.c | 45 | ||||
-rw-r--r-- | nest/protocol.h | 4 | ||||
-rw-r--r-- | nest/route.h | 57 | ||||
-rw-r--r-- | nest/rt-attr.c | 22 | ||||
-rw-r--r-- | nest/rt-dev.c | 6 |
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); +} |