summaryrefslogtreecommitdiffstats
path: root/ospf6d/ospf6_interface.c
diff options
context:
space:
mode:
authorVincent Bernat <bernat@luffy.cx>2012-10-24 14:45:53 +0000
committerDavid Lamparter <equinox@opensourcerouting.org>2014-03-21 06:28:47 +0100
commitc19543b223d3b8463c048f346b8044589e0cce39 (patch)
tree7da71baef36e7c7b4e628c645580f8cc18c1aabe /ospf6d/ospf6_interface.c
parent1db65fadf627637621c342b789b9a3604ca5fab5 (diff)
downloadquagga-c19543b223d3b8463c048f346b8044589e0cce39.tar.bz2
quagga-c19543b223d3b8463c048f346b8044589e0cce39.tar.xz
ospf6d: compute interface cost from its bandwidth
Previously, the interface cost was a fixed default value that a user was allowed to change with "ipv6 ospf6 cost XX". As what is done with OSPFv2, we change this behaviour to compute the default interface cost from the interface bandwidth. The user can still force a cost with "ipv6 ospf6 cost XX". He can get the default value with "no ipv6 ospf6 cost". Moreover, the default cost value was 1. The cost is now computed from the bandwidth and a default reference bandwidth of 100 MBps (as for OSPFv2). Since the default bandwidth for an interface is 10 MBps, the "default" cost becomes 10 instead of 1. [DL: resolved conflict in ospf6d/ospf6_interface.c] Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'ospf6d/ospf6_interface.c')
-rw-r--r--ospf6d/ospf6_interface.c98
1 files changed, 84 insertions, 14 deletions
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index b0f11194..e6988930 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -117,6 +117,52 @@ ospf6_default_iftype(struct interface *ifp)
return OSPF_IFTYPE_BROADCAST;
}
+static u_int32_t
+ospf6_interface_get_cost (struct ospf6_interface *oi)
+{
+ /* If all else fails, use default OSPF cost */
+ u_int32_t cost;
+ u_int32_t bw, refbw;
+
+ bw = oi->interface->bandwidth ? oi->interface->bandwidth : OSPF6_INTERFACE_BANDWIDTH;
+ refbw = OSPF6_REFERENCE_BANDWIDTH;
+
+ /* A specifed ip ospf cost overrides a calculated one. */
+ if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
+ cost = oi->cost;
+ else
+ {
+ cost = (u_int32_t) ((double)refbw / (double)bw + (double)0.5);
+ if (cost < 1) cost = 1;
+ else if (cost > UINT32_MAX) cost = UINT32_MAX;
+ }
+
+ return cost;
+}
+
+static void
+ospf6_interface_recalculate_cost (struct ospf6_interface *oi)
+{
+ u_int32_t newcost;
+
+ newcost = ospf6_interface_get_cost (oi);
+ if (newcost == oi->cost) return;
+ oi->cost = newcost;
+
+ /* update cost held in route_connected list in ospf6_interface */
+ ospf6_interface_connected_route_update (oi->interface);
+
+ /* execute LSA hooks */
+ if (oi->area)
+ {
+ OSPF6_LINK_LSA_SCHEDULE (oi);
+ OSPF6_ROUTER_LSA_SCHEDULE (oi->area);
+ OSPF6_NETWORK_LSA_SCHEDULE (oi);
+ OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
+ OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
+ }
+}
+
/* Create new ospf6 interface structure */
struct ospf6_interface *
ospf6_interface_create (struct interface *ifp)
@@ -144,7 +190,6 @@ ospf6_interface_create (struct interface *ifp)
oi->hello_interval = OSPF_HELLO_INTERVAL_DEFAULT;
oi->dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
oi->rxmt_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
- oi->cost = OSPF6_INTERFACE_COST;
oi->type = ospf6_default_iftype (ifp);
oi->state = OSPF6_INTERFACE_DOWN;
oi->flag = 0;
@@ -175,6 +220,9 @@ ospf6_interface_create (struct interface *ifp)
oi->interface = ifp;
ifp->info = oi;
+ /* Compute cost. */
+ oi->cost = ospf6_interface_get_cost(oi);
+
return oi;
}
@@ -658,6 +706,9 @@ interface_up (struct thread *thread)
return 0;
}
+ /* Recompute cost */
+ ospf6_interface_recalculate_cost (oi);
+
/* if already enabled, do nothing */
if (oi->state > OSPF6_INTERFACE_DOWN)
{
@@ -1214,19 +1265,37 @@ DEFUN (ipv6_ospf6_cost,
return CMD_SUCCESS;
oi->cost = lcost;
-
- /* update cost held in route_connected list in ospf6_interface */
- ospf6_interface_connected_route_update (oi->interface);
+ SET_FLAG (oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
- /* execute LSA hooks */
- if (oi->area)
- {
- OSPF6_LINK_LSA_SCHEDULE (oi);
- OSPF6_ROUTER_LSA_SCHEDULE (oi->area);
- OSPF6_NETWORK_LSA_SCHEDULE (oi);
- OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
- OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
- }
+ ospf6_interface_recalculate_cost(oi);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ipv6_ospf6_cost,
+ no_ipv6_ospf6_cost_cmd,
+ "no ipv6 ospf6 cost",
+ NO_STR
+ IP6_STR
+ OSPF6_STR
+ "Calculate interface cost from bandwidth\n"
+ )
+{
+ struct ospf6_interface *oi;
+ struct interface *ifp;
+ unsigned long int lcost;
+
+ ifp = (struct interface *) vty->index;
+ assert (ifp);
+
+ oi = (struct ospf6_interface *) ifp->info;
+ if (oi == NULL)
+ oi = ospf6_interface_create (ifp);
+ assert (oi);
+
+ UNSET_FLAG (oi->flag, OSPF6_INTERFACE_NOAUTOCOST);
+
+ ospf6_interface_recalculate_cost(oi);
return CMD_SUCCESS;
}
@@ -1681,7 +1750,7 @@ config_write_ospf6_interface (struct vty *vty)
if (ifp->mtu6 != oi->ifmtu)
vty_out (vty, " ipv6 ospf6 ifmtu %d%s", oi->ifmtu, VNL);
- if (oi->cost != OSPF6_INTERFACE_COST)
+ if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_NOAUTOCOST))
vty_out (vty, " ipv6 ospf6 cost %d%s",
oi->cost, VNL);
@@ -1764,6 +1833,7 @@ ospf6_interface_init (void)
install_element (INTERFACE_NODE, &interface_desc_cmd);
install_element (INTERFACE_NODE, &no_interface_desc_cmd);
install_element (INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
+ install_element (INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd);
install_element (INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
install_element (INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
install_element (INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);