struct in_addr area_id;
int ret, format;
+ if (ospf->if_ospf_cli_count > 0)
+ {
+ vty_out (vty, "Please remove all ip ospf area x.x.x.x commands first.%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
/* Get network prefix and Area ID. */
VTY_GET_IPV4_PREFIX ("network prefix", p, argv[0]);
VTY_GET_OSPF_AREA_ID (area_id, format, argv[1]);
"OSPF interface commands\n"
"Link state transmit delay\n")
+DEFUN (ip_ospf_area,
+ ip_ospf_area_cmd,
+ "ip ospf area (A.B.C.D|<0-4294967295>)",
+ "IP Information\n"
+ "OSPF interface commands\n"
+ "Enable OSPF on this interface\n"
+ "OSPF area ID in IP address format\n"
+ "OSPF area ID as a decimal value\n")
+{
+ struct interface *ifp = vty->index;
+ int format, ret;
+ struct in_addr area_id;
+ struct ospf *ospf;
+ struct ospf_if_params *params;
+ struct route_node *rn;
+
+ ospf = ospf_lookup ();
+ if (ospf == NULL)
+ {
+ vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ ret = ospf_str2area_id (argv[0], &area_id, &format);
+ if (ret < 0)
+ {
+ vty_out (vty, "Please specify area by A.B.C.D|<0-4294967295>%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (memcmp (ifp->name, "VLINK", 5) == 0)
+ {
+ vty_out (vty, "Cannot enable OSPF on a virtual link.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ params = IF_DEF_PARAMS (ifp);
+ if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
+ {
+ return CMD_WARNING;
+ }
+
+ for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
+ {
+ if (rn->info != NULL)
+ {
+ vty_out (vty, "Please remove all network commands first.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ /* enable ospf on this interface with area_id */
+ ospf_interface_set (ifp, area_id);
+ ospf->if_ospf_cli_count++;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ip_ospf_area,
+ no_ip_ospf_area_cmd,
+ "no ip ospf area",
+ NO_STR
+ "IP Information\n"
+ "OSPF interface commands\n"
+ "Disable OSPF on this interface\n")
+{
+ struct interface *ifp = vty->index;
+ struct ospf *ospf;
+ struct ospf_if_params *params;
+
+ ospf = ospf_lookup ();
+ if (ospf == NULL)
+ {
+ vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+
+ params = IF_DEF_PARAMS (ifp);
+ if (!OSPF_IF_PARAM_CONFIGURED(params, if_area))
+ {
+ vty_out (vty, "Can't find specified inteface area configuration.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ospf_interface_unset (ifp);
+ ospf->if_ospf_cli_count--;
+ return CMD_SUCCESS;
+}
+
DEFUN (ospf_redistribute_source,
ospf_redistribute_source_cmd,
"redistribute " QUAGGA_REDIST_STR_OSPFD
vty_out (vty, "%s", VTY_NEWLINE);
}
+ /* Area print. */
+ if (OSPF_IF_PARAM_CONFIGURED (params, if_area))
+ {
+ vty_out (vty, " ip ospf area %s%s",
+ inet_ntoa (params->if_area), VTY_NEWLINE);
+
+ }
+
/* bfd print. */
if (OSPF_IF_PARAM_CONFIGURED (params, bfd))
vty_out (vty, " ip ospf bfd%s", VTY_NEWLINE);
install_element (INTERFACE_NODE, &no_ip_ospf_transmit_delay_addr_cmd);
install_element (INTERFACE_NODE, &no_ip_ospf_transmit_delay_cmd);
+ /* "ip ospf area" commands. */
+ install_element (INTERFACE_NODE, &ip_ospf_area_cmd);
+ install_element (INTERFACE_NODE, &no_ip_ospf_area_cmd);
+
/* These commands are compatibitliy for previous version. */
install_element (INTERFACE_NODE, &ospf_authentication_key_cmd);
install_element (INTERFACE_NODE, &no_ospf_authentication_key_cmd);
struct route_node *rn;
struct ospf_nbr_nbma *nbr_nbma;
struct ospf_lsa *lsa;
+ struct interface *ifp;
struct ospf_interface *oi;
struct ospf_area *area;
struct ospf_vl_data *vl_data;
list_delete (ospf->vlinks);
+ /* Remove any ospf interface config params */
+ for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
+ {
+ struct ospf_if_params *params;
+
+ params = IF_DEF_PARAMS (ifp);
+ if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
+ UNSET_IF_PARAM (params, if_area);
+ }
+
/* Reset interface. */
for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
ospf_if_free (oi);
listnode_delete (area->oiflist, oi);
}
+static struct ospf_interface *
+add_ospf_interface (struct interface *ifp, struct ospf_area *area,
+ struct connected *co)
+{
+ struct ospf_interface *oi;
+
+ oi = ospf_if_new (area->ospf, ifp, co->address);
+ oi->connected = co;
+
+ oi->area = area;
+
+ oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
+ oi->output_cost = ospf_if_get_output_cost (oi);
+
+ /* Add pseudo neighbor. */
+ ospf_nbr_add_self (oi);
+
+ /* Relate ospf interface to ospf instance. */
+ oi->ospf = area->ospf;
+
+ /* update network type as interface flag */
+ /* If network type is specified previously,
+ skip network type setting. */
+ oi->type = IF_DEF_PARAMS (ifp)->type;
+
+ ospf_area_add_if (oi->area, oi);
+
+ /* if router_id is not configured, dont bring up
+ * interfaces.
+ * ospf_router_id_update() will call ospf_if_update
+ * whenever r-id is configured instead.
+ */
+ if ((area->ospf->router_id.s_addr != 0)
+ && if_is_operative (ifp))
+ ospf_if_up (oi);
+
+ return (oi);
+}
+
+static void update_redistributed(struct ospf *ospf, int add_to_ospf)
+{
+ struct route_node *rn;
+ struct external_info *ei;
+
+ if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
+ if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
+ {
+ for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
+ rn; rn = route_next (rn))
+ {
+ if ((ei = rn->info) != NULL)
+ {
+ if (add_to_ospf)
+ {
+ if (ospf_external_info_find_lsa (ospf, &ei->p))
+ if (!ospf_distribute_check_connected (ospf, ei))
+ ospf_external_lsa_flush (ospf, ei->type, &ei->p,
+ ei->ifindex /*, ei->nexthop */);
+ }
+ else
+ {
+ if (!ospf_external_info_find_lsa (ospf, &ei->p))
+ if (ospf_distribute_check_connected (ospf, ei))
+ ospf_external_lsa_originate (ospf, ei);
+ }
+ }
+ }
+ }
+}
+
/* Config network statement related functions. */
static struct ospf_network *
struct ospf_network *network;
struct ospf_area *area;
struct route_node *rn;
- struct external_info *ei;
int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
rn = route_node_get (ospf->networks, (struct prefix *)p);
ospf_network_run ((struct prefix *)p, area);
/* Update connected redistribute. */
- if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
- if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
- for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
- rn; rn = route_next (rn))
- if ((ei = rn->info) != NULL)
- if (ospf_external_info_find_lsa (ospf, &ei->p))
- if (!ospf_distribute_check_connected (ospf, ei))
- ospf_external_lsa_flush (ospf, ei->type, &ei->p,
- ei->ifindex /*, ei->nexthop */);
+ update_redistributed(ospf, 1); /* interfaces possibly added */
ospf_area_check_free (ospf, area_id);
{
struct route_node *rn;
struct ospf_network *network;
- struct external_info *ei;
struct listnode *node, *nnode;
struct ospf_interface *oi;
}
/* Update connected redistribute. */
- if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
- if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
- for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
- rn; rn = route_next (rn))
- if ((ei = rn->info) != NULL)
- if (!ospf_external_info_find_lsa (ospf, &ei->p))
- if (ospf_distribute_check_connected (ospf, ei))
- ospf_external_lsa_originate (ospf, ei);
+ update_redistributed(ospf, 0); /* interfaces possibly removed */
+ ospf_area_check_free (ospf, area_id);
+
+ return 1;
+}
+
+int
+ospf_interface_set (struct interface *ifp, struct in_addr area_id)
+{
+ struct ospf_area *area;
+ struct listnode *cnode;
+ struct connected *co;
+ struct ospf *ospf;
+ struct ospf_if_params *params;
+ int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
+
+ if ((ospf = ospf_lookup ()) == NULL)
+ return 1; /* Ospf not ready yet */
+
+ params = IF_DEF_PARAMS (ifp);
+
+ SET_IF_PARAM (params, if_area);
+ params->if_area = area_id;
+
+ area = ospf_area_get (ospf, area_id, ret);
+
+ for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
+ {
+ if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
+ continue;
+
+ if (co->address->family == AF_INET
+ && !ospf_if_table_lookup(ifp, co->address))
+ {
+ add_ospf_interface(ifp, area, co);
+ }
+ }
+
+ /* Update connected redistribute. */
+ update_redistributed(ospf, 1); /* interface possibly added */
+ return 1;
+}
+
+int
+ospf_interface_unset (struct interface *ifp)
+{
+ struct ospf *ospf;
+ struct ospf_if_params *params;
+ struct listnode *node, *nnode;
+ struct ospf_interface *oi;
+ struct in_addr area_id;
+
+ ospf = ospf_lookup ();
+ if (!ospf)
+ return 1; /* Ospf not ready yet */
+
+ params = IF_DEF_PARAMS (ifp);
+ UNSET_IF_PARAM (params, if_area);
+ area_id = params->if_area;
+
+ for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
+ {
+ if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
+ continue;
+ if (oi->ifp == ifp) ospf_if_free (oi);
+ }
+
+ /* Update connected redistribute. */
+ update_redistributed(ospf, 0); /* interfaces possibly removed */
+ ospf_area_check_free (ospf, area_id);
return 1;
}
struct route_node *rn;
struct ospf_network *network;
struct ospf_area *area;
-
+ struct ospf_if_params *params;
+
if (!ospf)
ospf = ospf_lookup ();
area = ospf_area_get (ospf, network->area_id, network->format);
ospf_network_run_interface (&rn->p, area, ifp);
}
+
+ /* create oif for any new co */
+ params = IF_DEF_PARAMS (ifp);
+ if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
+ {
+ ospf_interface_set (ifp, params->if_area);
+ }
}
void