From e9f1847e25178cf9e842c063a3b155c86319786b Mon Sep 17 00:00:00 2001 From: Donnie Savage Date: Fri, 11 Dec 2020 17:05:59 -0500 Subject: [PATCH] eigrpd: Introduce eigrp_metric.[ch] and eigrp_types.h Add these file and introduce some new fundamental types Signed-off-by: Donald Sharp Signed-off-by: Donnie Savage --- eigrpd/eigrp_fsm.c | 2 + eigrpd/eigrp_interface.c | 32 +-------- eigrpd/eigrp_interface.h | 5 -- eigrpd/eigrp_metric.c | 146 +++++++++++++++++++++++++++++++++++++++ eigrpd/eigrp_metric.h | 63 +++++++++++++++++ eigrpd/eigrp_network.c | 70 ------------------- eigrpd/eigrp_network.h | 5 -- eigrpd/eigrp_topology.c | 2 + eigrpd/eigrp_types.h | 36 ++++++++++ eigrpd/eigrp_update.c | 2 + eigrpd/eigrp_zebra.c | 2 + eigrpd/subdir.am | 3 + 12 files changed, 258 insertions(+), 110 deletions(-) create mode 100644 eigrpd/eigrp_metric.c create mode 100644 eigrpd/eigrp_metric.h create mode 100644 eigrpd/eigrp_types.h diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c index fb7336879e..d2d435bf2d 100644 --- a/eigrpd/eigrp_fsm.c +++ b/eigrpd/eigrp_fsm.c @@ -77,6 +77,7 @@ #include "linklist.h" #include "vty.h" +#include "eigrpd/eigrp_types.h" #include "eigrpd/eigrp_structs.h" #include "eigrpd/eigrpd.h" #include "eigrpd/eigrp_interface.h" @@ -88,6 +89,7 @@ #include "eigrpd/eigrp_dump.h" #include "eigrpd/eigrp_topology.h" #include "eigrpd/eigrp_fsm.h" +#include "eigrpd/eigrp_metric.h" /* * Prototypes diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index 8400102c8a..74eff958da 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -55,6 +55,8 @@ #include "eigrpd/eigrp_memory.h" #include "eigrpd/eigrp_fsm.h" #include "eigrpd/eigrp_dump.h" +#include "eigrpd/eigrp_types.h" +#include "eigrpd/eigrp_metric.h" struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp, struct prefix *p) @@ -495,33 +497,3 @@ struct eigrp_interface *eigrp_if_lookup_by_name(struct eigrp *eigrp, return NULL; } - -uint32_t eigrp_bandwidth_to_scaled(uint32_t bandwidth) -{ - uint64_t temp_bandwidth = (256ull * 10000000) / bandwidth; - - temp_bandwidth = temp_bandwidth < EIGRP_MAX_METRIC ? temp_bandwidth - : EIGRP_MAX_METRIC; - - return (uint32_t)temp_bandwidth; -} - -uint32_t eigrp_scaled_to_bandwidth(uint32_t scaled) -{ - uint64_t temp_scaled = scaled * (256ull * 10000000); - - temp_scaled = - temp_scaled < EIGRP_MAX_METRIC ? temp_scaled : EIGRP_MAX_METRIC; - - return (uint32_t)temp_scaled; -} - -uint32_t eigrp_delay_to_scaled(uint32_t delay) -{ - return delay * 256; -} - -uint32_t eigrp_scaled_to_delay(uint32_t scaled) -{ - return scaled / 256; -} diff --git a/eigrpd/eigrp_interface.h b/eigrpd/eigrp_interface.h index 1e66dafde2..68ab5125e3 100644 --- a/eigrpd/eigrp_interface.h +++ b/eigrpd/eigrp_interface.h @@ -58,9 +58,4 @@ extern struct eigrp_interface *eigrp_if_lookup_by_name(struct eigrp *, /* Simulate down/up on the interface. */ extern void eigrp_if_reset(struct interface *); -extern uint32_t eigrp_bandwidth_to_scaled(uint32_t); -extern uint32_t eigrp_scaled_to_bandwidth(uint32_t); -extern uint32_t eigrp_delay_to_scaled(uint32_t); -extern uint32_t eigrp_scaled_to_delay(uint32_t); - #endif /* ZEBRA_EIGRP_INTERFACE_H_ */ diff --git a/eigrpd/eigrp_metric.c b/eigrpd/eigrp_metric.c new file mode 100644 index 0000000000..2b05db71d5 --- /dev/null +++ b/eigrpd/eigrp_metric.c @@ -0,0 +1,146 @@ +/* + * EIGRP Metric Math Functions. + * Copyright (C) 2013-2016 + * Authors: + * Donnie Savage + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "eigrpd/eigrp_structs.h" +#include "eigrpd/eigrpd.h" +#include "eigrpd/eigrp_types.h" +#include "eigrpd/eigrp_metric.h" + +eigrp_scaled_t eigrp_bandwidth_to_scaled(eigrp_bandwidth_t bandwidth) +{ + eigrp_bandwidth_t scaled = EIGRP_BANDWIDTH_MAX; + + if (bandwidth != EIGRP_BANDWIDTH_MAX) { + scaled = (EIGRP_CLASSIC_SCALER * EIGRP_BANDWIDTH_SCALER); + scaled = scaled / bandwidth; + + scaled = scaled ? scaled : EIGRP_BANDWIDTH_MIN; + } + + scaled = (scaled < EIGRP_METRIC_MAX) ? scaled : EIGRP_METRIC_MAX; + return (eigrp_scaled_t)scaled; +} + +eigrp_bandwidth_t eigrp_scaled_to_bandwidth(eigrp_scaled_t scaled) +{ + eigrp_bandwidth_t bandwidth = EIGRP_BANDWIDTH_MAX; + + if (scaled != EIGRP_CLASSIC_MAX) { + bandwidth = (EIGRP_CLASSIC_SCALER * EIGRP_BANDWIDTH_SCALER); + bandwidth = scaled * bandwidth; + bandwidth = (bandwidth < EIGRP_METRIC_MAX) + ? bandwidth + : EIGRP_BANDWIDTH_MAX; + } + + return bandwidth; +} + +eigrp_scaled_t eigrp_delay_to_scaled(eigrp_delay_t delay) +{ + delay = delay ? delay : EIGRP_DELAY_MIN; + return delay * EIGRP_CLASSIC_SCALER; +} + +eigrp_delay_t eigrp_scaled_to_delay(eigrp_scaled_t scaled) +{ + scaled = scaled / EIGRP_CLASSIC_SCALER; + scaled = scaled ? scaled : EIGRP_DELAY_MIN; + + return scaled; +} + +eigrp_metric_t eigrp_calculate_metrics(struct eigrp *eigrp, + struct eigrp_metrics metric) +{ + eigrp_metric_t composite = 0; + + if (metric.delay == EIGRP_MAX_METRIC) + return EIGRP_METRIC_MAX; + + /* + * EIGRP Composite = + * {K1*BW+[(K2*BW)/(256-load)]+(K3*delay)}*{K5/(reliability+K4)} + */ + + if (eigrp->k_values[0]) + composite += (eigrp->k_values[0] * metric.bandwidth); + if (eigrp->k_values[1]) + composite += ((eigrp->k_values[1] * metric.bandwidth) + / (256 - metric.load)); + if (eigrp->k_values[2]) + composite += (eigrp->k_values[2] * metric.delay); + if (eigrp->k_values[3] && !eigrp->k_values[4]) + composite *= eigrp->k_values[3]; + if (!eigrp->k_values[3] && eigrp->k_values[4]) + composite *= (eigrp->k_values[4] / metric.reliability); + if (eigrp->k_values[3] && eigrp->k_values[4]) + composite *= ((eigrp->k_values[4] / metric.reliability) + + eigrp->k_values[3]); + + composite = + (composite <= EIGRP_METRIC_MAX) ? composite : EIGRP_METRIC_MAX; + + return composite; +} + +eigrp_metric_t +eigrp_calculate_total_metrics(struct eigrp *eigrp, + struct eigrp_route_descriptor *entry) +{ + struct eigrp_interface *ei = entry->ei; + eigrp_delay_t temp_delay; + eigrp_bandwidth_t bw; + + entry->total_metric = entry->reported_metric; + temp_delay = entry->total_metric.delay + + eigrp_delay_to_scaled(ei->params.delay); + + entry->total_metric.delay = temp_delay > EIGRP_METRIC_MAX_CLASSIC + ? EIGRP_METRIC_MAX_CLASSIC + : temp_delay; + + bw = eigrp_bandwidth_to_scaled(ei->params.bandwidth); + entry->total_metric.bandwidth = entry->total_metric.bandwidth > bw + ? bw + : entry->total_metric.bandwidth; + + return eigrp_calculate_metrics(eigrp, entry->total_metric); +} + +bool eigrp_metrics_is_same(struct eigrp_metrics metric1, + struct eigrp_metrics metric2) +{ + if ((metric1.bandwidth == metric2.bandwidth) + && (metric1.delay == metric2.delay) + && (metric1.hop_count == metric2.hop_count) + && (metric1.load == metric2.load) + && (metric1.reliability == metric2.reliability) + && (metric1.mtu[0] == metric2.mtu[0]) + && (metric1.mtu[1] == metric2.mtu[1]) + && (metric1.mtu[2] == metric2.mtu[2])) { + return true; + } + + return false; /* if different */ +} diff --git a/eigrpd/eigrp_metric.h b/eigrpd/eigrp_metric.h new file mode 100644 index 0000000000..8e9cd66747 --- /dev/null +++ b/eigrpd/eigrp_metric.h @@ -0,0 +1,63 @@ +/* + * EIGRP Metric Math Functions. + * Copyright (C) 2013-2016 + * Authors: + * Donnie Savage + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _ZEBRA_EIGRP_METRIC_H_ +#define _ZEBRA_EIGRP_METRIC_H_ + +/* Constants */ +#define EIGRP_BANDWIDTH_MIN 0x1ull /* 1 */ +#define EIGRP_BANDWIDTH_SCALER 10000000ull /* Inversion value */ +#define EIGRP_BANDWIDTH_MAX 0xffffffffffffffffull /* 1.84467441x10^19 */ + +#define EIGRP_DELAY_MIN 0x1ull /* 1 */ +#define EIGRP_DELAY_PICO 1000000ull +#define EIGRP_DELAY_MAX 0xffffffffffffffffull /* 1.84467441x10^19 */ + +#define EIGRP_MAX_LOAD 256 +#define EIGRP_MAX_HOPS 100 + +#define EIGRP_INACCESSIBLE 0xFFFFFFFFFFFFFFFFull + +#define EIGRP_METRIC_MAX 0xffffffffffffffffull /* 1.84467441x10^19 */ +#define EIGRP_METRIC_MAX_CLASSIC 0xffffffff +#define EIGRP_METRIC_SCALER 65536 /* CLASSIC to WIDE conversion */ + +#define EIGRP_CLASSIC_MAX 0xffffffff /* 4294967295 */ +#define EIGRP_CLASSIC_SCALER 256 /* IGRP to EIGRP conversion */ + + +/* Prototypes */ +extern eigrp_scaled_t eigrp_bandwidth_to_scaled(eigrp_bandwidth_t bw); +extern eigrp_bandwidth_t eigrp_scaled_to_bandwidth(eigrp_scaled_t scale); +extern eigrp_scaled_t eigrp_delay_to_scaled(eigrp_delay_t delay); +extern eigrp_delay_t eigrp_scaled_to_delay(eigrp_scaled_t scale); + +extern eigrp_metric_t eigrp_calculate_metrics(struct eigrp *eigrp, + struct eigrp_metrics metric); +extern eigrp_metric_t +eigrp_calculate_total_metrics(struct eigrp *eigrp, + struct eigrp_route_descriptor *rd); +extern bool eigrp_metrics_is_same(struct eigrp_metrics m1, + struct eigrp_metrics m2); + +#endif /* _ZEBRA_EIGRP_METRIC_H_ */ diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c index cb8f52c6d9..69dcc20253 100644 --- a/eigrpd/eigrp_network.c +++ b/eigrpd/eigrp_network.c @@ -346,76 +346,6 @@ int eigrp_network_unset(struct eigrp *eigrp, struct prefix *p) return 1; } -uint32_t eigrp_calculate_metrics(struct eigrp *eigrp, - struct eigrp_metrics metric) -{ - uint64_t temp_metric; - temp_metric = 0; - - if (metric.delay == EIGRP_MAX_METRIC) - return EIGRP_MAX_METRIC; - - // EIGRP Metric = - // {K1*BW+[(K2*BW)/(256-load)]+(K3*delay)}*{K5/(reliability+K4)} - - if (eigrp->k_values[0]) - temp_metric += (eigrp->k_values[0] * metric.bandwidth); - if (eigrp->k_values[1]) - temp_metric += ((eigrp->k_values[1] * metric.bandwidth) - / (256 - metric.load)); - if (eigrp->k_values[2]) - temp_metric += (eigrp->k_values[2] * metric.delay); - if (eigrp->k_values[3] && !eigrp->k_values[4]) - temp_metric *= eigrp->k_values[3]; - if (!eigrp->k_values[3] && eigrp->k_values[4]) - temp_metric *= (eigrp->k_values[4] / metric.reliability); - if (eigrp->k_values[3] && eigrp->k_values[4]) - temp_metric *= ((eigrp->k_values[4] / metric.reliability) - + eigrp->k_values[3]); - - if (temp_metric <= EIGRP_MAX_METRIC) - return (uint32_t)temp_metric; - else - return EIGRP_MAX_METRIC; -} - -uint32_t eigrp_calculate_total_metrics(struct eigrp *eigrp, - struct eigrp_route_descriptor *entry) -{ - struct eigrp_interface *ei = entry->ei; - - entry->total_metric = entry->reported_metric; - uint64_t temp_delay = - (uint64_t)entry->total_metric.delay - + (uint64_t)eigrp_delay_to_scaled(ei->params.delay); - entry->total_metric.delay = temp_delay > EIGRP_MAX_METRIC - ? EIGRP_MAX_METRIC - : (uint32_t)temp_delay; - - uint32_t bw = eigrp_bandwidth_to_scaled(ei->params.bandwidth); - entry->total_metric.bandwidth = entry->total_metric.bandwidth > bw - ? bw - : entry->total_metric.bandwidth; - - return eigrp_calculate_metrics(eigrp, entry->total_metric); -} - -uint8_t eigrp_metrics_is_same(struct eigrp_metrics metric1, - struct eigrp_metrics metric2) -{ - if ((metric1.bandwidth == metric2.bandwidth) - && (metric1.delay == metric2.delay) - && (metric1.hop_count == metric2.hop_count) - && (metric1.load == metric2.load) - && (metric1.reliability == metric2.reliability) - && (metric1.mtu[0] == metric2.mtu[0]) - && (metric1.mtu[1] == metric2.mtu[1]) - && (metric1.mtu[2] == metric2.mtu[2])) - return 1; - - return 0; // if different -} - void eigrp_external_routes_refresh(struct eigrp *eigrp, int type) { } diff --git a/eigrpd/eigrp_network.h b/eigrpd/eigrp_network.h index 831810abeb..eeb32ba356 100644 --- a/eigrpd/eigrp_network.h +++ b/eigrpd/eigrp_network.h @@ -43,11 +43,6 @@ extern int eigrp_if_drop_allspfrouters(struct eigrp *top, struct prefix *p, unsigned int ifindex); extern void eigrp_adjust_sndbuflen(struct eigrp *, unsigned int); -extern uint32_t eigrp_calculate_metrics(struct eigrp *, struct eigrp_metrics); -extern uint32_t eigrp_calculate_total_metrics(struct eigrp *, - struct eigrp_route_descriptor *); -extern uint8_t eigrp_metrics_is_same(struct eigrp_metrics, - struct eigrp_metrics); extern void eigrp_external_routes_refresh(struct eigrp *, int); #endif /* EIGRP_NETWORK_H_ */ diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 8c3de2a901..1b7e9fc15b 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -39,6 +39,7 @@ #include "vty.h" #include "lib_errors.h" +#include "eigrpd/eigrp_types.h" #include "eigrpd/eigrp_structs.h" #include "eigrpd/eigrpd.h" #include "eigrpd/eigrp_interface.h" @@ -51,6 +52,7 @@ #include "eigrpd/eigrp_topology.h" #include "eigrpd/eigrp_fsm.h" #include "eigrpd/eigrp_memory.h" +#include "eigrpd/eigrp_metric.h" static int eigrp_route_descriptor_cmp(struct eigrp_route_descriptor *rd1, struct eigrp_route_descriptor *rd2); diff --git a/eigrpd/eigrp_types.h b/eigrpd/eigrp_types.h new file mode 100644 index 0000000000..bd6510733b --- /dev/null +++ b/eigrpd/eigrp_types.h @@ -0,0 +1,36 @@ +/* + * EIGRP Definition of Data Types + * Copyright (C) 2018 + * Authors: + * Donnie Savage + * + * This file is part of FRR. + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _ZEBRA_EIGRP_TYPES_H_ +#define _ZEBRA_EIGRP_TYPES_H_ + +typedef uint64_t eigrp_bandwidth_t; +typedef uint64_t eigrp_delay_t; +typedef uint64_t eigrp_metric_t; +typedef uint32_t eigrp_scaled_t; + +typedef uint32_t eigrp_system_metric_t; +typedef uint32_t eigrp_system_delay_t; +typedef uint32_t eigrp_system_bandwidth_t; + +#endif /* _ZEBRA_EIGRP_TYPES_H_ */ diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c index db7b6d203e..91f3b3218b 100644 --- a/eigrpd/eigrp_update.c +++ b/eigrpd/eigrp_update.c @@ -49,6 +49,7 @@ #include "routemap.h" #include "vty.h" +#include "eigrpd/eigrp_types.h" #include "eigrpd/eigrp_structs.h" #include "eigrpd/eigrpd.h" #include "eigrpd/eigrp_interface.h" @@ -62,6 +63,7 @@ #include "eigrpd/eigrp_fsm.h" #include "eigrpd/eigrp_network.h" #include "eigrpd/eigrp_memory.h" +#include "eigrpd/eigrp_metric.h" bool eigrp_update_prefix_apply(struct eigrp *eigrp, struct eigrp_interface *ei, int in, struct prefix *prefix) diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index ec6b7d49de..e79123e6b4 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -41,6 +41,7 @@ #include "log.h" #include "nexthop.h" +#include "eigrpd/eigrp_types.h" #include "eigrpd/eigrp_structs.h" #include "eigrpd/eigrpd.h" #include "eigrpd/eigrp_interface.h" @@ -52,6 +53,7 @@ #include "eigrpd/eigrp_network.h" #include "eigrpd/eigrp_topology.h" #include "eigrpd/eigrp_fsm.h" +#include "eigrpd/eigrp_metric.h" static int eigrp_interface_address_add(ZAPI_CALLBACK_ARGS); static int eigrp_interface_address_delete(ZAPI_CALLBACK_ARGS); diff --git a/eigrpd/subdir.am b/eigrpd/subdir.am index 65922ea3a6..13c9f7f8ae 100644 --- a/eigrpd/subdir.am +++ b/eigrpd/subdir.am @@ -25,6 +25,7 @@ eigrpd_libeigrp_a_SOURCES = \ eigrpd/eigrp_hello.c \ eigrpd/eigrp_interface.c \ eigrpd/eigrp_memory.c \ + eigrpd/eigrp_metric.c \ eigrpd/eigrp_neighbor.c \ eigrpd/eigrp_network.c \ eigrpd/eigrp_northbound.c \ @@ -63,11 +64,13 @@ noinst_HEADERS += \ eigrpd/eigrp_interface.h \ eigrpd/eigrp_macros.h \ eigrpd/eigrp_memory.h \ + eigrpd/eigrp_metric.h \ eigrpd/eigrp_neighbor.h \ eigrpd/eigrp_network.h \ eigrpd/eigrp_packet.h \ eigrpd/eigrp_snmp.h \ eigrpd/eigrp_structs.h \ + eigrpd/eigrp_types.h \ eigrpd/eigrp_vrf.h \ eigrpd/eigrp_vty.h \ eigrpd/eigrp_yang.h \ -- 2.39.5