summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmanuele Di Pascale <emanuele@voltanet.io>2018-11-13 17:33:49 +0100
committerEmanuele Di Pascale <emanuele@voltanet.io>2018-12-18 15:21:15 +0100
commitf084ea552361c94d008ed0bfe5c87224ff06a55d (patch)
treec0a342ca75d92c870b0541f818dccdaf68900c84
parentisisd: retrofit 'router isis' and 'ip router isis' cmds (diff)
downloadfrr-f084ea552361c94d008ed0bfe5c87224ff06a55d.tar.xz
frr-f084ea552361c94d008ed0bfe5c87224ff06a55d.zip
isisd: retrofit the 'net' command
This is a simple command but with a complex callback, the only one in isisd which uses the resource allocation API implemented in the northbound (i.e. the PREPARE phase). Signed-off-by: Emanuele Di Pascale <emanuele@voltanet.io>
Diffstat (limited to '')
-rw-r--r--isisd/isis_cli.c22
-rw-r--r--isisd/isis_cli.h2
-rw-r--r--isisd/isis_northbound.c113
-rw-r--r--isisd/isis_vty_fabricd.c1
-rw-r--r--isisd/isisd.c6
5 files changed, 140 insertions, 4 deletions
diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c
index 2650c5bcb..41632b0a7 100644
--- a/isisd/isis_cli.c
+++ b/isisd/isis_cli.c
@@ -302,6 +302,26 @@ void cli_show_ip_isis_ipv6(struct vty *vty, struct lyd_node *dnode,
yang_dnode_get_string(dnode, "../area-tag"));
}
+/*
+ * XPath: /frr-isisd:isis/instance/area-address
+ */
+DEFPY(net, net_cmd, "[no] net WORD",
+ "Remove an existing Network Entity Title for this process\n"
+ "A Network Entity Title for this process (OSI only)\n"
+ "XX.XXXX. ... .XXX.XX Network entity title (NET)\n")
+{
+ nb_cli_enqueue_change(vty, "./area-address",
+ no ? NB_OP_DELETE : NB_OP_CREATE, net);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_area_address(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults)
+{
+ vty_out(vty, " net %s\n", yang_dnode_get_string(dnode, NULL));
+}
+
void isis_cli_init(void)
{
install_element(CONFIG_NODE, &router_isis_cmd);
@@ -310,6 +330,8 @@ void isis_cli_init(void)
install_element(INTERFACE_NODE, &ip_router_isis_cmd);
install_element(INTERFACE_NODE, &ip6_router_isis_cmd);
install_element(INTERFACE_NODE, &no_ip_router_isis_cmd);
+
+ install_element(ISIS_NODE, &net_cmd);
}
#endif /* ifndef FABRICD */
diff --git a/isisd/isis_cli.h b/isisd/isis_cli.h
index e98608759..b052f75c2 100644
--- a/isisd/isis_cli.h
+++ b/isisd/isis_cli.h
@@ -27,5 +27,7 @@ void cli_show_ip_isis_ipv4(struct vty *vty, struct lyd_node *dnode,
bool show_defaults);
void cli_show_ip_isis_ipv6(struct vty *vty, struct lyd_node *dnode,
bool show_defaults);
+void cli_show_isis_area_address(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
#endif /* ISISD_ISIS_CLI_H_ */
diff --git a/isisd/isis_northbound.c b/isisd/isis_northbound.c
index 711451234..10f8f1e75 100644
--- a/isisd/isis_northbound.c
+++ b/isisd/isis_northbound.c
@@ -113,14 +113,122 @@ static int isis_instance_area_address_create(enum nb_event event,
const struct lyd_node *dnode,
union nb_resource *resource)
{
- /* TODO: implement me. */
+ struct isis_area *area;
+ struct area_addr addr, *addrr = NULL, *addrp = NULL;
+ struct listnode *node;
+ uint8_t buff[255];
+ const char *net_title = yang_dnode_get_string(dnode, NULL);
+
+ switch (event) {
+ case NB_EV_VALIDATE:
+ addr.addr_len = dotformat2buff(buff, net_title);
+ memcpy(addr.area_addr, buff, addr.addr_len);
+ if (addr.area_addr[addr.addr_len - 1] != 0) {
+ flog_warn(
+ EC_LIB_NB_CB_CONFIG_VALIDATE,
+ "nsel byte (last byte) in area address must be 0");
+ return NB_ERR_VALIDATION;
+ }
+ if (isis->sysid_set) {
+ /* Check that the SystemID portions match */
+ if (memcmp(isis->sysid, GETSYSID((&addr)),
+ ISIS_SYS_ID_LEN)) {
+ flog_warn(
+ EC_LIB_NB_CB_CONFIG_VALIDATE,
+ "System ID must not change when defining additional area addresses");
+ return NB_ERR_VALIDATION;
+ }
+ }
+ break;
+ case NB_EV_PREPARE:
+ addrr = XMALLOC(MTYPE_ISIS_AREA_ADDR, sizeof(struct area_addr));
+ addrr->addr_len = dotformat2buff(buff, net_title);
+ memcpy(addrr->area_addr, buff, addrr->addr_len);
+ resource->ptr = addrr;
+ break;
+ case NB_EV_ABORT:
+ XFREE(MTYPE_ISIS_AREA_ADDR, resource->ptr);
+ break;
+ case NB_EV_APPLY:
+ area = yang_dnode_get_entry(dnode, true);
+ addrr = resource->ptr;
+
+ if (isis->sysid_set == 0) {
+ /*
+ * First area address - get the SystemID for this router
+ */
+ memcpy(isis->sysid, GETSYSID(addrr), ISIS_SYS_ID_LEN);
+ isis->sysid_set = 1;
+ } else {
+ /* check that we don't already have this address */
+ for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node,
+ addrp)) {
+ if ((addrp->addr_len + ISIS_SYS_ID_LEN
+ + ISIS_NSEL_LEN)
+ != (addrr->addr_len))
+ continue;
+ if (!memcmp(addrp->area_addr, addrr->area_addr,
+ addrr->addr_len)) {
+ XFREE(MTYPE_ISIS_AREA_ADDR, addrr);
+ return NB_OK; /* silent fail */
+ }
+ }
+ }
+
+ /*Forget the systemID part of the address */
+ addrr->addr_len -= (ISIS_SYS_ID_LEN + ISIS_NSEL_LEN);
+ assert(area->area_addrs); /* to silence scan-build sillyness */
+ listnode_add(area->area_addrs, addrr);
+
+ /* only now we can safely generate our LSPs for this area */
+ if (listcount(area->area_addrs) > 0) {
+ if (area->is_type & IS_LEVEL_1)
+ lsp_generate(area, IS_LEVEL_1);
+ if (area->is_type & IS_LEVEL_2)
+ lsp_generate(area, IS_LEVEL_2);
+ }
+ break;
+ }
+
return NB_OK;
}
static int isis_instance_area_address_delete(enum nb_event event,
const struct lyd_node *dnode)
{
- /* TODO: implement me. */
+ struct area_addr addr, *addrp = NULL;
+ struct listnode *node;
+ uint8_t buff[255];
+ struct isis_area *area;
+ const char *net_title;
+
+ if (event != NB_EV_APPLY)
+ return NB_OK;
+
+ net_title = yang_dnode_get_string(dnode, NULL);
+ addr.addr_len = dotformat2buff(buff, net_title);
+ memcpy(addr.area_addr, buff, (int)addr.addr_len);
+ area = yang_dnode_get_entry(dnode, true);
+ for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node, addrp)) {
+ if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) == addr.addr_len
+ && !memcmp(addrp->area_addr, addr.area_addr, addr.addr_len))
+ break;
+ }
+ if (!addrp)
+ return NB_ERR_INCONSISTENCY;
+
+ listnode_delete(area->area_addrs, addrp);
+ XFREE(MTYPE_ISIS_AREA_ADDR, addrp);
+ /*
+ * Last area address - reset the SystemID for this router
+ */
+ if (listcount(area->area_addrs) == 0) {
+ memset(isis->sysid, 0, ISIS_SYS_ID_LEN);
+ isis->sysid_set = 0;
+ if (isis->debugs & DEBUG_EVENTS)
+ zlog_debug("Router has no SystemID");
+ }
+
return NB_OK;
}
@@ -1605,6 +1713,7 @@ const struct frr_yang_module_info frr_isisd_info = {
.xpath = "/frr-isisd:isis/instance/area-address",
.cbs.create = isis_instance_area_address_create,
.cbs.delete = isis_instance_area_address_delete,
+ .cbs.cli_show = cli_show_isis_area_address,
},
{
.xpath = "/frr-isisd:isis/instance/dynamic-hostname",
diff --git a/isisd/isis_vty_fabricd.c b/isisd/isis_vty_fabricd.c
index 819b61dc7..e420988f1 100644
--- a/isisd/isis_vty_fabricd.c
+++ b/isisd/isis_vty_fabricd.c
@@ -30,6 +30,7 @@
#include "isisd/isis_misc.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_csm.h"
+#include "isisd/isis_circuit.h"
DEFUN (fabric_tier,
fabric_tier_cmd,
diff --git a/isisd/isisd.c b/isisd/isisd.c
index 3721dff3b..084cbf16c 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -1483,6 +1483,7 @@ DEFUN (no_router_openfabric,
return isis_area_destroy(argv[idx_word]->arg);
}
#endif /* ifdef FABRICD */
+#ifdef FABRICD
/*
* 'net' command
*/
@@ -1509,7 +1510,7 @@ DEFUN (no_net,
int idx_word = 2;
return area_clear_net_title(vty, argv[idx_word]->arg);
}
-
+#endif /* ifdef FABRICD */
DEFUN (isis_topology,
isis_topology_cmd,
"topology " ISIS_MT_NAMES " [overload]",
@@ -2187,9 +2188,10 @@ void isis_init()
install_element(CONFIG_NODE, &router_openfabric_cmd);
install_element(CONFIG_NODE, &no_router_openfabric_cmd);
#endif /* ifdef FABRICD */
+#ifdef FABRICD
install_element(ROUTER_NODE, &net_cmd);
install_element(ROUTER_NODE, &no_net_cmd);
-
+#endif /* ifdef FABRICD */
install_element(ROUTER_NODE, &isis_topology_cmd);
install_element(ROUTER_NODE, &no_isis_topology_cmd);