eigrpd: Introduce eigrp_metric.[ch] and eigrp_types.h

Add these file and introduce some new fundamental types

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Signed-off-by: Donnie Savage <diivious@hotmail.com>
This commit is contained in:
Donnie Savage 2020-12-11 17:05:59 -05:00 committed by Donald Sharp
parent dc4accdd53
commit e9f1847e25
12 changed files with 258 additions and 110 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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_ */

146
eigrpd/eigrp_metric.c Normal file
View File

@ -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 */
}

63
eigrpd/eigrp_metric.h Normal file
View File

@ -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_ */

View File

@ -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)
{
}

View File

@ -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_ */

View File

@ -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);

36
eigrpd/eigrp_types.h Normal file
View File

@ -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_ */

View File

@ -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)

View File

@ -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);

View File

@ -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 \