Skip to content

Commit

Permalink
eigrpd: Introduce eigrp_metric.[ch] and eigrp_types.h
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
diivious authored and donaldsharp committed Jan 12, 2021
1 parent dc4accd commit e9f1847
Show file tree
Hide file tree
Showing 12 changed files with 258 additions and 110 deletions.
2 changes: 2 additions & 0 deletions eigrpd/eigrp_fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
Expand Down
32 changes: 2 additions & 30 deletions eigrpd/eigrp_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
5 changes: 0 additions & 5 deletions eigrpd/eigrp_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 146 additions & 0 deletions eigrpd/eigrp_metric.c
Original file line number Diff line number Diff line change
@@ -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 changes: 63 additions & 0 deletions eigrpd/eigrp_metric.h
Original file line number Diff line number Diff line change
@@ -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_ */
70 changes: 0 additions & 70 deletions eigrpd/eigrp_network.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
}
5 changes: 0 additions & 5 deletions eigrpd/eigrp_network.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ */
2 changes: 2 additions & 0 deletions eigrpd/eigrp_topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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);
Expand Down
Loading

0 comments on commit e9f1847

Please sign in to comment.