2 * EIGRP Metric Math Functions.
3 * Copyright (C) 2013-2016
7 * This file is part of GNU Zebra.
9 * GNU Zebra is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2, or (at your option) any
14 * GNU Zebra is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; see the file COPYING; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 #include "eigrpd/eigrp_structs.h"
27 #include "eigrpd/eigrpd.h"
28 #include "eigrpd/eigrp_types.h"
29 #include "eigrpd/eigrp_metric.h"
31 eigrp_scaled_t
eigrp_bandwidth_to_scaled(eigrp_bandwidth_t bandwidth
)
33 eigrp_bandwidth_t scaled
= EIGRP_BANDWIDTH_MAX
;
35 if (bandwidth
!= EIGRP_BANDWIDTH_MAX
) {
36 scaled
= (EIGRP_CLASSIC_SCALER
* EIGRP_BANDWIDTH_SCALER
);
37 scaled
= scaled
/ bandwidth
;
39 scaled
= scaled
? scaled
: EIGRP_BANDWIDTH_MIN
;
42 scaled
= (scaled
< EIGRP_METRIC_MAX
) ? scaled
: EIGRP_METRIC_MAX
;
43 return (eigrp_scaled_t
)scaled
;
46 eigrp_bandwidth_t
eigrp_scaled_to_bandwidth(eigrp_scaled_t scaled
)
48 eigrp_bandwidth_t bandwidth
= EIGRP_BANDWIDTH_MAX
;
50 if (scaled
!= EIGRP_CLASSIC_MAX
) {
51 bandwidth
= (EIGRP_CLASSIC_SCALER
* EIGRP_BANDWIDTH_SCALER
);
52 bandwidth
= scaled
* bandwidth
;
53 bandwidth
= (bandwidth
< EIGRP_METRIC_MAX
)
55 : EIGRP_BANDWIDTH_MAX
;
61 eigrp_scaled_t
eigrp_delay_to_scaled(eigrp_delay_t delay
)
63 delay
= delay
? delay
: EIGRP_DELAY_MIN
;
64 return delay
* EIGRP_CLASSIC_SCALER
;
67 eigrp_delay_t
eigrp_scaled_to_delay(eigrp_scaled_t scaled
)
69 scaled
= scaled
/ EIGRP_CLASSIC_SCALER
;
70 scaled
= scaled
? scaled
: EIGRP_DELAY_MIN
;
75 eigrp_metric_t
eigrp_calculate_metrics(struct eigrp
*eigrp
,
76 struct eigrp_metrics metric
)
78 eigrp_metric_t composite
= 0;
80 if (metric
.delay
== EIGRP_MAX_METRIC
)
81 return EIGRP_METRIC_MAX
;
85 * {K1*BW+[(K2*BW)/(256-load)]+(K3*delay)}*{K5/(reliability+K4)}
88 if (eigrp
->k_values
[0])
89 composite
+= ((eigrp_metric_t
)eigrp
->k_values
[0] *
90 (eigrp_metric_t
)metric
.bandwidth
);
91 if (eigrp
->k_values
[1])
92 composite
+= (((eigrp_metric_t
)eigrp
->k_values
[1] *
93 (eigrp_metric_t
)metric
.bandwidth
) /
95 if (eigrp
->k_values
[2])
96 composite
+= ((eigrp_metric_t
)eigrp
->k_values
[2] *
97 (eigrp_metric_t
)metric
.delay
);
98 if (eigrp
->k_values
[3] && !eigrp
->k_values
[4])
99 composite
*= (eigrp_metric_t
)eigrp
->k_values
[3];
100 if (!eigrp
->k_values
[3] && eigrp
->k_values
[4])
101 composite
*= ((eigrp_metric_t
)eigrp
->k_values
[4] /
102 (eigrp_metric_t
)metric
.reliability
);
103 if (eigrp
->k_values
[3] && eigrp
->k_values
[4])
104 composite
*= (((eigrp_metric_t
)eigrp
->k_values
[4] /
105 (eigrp_metric_t
)metric
.reliability
) +
106 (eigrp_metric_t
)eigrp
->k_values
[3]);
109 (composite
<= EIGRP_METRIC_MAX
) ? composite
: EIGRP_METRIC_MAX
;
115 eigrp_calculate_total_metrics(struct eigrp
*eigrp
,
116 struct eigrp_route_descriptor
*entry
)
118 struct eigrp_interface
*ei
= entry
->ei
;
119 eigrp_delay_t temp_delay
;
120 eigrp_bandwidth_t bw
;
122 entry
->total_metric
= entry
->reported_metric
;
123 temp_delay
= entry
->total_metric
.delay
124 + eigrp_delay_to_scaled(ei
->params
.delay
);
126 entry
->total_metric
.delay
= temp_delay
> EIGRP_METRIC_MAX_CLASSIC
127 ? EIGRP_METRIC_MAX_CLASSIC
130 bw
= eigrp_bandwidth_to_scaled(ei
->params
.bandwidth
);
131 entry
->total_metric
.bandwidth
= entry
->total_metric
.bandwidth
> bw
133 : entry
->total_metric
.bandwidth
;
135 return eigrp_calculate_metrics(eigrp
, entry
->total_metric
);
138 bool eigrp_metrics_is_same(struct eigrp_metrics metric1
,
139 struct eigrp_metrics metric2
)
141 if ((metric1
.bandwidth
== metric2
.bandwidth
)
142 && (metric1
.delay
== metric2
.delay
)
143 && (metric1
.hop_count
== metric2
.hop_count
)
144 && (metric1
.load
== metric2
.load
)
145 && (metric1
.reliability
== metric2
.reliability
)
146 && (metric1
.mtu
[0] == metric2
.mtu
[0])
147 && (metric1
.mtu
[1] == metric2
.mtu
[1])
148 && (metric1
.mtu
[2] == metric2
.mtu
[2])) {
152 return false; /* if different */