Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F152920780
D56322.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D56322.id.diff
View Options
diff --git a/sys/net/route.h b/sys/net/route.h
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -89,8 +89,9 @@
u_long rmx_rttvar; /* estimated rtt variance */
u_long rmx_pksent; /* packets sent using this route */
u_long rmx_weight; /* route weight */
+ u_long rmx_metric; /* route metric */
u_long rmx_nhidx; /* route nexhop index */
- u_long rmx_filler[2]; /* will be used for T/TCP later */
+ u_long rmx_filler[1];
};
/*
@@ -104,6 +105,7 @@
/* default route weight */
#define RT_DEFAULT_WEIGHT 1
#define RT_MAX_WEIGHT 16777215 /* 3 bytes */
+#define RT_MAX_METRIC 255 /* 1 byte */
/*
* Keep a generation count of routing table, incremented on route addition,
@@ -300,6 +302,7 @@
#define RTV_RTT 0x40 /* init or lock _rtt */
#define RTV_RTTVAR 0x80 /* init or lock _rttvar */
#define RTV_WEIGHT 0x100 /* init or lock _weight */
+#define RTV_METRIC 0x200 /* init or lock _metric */
#ifndef NETLINK_COMPAT
diff --git a/sys/net/route/nhgrp_ctl.c b/sys/net/route/nhgrp_ctl.c
--- a/sys/net/route/nhgrp_ctl.c
+++ b/sys/net/route/nhgrp_ctl.c
@@ -135,6 +135,7 @@
* comparable.
* Assumes @wn is sorted by weight ascending and each weight is > 0.
* Returns number of slots or 0 if precise calculation failed.
+ * We also filter nexthops with lower metrics here.
*
* Some examples:
* note: (i, X) pair means (nhop=i, weight=X):
@@ -146,15 +147,25 @@
calc_min_mpath_slots_fast(struct weightened_nhop *wn, size_t num_items,
uint64_t *ptotal)
{
- uint32_t i, last, xmin;
+ uint32_t i, last, xmin, max_metric;
uint64_t total = 0;
// Get sorted array of weights in .storage field
sort_weightened_nhops_weights(wn, num_items);
+ /* find nexthop with highest metric */
+ max_metric = 0;
+ for (i = 0; i < num_items; i++)
+ if ((wn[i].metric) > max_metric)
+ max_metric = wn[i].metric;
+
last = 0;
xmin = wn[0].storage;
for (i = 0; i < num_items; i++) {
+ /* filter nexthops with lower metric */
+ if (wn[i].metric < max_metric)
+ continue;
+
total += wn[i].storage;
if ((wn[i].storage != last) &&
((wn[i].storage - last < xmin) || xmin == 0)) {
@@ -235,26 +246,40 @@
{
struct nhgrp_object *dst;
int i, slot_idx, remaining_slots;
- uint64_t remaining_sum, nh_weight, nh_slots;
+ uint64_t remaining_sum, nh_slots;
+ uint32_t highest_metric, nh_weight;
slot_idx = 0;
dst = dst_priv->nhg;
- /* Calculate sum of all weights */
+
+ /* Find highest metric */
+ highest_metric = 0;
+ for (i = 0; i < dst_priv->nhg_nh_count; i++)
+ if (x[i].metric > highest_metric)
+ highest_metric = x[i].metric;
+
+ /* Calculate sum of the weights with highest metric */
remaining_sum = 0;
for (i = 0; i < dst_priv->nhg_nh_count; i++)
- remaining_sum += x[i].weight;
+ if (x[i].metric == highest_metric)
+ remaining_sum += x[i].pref;
+
remaining_slots = num_slots;
- FIB_NH_LOG(LOG_DEBUG3, x[0].nh, "sum: %lu, slots: %d",
- remaining_sum, remaining_slots);
+ FIB_NH_LOG(LOG_DEBUG3, x[0].nh, "sum: %lu, slots: %d, highest_metric: %lu",
+ remaining_sum, remaining_slots, highest_metric);
for (i = 0; i < dst_priv->nhg_nh_count; i++) {
+ /* Skip over lower metrics */
+ if (x[i].metric < highest_metric)
+ continue;
+
/* Calculate number of slots for the current nexthop */
if (remaining_sum > 0) {
- nh_weight = (uint64_t)x[i].weight;
+ nh_weight = x[i].pref;
nh_slots = (nh_weight * remaining_slots / remaining_sum);
} else
nh_slots = 0;
- remaining_sum -= x[i].weight;
+ remaining_sum -= x[i].pref;
remaining_slots -= nh_slots;
FIB_NH_LOG(LOG_DEBUG3, x[0].nh,
diff --git a/sys/net/route/nhop.h b/sys/net/route/nhop.h
--- a/sys/net/route/nhop.h
+++ b/sys/net/route/nhop.h
@@ -143,6 +143,7 @@
/* -- 128 bytes -- */
};
+
/*
* Nhop validness.
*
@@ -163,7 +164,13 @@
struct weightened_nhop {
struct nhop_object *nh;
- uint32_t weight;
+ union {
+ uint32_t weight;
+ struct {
+ uint32_t pref:24, /* 24-bit weight */
+ metric:8; /* 8-bit metric */
+ };
+ };
uint32_t storage;
};
diff --git a/sys/net/route/route_ctl.h b/sys/net/route/route_ctl.h
--- a/sys/net/route/route_ctl.h
+++ b/sys/net/route/route_ctl.h
@@ -38,7 +38,13 @@
struct rib_cmd_info {
uint8_t rc_cmd; /* RTM_ADD|RTM_DEL|RTM_CHANGE */
uint8_t spare[3];
- uint32_t rc_nh_weight; /* new nhop weight */
+ union {
+ uint32_t rc_nh_weight; /* new nhop weight */
+ struct {
+ uint32_t rc_nh_pref:24,
+ rc_nh_metric:8;
+ };
+ };
struct rtentry *rc_rt; /* Target entry */
struct nhop_object *rc_nh_old; /* Target nhop OR mpath */
struct nhop_object *rc_nh_new; /* Target nhop OR mpath */
@@ -49,7 +55,13 @@
struct nhop_object *rnd_nhop;
struct nhgrp_object *rnd_nhgrp;
};
- uint32_t rnd_weight;
+ union {
+ uint32_t rnd_weight;
+ struct {
+ uint32_t rnd_pref:24,
+ rnd_metric:8;
+ };
+ };
};
int rib_add_route_px(uint32_t fibnum, struct sockaddr *dst, int plen,
diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c
--- a/sys/net/route/route_ctl.c
+++ b/sys/net/route/route_ctl.c
@@ -192,13 +192,11 @@
{
uint32_t weight;
+ weight = 0;
+ if (info->rti_mflags & RTV_METRIC)
+ weight = info->rti_rmx->rmx_metric << 24;
if (info->rti_mflags & RTV_WEIGHT)
- weight = info->rti_rmx->rmx_weight;
- else
- weight = default_weight;
- /* Keep upper 1 byte for adm distance purposes */
- if (weight > RT_MAX_WEIGHT)
- weight = RT_MAX_WEIGHT;
+ weight += info->rti_rmx->rmx_weight;
else if (weight == 0)
weight = default_weight;
diff --git a/sys/net/route/route_helpers.c b/sys/net/route/route_helpers.c
--- a/sys/net/route/route_helpers.c
+++ b/sys/net/route/route_helpers.c
@@ -294,7 +294,7 @@
{
uint32_t num_old, num_new;
const struct weightened_nhop *wn_old, *wn_new;
- struct weightened_nhop tmp = { NULL, 0 };
+ struct weightened_nhop tmp = { 0 };
uint32_t idx_old = 0, idx_new = 0;
struct rib_cmd_info rc_del = { .rc_cmd = RTM_DELETE, .rc_rt = rc->rc_rt };
diff --git a/sys/net/route/route_var.h b/sys/net/route/route_var.h
--- a/sys/net/route/route_var.h
+++ b/sys/net/route/route_var.h
@@ -178,7 +178,13 @@
};
int rte_flags; /* up/down?, host/net */
- u_long rt_weight; /* absolute weight */
+ union {
+ uint32_t rt_weight; /* absolute weight */
+ struct {
+ uint32_t rt_pref:24, /* 24-bit weight */
+ rt_metric:8; /* 8-bit metric */
+ };
+ };
struct rtentry *rt_chain; /* pointer to next rtentry to delete */
struct epoch_context rt_epoch_ctx; /* net epoch tracker */
};
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1023,7 +1023,8 @@
rtm->rtm_flags = RTF_GATEWAY |
(rtm->rtm_flags & ~RTF_GWFLAG_COMPAT);
rt_getmetrics(rc->rc_rt, nh, &rtm->rtm_rmx);
- rtm->rtm_rmx.rmx_weight = rc->rc_nh_weight;
+ rtm->rtm_rmx.rmx_metric = rc->rc_nh_metric;
+ rtm->rtm_rmx.rmx_weight = rc->rc_nh_pref;
return (0);
}
@@ -1327,7 +1328,8 @@
bzero(out, sizeof(*out));
out->rmx_mtu = nh->nh_mtu;
- out->rmx_weight = rt->rt_weight;
+ out->rmx_metric = rt->rt_metric;
+ out->rmx_weight = rt->rt_pref;
out->rmx_nhidx = nhop_get_idx(nh);
/* Kernel -> userland timebase conversion. */
out->rmx_expire = nhop_get_expire(nh) ?
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Apr 19, 1:43 AM (10 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31728919
Default Alt Text
D56322.id.diff (7 KB)
Attached To
Mode
D56322: routing: Add support for route metric
Attached
Detach File
Event Timeline
Log In to Comment