summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nest/config.Y5
-rw-r--r--nest/route.h2
-rw-r--r--nest/rt-attr.c15
-rw-r--r--nest/rt-table.c5
-rw-r--r--proto/ospf/ospf.c6
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 */
}