diff options
41 files changed, 567 insertions, 508 deletions
diff --git a/Makefile.in b/Makefile.in index eb6cc5c9..8f6c0c8b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -95,7 +95,7 @@ clean = $(eval $(call clean_in,$(1))) include $(addsuffix /Makefile,$(addprefix $(srcdir)/,$(dirs))) # Generic rules - +# Object file rules $(objdir)/%.o: $(srcdir)/%.c $(objdir)/.dir-stamp $(objdir)/sysdep/paths.h $(E)echo CC -o $@ -c $< $(Q)$(CC) $(CFLAGS) -MMD -MP -o $@ -c $< @@ -104,7 +104,16 @@ $(objdir)/%.o: $(objdir)/%.c $(objdir)/.dir-stamp $(objdir)/sysdep/paths.h $(E)echo CC -o $@ -c $< $(Q)$(CC) $(CFLAGS) -MMD -MP -o $@ -c $< +# Debug: Preprocessed source rules +$(objdir)/%.E: $(srcdir)/%.c $(objdir)/.dir-stamp $(objdir)/sysdep/paths.h + $(E)echo CC -o $@ -E $< + $(Q)$(CC) $(CFLAGS) -MMD -MP -o $@ -E $< + +$(objdir)/%.E: $(objdir)/%.c $(objdir)/.dir-stamp $(objdir)/sysdep/paths.h + $(E)echo CC -o $@ -E $< + $(Q)$(CC) $(CFLAGS) -MMD -MP -o $@ -E $< +# Debug: Assembler object rules $(objdir)/%.S: $(srcdir)/%.c $(objdir)/.dir-stamp $(objdir)/sysdep/paths.h $(E)echo CC -o $@ -S $< $(Q)$(CC) $(CFLAGS) -MMD -MP -o $@ -S $< diff --git a/filter/config.Y b/filter/config.Y index e01e02ef..cf499b66 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -304,12 +304,10 @@ f_generate_lc(struct f_inst *t1, struct f_inst *t2, struct f_inst *t3) } else { - rv = cfg_allocz(sizeof(struct f_inst3)); - rv->lineno = ifs->lino; - rv->fi_code = FI_LC_CONSTRUCT; + rv = f_new_inst(FI_LC_CONSTRUCT); rv->a1.p = t1; rv->a2.p = t2; - INST3(rv).p = t3; + rv->a3.p = t3; } return rv; diff --git a/filter/f-util.c b/filter/f-util.c index 68aecd73..6170760b 100644 --- a/filter/f-util.c +++ b/filter/f-util.c @@ -77,6 +77,22 @@ f_generate_roa_check(struct rtable_config *table, struct f_inst *prefix, struct return &ret->i; } +static const char * const f_instruction_name_str[] = { +#define F(c,a,b) \ + [c] = #c, +FI__LIST +#undef F +}; + +const char * +f_instruction_name(enum f_instruction_code fi) +{ + if (fi < FI__MAX) + return f_instruction_name_str[fi]; + else + bug("Got unknown instruction code: %d", fi); +} + char * filter_name(struct filter *filter) { diff --git a/filter/filter.c b/filter/filter.c index 3d7b5c9f..6290e74a 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -538,14 +538,23 @@ val_format(struct f_val v, buffer *buf) static struct rte **f_rte; static struct rta *f_old_rta; -static struct ea_list **f_tmp_attrs; +static struct ea_list **f_eattrs; static struct linpool *f_pool; static struct buffer f_buf; static int f_flags; +static inline void f_cache_eattrs(void) +{ + f_eattrs = &((*f_rte)->attrs->eattrs); +} + static inline void f_rte_cow(void) { - *f_rte = rte_cow(*f_rte); + if (!((*f_rte)->flags & REF_COW)) + return; + + *f_rte = rte_do_cow(*f_rte); + f_eattrs = NULL; } /* @@ -570,6 +579,9 @@ f_rta_cow(void) * suppose hostentry is not changed by filters). */ (*f_rte)->attrs = rta_do_cow((*f_rte)->attrs, f_pool); + + /* Re-cache the ea_list */ + f_cache_eattrs(); } static char * @@ -590,19 +602,23 @@ static struct tbf rl_runtime_err = TBF_DEFAULT_LOG_LIMITS; return res; \ } while(0) -#define ARG(x,y) \ - x = interpret(what->y); \ - if (x.type & T_RETURN) \ - return x; - -#define ONEARG ARG(v1, a1.p) -#define TWOARGS ARG(v1, a1.p) \ - ARG(v2, a2.p) -#define TWOARGS_C TWOARGS \ - if (v1.type != v2.type) \ - runtime( "Can't operate with values of incompatible types" ); +#define ARG_ANY(n) INTERPRET(v##n, what->a##n.p) + +#define ARG(n,t) ARG_ANY(n) \ + if (v##n.type != t) \ + runtime("Argument %d of instruction %s must be of type %02x, got %02x", \ + n, f_instruction_name(what->fi_code), t, v##n.type); + +#define INTERPRET(val, what_) \ + val = interpret(what_); \ + if (val.type & T_RETURN) \ + return val; + #define ACCESS_RTE \ - do { if (!f_rte) runtime("No route to access"); } while (0) + do { if (!f_rte) runtime("No route to access"); else f_cache_eattrs(); } while (0) + +#define ACCESS_EATTRS \ + do { if (!f_eattrs) f_cache_eattrs(); } while (0) #define BITFIELD_MASK(what) \ (1u << (what->a2.i >> 24)) @@ -628,7 +644,7 @@ static struct f_val interpret(struct f_inst *what) { struct symbol *sym; - struct f_val v1, v2, res = { .type = T_VOID }, *vp; + struct f_val v1, v2, v3, res = { .type = T_VOID }, *vp; unsigned u1, u2; int i; u32 as; @@ -638,61 +654,44 @@ interpret(struct f_inst *what) switch(what->fi_code) { /* Binary operators */ case FI_ADD: - TWOARGS_C; - switch (res.type = v1.type) { - case T_VOID: runtime( "Can't operate with values of type void" ); - case T_INT: res.val.i = v1.val.i + v2.val.i; break; - default: runtime( "Usage of unknown type" ); - } + ARG(1,T_INT); + ARG(2,T_INT); + res.type = T_INT; + res.val.i = v1.val.i + v2.val.i; break; case FI_SUBTRACT: - TWOARGS_C; - switch (res.type = v1.type) { - case T_VOID: runtime( "Can't operate with values of type void" ); - case T_INT: res.val.i = v1.val.i - v2.val.i; break; - default: runtime( "Usage of unknown type" ); - } + ARG(1,T_INT); + ARG(2,T_INT); + res.type = T_INT; + res.val.i = v1.val.i - v2.val.i; break; case FI_MULTIPLY: - TWOARGS_C; - switch (res.type = v1.type) { - case T_VOID: runtime( "Can't operate with values of type void" ); - case T_INT: res.val.i = v1.val.i * v2.val.i; break; - default: runtime( "Usage of unknown type" ); - } + ARG(1,T_INT); + ARG(2,T_INT); + res.type = T_INT; + res.val.i = v1.val.i * v2.val.i; break; case FI_DIVIDE: - TWOARGS_C; - switch (res.type = v1.type) { - case T_VOID: runtime( "Can't operate with values of type void" ); - case T_INT: if (v2.val.i == 0) runtime( "Mother told me not to divide by 0" ); - res.val.i = v1.val.i / v2.val.i; break; - default: runtime( "Usage of unknown type" ); - } + ARG(1,T_INT); + ARG(2,T_INT); + res.type = T_INT; + if (v2.val.i == 0) runtime( "Mother told me not to divide by 0" ); + res.val.i = v1.val.i / v2.val.i; break; - case FI_AND: case FI_OR: - ARG(v1, a1.p); - if (v1.type != T_BOOL) - runtime( "Can't do boolean operation on non-booleans" ); + ARG(1,T_BOOL); if (v1.val.i == (what->fi_code == FI_OR)) { res.type = T_BOOL; res.val.i = v1.val.i; - break; + } else { + ARG(2,T_BOOL); + res = v2; } - - ARG(v2, a2.p); - if (v2.type != T_BOOL) - runtime( "Can't do boolean operation on non-booleans" ); - res.type = T_BOOL; - res.val.i = v2.val.i; break; - case FI_PAIR_CONSTRUCT: - TWOARGS; - if ((v1.type != T_INT) || (v2.type != T_INT)) - runtime( "Can't operate with value of non-integer type in pair constructor" ); + ARG(1,T_INT); + ARG(2,T_INT); u1 = v1.val.i; u2 = v2.val.i; if ((u1 > 0xFFFF) || (u2 > 0xFFFF)) @@ -703,7 +702,8 @@ interpret(struct f_inst *what) case FI_EC_CONSTRUCT: { - TWOARGS; + ARG_ANY(1); + ARG(2, T_INT); int check, ipv4_used; u32 key, val; @@ -721,8 +721,6 @@ interpret(struct f_inst *what) else runtime("Can't operate with key of non-integer/IPv4 type in EC constructor"); - if (v2.type != T_INT) - runtime("Can't operate with value of non-integer type in EC constructor"); val = v2.val.i; /* XXXX */ @@ -749,15 +747,9 @@ interpret(struct f_inst *what) case FI_LC_CONSTRUCT: { - TWOARGS; - - /* Third argument hack */ - struct f_val v3 = interpret(INST3(what).p); - if (v3.type & T_RETURN) - return v3; - - if ((v1.type != T_INT) || (v2.type != T_INT) || (v3.type != T_INT)) - runtime( "Can't operate with value of non-integer type in LC constructor" ); + ARG(1, T_INT); + ARG(2, T_INT); + ARG(3, T_INT); res.type = T_LC; res.val.lc = (lcomm) { v1.val.i, v2.val.i, v3.val.i }; @@ -772,7 +764,8 @@ interpret(struct f_inst *what) while (tt) { *vv = lp_alloc(f_pool, sizeof(struct f_path_mask)); if (tt->kind == PM_ASN_EXPR) { - struct f_val res = interpret((struct f_inst *) tt->val); + struct f_val res; + INTERPRET(res, (struct f_inst *) tt->val); (*vv)->kind = PM_ASN; if (res.type != T_INT) { runtime( "Error resolving path mask template: value not an integer" ); @@ -794,7 +787,8 @@ interpret(struct f_inst *what) /* Relational operators */ #define COMPARE(x) \ - TWOARGS; \ + ARG_ANY(1); \ + ARG_ANY(2); \ i = val_compare(v1, v2); \ if (i==CMP_ERROR) \ runtime( "Can't compare values of incompatible types" ); \ @@ -803,7 +797,8 @@ interpret(struct f_inst *what) break; #define SAME(x) \ - TWOARGS; \ + ARG_ANY(1); \ + ARG_ANY(2); \ i = val_same(v1, v2); \ res.type = T_BOOL; \ res.val.i = (x); \ @@ -815,15 +810,14 @@ interpret(struct f_inst *what) case FI_LTE: COMPARE(i!=1); case FI_NOT: - ONEARG; - if (v1.type != T_BOOL) - runtime( "Not applied to non-boolean" ); + ARG(1,T_BOOL); res = v1; res.val.i = !res.val.i; break; case FI_MATCH: - TWOARGS; + ARG_ANY(1); + ARG_ANY(2); res.type = T_BOOL; res.val.i = val_in_range(v1, v2); if (res.val.i == CMP_ERROR) @@ -832,7 +826,8 @@ interpret(struct f_inst *what) break; case FI_NOT_MATCH: - TWOARGS; + ARG_ANY(1); + ARG_ANY(2); res.type = T_BOOL; res.val.i = val_in_range(v1, v2); if (res.val.i == CMP_ERROR) @@ -841,12 +836,12 @@ interpret(struct f_inst *what) break; case FI_DEFINED: - ONEARG; + ARG_ANY(1); res.type = T_BOOL; res.val.i = (v1.type != T_VOID) && !undef_value(v1); break; case FI_TYPE: - ONEARG; + ARG_ANY(1); /* There may be more types supporting this operation */ switch (v1.type) { case T_NET: @@ -858,16 +853,14 @@ interpret(struct f_inst *what) } break; case FI_IS_V4: - ONEARG; - if (v1.type != T_IP) - runtime( "IP version check needs an IP address" ); + ARG(1, T_IP); res.type = T_BOOL; res.val.i = ipa_is_ip4(v1.val.ip); break; /* Set to indirect value, a1 = variable, a2 = value */ case FI_SET: - ARG(v2, a2.p); + ARG_ANY(2); sym = what->a1.p; vp = sym->def; if ((sym->class != (SYM_VARIABLE | v2.type)) && (v2.type != T_VOID)) @@ -902,24 +895,23 @@ interpret(struct f_inst *what) res = * ((struct f_val *) what->a1.p); break; case FI_PRINT: - ONEARG; + ARG_ANY(1); val_format(v1, &f_buf); break; case FI_CONDITION: /* ? has really strange error value, so we can implement if ... else nicely :-) */ - ONEARG; - if (v1.type != T_BOOL) - runtime( "If requires boolean expression" ); + ARG(1, T_BOOL); if (v1.val.i) { - ARG(res,a2.p); + ARG_ANY(2); res.val.i = 0; - } else res.val.i = 1; + } else + res.val.i = 1; res.type = T_BOOL; break; case FI_NOP: debug( "No operation\n" ); break; case FI_PRINT_AND_DIE: - ONEARG; + ARG_ANY(1); if ((what->a2.i == F_NOP || (what->a2.i != F_NONL && what->a1.p)) && !(f_flags & FF_SILENT)) log_commit(*L_INFO, &f_buf); @@ -966,7 +958,7 @@ interpret(struct f_inst *what) break; case FI_RTA_SET: ACCESS_RTE; - ONEARG; + ARG_ANY(1); if (what->aux != v1.type) runtime( "Attempt to set static attribute to incompatible type" ); @@ -1018,17 +1010,11 @@ interpret(struct f_inst *what) break; case FI_EA_GET: /* Access to extended attributes */ ACCESS_RTE; + ACCESS_EATTRS; { - eattr *e = NULL; u16 code = what->a2.i; int f_type = what->aux >> 8; - - if (!(f_flags & FF_FORCE_TMPATTR)) - e = ea_find((*f_rte)->attrs->eattrs, code); - if (!e) - e = ea_find((*f_tmp_attrs), code); - if ((!e) && (f_flags & FF_FORCE_TMPATTR)) - e = ea_find((*f_rte)->attrs->eattrs, code); + eattr *e = ea_find(*f_eattrs, code); if (!e) { /* A special case: undefined as_path looks like empty as_path */ @@ -1112,7 +1098,8 @@ interpret(struct f_inst *what) break; case FI_EA_SET: ACCESS_RTE; - ONEARG; + ACCESS_EATTRS; + ARG_ANY(1); { struct ea_list *l = lp_alloc(f_pool, sizeof(struct ea_list) + sizeof(eattr)); u16 code = what->a2.i; @@ -1166,13 +1153,7 @@ interpret(struct f_inst *what) runtime( "Setting bit in bitfield attribute to non-bool value" ); { /* First, we have to find the old value */ - eattr *e = NULL; - if (!(f_flags & FF_FORCE_TMPATTR)) - e = ea_find((*f_rte)->attrs->eattrs, code); - if (!e) - e = ea_find((*f_tmp_attrs), code); - if ((!e) && (f_flags & FF_FORCE_TMPATTR)) - e = ea_find((*f_rte)->attrs->eattrs, code); + eattr *e = ea_find(*f_eattrs, code); u32 data = e ? e->u.data : 0; if (v1.val.i) @@ -1204,14 +1185,9 @@ interpret(struct f_inst *what) default: bug("Unknown type in e,S"); } - if (!(what->aux & EAF_TEMP) && (!(f_flags & FF_FORCE_TMPATTR))) { - f_rta_cow(); - l->next = (*f_rte)->attrs->eattrs; - (*f_rte)->attrs->eattrs = l; - } else { - l->next = (*f_tmp_attrs); - (*f_tmp_attrs) = l; - } + f_rta_cow(); + l->next = *f_eattrs; + *f_eattrs = l; } break; case FI_PREF_GET: @@ -1221,16 +1197,14 @@ interpret(struct f_inst *what) break; case FI_PREF_SET: ACCESS_RTE; - ONEARG; - if (v1.type != T_INT) - runtime( "Can't set preference to non-integer" ); + ARG(1,T_INT); if (v1.val.i > 0xFFFF) runtime( "Setting preference value out of bounds" ); f_rte_cow(); (*f_rte)->pref = v1.val.i; break; case FI_LENGTH: /* Get length of */ - ONEARG; + ARG_ANY(1); res.type = T_INT; switch(v1.type) { case T_NET: res.val.i = net_pxlen(v1.val.net); break; @@ -1242,8 +1216,8 @@ interpret(struct f_inst *what) } break; case FI_SADR_SRC: /* Get SADR src prefix */ - ONEARG; - if (v1.type != T_NET || !net_is_sadr(v1.val.net)) + ARG(1, T_NET); + if (!net_is_sadr(v1.val.net)) runtime( "SADR expected" ); { @@ -1256,8 +1230,8 @@ interpret(struct f_inst *what) } break; case FI_ROA_MAXLEN: /* Get ROA max prefix length */ - ONEARG; - if (v1.type != T_NET || !net_is_roa(v1.val.net)) + ARG(1, T_NET); + if (!net_is_roa(v1.val.net)) runtime( "ROA expected" ); res.type = T_INT; @@ -1266,8 +1240,8 @@ interpret(struct f_inst *what) ((net_addr_roa6 *) v1.val.net)->max_pxlen; break; case FI_ROA_ASN: /* Get ROA ASN */ - ONEARG; - if (v1.type != T_NET || !net_is_roa(v1.val.net)) + ARG(1, T_NET); + if (!net_is_roa(v1.val.net)) runtime( "ROA expected" ); res.type = T_INT; @@ -1276,25 +1250,20 @@ interpret(struct f_inst *what) ((net_addr_roa6 *) v1.val.net)->asn; break; case FI_IP: /* Convert prefix to ... */ - ONEARG; - if (v1.type != T_NET) - runtime( "Prefix expected" ); + ARG(1, T_NET); res.type = T_IP; res.val.ip = net_prefix(v1.val.net); break; case FI_ROUTE_DISTINGUISHER: - ONEARG; - if (v1.type != T_NET) - runtime( "Prefix expected" ); + ARG(1, T_NET); + res.type = T_IP; if (!net_is_vpn(v1.val.net)) runtime( "VPN address expected" ); res.type = T_RD; res.val.ec = net_rd(v1.val.net); break; case FI_AS_PATH_FIRST: /* Get first ASN from AS PATH */ - ONEARG; - if (v1.type != T_PATH) - runtime( "AS path expected" ); + ARG(1, T_PATH); as = 0; as_path_get_first(v1.val.ad, &as); @@ -1302,9 +1271,7 @@ interpret(struct f_inst *what) res.val.i = as; break; case FI_AS_PATH_LAST: /* Get last ASN from AS PATH */ - ONEARG; - if (v1.type != T_PATH) - runtime( "AS path expected" ); + ARG(1, T_PATH); as = 0; as_path_get_last(v1.val.ad, &as); @@ -1312,20 +1279,18 @@ interpret(struct f_inst *what) res.val.i = as; break; case FI_AS_PATH_LAST_NAG: /* Get last ASN from non-aggregated part of AS PATH */ - ONEARG; - if (v1.type != T_PATH) - runtime( "AS path expected" ); + ARG(1, T_PATH); res.type = T_INT; res.val.i = as_path_get_last_nonaggregated(v1.val.ad); break; case FI_RETURN: - ONEARG; + ARG_ANY(1); res = v1; res.type |= T_RETURN; return res; case FI_CALL: /* CALL: this is special: if T_RETURN and returning some value, mask it out */ - ONEARG; + ARG_ANY(1); res = interpret(what->a2.p); if (res.type == T_RETURN) return res; @@ -1336,7 +1301,7 @@ interpret(struct f_inst *what) ((struct f_val *) sym->def)->type = T_VOID; break; case FI_SWITCH: - ONEARG; + ARG_ANY(1); { struct f_tree *t = find_tree(what->a2.p, v1); if (!t) { @@ -1349,17 +1314,12 @@ interpret(struct f_inst *what) } /* It is actually possible to have t->data NULL */ - res = interpret(t->data); - if (res.type & T_RETURN) - return res; + INTERPRET(res, t->data); } break; case FI_IP_MASK: /* IP.MASK(val) */ - TWOARGS; - if (v2.type != T_INT) - runtime( "Integer expected"); - if (v1.type != T_IP) - runtime( "You can mask only IP addresses" ); + ARG(1, T_IP); + ARG(2, T_INT); res.type = T_IP; res.val.ip = ipa_is_ip4(v1.val.ip) ? @@ -1372,18 +1332,16 @@ interpret(struct f_inst *what) res.val.ad = adata_empty(f_pool, 0); break; case FI_PATH_PREPEND: /* Path prepend */ - TWOARGS; - if (v1.type != T_PATH) - runtime("Can't prepend to non-path"); - if (v2.type != T_INT) - runtime("Can't prepend non-integer"); + ARG(1, T_PATH); + ARG(2, T_INT); res.type = T_PATH; res.val.ad = as_path_prepend(f_pool, v1.val.ad, v2.val.i); break; case FI_CLIST_ADD_DEL: /* (Extended) Community list add or delete */ - TWOARGS; + ARG_ANY(1); + ARG_ANY(2); if (v1.type == T_PATH) { struct f_tree *set = NULL; @@ -1551,20 +1509,20 @@ interpret(struct f_inst *what) case FI_ROA_CHECK: /* ROA Check */ if (what->arg1) { - TWOARGS; - if ((v1.type != T_NET) || (v2.type != T_INT)) - runtime("Invalid argument to roa_check()"); + ARG(1, T_NET); + ARG(2, T_INT); as = v2.val.i; } else { ACCESS_RTE; + ACCESS_EATTRS; v1.val.net = (*f_rte)->net->n.addr; /* We ignore temporary attributes, probably not a problem here */ /* 0x02 is a value of BA_AS_PATH, we don't want to include BGP headers */ - eattr *e = ea_find((*f_rte)->attrs->eattrs, EA_CODE(EAP_BGP, 0x02)); + eattr *e = ea_find(*f_eattrs, EA_CODE(PROTOCOL_BGP, 0x02)); if (!e || e->type != EAF_TYPE_AS_PATH) runtime("Missing AS_PATH attribute"); @@ -1589,17 +1547,14 @@ interpret(struct f_inst *what) break; case FI_FORMAT: /* Format */ - ONEARG; + ARG_ANY(1); res.type = T_STRING; res.val.s = val_format_str(v1); break; case FI_ASSERT: /* Birdtest Assert */ - ONEARG; - - if (v1.type != T_BOOL) - runtime("Should be boolean value"); + ARG(1, T_BOOL); res.type = v1.type; res.val = v1.val; @@ -1614,13 +1569,15 @@ interpret(struct f_inst *what) } #undef ARG -#define ARG(x,y) \ - if (!i_same(f1->y, f2->y)) \ +#undef ARG_ANY + +#define ARG(n) \ + if (!i_same(f1->a##n.p, f2->a##n.p)) \ return 0; -#define ONEARG ARG(v1, a1.p) -#define TWOARGS ARG(v1, a1.p) \ - ARG(v2, a2.p) +#define ONEARG ARG(1); +#define TWOARGS ONEARG; ARG(2); +#define THREEARGS TWOARGS; ARG(3); #define A2_SAME if (f1->a2.i != f2->a2.i) return 0; @@ -1664,13 +1621,11 @@ i_same(struct f_inst *f1, struct f_inst *f2) case FI_TYPE: ONEARG; break; case FI_LC_CONSTRUCT: - TWOARGS; - if (!i_same(INST3(f1).p, INST3(f2).p)) - return 0; + THREEARGS; break; case FI_SET: - ARG(v2, a2.p); + ARG(2); { struct symbol *s1, *s2; s1 = f1->a1.p; @@ -1765,7 +1720,6 @@ i_same(struct f_inst *f1, struct f_inst *f2) * f_run - run a filter for a route * @filter: filter to run * @rte: route being filtered, may be modified - * @tmp_attrs: temporary attributes, prepared by caller or generated by f_run() * @tmp_pool: all filter allocations go from this pool * @flags: flags * @@ -1787,7 +1741,7 @@ i_same(struct f_inst *f1, struct f_inst *f2) * modified in place, old cached rta is possibly freed. */ int -f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool, int flags) +f_run(struct filter *filter, struct rte **rte, struct linpool *tmp_pool, int flags) { if (filter == FILTER_ACCEPT) return F_ACCEPT; @@ -1800,7 +1754,6 @@ f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struc f_rte = rte; f_old_rta = NULL; - f_tmp_attrs = tmp_attrs; f_pool = tmp_pool; f_flags = flags; @@ -1842,11 +1795,9 @@ f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struc struct f_val f_eval_rte(struct f_inst *expr, struct rte **rte, struct linpool *tmp_pool) { - struct ea_list *tmp_attrs = NULL; f_rte = rte; f_old_rta = NULL; - f_tmp_attrs = &tmp_attrs; f_pool = tmp_pool; f_flags = 0; @@ -1855,9 +1806,6 @@ f_eval_rte(struct f_inst *expr, struct rte **rte, struct linpool *tmp_pool) /* Note that in this function we assume that rte->attrs is private / uncached */ struct f_val res = interpret(expr); - /* Hack to include EAF_TEMP attributes to the main list */ - (*rte)->attrs->eattrs = ea_append(tmp_attrs, (*rte)->attrs->eattrs); - return res; } @@ -1865,7 +1813,6 @@ struct f_val f_eval(struct f_inst *expr, struct linpool *tmp_pool) { f_flags = 0; - f_tmp_attrs = NULL; f_rte = NULL; f_pool = tmp_pool; diff --git a/filter/filter.h b/filter/filter.h index 982276f0..febfdc65 100644 --- a/filter/filter.h +++ b/filter/filter.h @@ -75,11 +75,14 @@ enum f_instruction_code { #define F(c,a,b) \ - c = FI__TWOCHAR(a,b), + c, FI__LIST #undef F + FI__MAX, } PACKED; +const char *f_instruction_name(enum f_instruction_code fi); + struct f_inst { /* Instruction */ struct f_inst *next; /* Structure is 16 bytes, anyway */ enum f_instruction_code fi_code; @@ -92,6 +95,10 @@ struct f_inst { /* Instruction */ uint i; void *p; } a2; /* The second argument */ + union { + int i; + void *p; + } a3; /* The third argument */ int lineno; }; @@ -104,17 +111,6 @@ struct f_inst_roa_check { struct rtable_config *rtc; }; -struct f_inst3 { - struct f_inst i; - union { - int i; - void *p; - } a3; -}; - -#define INST3(x) (((struct f_inst3 *) x)->a3) - - struct f_prefix { net_addr net; u8 lo, hi; @@ -179,7 +175,7 @@ void trie_format(struct f_trie *t, buffer *buf); struct ea_list; struct rte; -int f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool, int flags); +int f_run(struct filter *filter, struct rte **rte, struct linpool *tmp_pool, int flags); struct f_val f_eval_rte(struct f_inst *expr, struct rte **rte, struct linpool *tmp_pool); struct f_val f_eval(struct f_inst *expr, struct linpool *tmp_pool); uint f_eval_int(struct f_inst *expr); @@ -289,7 +285,6 @@ struct f_trie #define NEW_F_VAL struct f_val * val; val = cfg_alloc(sizeof(struct f_val)); -#define FF_FORCE_TMPATTR 1 /* Force all attributes to be temporary */ #define FF_SILENT 2 /* Silent filter execution */ /* Bird Tests */ diff --git a/lib/macro.h b/lib/macro.h new file mode 100644 index 00000000..24fc3393 --- /dev/null +++ b/lib/macro.h @@ -0,0 +1,98 @@ +/* + * BIRD Macro Tricks + * + * (c) 2018 Jan Maria Matejka <mq@jmq.cz> + * + * Can be freely distributed and used under the terms of the GNU GPL. + * + * Contains useful but dirty macro tricks: + * MACRO_CONCAT(a, b) -> concatenates a##b + * MACRO_BOOL(x) -> convert 0 to 0, anything else to 1 + * MACRO_IFELSE(b)(true-branch)(false-branch) + * -> b shall be 0 or 1; expands to the appropriate branch + * MACRO_ISEMPTY(...) -> 1 for empty argument list, 0 otherwise + * MACRO_FOREACH(func, ...) + * -> calling FOREACH(func, a, b, c, d) expands to + * func(a) func(b) func(c) func(d) + * MACRO_RPACK(func, terminator, ...) + * -> packs the list into recursive calls: + * func(func(func(func(terminator, a), b), c), d) + */ + +#ifndef _BIRD_MACRO_H_ +#define _BIRD_MACRO_H_ + +/* What to do with args */ +#define MACRO_DROP(...) +#define MACRO_UNPAREN(...) __VA_ARGS__ +#define MACRO_SEP(a, b, sep) a sep b + +/* Aliases for some special chars */ +#define MACRO_COMMA , +#define MACRO_LPAREN ( +#define MACRO_RPAREN ) +#define MACRO_LPAREN_() ( +#define MACRO_RPAREN_() ) + +/* Multiple expansion trick */ +#define MACRO_EXPAND0(...) __VA_ARGS__ +#define MACRO_EXPAND1(...) MACRO_EXPAND0(MACRO_EXPAND0(__VA_ARGS__)) +#define MACRO_EXPAND2(...) MACRO_EXPAND1(MACRO_EXPAND1(__VA_ARGS__)) +#define MACRO_EXPAND3(...) MACRO_EXPAND2(MACRO_EXPAND2(__VA_ARGS__)) +#define MACRO_EXPAND(...) MACRO_EXPAND3(MACRO_EXPAND3(__VA_ARGS__)) + +/* Deferring expansion in the expansion trick */ +#define MACRO_EMPTY() +#define MACRO_DEFER(t) t MACRO_EMPTY() +#define MACRO_DEFER2(t) t MACRO_EMPTY MACRO_EMPTY()() +#define MACRO_DEFER3(t) t MACRO_EMPTY MACRO_EMPTY MACRO_EMPTY()()() + +/* Token concatenation */ +#define MACRO_CONCAT(prefix, ...) prefix##__VA_ARGS__ +#define MACRO_CONCAT_AFTER(...) MACRO_CONCAT(__VA_ARGS__) + +/* Get first or second argument only */ +#define MACRO_FIRST(a, ...) a +#define MACRO_SECOND(a, b, ...) b +#define MACRO_SECOND_OR_ZERO(...) MACRO_SECOND(__VA_ARGS__, 0,) + +/* Macro Boolean auxiliary macros */ +#define MACRO_BOOL_CHECK_0 ~, 1 +#define MACRO_BOOL_NEG(x) MACRO_SECOND_OR_ZERO(MACRO_CONCAT(MACRO_BOOL_CHECK_, x)) + +#define MACRO_BOOL_NOT_0 1 +#define MACRO_BOOL_NOT_1 0 + +/* Macro Boolean negation */ +#define MACRO_NOT(x) MACRO_CONCAT(MACRO_BOOL_NOT_, x) + +/* Convert anything to bool (anything -> 1, 0 -> 0) */ +#define MACRO_BOOL(x) MACRO_NOT(MACRO_BOOL_NEG(x)) + +/* + * Macro If/Else condition + * Usage: MACRO_IFELSE(condition)(true-branch)(false-branch) + * Expands to true-branch if condition is true, otherwise to false-branch. + */ +#define MACRO_IFELSE(b) MACRO_CONCAT(MACRO_IFELSE_, b) +#define MACRO_IFELSE_0(...) MACRO_UNPAREN +#define MACRO_IFELSE_1(...) __VA_ARGS__ MACRO_DROP + +/* Auxiliary macros for MACRO_FOREACH */ +#define MACRO_ISLAST(...) MACRO_BOOL_NEG(MACRO_FIRST(MACRO_ISLAST_CHECK __VA_ARGS__)()) +#define MACRO_ISLAST_CHECK() 0 + +#define MACRO_FOREACH_EXPAND(call, a, ...) MACRO_IFELSE(MACRO_ISLAST(__VA_ARGS__))(call(a))(call(a) MACRO_DEFER2(MACRO_FOREACH_PAREN)()(call, __VA_ARGS__)) +#define MACRO_FOREACH_PAREN() MACRO_FOREACH_EXPAND + +#define MACRO_RPACK_EXPAND(call, terminator, a, ...) MACRO_IFELSE(MACRO_ISLAST(__VA_ARGS__))(call(terminator, a))(call(MACRO_DEFER2(MACRO_RPACK_PAREN)()(call, terminator, __VA_ARGS__), a)) +#define MACRO_RPACK_PAREN() MACRO_RPACK_EXPAND +/* + * Call the first argument for each following: + * MACRO_FOREACH(func, a, b, c, d) expands to func(a) func(b) func(c) func(d). + * It supports also macros as func. + */ +#define MACRO_FOREACH(call, ...) MACRO_EXPAND(MACRO_FOREACH_EXPAND(call, __VA_ARGS__)) +#define MACRO_RPACK(call, terminator, ...) MACRO_EXPAND(MACRO_RPACK_EXPAND(call, terminator, __VA_ARGS__)) + +#endif diff --git a/nest/proto.c b/nest/proto.c index 15d6f4de..49f71304 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -25,6 +25,7 @@ pool *proto_pool; list proto_list; static list protocol_list; +struct protocol *class_to_protocol[PROTOCOL__MAX]; #define PD(pr, msg, args...) do { if (pr->debug & D_STATES) { log(L_TRACE "%s: " msg, pr->name , ## args); } } while(0) @@ -1256,11 +1257,9 @@ void proto_build(struct protocol *p) { add_tail(&protocol_list, &p->n); - if (p->attr_class) - { - ASSERT(!attr_class_to_protocol[p->attr_class]); - attr_class_to_protocol[p->attr_class] = p; - } + ASSERT(p->class); + ASSERT(!class_to_protocol[p->class]); + class_to_protocol[p->class] = p; } /* FIXME: convert this call to some protocol hook */ diff --git a/nest/protocol.h b/nest/protocol.h index 8a22d76b..dd942c10 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -37,12 +37,31 @@ struct symbol; * Routing Protocol */ +enum protocol_class { + PROTOCOL_NONE, + PROTOCOL_BABEL, + PROTOCOL_BFD, + PROTOCOL_BGP, + PROTOCOL_DEVICE, + PROTOCOL_DIRECT, + PROTOCOL_KERNEL, + PROTOCOL_OSPF, + PROTOCOL_PIPE, + PROTOCOL_RADV, + PROTOCOL_RIP, + PROTOCOL_RPKI, + PROTOCOL_STATIC, + PROTOCOL__MAX +}; + +extern struct protocol *class_to_protocol[PROTOCOL__MAX]; + struct protocol { node n; char *name; char *template; /* Template for automatic generation of names */ int name_counter; /* Counter for automatic name generation */ - int attr_class; /* Attribute class known to this protocol */ + enum protocol_class class; /* Machine readable protocol class */ uint preference; /* Default protocol preference */ uint channel_mask; /* Mask of accepted channel types (NB_*) */ uint proto_size; /* Size of protocol data structure */ @@ -58,7 +77,7 @@ struct protocol { int (*shutdown)(struct proto *); /* Stop the instance */ void (*cleanup)(struct proto *); /* Called after shutdown when protocol became hungry/down */ void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */ - void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs); /* Get route information (for `show route' command) */ + void (*get_route_info)(struct rte *, byte *buf); /* Get route information (for `show route' command) */ int (*get_attr)(struct eattr *, byte *buf, int buflen); /* ASCIIfy dynamic attribute (returns GA_*) */ void (*show_proto_info)(struct proto *); /* Show protocol info (for `show protocols all' command) */ void (*copy_config)(struct proto_config *, struct proto_config *); /* Copy config from given protocol instance */ @@ -172,7 +191,7 @@ struct proto { * rt_notify Notify protocol about routing table updates. * neigh_notify Notify protocol about neighbor cache events. * make_tmp_attrs Construct ea_list from private attrs stored in rte. - * store_tmp_attrs Store private attrs back to the rte. + * store_tmp_attrs Store private attrs back to rta. The route MUST NOT be cached. * import_control Called as the first step of the route importing process. * It can construct a new rte, add private attributes and * decide whether the route shall be imported: 1=yes, -1=no, @@ -186,11 +205,11 @@ struct proto { void (*if_notify)(struct proto *, unsigned flags, struct iface *i); void (*ifa_notify)(struct proto *, unsigned flags, struct ifa *a); - void (*rt_notify)(struct proto *, struct channel *, struct network *net, struct rte *new, struct rte *old, struct ea_list *attrs); + void (*rt_notify)(struct proto *, struct channel *, struct network *net, struct rte *new, struct rte *old); void (*neigh_notify)(struct neighbor *neigh); struct ea_list *(*make_tmp_attrs)(struct rte *rt, struct linpool *pool); - void (*store_tmp_attrs)(struct rte *rt, struct ea_list *attrs); - int (*import_control)(struct proto *, struct rte **rt, struct ea_list **attrs, struct linpool *pool); + void (*store_tmp_attrs)(struct rte *rt); + int (*import_control)(struct proto *, struct rte **rt, struct linpool *pool); void (*reload_routes)(struct channel *); void (*feed_begin)(struct channel *, int initial); void (*feed_end)(struct channel *); @@ -273,12 +292,16 @@ proto_get_router_id(struct proto_config *pc) return pc->router_id ? pc->router_id : pc->global->router_id; } -static inline struct ea_list * -rte_make_tmp_attrs(struct rte *rt, struct linpool *pool) +static inline void +rte_make_tmp_attrs(struct rte **rt, struct linpool *pool) { struct ea_list *(*mta)(struct rte *rt, struct linpool *pool); - mta = rt->attrs->src->proto->make_tmp_attrs; - return mta ? mta(rt, pool) : NULL; + mta = (*rt)->attrs->src->proto->make_tmp_attrs; + if (!mta) return; + *rt = rte_cow_rta(*rt, pool); + struct ea_list *ea = mta(*rt, pool); + ea->next = (*rt)->attrs->eattrs; + (*rt)->attrs->eattrs = ea; } /* Moved from route.h to avoid dependency conflicts */ @@ -447,7 +470,7 @@ struct channel_class { void (*dump_attrs)(struct rte *); /* Dump protocol-dependent attributes */ void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */ - void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs); /* Get route information (for `show route' command) */ + void (*get_route_info)(struct rte *, byte *buf); /* Get route information (for `show route' command) */ int (*get_attr)(struct eattr *, byte *buf, int buflen); /* ASCIIfy dynamic attribute (returns GA_*) */ void (*show_proto_info)(struct proto *); /* Show protocol info (for `show protocols all' command) */ diff --git a/nest/route.h b/nest/route.h index 79127519..cad15440 100644 --- a/nest/route.h +++ b/nest/route.h @@ -294,7 +294,7 @@ rte *rte_get_temp(struct rta *); void rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src); /* rte_update() moved to protocol.h to avoid dependency conflicts */ int rt_examine(rtable *t, net_addr *a, struct proto *p, struct filter *filter); -rte *rt_export_merged(struct channel *c, net *net, rte **rt_free, struct ea_list **tmpa, linpool *pool, int silent); +rte *rt_export_merged(struct channel *c, net *net, rte **rt_free, linpool *pool, int silent); void rt_refresh_begin(rtable *t, struct channel *c); void rt_refresh_end(rtable *t, struct channel *c); void rt_schedule_prune(rtable *t); @@ -457,7 +457,7 @@ static inline int rte_is_reachable(rte *r) */ typedef struct eattr { - word id; /* EA_CODE(EAP_..., protocol-dependent ID) */ + word id; /* EA_CODE(PROTOCOL_..., protocol-dependent ID) */ byte flags; /* Protocol-dependent flags */ byte type; /* Attribute type and several flags (EAF_...) */ union { @@ -466,20 +466,11 @@ typedef struct eattr { } u; } eattr; -#define EAP_GENERIC 0 /* Generic attributes */ -#define EAP_BGP 1 /* BGP attributes */ -#define EAP_RIP 2 /* RIP */ -#define EAP_OSPF 3 /* OSPF */ -#define EAP_KRT 4 /* Kernel route attributes */ -#define EAP_BABEL 5 /* Babel attributes */ -#define EAP_RADV 6 /* Router advertisment attributes */ -#define EAP_MAX 7 - #define EA_CODE(proto,id) (((proto) << 8) | (id)) #define EA_PROTO(ea) ((ea) >> 8) #define EA_ID(ea) ((ea) & 0xff) -#define EA_GEN_IGP_METRIC EA_CODE(EAP_GENERIC, 0) +#define EA_GEN_IGP_METRIC EA_CODE(PROTOCOL_NONE, 0) #define EA_CODE_MASK 0xffff #define EA_ALLOW_UNDEF 0x10000 /* ea_find: allow EAF_TYPE_UNDEF */ @@ -555,6 +546,15 @@ uint 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); +#define ea_normalize(ea) do { \ + if (ea->next) { \ + ea_list *t = alloca(ea_scan(ea)); \ + ea_merge(ea, t); \ + ea = t; \ + } \ + ea_sort(ea); \ +} while(0) \ + static inline eattr * ea_set_attr(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, uintptr_t val) { @@ -620,7 +620,7 @@ rta *rta_do_cow(rta *o, linpool *lp); static inline rta * rta_cow(rta *r, linpool *lp) { return rta_is_cached(r) ? rta_do_cow(r, lp) : r; } void rta_dump(rta *); void rta_dump_all(void); -void rta_show(struct cli *, rta *, ea_list *); +void rta_show(struct cli *, rta *); struct hostentry * rt_get_hostentry(rtable *tab, ip_addr a, ip_addr ll, rtable *dep); void rta_apply_hostentry(rta *a, struct hostentry *he, mpls_label_stack *mls); @@ -656,9 +656,6 @@ rta_set_recursive_next_hop(rtable *dep, rta *a, rtable *tab, ip_addr gw, ip_addr static inline void rt_lock_hostentry(struct hostentry *he) { if (he) he->uc++; } static inline void rt_unlock_hostentry(struct hostentry *he) { if (he) he->uc--; } - -extern struct protocol *attr_class_to_protocol[EAP_MAX]; - /* * Default protocol preferences */ diff --git a/nest/rt-attr.c b/nest/rt-attr.c index 881687de..73ca4748 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -88,9 +88,6 @@ static struct idm src_ids; static HASH(struct rte_src) src_hash; -struct protocol *attr_class_to_protocol[EAP_MAX]; - - static void rte_src_init(void) { @@ -553,29 +550,47 @@ ea_do_sort(ea_list *e) while (ss); } +/** + * In place discard duplicates, undefs and temporary attributes in sorted + * ea_list. We use stable sort for this reason. + **/ static inline void ea_do_prune(ea_list *e) { eattr *s, *d, *l, *s0; int i = 0; - /* Discard duplicates and undefs. Do you remember sorting was stable? */ - s = d = e->attrs; - l = e->attrs + e->count; + s = d = e->attrs; /* Beginning of the list. @s is source, @d is destination. */ + l = e->attrs + e->count; /* End of the list */ + + /* Walk from begin to end. */ while (s < l) { s0 = s++; + /* Find a consecutive block of the same attribute */ while (s < l && s->id == s[-1].id) s++; - /* s0 is the most recent version, s[-1] the oldest one */ - if ((s0->type & EAF_TYPE_MASK) != EAF_TYPE_UNDEF) - { - *d = *s0; - d->type = (d->type & ~(EAF_ORIGINATED|EAF_FRESH)) | (s[-1].type & EAF_ORIGINATED); - d++; - i++; - } + + /* Now s0 is the most recent version, s[-1] the oldest one */ + /* Drop undefs */ + if ((s0->type & EAF_TYPE_MASK) == EAF_TYPE_UNDEF) + continue; + + /* Drop temporary attributes */ + if (s0->type & EAF_TEMP) + 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); + + /* Next destination */ + d++; + i++; } + e->count = i; } @@ -851,7 +866,7 @@ ea_show(struct cli *c, eattr *e) byte buf[CLI_MSG_SIZE]; byte *pos = buf, *end = buf + sizeof(buf); - if (p = attr_class_to_protocol[EA_PROTO(e->id)]) + if (p = class_to_protocol[EA_PROTO(e->id)]) { pos += bsprintf(pos, "%s.", p->name); if (p->get_attr) @@ -1131,15 +1146,7 @@ rta_lookup(rta *o) ASSERT(!(o->aflags & RTAF_CACHED)); if (o->eattrs) - { - if (o->eattrs->next) /* Multiple ea_list's, need to merge them */ - { - ea_list *ml = alloca(ea_scan(o->eattrs)); - ea_merge(o->eattrs, ml); - o->eattrs = ml; - } - ea_sort(o->eattrs); - } + ea_normalize(o->eattrs); h = rta_hash(o); for(r=rta_hash_table[h & rta_cache_mask]; r; r=r->next) @@ -1253,17 +1260,15 @@ rta_dump_all(void) } void -rta_show(struct cli *c, rta *a, ea_list *eal) +rta_show(struct cli *c, rta *a) { static char *src_names[] = { "dummy", "static", "inherit", "device", "static-device", "redirect", "RIP", "OSPF", "OSPF-IA", "OSPF-E1", "OSPF-E2", "BGP", "pipe" }; - int i; cli_printf(c, -1008, "\tType: %s %s", src_names[a->source], ip_scope_text(a->scope)); - if (!eal) - eal = a->eattrs; - for(; eal; eal=eal->next) - for(i=0; i<eal->count; i++) + + for(ea_list *eal = a->eattrs; eal; eal=eal->next) + for(int i=0; i<eal->count; i++) ea_show(c, &eal->attrs[i]); } diff --git a/nest/rt-dev.c b/nest/rt-dev.c index 66f458e7..61f025ce 100644 --- a/nest/rt-dev.c +++ b/nest/rt-dev.c @@ -185,6 +185,7 @@ dev_copy_config(struct proto_config *dest, struct proto_config *src) struct protocol proto_device = { .name = "Direct", .template = "direct%d", + .class = PROTOCOL_DIRECT, .preference = DEF_PREF_DIRECT, .channel_mask = NB_IP | NB_IP6_SADR, .proto_size = sizeof(struct rt_dev_proto), diff --git a/nest/rt-show.c b/nest/rt-show.c index 1f1b73d2..90165c57 100644 --- a/nest/rt-show.c +++ b/nest/rt-show.c @@ -29,14 +29,14 @@ rt_show_table(struct cli *c, struct rt_show_data *d) } static void -rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tmpa) +rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d) { byte from[IPA_MAX_TEXT_LENGTH+8]; byte tm[TM_DATETIME_BUFFER_SIZE], info[256]; rta *a = e->attrs; int primary = (e->net->routes == e); int sync_error = (e->net->n.flags & KRF_SYNC_ERROR); - void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs); + void (*get_route_info)(struct rte *, byte *buf); struct nexthop *nh; tm_format_time(tm, &config->tf_route, e->lastmod); @@ -46,17 +46,11 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tm from[0] = 0; get_route_info = a->src->proto->proto->get_route_info; - if (get_route_info || d->verbose) - { - /* Need to normalize the extended attributes */ - ea_list *t = tmpa; - t = ea_append(t, a->eattrs); - tmpa = alloca(ea_scan(t)); - ea_merge(t, tmpa); - ea_sort(tmpa); - } + /* Need to normalize the extended attributes */ + if ((get_route_info || d->verbose) && !rta_is_cached(a)) + ea_normalize(a->eattrs); if (get_route_info) - get_route_info(e, info, tmpa); + get_route_info(e, info); else bsprintf(info, " (%d)", e->pref); @@ -93,7 +87,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tm } if (d->verbose) - rta_show(c, a, tmpa); + rta_show(c, a); } static void @@ -101,7 +95,6 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d) { rte *e, *ee; byte ia[NET_MAX_TEXT_LENGTH+1]; - struct ea_list *tmpa; struct channel *ec = d->tab->export_channel; int first = 1; int pass = 0; @@ -121,7 +114,7 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d) continue; ee = e; - tmpa = rte_make_tmp_attrs(e, c->show_pool); + rte_make_tmp_attrs(&e, c->show_pool); /* Export channel is down, do not try to export routes to it */ if (ec && (ec->export_state == ES_DOWN)) @@ -131,7 +124,7 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d) if ((d->export_mode == RSEM_EXPORT) && (ec->ra_mode == RA_MERGED)) { rte *rt_free; - e = rt_export_merged(ec, n, &rt_free, &tmpa, c->show_pool, 1); + e = rt_export_merged(ec, n, &rt_free, c->show_pool, 1); pass = 1; if (!e) @@ -140,7 +133,7 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d) else if (d->export_mode) { struct proto *ep = ec->proto; - int ic = ep->import_control ? ep->import_control(ep, &e, &tmpa, c->show_pool) : 0; + int ic = ep->import_control ? ep->import_control(ep, &e, c->show_pool) : 0; if (ec->ra_mode == RA_OPTIMAL || ec->ra_mode == RA_MERGED) pass = 1; @@ -156,8 +149,7 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d) * command may change the export filter and do not update routes. */ int do_export = (ic > 0) || - (f_run(ec->out_filter, &e, &tmpa, c->show_pool, - FF_FORCE_TMPATTR | FF_SILENT) <= F_ACCEPT); + (f_run(ec->out_filter, &e, c->show_pool, FF_SILENT) <= F_ACCEPT); if (do_export != (d->export_mode == RSEM_EXPORT)) goto skip; @@ -170,11 +162,11 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d) if (d->show_protocol && (d->show_protocol != e->attrs->src->proto)) goto skip; - if (f_run(d->filter, &e, &tmpa, c->show_pool, FF_FORCE_TMPATTR) > F_ACCEPT) + if (f_run(d->filter, &e, c->show_pool, 0) > F_ACCEPT) goto skip; if (d->stats < 2) - rt_show_rte(c, ia, e, d, tmpa); + rt_show_rte(c, ia, e, d); d->show_counter++; ia[0] = 0; diff --git a/nest/rt-table.c b/nest/rt-table.c index b885c6e3..de7b05fc 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -317,11 +317,11 @@ rte_cow_rta(rte *r, linpool *lp) if (!rta_is_cached(r->attrs)) return r; - rte *e = rte_cow(r); + r = rte_cow(r); rta *a = rta_do_cow(r->attrs, lp); - rta_free(e->attrs); - e->attrs = a; - return e; + rta_free(r->attrs); + r->attrs = a; + return r; } static int /* Actually better or at least as good as */ @@ -393,24 +393,20 @@ rte_trace_out(uint flag, struct proto *p, rte *e, char *msg) } static rte * -export_filter_(struct channel *c, rte *rt0, rte **rt_free, ea_list **tmpa, linpool *pool, int silent) +export_filter_(struct channel *c, rte *rt0, rte **rt_free, linpool *pool, int silent) { struct proto *p = c->proto; struct filter *filter = c->out_filter; struct proto_stats *stats = &c->stats; - ea_list *tmpb = NULL; rte *rt; int v; rt = rt0; *rt_free = NULL; - if (!tmpa) - tmpa = &tmpb; + rte_make_tmp_attrs(&rt, pool); - *tmpa = rte_make_tmp_attrs(rt, pool); - - v = p->import_control ? p->import_control(p, &rt, tmpa, pool) : 0; + v = p->import_control ? p->import_control(p, &rt, pool) : 0; if (v < 0) { if (silent) @@ -429,8 +425,8 @@ export_filter_(struct channel *c, rte *rt0, rte **rt_free, ea_list **tmpa, linpo } v = filter && ((filter == FILTER_REJECT) || - (f_run(filter, &rt, tmpa, pool, - FF_FORCE_TMPATTR | (silent ? FF_SILENT : 0)) > F_ACCEPT)); + (f_run(filter, &rt, pool, + (silent ? FF_SILENT : 0)) > F_ACCEPT)); if (v) { if (silent) @@ -454,13 +450,13 @@ export_filter_(struct channel *c, rte *rt0, rte **rt_free, ea_list **tmpa, linpo } static inline rte * -export_filter(struct channel *c, rte *rt0, rte **rt_free, ea_list **tmpa, int silent) +export_filter(struct channel *c, rte *rt0, rte **rt_free, int silent) { - return export_filter_(c, rt0, rt_free, tmpa, rte_update_pool, silent); + return export_filter_(c, rt0, rt_free, rte_update_pool, silent); } static void -do_rt_notify(struct channel *c, net *net, rte *new, rte *old, ea_list *tmpa, int refeed) +do_rt_notify(struct channel *c, net *net, rte *new, rte *old, int refeed) { struct proto *p = c->proto; struct proto_stats *stats = &c->stats; @@ -533,19 +529,7 @@ do_rt_notify(struct channel *c, net *net, rte *new, rte *old, ea_list *tmpa, int else if (old) rte_trace_out(D_ROUTES, p, old, "removed"); } - if (!new) - p->rt_notify(p, c, net, NULL, old, NULL); - else if (tmpa) - { - ea_list *t = tmpa; - while (t->next) - t = t->next; - t->next = new->attrs->eattrs; - p->rt_notify(p, c, net, new, old, tmpa); - t->next = NULL; - } - else - p->rt_notify(p, c, net, new, old, new->attrs->eattrs); + p->rt_notify(p, c, net, new, old); } static void @@ -557,7 +541,6 @@ rt_notify_basic(struct channel *c, net *net, rte *new0, rte *old0, int refeed) rte *old = old0; rte *new_free = NULL; rte *old_free = NULL; - ea_list *tmpa = NULL; if (new) c->stats.exp_updates_received++; @@ -585,10 +568,10 @@ rt_notify_basic(struct channel *c, net *net, rte *new0, rte *old0, int refeed) */ if (new) - new = export_filter(c, new, &new_free, &tmpa, 0); + new = export_filter(c, new, &new_free, 0); if (old && !refeed) - old = export_filter(c, old, &old_free, NULL, 1); + old = export_filter(c, old, &old_free, 1); if (!new && !old) { @@ -605,13 +588,13 @@ rt_notify_basic(struct channel *c, net *net, rte *new0, rte *old0, int refeed) #ifdef CONFIG_PIPE if ((p->proto == &proto_pipe) && !new0 && (p != old0->sender->proto)) - p->rt_notify(p, c, net, NULL, old0, NULL); + p->rt_notify(p, c, net, NULL, old0); #endif return; } - do_rt_notify(c, net, new, old, tmpa, refeed); + do_rt_notify(c, net, new, old, refeed); /* Discard temporary rte's */ if (new_free) @@ -630,7 +613,6 @@ rt_notify_accepted(struct channel *c, net *net, rte *new_changed, rte *old_chang rte *old_best = NULL; rte *new_free = NULL; rte *old_free = NULL; - ea_list *tmpa = NULL; /* Used to track whether we met old_changed position. If before_old is NULL old_changed was the first and we met it implicitly before current best route. */ @@ -648,7 +630,7 @@ rt_notify_accepted(struct channel *c, net *net, rte *new_changed, rte *old_chang /* First, find the new_best route - first accepted by filters */ for (r=net->routes; rte_is_valid(r); r=r->next) { - if (new_best = export_filter(c, r, &new_free, &tmpa, 0)) + if (new_best = export_filter(c, r, &new_free, 0)) break; /* Note if we walked around the position of old_changed route */ @@ -699,7 +681,7 @@ rt_notify_accepted(struct channel *c, net *net, rte *new_changed, rte *old_chang /* First case */ if (old_meet) - if (old_best = export_filter(c, old_changed, &old_free, NULL, 1)) + if (old_best = export_filter(c, old_changed, &old_free, 1)) goto found; /* Second case */ @@ -717,18 +699,18 @@ rt_notify_accepted(struct channel *c, net *net, rte *new_changed, rte *old_chang /* Fourth case */ for (r=r->next; rte_is_valid(r); r=r->next) { - if (old_best = export_filter(c, r, &old_free, NULL, 1)) + if (old_best = export_filter(c, r, &old_free, 1)) goto found; if (r == before_old) - if (old_best = export_filter(c, old_changed, &old_free, NULL, 1)) + if (old_best = export_filter(c, old_changed, &old_free, 1)) goto found; } /* Implicitly, old_best is NULL and new_best is non-NULL */ found: - do_rt_notify(c, net, new_best, old_best, tmpa, (feed == 2)); + do_rt_notify(c, net, new_best, old_best, (feed == 2)); /* Discard temporary rte's */ if (new_free) @@ -745,7 +727,7 @@ nexthop_merge_rta(struct nexthop *nhs, rta *a, linpool *pool, int max) } rte * -rt_export_merged(struct channel *c, net *net, rte **rt_free, ea_list **tmpa, linpool *pool, int silent) +rt_export_merged(struct channel *c, net *net, rte **rt_free, linpool *pool, int silent) { // struct proto *p = c->proto; struct nexthop *nhs = NULL; @@ -757,7 +739,7 @@ rt_export_merged(struct channel *c, net *net, rte **rt_free, ea_list **tmpa, lin if (!rte_is_valid(best0)) return NULL; - best = export_filter_(c, best0, rt_free, tmpa, pool, silent); + best = export_filter_(c, best0, rt_free, pool, silent); if (!best || !rte_is_reachable(best)) return best; @@ -767,7 +749,7 @@ rt_export_merged(struct channel *c, net *net, rte **rt_free, ea_list **tmpa, lin if (!rte_mergable(best0, rt0)) continue; - rt = export_filter_(c, rt0, &tmp, NULL, pool, 1); + rt = export_filter_(c, rt0, &tmp, pool, 1); if (!rt) continue; @@ -807,7 +789,6 @@ rt_notify_merged(struct channel *c, net *net, rte *new_changed, rte *old_changed rte *old_best_free = NULL; rte *new_changed_free = NULL; rte *old_changed_free = NULL; - ea_list *tmpa = NULL; /* We assume that all rte arguments are either NULL or rte_is_valid() */ @@ -819,10 +800,10 @@ rt_notify_merged(struct channel *c, net *net, rte *new_changed, rte *old_changed if ((new_best == old_best) && !refeed) { new_changed = rte_mergable(new_best, new_changed) ? - export_filter(c, new_changed, &new_changed_free, NULL, 1) : NULL; + export_filter(c, new_changed, &new_changed_free, 1) : NULL; old_changed = rte_mergable(old_best, old_changed) ? - export_filter(c, old_changed, &old_changed_free, NULL, 1) : NULL; + export_filter(c, old_changed, &old_changed_free, 1) : NULL; if (!new_changed && !old_changed) return; @@ -835,15 +816,15 @@ rt_notify_merged(struct channel *c, net *net, rte *new_changed, rte *old_changed /* Prepare new merged route */ if (new_best) - new_best = rt_export_merged(c, net, &new_best_free, &tmpa, rte_update_pool, 0); + new_best = rt_export_merged(c, net, &new_best_free, rte_update_pool, 0); /* Prepare old merged route (without proper merged next hops) */ /* There are some issues with running filter on old route - see rt_notify_basic() */ if (old_best && !refeed) - old_best = export_filter(c, old_best, &old_best_free, NULL, 1); + old_best = export_filter(c, old_best, &old_best_free, 1); if (new_best || old_best) - do_rt_notify(c, net, new_best, old_best, tmpa, refeed); + do_rt_notify(c, net, new_best, old_best, refeed); /* Discard temporary rte's */ if (new_best_free) @@ -1341,7 +1322,6 @@ rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src) struct proto *p = c->proto; struct proto_stats *stats = &c->stats; struct filter *filter = c->in_filter; - ea_list *tmpa = NULL; rte *dummy = NULL; net *nn; @@ -1379,11 +1359,11 @@ rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src) } else { - tmpa = rte_make_tmp_attrs(new, rte_update_pool); + rte_make_tmp_attrs(&new, rte_update_pool); if (filter && (filter != FILTER_REJECT)) { - ea_list *old_tmpa = tmpa; - int fr = f_run(filter, &new, &tmpa, rte_update_pool, 0); + ea_list *oldea = new->attrs->eattrs; + int fr = f_run(filter, &new, rte_update_pool, 0); if (fr > F_ACCEPT) { stats->imp_updates_filtered++; @@ -1394,8 +1374,8 @@ rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src) new->flags |= REF_FILTERED; } - if (tmpa != old_tmpa && src->proto->store_tmp_attrs) - src->proto->store_tmp_attrs(new, tmpa); + if (new->attrs->eattrs != oldea && src->proto->store_tmp_attrs) + src->proto->store_tmp_attrs(new); } } if (!rta_is_cached(new->attrs)) /* Need to copy attributes */ @@ -1459,11 +1439,10 @@ rt_examine(rtable *t, net_addr *a, struct proto *p, struct filter *filter) rte_update_lock(); /* Rest is stripped down export_filter() */ - ea_list *tmpa = rte_make_tmp_attrs(rt, rte_update_pool); - int v = p->import_control ? p->import_control(p, &rt, &tmpa, rte_update_pool) : 0; + rte_make_tmp_attrs(&rt, rte_update_pool); + int v = p->import_control ? p->import_control(p, &rt, rte_update_pool) : 0; if (v == RIC_PROCESS) - v = (f_run(filter, &rt, &tmpa, rte_update_pool, - FF_FORCE_TMPATTR | FF_SILENT) <= F_ACCEPT); + v = (f_run(filter, &rt, rte_update_pool, FF_SILENT) <= F_ACCEPT); /* Discard temporary rte */ if (rt != n->routes) diff --git a/proto/babel/babel.c b/proto/babel/babel.c index 20953044..b4404f45 100644 --- a/proto/babel/babel.c +++ b/proto/babel/babel.c @@ -1833,7 +1833,7 @@ babel_dump(struct proto *P) } static void -babel_get_route_info(rte *rte, byte *buf, ea_list *attrs UNUSED) +babel_get_route_info(rte *rte, byte *buf) { buf += bsprintf(buf, " (%d/%d) [%lR]", rte->pref, rte->u.babel.metric, rte->u.babel.router_id); } @@ -2091,12 +2091,13 @@ babel_prepare_attrs(struct linpool *pool, ea_list *next, uint metric, u64 router static int -babel_import_control(struct proto *P, struct rte **new, struct ea_list **attrs UNUSED, struct linpool *pool UNUSED) +babel_import_control(struct proto *P, struct rte **new, struct linpool *pool) { - rte *e = *new; + struct babel_proto *p = (void *) P; + struct rta *a = (*new)->attrs; /* Reject our own unreachable routes */ - if ((e->attrs->dest == RTD_UNREACHABLE) && (e->attrs->src->proto == P)) + if ((a->dest == RTD_UNREACHABLE) && (a->src->proto == P)) return -1; return 0; @@ -2109,9 +2110,9 @@ babel_make_tmp_attrs(struct rte *rt, struct linpool *pool) } static void -babel_store_tmp_attrs(struct rte *rt, struct ea_list *attrs) +babel_store_tmp_attrs(struct rte *rt) { - rt->u.babel.metric = ea_get_int(attrs, EA_BABEL_METRIC, 0); + rt->u.babel.metric = ea_get_int(rt->attrs->eattrs, EA_BABEL_METRIC, 0); } /* @@ -2120,7 +2121,7 @@ babel_store_tmp_attrs(struct rte *rt, struct ea_list *attrs) */ static void babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net, - struct rte *new, struct rte *old UNUSED, struct ea_list *attrs UNUSED) + struct rte *new, struct rte *old UNUSED) { struct babel_proto *p = (void *) P; struct babel_entry *e; @@ -2130,7 +2131,7 @@ babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net, /* Update */ uint internal = (new->attrs->src->proto == P); uint rt_seqno = internal ? new->u.babel.seqno : p->update_seqno; - uint rt_metric = ea_get_int(attrs, EA_BABEL_METRIC, 0); + uint rt_metric = ea_get_int(new->attrs->eattrs, EA_BABEL_METRIC, 0); u64 rt_router_id = internal ? new->u.babel.router_id : p->router_id; if (rt_metric > BABEL_INFINITY) @@ -2316,7 +2317,7 @@ babel_reconfigure(struct proto *P, struct proto_config *CF) struct protocol proto_babel = { .name = "Babel", .template = "babel%d", - .attr_class = EAP_BABEL, + .class = PROTOCOL_BABEL, .preference = DEF_PREF_BABEL, .channel_mask = NB_IP | NB_IP6_SADR, .proto_size = sizeof(struct babel_proto), diff --git a/proto/babel/babel.h b/proto/babel/babel.h index e5c9cd5b..14765c60 100644 --- a/proto/babel/babel.h +++ b/proto/babel/babel.h @@ -25,8 +25,8 @@ #include "lib/string.h" #include "lib/timer.h" -#define EA_BABEL_METRIC EA_CODE(EAP_BABEL, 0) -#define EA_BABEL_ROUTER_ID EA_CODE(EAP_BABEL, 1) +#define EA_BABEL_METRIC EA_CODE(PROTOCOL_BABEL, 0) +#define EA_BABEL_ROUTER_ID EA_CODE(PROTOCOL_BABEL, 1) #define BABEL_MAGIC 42 #define BABEL_VERSION 2 diff --git a/proto/babel/config.Y b/proto/babel/config.Y index 205b4e4f..2b20c43f 100644 --- a/proto/babel/config.Y +++ b/proto/babel/config.Y @@ -125,7 +125,7 @@ babel_iface_opt_list: babel_iface: babel_iface_start iface_patt_list_nopx babel_iface_opt_list babel_iface_finish; -CF_ADDTO(dynamic_attr, BABEL_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_BABEL_METRIC); }) +CF_ADDTO(dynamic_attr, BABEL_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_BABEL_METRIC); }) CF_CLI_HELP(SHOW BABEL, ..., [[Show information about Babel protocol]]); diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c index 67ec2270..64d5007b 100644 --- a/proto/bfd/bfd.c +++ b/proto/bfd/bfd.c @@ -1116,6 +1116,7 @@ bfd_show_sessions(struct proto *P) struct protocol proto_bfd = { .name = "BFD", .template = "bfd%d", + .class = PROTOCOL_BFD, .proto_size = sizeof(struct bfd_proto), .config_size = sizeof(struct bfd_config), .init = bfd_init, diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index d7a4e692..8ecfaaa2 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -92,7 +92,7 @@ bgp_set_attr(ea_list **attrs, struct linpool *pool, uint code, uint flags, uintp a->next = *attrs; *attrs = a; - e->id = EA_CODE(EAP_BGP, code); + e->id = EA_CODE(PROTOCOL_BGP, code); e->type = bgp_attr_table[code].type; e->flags = flags; @@ -702,7 +702,7 @@ static inline void bgp_decode_unknown(struct bgp_parse_state *s, uint code, uint flags, byte *data, uint len, ea_list **to) { /* Cannot use bgp_set_attr_data() as it works on known attributes only */ - ea_set_attr_data(to, s->pool, EA_CODE(EAP_BGP, code), flags, EAF_TYPE_OPAQUE, data, len); + ea_set_attr_data(to, s->pool, EA_CODE(PROTOCOL_BGP, code), flags, EAF_TYPE_OPAQUE, data, len); } @@ -857,7 +857,7 @@ bgp_attr_known(uint code) static inline void bgp_export_attr(struct bgp_export_state *s, eattr *a, ea_list *to) { - if (EA_PROTO(a->id) != EAP_BGP) + if (EA_PROTO(a->id) != PROTOCOL_BGP) return; uint code = EA_ID(a->id); @@ -937,7 +937,7 @@ bgp_export_attrs(struct bgp_export_state *s, ea_list *attrs) static inline int bgp_encode_attr(struct bgp_write_state *s, eattr *a, byte *buf, uint size) { - ASSERT(EA_PROTO(a->id) == EAP_BGP); + ASSERT(EA_PROTO(a->id) == PROTOCOL_BGP); uint code = EA_ID(a->id); @@ -1375,7 +1375,7 @@ bgp_free_prefix(struct bgp_channel *c, struct bgp_prefix *px) */ int -bgp_import_control(struct proto *P, rte **new, ea_list **attrs UNUSED, struct linpool *pool UNUSED) +bgp_import_control(struct proto *P, rte **new, struct linpool *pool UNUSED) { rte *e = *new; struct proto *SRC = e->attrs->src->proto; @@ -1408,7 +1408,7 @@ bgp_import_control(struct proto *P, rte **new, ea_list **attrs UNUSED, struct li /* Handle well-known communities, RFC 1997 */ struct eattr *c; if (p->cf->interpret_communities && - (c = ea_find(e->attrs->eattrs, EA_CODE(EAP_BGP, BA_COMMUNITY)))) + (c = ea_find(e->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_COMMUNITY)))) { struct adata *d = c->u.ptr; @@ -1539,7 +1539,7 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at } void -bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old, ea_list *attrs) +bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old) { struct bgp_proto *p = (void *) P; struct bgp_channel *c = (void *) C; @@ -1549,7 +1549,7 @@ bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old, ea if (new) { - attrs = bgp_update_attrs(p, c, new, attrs, bgp_linpool2); + struct ea_list *attrs = bgp_update_attrs(p, c, new, new->attrs->eattrs, bgp_linpool2); /* If attributes are invalid, we fail back to withdraw */ buck = attrs ? bgp_get_bucket(c, attrs) : bgp_get_withdraw_bucket(c); @@ -1573,7 +1573,7 @@ bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old, ea static inline u32 bgp_get_neighbor(rte *r) { - eattr *e = ea_find(r->attrs->eattrs, EA_CODE(EAP_BGP, BA_AS_PATH)); + eattr *e = ea_find(r->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_AS_PATH)); u32 as; if (e && as_path_get_first_regular(e->u.ptr, &as)) @@ -1615,8 +1615,8 @@ bgp_rte_better(rte *new, rte *old) return 0; /* Start with local preferences */ - x = ea_find(new->attrs->eattrs, EA_CODE(EAP_BGP, BA_LOCAL_PREF)); - y = ea_find(old->attrs->eattrs, EA_CODE(EAP_BGP, BA_LOCAL_PREF)); + x = ea_find(new->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_LOCAL_PREF)); + y = ea_find(old->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_LOCAL_PREF)); n = x ? x->u.data : new_bgp->cf->default_local_pref; o = y ? y->u.data : old_bgp->cf->default_local_pref; if (n > o) @@ -1627,8 +1627,8 @@ bgp_rte_better(rte *new, rte *old) /* RFC 4271 9.1.2.2. a) Use AS path lengths */ if (new_bgp->cf->compare_path_lengths || old_bgp->cf->compare_path_lengths) { - x = ea_find(new->attrs->eattrs, EA_CODE(EAP_BGP, BA_AS_PATH)); - y = ea_find(old->attrs->eattrs, EA_CODE(EAP_BGP, BA_AS_PATH)); + x = ea_find(new->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_AS_PATH)); + y = ea_find(old->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_AS_PATH)); n = x ? as_path_getlen(x->u.ptr) : AS_PATH_MAXLEN; o = y ? as_path_getlen(y->u.ptr) : AS_PATH_MAXLEN; if (n < o) @@ -1638,8 +1638,8 @@ bgp_rte_better(rte *new, rte *old) } /* RFC 4271 9.1.2.2. b) Use origins */ - x = ea_find(new->attrs->eattrs, EA_CODE(EAP_BGP, BA_ORIGIN)); - y = ea_find(old->attrs->eattrs, EA_CODE(EAP_BGP, BA_ORIGIN)); + x = ea_find(new->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_ORIGIN)); + y = ea_find(old->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_ORIGIN)); n = x ? x->u.data : ORIGIN_INCOMPLETE; o = y ? y->u.data : ORIGIN_INCOMPLETE; if (n < o) @@ -1661,8 +1661,8 @@ bgp_rte_better(rte *new, rte *old) if (new_bgp->cf->med_metric || old_bgp->cf->med_metric || (bgp_get_neighbor(new) == bgp_get_neighbor(old))) { - x = ea_find(new->attrs->eattrs, EA_CODE(EAP_BGP, BA_MULTI_EXIT_DISC)); - y = ea_find(old->attrs->eattrs, EA_CODE(EAP_BGP, BA_MULTI_EXIT_DISC)); + x = ea_find(new->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_MULTI_EXIT_DISC)); + y = ea_find(old->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_MULTI_EXIT_DISC)); n = x ? x->u.data : new_bgp->cf->default_med; o = y ? y->u.data : old_bgp->cf->default_med; if (n < o) @@ -1687,8 +1687,8 @@ bgp_rte_better(rte *new, rte *old) /* RFC 4271 9.1.2.2. f) Compare BGP identifiers */ /* RFC 4456 9. a) Use ORIGINATOR_ID instead of local neighbor ID */ - x = ea_find(new->attrs->eattrs, EA_CODE(EAP_BGP, BA_ORIGINATOR_ID)); - y = ea_find(old->attrs->eattrs, EA_CODE(EAP_BGP, BA_ORIGINATOR_ID)); + x = ea_find(new->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_ORIGINATOR_ID)); + y = ea_find(old->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_ORIGINATOR_ID)); n = x ? x->u.data : new_bgp->remote_id; o = y ? y->u.data : old_bgp->remote_id; @@ -1705,8 +1705,8 @@ bgp_rte_better(rte *new, rte *old) return 0; /* RFC 4456 9. b) Compare cluster list lengths */ - x = ea_find(new->attrs->eattrs, EA_CODE(EAP_BGP, BA_CLUSTER_LIST)); - y = ea_find(old->attrs->eattrs, EA_CODE(EAP_BGP, BA_CLUSTER_LIST)); + x = ea_find(new->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_CLUSTER_LIST)); + y = ea_find(old->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_CLUSTER_LIST)); n = x ? int_set_get_size(x->u.ptr) : 0; o = y ? int_set_get_size(y->u.ptr) : 0; if (n < o) @@ -1736,8 +1736,8 @@ bgp_rte_mergable(rte *pri, rte *sec) return 0; /* Start with local preferences */ - x = ea_find(pri->attrs->eattrs, EA_CODE(EAP_BGP, BA_LOCAL_PREF)); - y = ea_find(sec->attrs->eattrs, EA_CODE(EAP_BGP, BA_LOCAL_PREF)); + x = ea_find(pri->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_LOCAL_PREF)); + y = ea_find(sec->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_LOCAL_PREF)); p = x ? x->u.data : pri_bgp->cf->default_local_pref; s = y ? y->u.data : sec_bgp->cf->default_local_pref; if (p != s) @@ -1746,8 +1746,8 @@ bgp_rte_mergable(rte *pri, rte *sec) /* RFC 4271 9.1.2.2. a) Use AS path lengths */ if (pri_bgp->cf->compare_path_lengths || sec_bgp->cf->compare_path_lengths) { - x = ea_find(pri->attrs->eattrs, EA_CODE(EAP_BGP, BA_AS_PATH)); - y = ea_find(sec->attrs->eattrs, EA_CODE(EAP_BGP, BA_AS_PATH)); + x = ea_find(pri->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_AS_PATH)); + y = ea_find(sec->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_AS_PATH)); p = x ? as_path_getlen(x->u.ptr) : AS_PATH_MAXLEN; s = y ? as_path_getlen(y->u.ptr) : AS_PATH_MAXLEN; @@ -1759,8 +1759,8 @@ bgp_rte_mergable(rte *pri, rte *sec) } /* RFC 4271 9.1.2.2. b) Use origins */ - x = ea_find(pri->attrs->eattrs, EA_CODE(EAP_BGP, BA_ORIGIN)); - y = ea_find(sec->attrs->eattrs, EA_CODE(EAP_BGP, BA_ORIGIN)); + x = ea_find(pri->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_ORIGIN)); + y = ea_find(sec->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_ORIGIN)); p = x ? x->u.data : ORIGIN_INCOMPLETE; s = y ? y->u.data : ORIGIN_INCOMPLETE; if (p != s) @@ -1770,8 +1770,8 @@ bgp_rte_mergable(rte *pri, rte *sec) if (pri_bgp->cf->med_metric || sec_bgp->cf->med_metric || (bgp_get_neighbor(pri) == bgp_get_neighbor(sec))) { - x = ea_find(pri->attrs->eattrs, EA_CODE(EAP_BGP, BA_MULTI_EXIT_DISC)); - y = ea_find(sec->attrs->eattrs, EA_CODE(EAP_BGP, BA_MULTI_EXIT_DISC)); + x = ea_find(pri->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_MULTI_EXIT_DISC)); + y = ea_find(sec->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_MULTI_EXIT_DISC)); p = x ? x->u.data : pri_bgp->cf->default_med; s = y ? y->u.data : sec_bgp->cf->default_med; if (p != s) @@ -2010,10 +2010,10 @@ bgp_get_attr(eattr *a, byte *buf, int buflen) } void -bgp_get_route_info(rte *e, byte *buf, ea_list *attrs) +bgp_get_route_info(rte *e, byte *buf) { - eattr *p = ea_find(attrs, EA_CODE(EAP_BGP, BA_AS_PATH)); - eattr *o = ea_find(attrs, EA_CODE(EAP_BGP, BA_ORIGIN)); + eattr *p = ea_find(e->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_AS_PATH)); + eattr *o = ea_find(e->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_ORIGIN)); u32 origas; buf += bsprintf(buf, " (%d", e->pref); diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 9db26050..932ad9f3 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -2148,7 +2148,7 @@ struct channel_class channel_bgp = { struct protocol proto_bgp = { .name = "BGP", .template = "bgp%d", - .attr_class = EAP_BGP, + .class = PROTOCOL_BGP, .preference = DEF_PREF_BGP, .channel_mask = NB_IP | NB_VPN | NB_FLOW, .proto_size = sizeof(struct bgp_proto), diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index 30424abb..1235ee78 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -462,7 +462,7 @@ struct rte_source *bgp_get_source(struct bgp_proto *p, u32 path_id); static inline eattr * bgp_find_attr(ea_list *attrs, uint code) { - return ea_find(attrs, EA_CODE(EAP_BGP, code)); + return ea_find(attrs, EA_CODE(PROTOCOL_BGP, code)); } eattr * @@ -505,10 +505,10 @@ void bgp_free_prefix(struct bgp_channel *c, struct bgp_prefix *bp); int bgp_rte_better(struct rte *, struct rte *); int bgp_rte_mergable(rte *pri, rte *sec); int bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best); -void bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old, ea_list *attrs); -int bgp_import_control(struct proto *, struct rte **, struct ea_list **, struct linpool *); +void bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old); +int bgp_import_control(struct proto *, struct rte **, struct linpool *); int bgp_get_attr(struct eattr *e, byte *buf, int buflen); -void bgp_get_route_info(struct rte *, byte *buf, struct ea_list *attrs); +void bgp_get_route_info(struct rte *, byte *buf); /* packets.c */ diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y index 41eaa729..c731c4c7 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -253,29 +253,29 @@ bgp_proto_channel: bgp_channel_start bgp_channel_opt_list bgp_channel_end; CF_ADDTO(dynamic_attr, BGP_ORIGIN - { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_ENUM_BGP_ORIGIN, EA_CODE(EAP_BGP, BA_ORIGIN)); }) + { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_ENUM_BGP_ORIGIN, EA_CODE(PROTOCOL_BGP, BA_ORIGIN)); }) CF_ADDTO(dynamic_attr, BGP_PATH - { $$ = f_new_dynamic_attr(EAF_TYPE_AS_PATH, T_PATH, EA_CODE(EAP_BGP, BA_AS_PATH)); }) + { $$ = f_new_dynamic_attr(EAF_TYPE_AS_PATH, T_PATH, EA_CODE(PROTOCOL_BGP, BA_AS_PATH)); }) CF_ADDTO(dynamic_attr, BGP_NEXT_HOP - { $$ = f_new_dynamic_attr(EAF_TYPE_IP_ADDRESS, T_IP, EA_CODE(EAP_BGP, BA_NEXT_HOP)); }) + { $$ = f_new_dynamic_attr(EAF_TYPE_IP_ADDRESS, T_IP, EA_CODE(PROTOCOL_BGP, BA_NEXT_HOP)); }) CF_ADDTO(dynamic_attr, BGP_MED - { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_CODE(EAP_BGP, BA_MULTI_EXIT_DISC)); }) + { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_CODE(PROTOCOL_BGP, BA_MULTI_EXIT_DISC)); }) CF_ADDTO(dynamic_attr, BGP_LOCAL_PREF - { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_CODE(EAP_BGP, BA_LOCAL_PREF)); }) + { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_CODE(PROTOCOL_BGP, BA_LOCAL_PREF)); }) CF_ADDTO(dynamic_attr, BGP_ATOMIC_AGGR - { $$ = f_new_dynamic_attr(EAF_TYPE_OPAQUE, T_ENUM_EMPTY, EA_CODE(EAP_BGP, BA_ATOMIC_AGGR)); }) + { $$ = f_new_dynamic_attr(EAF_TYPE_OPAQUE, T_ENUM_EMPTY, EA_CODE(PROTOCOL_BGP, BA_ATOMIC_AGGR)); }) CF_ADDTO(dynamic_attr, BGP_AGGREGATOR - { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_CODE(EAP_BGP, BA_AGGREGATOR)); }) + { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_CODE(PROTOCOL_BGP, BA_AGGREGATOR)); }) CF_ADDTO(dynamic_attr, BGP_COMMUNITY - { $$ = f_new_dynamic_attr(EAF_TYPE_INT_SET, T_CLIST, EA_CODE(EAP_BGP, BA_COMMUNITY)); }) + { $$ = f_new_dynamic_attr(EAF_TYPE_INT_SET, T_CLIST, EA_CODE(PROTOCOL_BGP, BA_COMMUNITY)); }) CF_ADDTO(dynamic_attr, BGP_ORIGINATOR_ID - { $$ = f_new_dynamic_attr(EAF_TYPE_ROUTER_ID, T_QUAD, EA_CODE(EAP_BGP, BA_ORIGINATOR_ID)); }) + { $$ = f_new_dynamic_attr(EAF_TYPE_ROUTER_ID, T_QUAD, EA_CODE(PROTOCOL_BGP, BA_ORIGINATOR_ID)); }) CF_ADDTO(dynamic_attr, BGP_CLUSTER_LIST - { $$ = f_new_dynamic_attr(EAF_TYPE_INT_SET, T_CLIST, EA_CODE(EAP_BGP, BA_CLUSTER_LIST)); }) + { $$ = f_new_dynamic_attr(EAF_TYPE_INT_SET, T_CLIST, EA_CODE(PROTOCOL_BGP, BA_CLUSTER_LIST)); }) CF_ADDTO(dynamic_attr, BGP_EXT_COMMUNITY - { $$ = f_new_dynamic_attr(EAF_TYPE_EC_SET, T_ECLIST, EA_CODE(EAP_BGP, BA_EXT_COMMUNITY)); }) + { $$ = f_new_dynamic_attr(EAF_TYPE_EC_SET, T_ECLIST, EA_CODE(PROTOCOL_BGP, BA_EXT_COMMUNITY)); }) CF_ADDTO(dynamic_attr, BGP_LARGE_COMMUNITY - { $$ = f_new_dynamic_attr(EAF_TYPE_LC_SET, T_LCLIST, EA_CODE(EAP_BGP, BA_LARGE_COMMUNITY)); }) + { $$ = f_new_dynamic_attr(EAF_TYPE_LC_SET, T_LCLIST, EA_CODE(PROTOCOL_BGP, BA_LARGE_COMMUNITY)); }) diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y index 0b09966d..c439a614 100644 --- a/proto/ospf/config.Y +++ b/proto/ospf/config.Y @@ -497,10 +497,10 @@ ospf_iface: ospf_iface_start ospf_iface_patt_list ospf_iface_opt_list { ospf_iface_finish(); } ; -CF_ADDTO(dynamic_attr, OSPF_METRIC1 { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_METRIC1); }) -CF_ADDTO(dynamic_attr, OSPF_METRIC2 { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_METRIC2); }) -CF_ADDTO(dynamic_attr, OSPF_TAG { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_TAG); }) -CF_ADDTO(dynamic_attr, OSPF_ROUTER_ID { $$ = f_new_dynamic_attr(EAF_TYPE_ROUTER_ID | EAF_TEMP, T_QUAD, EA_OSPF_ROUTER_ID); }) +CF_ADDTO(dynamic_attr, OSPF_METRIC1 { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_OSPF_METRIC1); }) +CF_ADDTO(dynamic_attr, OSPF_METRIC2 { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_OSPF_METRIC2); }) +CF_ADDTO(dynamic_attr, OSPF_TAG { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_OSPF_TAG); }) +CF_ADDTO(dynamic_attr, OSPF_ROUTER_ID { $$ = f_new_dynamic_attr(EAF_TYPE_ROUTER_ID, T_QUAD, EA_OSPF_ROUTER_ID); }) CF_CLI_HELP(SHOW OSPF, ..., [[Show information about OSPF protocol]]); CF_CLI(SHOW OSPF, optsym, [<name>], [[Show information about OSPF protocol]]) diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 0a9efd19..fa122f01 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -101,9 +101,9 @@ #include <stdlib.h> #include "ospf.h" -static int ospf_import_control(struct proto *P, rte **new, ea_list **attrs, struct linpool *pool); +static int ospf_import_control(struct proto *P, rte **new, struct linpool *pool); static struct ea_list *ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool); -static void ospf_store_tmp_attrs(struct rte *rt, struct ea_list *attrs); +static void ospf_store_tmp_attrs(struct rte *rt); static void ospf_reload_routes(struct channel *C); static int ospf_rte_better(struct rte *new, struct rte *old); static int ospf_rte_same(struct rte *new, struct rte *old); @@ -446,7 +446,7 @@ ospf_disp(timer * timer) * import to the filters. */ static int -ospf_import_control(struct proto *P, rte **new, ea_list **attrs UNUSED, struct linpool *pool UNUSED) +ospf_import_control(struct proto *P, rte **new, struct linpool *pool) { struct ospf_proto *p = (struct ospf_proto *) P; struct ospf_area *oa = ospf_main_area(p); @@ -471,12 +471,12 @@ ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool) } static void -ospf_store_tmp_attrs(struct rte *rt, struct ea_list *attrs) +ospf_store_tmp_attrs(struct rte *rt) { - rt->u.ospf.metric1 = ea_get_int(attrs, EA_OSPF_METRIC1, LSINFINITY); - rt->u.ospf.metric2 = ea_get_int(attrs, EA_OSPF_METRIC2, 10000); - rt->u.ospf.tag = ea_get_int(attrs, EA_OSPF_TAG, 0); - rt->u.ospf.router_id = ea_get_int(attrs, EA_OSPF_ROUTER_ID, 0); + rt->u.ospf.metric1 = ea_get_int(rt->attrs->eattrs, EA_OSPF_METRIC1, LSINFINITY); + rt->u.ospf.metric2 = ea_get_int(rt->attrs->eattrs, EA_OSPF_METRIC2, 10000); + rt->u.ospf.tag = ea_get_int(rt->attrs->eattrs, EA_OSPF_TAG, 0); + rt->u.ospf.router_id = ea_get_int(rt->attrs->eattrs, EA_OSPF_ROUTER_ID, 0); } /** @@ -535,7 +535,7 @@ ospf_get_status(struct proto *P, byte * buf) } static void -ospf_get_route_info(rte * rte, byte * buf, ea_list * attrs UNUSED) +ospf_get_route_info(rte * rte, byte * buf) { char *type = "<bug>"; @@ -1463,7 +1463,7 @@ ospf_sh_lsadb(struct lsadb_show_data *ld) struct protocol proto_ospf = { .name = "OSPF", .template = "ospf%d", - .attr_class = EAP_OSPF, + .class = PROTOCOL_OSPF, .preference = DEF_PREF_OSPF, .channel_mask = NB_IP, .proto_size = sizeof(struct ospf_proto), diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index f26ed99c..ff55621a 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -863,10 +863,10 @@ struct lsadb_show_data { }; -#define EA_OSPF_METRIC1 EA_CODE(EAP_OSPF, 0) -#define EA_OSPF_METRIC2 EA_CODE(EAP_OSPF, 1) -#define EA_OSPF_TAG EA_CODE(EAP_OSPF, 2) -#define EA_OSPF_ROUTER_ID EA_CODE(EAP_OSPF, 3) +#define EA_OSPF_METRIC1 EA_CODE(PROTOCOL_OSPF, 0) +#define EA_OSPF_METRIC2 EA_CODE(PROTOCOL_OSPF, 1) +#define EA_OSPF_TAG EA_CODE(PROTOCOL_OSPF, 2) +#define EA_OSPF_ROUTER_ID EA_CODE(PROTOCOL_OSPF, 3) /* ospf.c */ diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c index e909bbe9..54b255c9 100644 --- a/proto/ospf/topology.c +++ b/proto/ospf/topology.c @@ -1243,11 +1243,12 @@ find_surrogate_fwaddr(struct ospf_proto *p, struct ospf_area *oa) } void -ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte *old UNUSED, ea_list *ea) +ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte *old UNUSED) { struct ospf_proto *p = (struct ospf_proto *) P; struct ospf_area *oa = NULL; /* non-NULL for NSSA-LSA */ ort *nf; + struct ea_list *ea = new->attrs->eattrs; /* * There are several posibilities: diff --git a/proto/ospf/topology.h b/proto/ospf/topology.h index ac87334b..54ec9ccf 100644 --- a/proto/ospf/topology.h +++ b/proto/ospf/topology.h @@ -188,7 +188,7 @@ void ospf_originate_sum_net_lsa(struct ospf_proto *p, struct ospf_area *oa, ort void ospf_originate_sum_rt_lsa(struct ospf_proto *p, struct ospf_area *oa, u32 drid, int metric, u32 options); void ospf_originate_ext_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, u8 mode, u32 metric, u32 ebit, ip_addr fwaddr, u32 tag, int pbit); -void ospf_rt_notify(struct proto *P, struct channel *ch, net *n, rte *new, rte *old, ea_list *attrs); +void ospf_rt_notify(struct proto *P, struct channel *ch, net *n, rte *new, rte *old); void ospf_update_topology(struct ospf_proto *p); struct top_hash_entry *ospf_hash_find(struct top_graph *, u32 domain, u32 lsa, u32 rtr, u32 type); diff --git a/proto/pipe/pipe.c b/proto/pipe/pipe.c index 49ff52e2..7aada37e 100644 --- a/proto/pipe/pipe.c +++ b/proto/pipe/pipe.c @@ -44,7 +44,7 @@ #include "pipe.h" static void -pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *old, ea_list *attrs) +pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *old) { struct pipe_proto *p = (void *) P; struct channel *dst = (src_ch == p->pri) ? p->sec : p->pri; @@ -69,7 +69,6 @@ pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *o memcpy(a, new->attrs, rta_size(new->attrs)); a->aflags = 0; - a->eattrs = attrs; a->hostentry = NULL; e = rte_get_temp(a); e->pflags = 0; @@ -93,7 +92,7 @@ pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *o } static int -pipe_import_control(struct proto *P, rte **ee, ea_list **ea UNUSED, struct linpool *p UNUSED) +pipe_import_control(struct proto *P, rte **ee, struct linpool *p UNUSED) { struct proto *pp = (*ee)->sender->proto; @@ -275,6 +274,7 @@ pipe_show_proto_info(struct proto *P) struct protocol proto_pipe = { .name = "Pipe", .template = "pipe%d", + .class = PROTOCOL_PIPE, .proto_size = sizeof(struct pipe_proto), .config_size = sizeof(struct pipe_config), .postconfig = pipe_postconfig, diff --git a/proto/radv/radv.c b/proto/radv/radv.c index 8a79dfaf..ce88c7cc 100644 --- a/proto/radv/radv.c +++ b/proto/radv/radv.c @@ -395,7 +395,7 @@ radv_net_match_trigger(struct radv_config *cf, net *n) } int -radv_import_control(struct proto *P, rte **new, ea_list **attrs UNUSED, struct linpool *pool UNUSED) +radv_import_control(struct proto *P, rte **new, struct linpool *pool UNUSED) { // struct radv_proto *p = (struct radv_proto *) P; struct radv_config *cf = (struct radv_config *) (P->cf); @@ -410,7 +410,7 @@ radv_import_control(struct proto *P, rte **new, ea_list **attrs UNUSED, struct l } static void -radv_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte *old UNUSED, ea_list *attrs) +radv_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte *old UNUSED) { struct radv_proto *p = (struct radv_proto *) P; struct radv_config *cf = (struct radv_config *) (P->cf); @@ -448,11 +448,11 @@ radv_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte { /* Update */ - ea = ea_find(attrs, EA_RA_PREFERENCE); + ea = ea_find(new->attrs->eattrs, EA_RA_PREFERENCE); uint preference = ea ? ea->u.data : RA_PREF_MEDIUM; uint preference_set = !!ea; - ea = ea_find(attrs, EA_RA_LIFETIME); + ea = ea_find(new->attrs->eattrs, EA_RA_LIFETIME); uint lifetime = ea ? ea->u.data : 0; uint lifetime_set = !!ea; @@ -762,7 +762,7 @@ radv_get_attr(eattr *a, byte *buf, int buflen UNUSED) struct protocol proto_radv = { .name = "RAdv", .template = "radv%d", - .attr_class = EAP_RADV, + .class = PROTOCOL_RADV, .channel_mask = NB_IP6, .proto_size = sizeof(struct radv_proto), .config_size = sizeof(struct radv_config), diff --git a/proto/radv/radv.h b/proto/radv/radv.h index 66f785a7..719948d5 100644 --- a/proto/radv/radv.h +++ b/proto/radv/radv.h @@ -192,8 +192,8 @@ struct radv_iface #define RA_PREF_MASK 0x18 /* Attributes */ -#define EA_RA_PREFERENCE EA_CODE(EAP_RADV, 0) -#define EA_RA_LIFETIME EA_CODE(EAP_RADV, 1) +#define EA_RA_PREFERENCE EA_CODE(PROTOCOL_RADV, 0) +#define EA_RA_LIFETIME EA_CODE(PROTOCOL_RADV, 1) #ifdef LOCAL_DEBUG #define RADV_FORCE_DEBUG 1 diff --git a/proto/rip/config.Y b/proto/rip/config.Y index aff63f03..c46cf00c 100644 --- a/proto/rip/config.Y +++ b/proto/rip/config.Y @@ -186,8 +186,8 @@ rip_iface: rip_iface_start iface_patt_list_nopx rip_iface_opt_list rip_iface_finish; -CF_ADDTO(dynamic_attr, RIP_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_RIP_METRIC); }) -CF_ADDTO(dynamic_attr, RIP_TAG { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_RIP_TAG); }) +CF_ADDTO(dynamic_attr, RIP_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_RIP_METRIC); }) +CF_ADDTO(dynamic_attr, RIP_TAG { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_RIP_TAG); }) CF_CLI_HELP(SHOW RIP, ..., [[Show information about RIP protocol]]); diff --git a/proto/rip/rip.c b/proto/rip/rip.c index baf98737..90bf8e5c 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -298,7 +298,7 @@ rip_withdraw_rte(struct rip_proto *p, net_addr *n, struct rip_neighbor *from) */ static void rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, struct rte *new, - struct rte *old UNUSED, struct ea_list *attrs) + struct rte *old UNUSED) { struct rip_proto *p = (struct rip_proto *) P; struct rip_entry *en; @@ -307,8 +307,8 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, s if (new) { /* Update */ - u32 rt_metric = ea_get_int(attrs, EA_RIP_METRIC, 1); - u32 rt_tag = ea_get_int(attrs, EA_RIP_TAG, 0); + u32 rt_metric = ea_get_int(new->attrs->eattrs, EA_RIP_METRIC, 1); + u32 rt_tag = ea_get_int(new->attrs->eattrs, EA_RIP_TAG, 0); if (rt_metric > p->infinity) { @@ -1040,10 +1040,10 @@ rip_make_tmp_attrs(struct rte *rt, struct linpool *pool) } static void -rip_store_tmp_attrs(struct rte *rt, struct ea_list *attrs) +rip_store_tmp_attrs(struct rte *rt) { - rt->u.rip.metric = ea_get_int(attrs, EA_RIP_METRIC, 1); - rt->u.rip.tag = ea_get_int(attrs, EA_RIP_TAG, 0); + rt->u.rip.metric = ea_get_int(rt->attrs->eattrs, EA_RIP_METRIC, 1); + rt->u.rip.tag = ea_get_int(rt->attrs->eattrs, EA_RIP_TAG, 0); } static int @@ -1081,7 +1081,6 @@ rip_init(struct proto_config *CF) P->if_notify = rip_if_notify; P->rt_notify = rip_rt_notify; P->neigh_notify = rip_neigh_notify; - // P->import_control = rip_import_control; P->reload_routes = rip_reload_routes; P->make_tmp_attrs = rip_make_tmp_attrs; P->store_tmp_attrs = rip_store_tmp_attrs; @@ -1145,7 +1144,7 @@ rip_reconfigure(struct proto *P, struct proto_config *CF) } static void -rip_get_route_info(rte *rte, byte *buf, ea_list *attrs UNUSED) +rip_get_route_info(rte *rte, byte *buf) { buf += bsprintf(buf, " (%d/%d)", rte->pref, rte->u.rip.metric); @@ -1274,7 +1273,7 @@ rip_dump(struct proto *P) struct protocol proto_rip = { .name = "RIP", .template = "rip%d", - .attr_class = EAP_RIP, + .class = PROTOCOL_RIP, .preference = DEF_PREF_RIP, .channel_mask = NB_IP, .proto_size = sizeof(struct rip_proto), diff --git a/proto/rip/rip.h b/proto/rip/rip.h index 55696333..2dc34862 100644 --- a/proto/rip/rip.h +++ b/proto/rip/rip.h @@ -182,8 +182,8 @@ struct rip_rte #define RIP_ENTRY_VALID 1 /* Valid outgoing route */ #define RIP_ENTRY_STALE 2 /* Stale outgoing route, waiting for GC */ -#define EA_RIP_METRIC EA_CODE(EAP_RIP, 0) -#define EA_RIP_TAG EA_CODE(EAP_RIP, 1) +#define EA_RIP_METRIC EA_CODE(PROTOCOL_RIP, 0) +#define EA_RIP_TAG EA_CODE(PROTOCOL_RIP, 1) static inline int rip_is_v2(struct rip_proto *p) { return p->rip2; } diff --git a/proto/rpki/rpki.c b/proto/rpki/rpki.c index 74860071..36097dc5 100644 --- a/proto/rpki/rpki.c +++ b/proto/rpki/rpki.c @@ -913,6 +913,7 @@ rpki_copy_config(struct proto_config *dest UNUSED, struct proto_config *src UNUS struct protocol proto_rpki = { .name = "RPKI", .template = "rpki%d", + .class = PROTOCOL_RPKI, .preference = DEF_PREF_RPKI, .proto_size = sizeof(struct rpki_proto), .config_size = sizeof(struct rpki_config), diff --git a/proto/static/static.c b/proto/static/static.c index ede4c734..8dfa6f35 100644 --- a/proto/static/static.c +++ b/proto/static/static.c @@ -656,6 +656,7 @@ static_show(struct proto *P) struct protocol proto_static = { .name = "Static", .template = "static%d", + .class = PROTOCOL_STATIC, .preference = DEF_PREF_STATIC, .channel_mask = NB_ANY, .proto_size = sizeof(struct static_proto), diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c index e56dd616..8522e415 100644 --- a/sysdep/bsd/krt-sock.c +++ b/sysdep/bsd/krt-sock.c @@ -347,8 +347,7 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e) } void -krt_replace_rte(struct krt_proto *p, net *n, rte *new, rte *old, - struct ea_list *eattrs UNUSED) +krt_replace_rte(struct krt_proto *p, net *n, rte *new, rte *old) { int err = 0; diff --git a/sysdep/linux/krt-sys.h b/sysdep/linux/krt-sys.h index 76ae29b7..2b8cdaa7 100644 --- a/sysdep/linux/krt-sys.h +++ b/sysdep/linux/krt-sys.h @@ -34,9 +34,9 @@ static inline struct ifa * kif_get_primary_ip(struct iface *i UNUSED) { return N #define KRT_ALLOW_MERGE_PATHS 1 -#define EA_KRT_PREFSRC EA_CODE(EAP_KRT, 0x10) -#define EA_KRT_REALM EA_CODE(EAP_KRT, 0x11) -#define EA_KRT_SCOPE EA_CODE(EAP_KRT, 0x12) +#define EA_KRT_PREFSRC EA_CODE(PROTOCOL_KERNEL, 0x10) +#define EA_KRT_REALM EA_CODE(PROTOCOL_KERNEL, 0x11) +#define EA_KRT_SCOPE EA_CODE(PROTOCOL_KERNEL, 0x12) #define KRT_METRICS_MAX 0x10 /* RTAX_QUICKACK+1 */ @@ -48,22 +48,22 @@ static inline struct ifa * kif_get_primary_ip(struct iface *i UNUSED) { return N * Following attributes are parts of RTA_METRICS kernel route attribute, their * ids must be consistent with their RTAX_* constants (+ KRT_METRICS_OFFSET) */ -#define EA_KRT_METRICS EA_CODE(EAP_KRT, 0x20) /* Dummy one */ -#define EA_KRT_LOCK EA_CODE(EAP_KRT, 0x21) -#define EA_KRT_MTU EA_CODE(EAP_KRT, 0x22) -#define EA_KRT_WINDOW EA_CODE(EAP_KRT, 0x23) -#define EA_KRT_RTT EA_CODE(EAP_KRT, 0x24) -#define EA_KRT_RTTVAR EA_CODE(EAP_KRT, 0x25) -#define EA_KRT_SSTRESH EA_CODE(EAP_KRT, 0x26) -#define EA_KRT_CWND EA_CODE(EAP_KRT, 0x27) -#define EA_KRT_ADVMSS EA_CODE(EAP_KRT, 0x28) -#define EA_KRT_REORDERING EA_CODE(EAP_KRT, 0x29) -#define EA_KRT_HOPLIMIT EA_CODE(EAP_KRT, 0x2a) -#define EA_KRT_INITCWND EA_CODE(EAP_KRT, 0x2b) -#define EA_KRT_FEATURES EA_CODE(EAP_KRT, 0x2c) -#define EA_KRT_RTO_MIN EA_CODE(EAP_KRT, 0x2d) -#define EA_KRT_INITRWND EA_CODE(EAP_KRT, 0x2e) -#define EA_KRT_QUICKACK EA_CODE(EAP_KRT, 0x2f) +#define EA_KRT_METRICS EA_CODE(PROTOCOL_KERNEL, 0x20) /* Dummy one */ +#define EA_KRT_LOCK EA_CODE(PROTOCOL_KERNEL, 0x21) +#define EA_KRT_MTU EA_CODE(PROTOCOL_KERNEL, 0x22) +#define EA_KRT_WINDOW EA_CODE(PROTOCOL_KERNEL, 0x23) +#define EA_KRT_RTT EA_CODE(PROTOCOL_KERNEL, 0x24) +#define EA_KRT_RTTVAR EA_CODE(PROTOCOL_KERNEL, 0x25) +#define EA_KRT_SSTRESH EA_CODE(PROTOCOL_KERNEL, 0x26) +#define EA_KRT_CWND EA_CODE(PROTOCOL_KERNEL, 0x27) +#define EA_KRT_ADVMSS EA_CODE(PROTOCOL_KERNEL, 0x28) +#define EA_KRT_REORDERING EA_CODE(PROTOCOL_KERNEL, 0x29) +#define EA_KRT_HOPLIMIT EA_CODE(PROTOCOL_KERNEL, 0x2a) +#define EA_KRT_INITCWND EA_CODE(PROTOCOL_KERNEL, 0x2b) +#define EA_KRT_FEATURES EA_CODE(PROTOCOL_KERNEL, 0x2c) +#define EA_KRT_RTO_MIN EA_CODE(PROTOCOL_KERNEL, 0x2d) +#define EA_KRT_INITRWND EA_CODE(PROTOCOL_KERNEL, 0x2e) +#define EA_KRT_QUICKACK EA_CODE(PROTOCOL_KERNEL, 0x2f) /* Bits of EA_KRT_LOCK, also based on RTAX_* constants */ #define EA_KRT_LOCK_MTU EA_KRT_LOCK | EA_BIT(0x2) diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c index 84591eb2..73f77147 100644 --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@ -1177,11 +1177,12 @@ nh_bufsize(struct nexthop *nh) } static int -nl_send_route(struct krt_proto *p, rte *e, struct ea_list *eattrs, int op, int dest, struct nexthop *nh) +nl_send_route(struct krt_proto *p, rte *e, int op, int dest, struct nexthop *nh) { eattr *ea; net *net = e->net; rta *a = e->attrs; + ea_list *eattrs = a->eattrs; int bufsize = 128 + KRT_METRICS_MAX*8 + nh_bufsize(&(a->nh)); u32 priority = 0; @@ -1328,7 +1329,7 @@ dest: } static inline int -nl_add_rte(struct krt_proto *p, rte *e, struct ea_list *eattrs) +nl_add_rte(struct krt_proto *p, rte *e) { rta *a = e->attrs; int err = 0; @@ -1337,34 +1338,34 @@ nl_add_rte(struct krt_proto *p, rte *e, struct ea_list *eattrs) { struct nexthop *nh = &(a->nh); - err = nl_send_route(p, e, eattrs, NL_OP_ADD, RTD_UNICAST, nh); + err = nl_send_route(p, e, NL_OP_ADD, RTD_UNICAST, nh); if (err < 0) return err; for (nh = nh->next; nh; nh = nh->next) - err += nl_send_route(p, e, eattrs, NL_OP_APPEND, RTD_UNICAST, nh); + err += nl_send_route(p, e, NL_OP_APPEND, RTD_UNICAST, nh); return err; } - return nl_send_route(p, e, eattrs, NL_OP_ADD, a->dest, &(a->nh)); + return nl_send_route(p, e, NL_OP_ADD, a->dest, &(a->nh)); } static inline int -nl_delete_rte(struct krt_proto *p, rte *e, struct ea_list *eattrs) +nl_delete_rte(struct krt_proto *p, rte *e) { int err = 0; /* For IPv6, we just repeatedly request DELETE until we get error */ do - err = nl_send_route(p, e, eattrs, NL_OP_DELETE, RTD_NONE, NULL); + err = nl_send_route(p, e, NL_OP_DELETE, RTD_NONE, NULL); while (krt_ecmp6(p) && !err); return err; } void -krt_replace_rte(struct krt_proto *p, net *n, rte *new, rte *old, struct ea_list *eattrs) +krt_replace_rte(struct krt_proto *p, net *n, rte *new, rte *old) { int err = 0; @@ -1380,10 +1381,10 @@ krt_replace_rte(struct krt_proto *p, net *n, rte *new, rte *old, struct ea_list */ if (old) - nl_delete_rte(p, old, eattrs); + nl_delete_rte(p, old); if (new) - err = nl_add_rte(p, new, eattrs); + err = nl_add_rte(p, new); if (err < 0) n->n.flags |= KRF_SYNC_ERROR; @@ -1751,7 +1752,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h) for (t = 1; t < KRT_METRICS_MAX; t++) if (metrics[0] & (1 << t)) { - ea->attrs[n].id = EA_CODE(EAP_KRT, KRT_METRICS_OFFSET + t); + ea->attrs[n].id = EA_CODE(PROTOCOL_KERNEL, KRT_METRICS_OFFSET + t); ea->attrs[n].flags = 0; ea->attrs[n].type = EAF_TYPE_INT; /* FIXME: Some are EAF_TYPE_BITFIELD */ ea->attrs[n].u.data = metrics[t]; diff --git a/sysdep/unix/krt.Y b/sysdep/unix/krt.Y index 9aac8668..98740b70 100644 --- a/sysdep/unix/krt.Y +++ b/sysdep/unix/krt.Y @@ -122,8 +122,8 @@ kif_iface: kif_iface_start iface_patt_list_nopx kif_iface_opt_list; -CF_ADDTO(dynamic_attr, KRT_SOURCE { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_KRT_SOURCE); }) -CF_ADDTO(dynamic_attr, KRT_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_KRT_METRIC); }) +CF_ADDTO(dynamic_attr, KRT_SOURCE { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_SOURCE); }) +CF_ADDTO(dynamic_attr, KRT_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_METRIC); }) CF_CODE diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index b4fb1967..a79df54e 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -232,6 +232,7 @@ kif_copy_config(struct proto_config *dest, struct proto_config *src) struct protocol proto_unix_iface = { .name = "Device", .template = "device%d", + .class = PROTOCOL_DEVICE, .proto_size = sizeof(struct kif_proto), .config_size = sizeof(struct kif_config), .preconfig = kif_preconfig, @@ -550,7 +551,7 @@ krt_flush_routes(struct krt_proto *p) if (rte_is_valid(e) && (n->n.flags & KRF_INSTALLED)) { /* FIXME: this does not work if gw is changed in export filter */ - krt_replace_rte(p, e->net, NULL, e, NULL); + krt_replace_rte(p, e->net, NULL, e); n->n.flags &= ~KRF_INSTALLED; } } @@ -558,14 +559,14 @@ krt_flush_routes(struct krt_proto *p) } static struct rte * -krt_export_net(struct krt_proto *p, net *net, rte **rt_free, ea_list **tmpa) +krt_export_net(struct krt_proto *p, net *net, rte **rt_free) { struct channel *c = p->p.main_channel; struct filter *filter = c->out_filter; rte *rt; if (c->ra_mode == RA_MERGED) - return rt_export_merged(c, net, rt_free, tmpa, krt_filter_lp, 1); + return rt_export_merged(c, net, rt_free, krt_filter_lp, 1); rt = net->routes; *rt_free = NULL; @@ -576,15 +577,14 @@ krt_export_net(struct krt_proto *p, net *net, rte **rt_free, ea_list **tmpa) if (filter == FILTER_REJECT) return NULL; - struct proto *src = rt->attrs->src->proto; - *tmpa = src->make_tmp_attrs ? src->make_tmp_attrs(rt, krt_filter_lp) : NULL; + rte_make_tmp_attrs(&rt, krt_filter_lp); /* We could run krt_import_control() here, but it is already handled by KRF_INSTALLED */ if (filter == FILTER_ACCEPT) goto accept; - if (f_run(filter, &rt, tmpa, krt_filter_lp, FF_FORCE_TMPATTR | FF_SILENT) > F_ACCEPT) + if (f_run(filter, &rt, krt_filter_lp, FF_SILENT) > F_ACCEPT) goto reject; @@ -666,9 +666,8 @@ krt_got_route(struct krt_proto *p, rte *e) if (net->n.flags & KRF_INSTALLED) { rte *new, *rt_free; - ea_list *tmpa; - new = krt_export_net(p, net, &rt_free, &tmpa); + new = krt_export_net(p, net, &rt_free); /* TODO: There also may be changes in route eattrs, we ignore that for now. */ @@ -713,7 +712,6 @@ krt_prune(struct krt_proto *p) { int verdict = n->n.flags & KRF_VERDICT_MASK; rte *new, *old, *rt_free = NULL; - ea_list *tmpa = NULL; if (verdict == KRF_UPDATE || verdict == KRF_DELETE) { @@ -727,12 +725,10 @@ krt_prune(struct krt_proto *p) if (verdict == KRF_CREATE || verdict == KRF_UPDATE) { /* We have to run export filter to get proper 'new' route */ - new = krt_export_net(p, n, &rt_free, &tmpa); + new = krt_export_net(p, n, &rt_free); if (!new) verdict = (verdict == KRF_CREATE) ? KRF_IGNORE : KRF_DELETE; - else - tmpa = ea_append(tmpa, new->attrs->eattrs); } else new = NULL; @@ -743,7 +739,7 @@ krt_prune(struct krt_proto *p) if (new && (n->n.flags & KRF_INSTALLED)) { krt_trace_in(p, new, "reinstalling"); - krt_replace_rte(p, n, new, NULL, tmpa); + krt_replace_rte(p, n, new, NULL); } break; case KRF_SEEN: @@ -752,11 +748,11 @@ krt_prune(struct krt_proto *p) break; case KRF_UPDATE: krt_trace_in(p, new, "updating"); - krt_replace_rte(p, n, new, old, tmpa); + krt_replace_rte(p, n, new, old); break; case KRF_DELETE: krt_trace_in(p, old, "deleting"); - krt_replace_rte(p, n, NULL, old, NULL); + krt_replace_rte(p, n, NULL, old); break; default: bug("krt_prune: invalid route status"); @@ -794,7 +790,7 @@ krt_got_route_async(struct krt_proto *p, rte *e, int new) if (new) { krt_trace_in(p, e, "[redirect] deleting"); - krt_replace_rte(p, net, NULL, e, NULL); + krt_replace_rte(p, net, NULL, e); } /* If !new, it is probably echo of our deletion */ break; @@ -936,14 +932,14 @@ krt_make_tmp_attrs(rte *rt, struct linpool *pool) } static void -krt_store_tmp_attrs(rte *rt, struct ea_list *attrs) +krt_store_tmp_attrs(rte *rt) { /* EA_KRT_SOURCE is read-only */ - rt->u.krt.metric = ea_get_int(attrs, EA_KRT_METRIC, 0); + rt->u.krt.metric = ea_get_int(rt->attrs->eattrs, EA_KRT_METRIC, 0); } static int -krt_import_control(struct proto *P, rte **new, ea_list **attrs UNUSED, struct linpool *pool UNUSED) +krt_import_control(struct proto *P, rte **new, struct linpool *pool UNUSED) { // struct krt_proto *p = (struct krt_proto *) P; rte *e = *new; @@ -974,7 +970,7 @@ krt_import_control(struct proto *P, rte **new, ea_list **attrs UNUSED, struct li static void krt_rt_notify(struct proto *P, struct channel *ch UNUSED, net *net, - rte *new, rte *old, struct ea_list *eattrs) + rte *new, rte *old) { struct krt_proto *p = (struct krt_proto *) P; @@ -987,7 +983,7 @@ krt_rt_notify(struct proto *P, struct channel *ch UNUSED, net *net, else net->n.flags &= ~KRF_INSTALLED; if (p->initialized) /* Before first scan we don't touch the routes */ - krt_replace_rte(p, net, new, old, eattrs); + krt_replace_rte(p, net, new, old); } static void @@ -1235,7 +1231,7 @@ krt_get_attr(eattr *a, byte *buf, int buflen) struct protocol proto_unix_kernel = { .name = "Kernel", .template = "kernel%d", - .attr_class = EAP_KRT, + .class = PROTOCOL_KERNEL, .preference = DEF_PREF_INHERITED, .channel_mask = NB_IP | MAYBE_IP6_SADR | MAYBE_MPLS, .proto_size = sizeof(struct krt_proto), diff --git a/sysdep/unix/krt.h b/sysdep/unix/krt.h index b627882d..6ace2a86 100644 --- a/sysdep/unix/krt.h +++ b/sysdep/unix/krt.h @@ -30,8 +30,8 @@ struct kif_proto; #define KRT_DEFAULT_ECMP_LIMIT 16 -#define EA_KRT_SOURCE EA_CODE(EAP_KRT, 0) -#define EA_KRT_METRIC EA_CODE(EAP_KRT, 1) +#define EA_KRT_SOURCE EA_CODE(PROTOCOL_KERNEL, 0) +#define EA_KRT_METRIC EA_CODE(PROTOCOL_KERNEL, 1) /* Whenever we recognize our own routes, we allow learing of foreign routes */ @@ -139,7 +139,7 @@ void krt_sys_copy_config(struct krt_config *, struct krt_config *); int krt_capable(rte *e); void krt_do_scan(struct krt_proto *); -void krt_replace_rte(struct krt_proto *p, net *n, rte *new, rte *old, struct ea_list *eattrs); +void krt_replace_rte(struct krt_proto *p, net *n, rte *new, rte *old); int krt_sys_get_attr(eattr *a, byte *buf, int buflen); diff --git a/test/bt-utils.c b/test/bt-utils.c index 571ef2fa..7653abf6 100644 --- a/test/bt-utils.c +++ b/test/bt-utils.c @@ -75,8 +75,8 @@ bt_bird_init(void) void bt_bird_cleanup(void) { - for (int i = 0; i < EAP_MAX; i++) - attr_class_to_protocol[i] = NULL; + for (int i = 0; i < PROTOCOL__MAX; i++) + class_to_protocol[i] = NULL; config = new_config = NULL; } |