Page MenuHomeFreeBSD

D56322.id.diff
No OneTemporary

D56322.id.diff

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

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)

Event Timeline