From ba5e5940aa1f11128c76a3964823bda22e47ab04 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Mon, 2 Aug 2010 13:11:53 +0200 Subject: [PATCH] Adds igp_metric attribute. --- nest/config.Y | 5 ++++- nest/route.h | 2 ++ nest/rt-attr.c | 15 +++++++++++++++ nest/rt-table.c | 5 +++++ proto/ospf/ospf.c | 6 +++++- 5 files changed, 31 insertions(+), 2 deletions(-) diff --git a/nest/config.Y b/nest/config.Y index a8e6bf8c..39cd9015 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -45,7 +45,7 @@ CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILT CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES) CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE) CF_KEYWORDS(LISTEN, BGP, V6ONLY, ADDRESS, PORT, PASSWORDS, DESCRIPTION) -CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY) +CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC) CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT, RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE) @@ -497,6 +497,9 @@ proto_patt2: | TEXT { $$.ptr = $1; $$.patt = 1; } ; +CF_ADDTO(dynamic_attr, IGP_METRIC + { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_GEN_IGP_METRIC); }) + CF_CODE diff --git a/nest/route.h b/nest/route.h index d062e600..a849bf00 100644 --- a/nest/route.h +++ b/nest/route.h @@ -340,6 +340,8 @@ typedef struct eattr { #define EA_PROTO(ea) ((ea) >> 8) #define EA_ID(ea) ((ea) & 0xff) +#define EA_GEN_IGP_METRIC EA_CODE(EAP_GENERIC, 0) + #define EA_CODE_MASK 0xffff #define EA_ALLOW_UNDEF 0x10000 /* ea_find: allow EAF_TYPE_UNDEF */ diff --git a/nest/rt-attr.c b/nest/rt-attr.c index d7148188..ce6fe85d 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -362,6 +362,18 @@ ea_free(ea_list *o) } } +static int +get_generic_attr(eattr *a, byte **buf, int buflen UNUSED) +{ + if (a->id == EA_GEN_IGP_METRIC) + { + *buf += bsprintf(*buf, "igp_metric"); + return GA_NAME; + } + + return GA_UNKNOWN; +} + /** * ea_format - format an &eattr for printing * @e: attribute to be formatted @@ -392,6 +404,9 @@ ea_format(eattr *e, byte *buf) } else if (EA_PROTO(e->id)) buf += bsprintf(buf, "%02x.", EA_PROTO(e->id)); + else + status = get_generic_attr(e, &buf, end - buf); + if (status < GA_NAME) buf += bsprintf(buf, "%02x", EA_ID(e->id)); if (status < GA_FULL) diff --git a/nest/rt-table.c b/nest/rt-table.c index b73f52fa..ef070428 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -1473,6 +1473,11 @@ if_local_addr(ip_addr a, struct iface *i) static u32 rt_get_igp_metric(rte *rt) { + eattr *ea = ea_find(rt->attrs->eattrs, EA_GEN_IGP_METRIC); + + if (ea) + return ea->u.data; + rta *a = rt->attrs; if ((a->source == RTS_OSPF) || (a->source == RTS_OSPF_IA) || diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 316d7292..e1ba96a4 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -467,7 +467,11 @@ ospf_import_control(struct proto *p, rte ** new, ea_list ** attrs, if (p == e->attrs->proto) return -1; /* Reject our own routes */ - *attrs = ospf_build_attrs(*attrs, pool, LSINFINITY, 10000, 0, 0); + + eattr *ea = ea_find(e->attrs->eattrs, EA_GEN_IGP_METRIC); + u32 m1 = (ea && (ea->u.data < LSINFINITY)) ? ea->u.data : LSINFINITY; + + *attrs = ospf_build_attrs(*attrs, pool, m1, 10000, 0, 0); return 0; /* Leave decision to the filters */ }