ospfd: Impl. per interface 'ip ospf area' command
Use with interface command:
interface ppp0
ip ospf area 0.0.0.0
This will enable OSPF on ppp0 with area 0.0.0.0
Remove with "no ip ospf area"
* ospf_vty.c: add "ip ospf area (A.B.C.D|<0-4294967295>)" interface command
* ospfd.c: (ospf_interface_{un,}set) new helper function to enable/disable
OSPF on a specific interface.
(ospf_if_update) 2 possible paths now to deal with interface updates.
Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index c8ad25f..f6669d7 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -871,12 +871,17 @@
/* Find interfaces that not configured already. */
for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
{
+ struct ospf_if_params *params;
int found = 0;
struct connected *co = oi->connected;
if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
continue;
+ params = IF_DEF_PARAMS (oi->ifp);
+ if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
+ continue;
+
for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
{
if (rn->info == NULL)
@@ -902,6 +907,97 @@
return 1;
}
+int
+ospf_interface_set (struct interface *ifp)
+{
+ struct ospf_area *area;
+ struct listnode *cnode;
+ struct connected *co;
+ struct ospf *ospf;
+ struct ospf_if_params *params;
+ struct in_addr area_id;
+ int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
+
+ if ((ospf = ospf_lookup ()) == NULL)
+ return 1; /* Ospf not ready yet */
+
+ params = IF_DEF_PARAMS (ifp);
+ area_id = params->if_area;
+
+ area = ospf_area_get (ospf, area_id, ret);
+
+ for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
+ {
+ struct ospf_interface *oi;
+
+ if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
+ continue;
+
+ oi = ospf_if_table_lookup(ifp, co->address);
+ if (oi)
+ { /* Just adjust area for existing interface */
+ ospf_area_del_if (oi->area, oi);
+ oi->area = area;
+ ospf_area_add_if (oi->area, oi);
+ }
+ else
+ {
+ add_ospf_interface(ifp, area, co);
+ }
+ }
+
+ /* Update connected redistribute. */
+ update_redistributed(ospf, 1); /* interface possibly added */
+ ospf_area_check_free (ospf, area_id);
+
+ return 1;
+}
+
+int
+ospf_interface_unset (struct interface *ifp)
+{
+ struct route_node *rn_oi, *rn;
+ struct ospf *ospf;
+
+ if ((ospf = ospf_lookup ()) == NULL)
+ return 1; /* Ospf not ready yet */
+
+ /* Find interfaces that may need to be removed. */
+ for (rn_oi = route_top (IF_OIFS (ifp)); rn_oi; rn_oi = route_next (rn_oi))
+ {
+ struct ospf_interface *oi;
+ struct connected *co;
+ int found = 0;
+
+ if ( (oi = rn_oi->info) == NULL)
+ continue;
+ if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
+ continue;
+ co = oi->connected;
+
+ for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
+ {
+ if (rn->info == NULL)
+ continue;
+
+ if (ospf_network_match_iface(co,&rn->p))
+ {
+ found = 1;
+ route_unlock_node (rn);
+ break;
+ }
+ }
+
+ if (found == 0)
+ ospf_if_free (oi);
+ }
+
+ /* Update connected redistribute. */
+ update_redistributed(ospf, 0); /* interfaces possibly removed */
+ return 1;
+ }
+
+
/* Check whether interface matches given network
* returns: 1, true. 0, false
*/
@@ -994,15 +1090,20 @@
/* OSPF must be on and Router-ID must be configured. */
if (!ospf || ospf->router_id.s_addr == 0)
return;
-
- /* Run each netowrk for this interface. */
- for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
- if (rn->info != NULL)
- {
- network = (struct ospf_network *) rn->info;
- area = ospf_area_get (ospf, network->area_id, network->format);
- ospf_network_run_interface (&rn->p, area, ifp);
- }
+
+ if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS (ifp), if_area))
+ ospf_interface_set (ifp);
+ else
+ {
+ /* Run each netowrk for this interface. */
+ for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
+ if (rn->info != NULL)
+ {
+ network = (struct ospf_network *) rn->info;
+ area = ospf_area_get (ospf, network->area_id, network->format);
+ ospf_network_run_interface (&rn->p, area, ifp);
+ }
+ }
}
void