ospfd: Extend 'ip ospf area' to take address argument + rationalise ospf enable
* ospfd.c: (general) Clean up the whole running of OSPF on interfaces.
(add_ospf_interface) taking (struct interface *) arg is pointless here.
(ospf_is_ready) new helper.
(ospf_network_run_subnet) Put all the code for choosing whether to enable
OSPF on a subnet, and if so which area configuration to use, here. If a
subnet should not be enabled, ensure an existing oi is freed.
(ospf_network_run_interface) Just call run_subnet for all subnets on an
interface.
(ospf_network_run) Just call run_interface for all interfaces.
(ospf_if_update) Just call run_interface for the given interface.
(ospf_network_unset) Just call run_subnet for existing ois.
(ospf_update_interface_area) helper: update area on an oi, or create it.
(ospf_interface_set) renamed to ospf_interface_area_set for clarity.
Ensures OSPF is created, then into if_update.
(ospf_interface_unset) renamed to ospf_interface_area_unset and collapses
down to simple loop to call run_subnet for all ois.
* ospf_interface.h: add a more general OSPF_IF_PARAM_IS_SET, which does the
right thing and takes default config into account.
* ospf_vty.c: (OSPF_VTY_GET_IF_PARAMS) new macro with common code for handling
interface parameter commands - only used for 'ip ospf area' in this commit.
(OSPF_VTY_PARAM_UNSET) similar
({no,}ip_ospf_area) Use said macros.
* doc/ospfd.texi: add 'ip ospf area' command.
Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index dd4d312..45a19c0 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -292,6 +292,41 @@
}
}
+/* get the appropriate ospf parameters structure, checking if
+ * there's a valid interface address at the argi'th argv index
+ */
+enum {
+ VTY_SET = 0,
+ VTY_UNSET,
+};
+#define OSPF_VTY_GET_IF_PARAMS(ifp,params,argi,addr,set) \
+ (params) = IF_DEF_PARAMS ((ifp)); \
+ \
+ if (argc == (argi) + 1) \
+ { \
+ int ret = inet_aton(argv[(argi)], &(addr)); \
+ if (!ret) \
+ { \
+ vty_out (vty, "Please specify interface address by A.B.C.D%s", \
+ VTY_NEWLINE); \
+ return CMD_WARNING; \
+ } \
+ (params) = ospf_get_if_params ((ifp), (addr)); \
+ \
+ if (set) \
+ ospf_if_update_params ((ifp), (addr)); \
+ else if ((params) == NULL) \
+ return CMD_SUCCESS; \
+ }
+
+#define OSPF_VTY_PARAM_UNSET(params,var,ifp,addr) \
+ UNSET_IF_PARAM ((params), var); \
+ if ((params) != IF_DEF_PARAMS ((ifp))) \
+ { \
+ ospf_free_if_params ((ifp), (addr)); \
+ ospf_if_update_params ((ifp), (addr)); \
+ }
+
DEFUN (ospf_passive_interface,
ospf_passive_interface_addr_cmd,
"passive-interface IFNAME A.B.C.D",
@@ -453,7 +488,7 @@
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n")
{
- struct ospf *ospf= vty->index;
+ struct ospf *ospf = vty->index;
struct prefix_ipv4 p;
struct in_addr area_id;
int ret, format;
@@ -5885,31 +5920,28 @@
DEFUN (ip_ospf_area,
ip_ospf_area_cmd,
- "ip ospf area (A.B.C.D|<0-4294967295>)",
+ "ip ospf area (A.B.C.D|<0-4294967295>) [A.B.C.D]",
"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")
+ "OSPF area ID as a decimal value\n"
+ "Address of interface\n")
{
struct interface *ifp = vty->index;
- int format, ret;
struct in_addr area_id;
- struct ospf *ospf;
+ struct in_addr addr;
+ int format;
struct ospf_if_params *params;
- ret = ospf_str2area_id (argv[0], &area_id, &format);
+ VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
- if (ret < 0)
- {
- vty_out (vty, "Please specify area by A.B.C.D|<0-4294967295>%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- params = IF_DEF_PARAMS (ifp);
+ OSPF_VTY_GET_IF_PARAMS(ifp, params, 1, addr, VTY_SET);
+
if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
{
- vty_out (vty, "There is already a interface statement.%s", VTY_NEWLINE);
+ vty_out (vty, "There is already an interface area statement.%s",
+ VTY_NEWLINE);
return CMD_WARNING;
}
if (memcmp (ifp->name, "VLINK", 5) == 0)
@@ -5917,33 +5949,36 @@
vty_out (vty, "Cannot enable OSPF on a virtual link.%s", VTY_NEWLINE);
return CMD_WARNING;
}
-
+
SET_IF_PARAM (params, if_area);
params->if_area = area_id;
- ospf_interface_set (ifp);
+ ospf_interface_area_set (ifp);
return CMD_SUCCESS;
}
DEFUN (no_ip_ospf_area,
no_ip_ospf_area_cmd,
- "no ip ospf area",
+ "no ip ospf area [A.B.C.D]",
NO_STR
"IP Information\n"
"OSPF interface commands\n"
- "Disable OSPF on this interface\n")
+ "Disable OSPF on this interface\n"
+ "Address of interface\n")
{
struct interface *ifp = vty->index;
- struct ospf *ospf;
struct ospf_if_params *params;
+ struct in_addr addr;
- params = IF_DEF_PARAMS (ifp);
+ OSPF_VTY_GET_IF_PARAMS(ifp, params, 0, addr, VTY_UNSET);
+
if (!OSPF_IF_PARAM_CONFIGURED(params, if_area))
return CMD_SUCCESS;
+
+ OSPF_VTY_PARAM_UNSET(params, if_area, ifp, addr);
+
+ ospf_interface_area_unset (ifp);
- UNSET_IF_PARAM (params, if_area);
-
- ospf_interface_unset (ifp);
return CMD_SUCCESS;
}
@@ -7014,9 +7049,10 @@
/* 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);
+ vty_out (vty, " ip ospf area %s", inet_ntoa (params->if_area));
+ if (params != IF_DEF_PARAMS (ifp))
+ vty_out (vty, " %s", inet_ntoa (rn->p.u.prefix4));
+ vty_out (vty, "%s", VTY_NEWLINE);
}
/* MTU ignore print. */