From 17f91f9e6e70f7e3f29502e854823c0d48571eaa Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Sat, 19 Mar 2022 16:23:42 +0100 Subject: Explicit definition structures of route attributes Changes in internal API: * Every route attribute must be defined as struct ea_class somewhere. * Registration of route attributes known at startup must be done by ea_register_init() from protocol build functions. * Every attribute has now its symbol registered in a global symbol table defined as SYM_ATTRIBUTE * All attribute ID's are dynamically allocated. * Attribute value custom formatting hook is defined in the ea_class. * Attribute names are the same for display and filters, always prefixed by protocol name. Also added some unit testing code for filters with route attributes. --- proto/rip/config.Y | 3 --- proto/rip/rip.c | 65 +++++++++++++++++++++++++++++++----------------------- proto/rip/rip.h | 4 ---- 3 files changed, 38 insertions(+), 34 deletions(-) (limited to 'proto/rip') diff --git a/proto/rip/config.Y b/proto/rip/config.Y index 3934d337..234e9029 100644 --- a/proto/rip/config.Y +++ b/proto/rip/config.Y @@ -190,9 +190,6 @@ rip_iface: rip_iface_start iface_patt_list_nopx rip_iface_opt_list rip_iface_finish; -dynamic_attr: RIP_METRIC { $$ = f_new_dynamic_attr(T_INT, EA_RIP_METRIC); } ; -dynamic_attr: RIP_TAG { $$ = f_new_dynamic_attr(T_INT, EA_RIP_TAG); } ; - CF_CLI_HELP(SHOW RIP, ..., [[Show information about RIP protocol]]); CF_CLI(SHOW RIP INTERFACES, optproto opttext, [] [\"\"], [[Show information about RIP interfaces]]) diff --git a/proto/rip/rip.c b/proto/rip/rip.c index 2b5babcb..52a3bd2c 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -78,6 +78,7 @@ #include #include "rip.h" +#include "lib/macro.h" static inline void rip_lock_neighbor(struct rip_neighbor *n); @@ -88,6 +89,7 @@ static inline void rip_iface_kick_timer(struct rip_iface *ifa); static void rip_iface_timer(timer *timer); static void rip_trigger_update(struct rip_proto *p); +static struct ea_class ea_rip_metric, ea_rip_tag, ea_rip_from; /* * RIP routes @@ -200,9 +202,9 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) } ea_block = { .l.count = 3, .a = { - EA_LITERAL_EMBEDDED(EA_RIP_METRIC, T_INT, 0, rt_metric), - EA_LITERAL_EMBEDDED(EA_RIP_TAG, T_INT, 0, rt_tag), - EA_LITERAL_DIRECT_ADATA(EA_RIP_FROM, T_IFACE, 0, &ea_block.riad.ad), + EA_LITERAL_EMBEDDED(&ea_rip_metric, 0, rt_metric), + EA_LITERAL_EMBEDDED(&ea_rip_tag, 0, rt_tag), + EA_LITERAL_DIRECT_ADATA(&ea_rip_from, 0, &ea_block.riad.ad), }, .riad = { .ad = { .length = sizeof(struct rip_iface_adata) - sizeof(struct adata) }, @@ -326,9 +328,9 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, s if (new) { /* Update */ - u32 rt_tag = ea_get_int(new->attrs->eattrs, EA_RIP_TAG, 0); - u32 rt_metric = ea_get_int(new->attrs->eattrs, EA_RIP_METRIC, 1); - const eattr *rie = ea_find(new->attrs->eattrs, EA_RIP_FROM); + u32 rt_tag = ea_get_int(new->attrs->eattrs, &ea_rip_tag, 0); + u32 rt_metric = ea_get_int(new->attrs->eattrs, &ea_rip_metric, 1); + const eattr *rie = ea_find(new->attrs->eattrs, &ea_rip_from); struct iface *rt_from = rie ? ((struct rip_iface_adata *) rie->u.ptr)->iface : NULL; if (rt_metric > p->infinity) @@ -1095,8 +1097,8 @@ rip_rte_better(struct rte *new, struct rte *old) ASSERT_DIE(new->src == old->src); struct rip_proto *p = (struct rip_proto *) new->src->proto; - u32 new_metric = ea_get_int(new->attrs->eattrs, EA_RIP_METRIC, p->infinity); - u32 old_metric = ea_get_int(old->attrs->eattrs, EA_RIP_METRIC, p->infinity); + u32 new_metric = ea_get_int(new->attrs->eattrs, &ea_rip_metric, p->infinity); + u32 old_metric = ea_get_int(old->attrs->eattrs, &ea_rip_metric, p->infinity); return new_metric < old_metric; } @@ -1104,7 +1106,7 @@ rip_rte_better(struct rte *new, struct rte *old) static u32 rip_rte_igp_metric(struct rte *rt) { - return ea_get_int(rt->attrs->eattrs, EA_RIP_METRIC, IGP_METRIC_UNKNOWN); + return ea_get_int(rt->attrs->eattrs, &ea_rip_metric, IGP_METRIC_UNKNOWN); } static void @@ -1205,8 +1207,8 @@ static void rip_get_route_info(rte *rte, byte *buf) { struct rip_proto *p = (struct rip_proto *) rte->src->proto; - u32 rt_metric = ea_get_int(rte->attrs->eattrs, EA_RIP_METRIC, p->infinity); - u32 rt_tag = ea_get_int(rte->attrs->eattrs, EA_RIP_TAG, 0); + u32 rt_metric = ea_get_int(rte->attrs->eattrs, &ea_rip_metric, p->infinity); + u32 rt_tag = ea_get_int(rte->attrs->eattrs, &ea_rip_tag, 0); buf += bsprintf(buf, " (%d/%d)", rte->attrs->pref, rt_metric); @@ -1214,23 +1216,28 @@ rip_get_route_info(rte *rte, byte *buf) bsprintf(buf, " [%04x]", rt_tag); } -static int -rip_get_attr(const eattr *a, byte *buf, int buflen UNUSED) +static void +rip_tag_format(const eattr *a, byte *buf, uint buflen) { - switch (a->id) - { - case EA_RIP_METRIC: - bsprintf(buf, "metric: %d", a->u.data); - return GA_FULL; + bsnprintf(buf, buflen, "tag: %04x", a->u.data); +} - case EA_RIP_TAG: - bsprintf(buf, "tag: %04x", a->u.data); - return GA_FULL; +static struct ea_class ea_rip_metric = { + .name = "rip_metric", + .type = T_INT, +}; - default: - return GA_UNKNOWN; - } -} +static struct ea_class ea_rip_tag = { + .name = "rip_tag", + .type = T_INT, + .format = rip_tag_format, +}; + +static struct ea_class ea_rip_from = { + .name = "rip_from", + .type = T_IFACE, + .readonly = 1, +}; void rip_show_interfaces(struct proto *P, const char *iff) @@ -1334,7 +1341,6 @@ rip_dump(struct proto *P) struct protocol proto_rip = { .name = "RIP", .template = "rip%d", - .class = PROTOCOL_RIP, .preference = DEF_PREF_RIP, .channel_mask = NB_IP, .proto_size = sizeof(struct rip_proto), @@ -1346,11 +1352,16 @@ struct protocol proto_rip = { .shutdown = rip_shutdown, .reconfigure = rip_reconfigure, .get_route_info = rip_get_route_info, - .get_attr = rip_get_attr }; void rip_build(void) { proto_build(&proto_rip); + + EA_REGISTER_ALL( + &ea_rip_metric, + &ea_rip_tag, + &ea_rip_from + ); } diff --git a/proto/rip/rip.h b/proto/rip/rip.h index a6fa3326..a01f8d3b 100644 --- a/proto/rip/rip.h +++ b/proto/rip/rip.h @@ -195,10 +195,6 @@ 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(PROTOCOL_RIP, 0) -#define EA_RIP_TAG EA_CODE(PROTOCOL_RIP, 1) -#define EA_RIP_FROM EA_CODE(PROTOCOL_RIP, 2) - static inline int rip_is_v2(struct rip_proto *p) { return p->rip2; } -- cgit v1.2.3