summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/bird.sgml9
-rw-r--r--filter/config.Y3
-rw-r--r--filter/data.h1
-rw-r--r--filter/f-inst.c15
4 files changed, 27 insertions, 1 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml
index 05216c4a..5408cb2a 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -1674,6 +1674,15 @@ Common route attributes are:
creation/removal. Zero is returned for routes with undefined outgoing
interfaces. Read-only.
+ <tag><label id="rta-weight"><m/int/ weight</tag>
+ Multipath weight of route next hops. Valid values are 1-256. Reading
+ returns the weight of the first next hop, setting it sets weights of all
+ next hops to the specified value. Therefore, this attribute is not much
+ useful for manipulating individual next hops of an ECMP route, but can
+ be used in BGP multipath setup to set weights of individual routes that
+ are merged to one ECMP route during export to the Kernel protocol
+ (with active <ref id="krt-merge-paths" name="marge paths"> option).
+
<tag><label id="rta-igp-metric"><m/int/ igp_metric</tag>
The optional attribute that can be used to specify a distance to the
network for routes that do not have a native protocol metric attribute
diff --git a/filter/config.Y b/filter/config.Y
index 557a951f..5cd52e40 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -278,7 +278,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
SET, STRING, BGPMASK, BGPPATH, CLIST, ECLIST, LCLIST,
IF, THEN, ELSE, CASE,
TRUE, FALSE, RT, RO, UNKNOWN, GENERIC,
- FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX,
+ FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT,
PREFERENCE,
ROA_CHECK, ASN, SRC, DST,
IS_V4, IS_V6,
@@ -750,6 +750,7 @@ static_attr:
| DEST { $$ = f_new_static_attr(T_ENUM_RTD, SA_DEST, 0); }
| IFNAME { $$ = f_new_static_attr(T_STRING, SA_IFNAME, 0); }
| IFINDEX { $$ = f_new_static_attr(T_INT, SA_IFINDEX, 1); }
+ | WEIGHT { $$ = f_new_static_attr(T_INT, SA_WEIGHT, 0); }
;
term:
diff --git a/filter/data.h b/filter/data.h
index 4ebce73b..a0ec3819 100644
--- a/filter/data.h
+++ b/filter/data.h
@@ -99,6 +99,7 @@ enum f_sa_code {
SA_DEST,
SA_IFNAME,
SA_IFINDEX,
+ SA_WEIGHT,
} PACKED;
/* Static attribute definition (members of struct rta) */
diff --git a/filter/f-inst.c b/filter/f-inst.c
index df908e26..58717d55 100644
--- a/filter/f-inst.c
+++ b/filter/f-inst.c
@@ -516,6 +516,7 @@
case SA_DEST: RESULT(sa.f_type, i, rta->dest); break;
case SA_IFNAME: RESULT(sa.f_type, s, rta->nh.iface ? rta->nh.iface->name : ""); break;
case SA_IFINDEX: RESULT(sa.f_type, i, rta->nh.iface ? rta->nh.iface->index : 0); break;
+ case SA_WEIGHT: RESULT(sa.f_type, i, rta->nh.weight + 1); break;
default:
bug("Invalid static attribute access (%u/%u)", sa.f_type, sa.sa_code);
@@ -586,6 +587,20 @@
}
break;
+ case SA_WEIGHT:
+ {
+ int i = v1.val.i;
+ if (i < 1 || i > 256)
+ runtime( "Setting weight value out of bounds" );
+ if (rta->dest != RTD_UNICAST)
+ runtime( "Setting weight needs regular nexthop " );
+
+ /* Set weight on all next hops */
+ for (struct nexthop *nh = &rta->nh; nh; nh = nh->next)
+ nh->weight = i - 1;
+ }
+ break;
+
default:
bug("Invalid static attribute access (%u/%u)", sa.f_type, sa.sa_code);
}