summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ospfclient/ospf_apiclient.c9
-rw-r--r--ospfclient/ospf_apiclient.h5
-rw-r--r--ospfclient/ospfclient.c7
-rwxr-xr-xospfclient/ospfclient.py45
-rw-r--r--ospfd/ospf_api.c7
-rw-r--r--ospfd/ospf_api.h17
-rw-r--r--ospfd/ospf_apiserver.c19
-rw-r--r--ospfd/ospf_lsa.c1
-rw-r--r--ospfd/ospf_lsa.h3
-rw-r--r--ospfd/ospf_opaque.c11
-rw-r--r--pimd/pim_nht.c5
-rw-r--r--pimd/pim_tib.c3
-rw-r--r--tests/topotests/ospfapi/test_ospf_clientapi.py372
13 files changed, 379 insertions, 125 deletions
diff --git a/ospfclient/ospf_apiclient.c b/ospfclient/ospf_apiclient.c
index b5f5d77d82..4ce65e379a 100644
--- a/ospfclient/ospf_apiclient.c
+++ b/ospfclient/ospf_apiclient.c
@@ -487,8 +487,9 @@ int ospf_apiclient_lsa_originate(struct ospf_apiclient *oclient,
}
int ospf_apiclient_lsa_delete(struct ospf_apiclient *oclient,
- struct in_addr area_id, uint8_t lsa_type,
- uint8_t opaque_type, uint32_t opaque_id)
+ struct in_addr addr, uint8_t lsa_type,
+ uint8_t opaque_type, uint32_t opaque_id,
+ uint8_t flags)
{
struct msg *msg;
int rc;
@@ -502,8 +503,8 @@ int ospf_apiclient_lsa_delete(struct ospf_apiclient *oclient,
/* opaque_id is in host byte order and will be converted
* to network byte order by new_msg_delete_request */
- msg = new_msg_delete_request(ospf_apiclient_get_seqnr(), area_id,
- lsa_type, opaque_type, opaque_id);
+ msg = new_msg_delete_request(ospf_apiclient_get_seqnr(), addr, lsa_type,
+ opaque_type, opaque_id, flags);
rc = ospf_apiclient_send_request(oclient, msg);
return rc;
diff --git a/ospfclient/ospf_apiclient.h b/ospfclient/ospf_apiclient.h
index 6d1eb7f64f..b904937c2a 100644
--- a/ospfclient/ospf_apiclient.h
+++ b/ospfclient/ospf_apiclient.h
@@ -94,8 +94,9 @@ int ospf_apiclient_lsa_originate(struct ospf_apiclient *oclient,
/* Synchronous request to delete opaque LSA. Parameter opaque_id is in
host byte order */
int ospf_apiclient_lsa_delete(struct ospf_apiclient *oclient,
- struct in_addr area_id, uint8_t lsa_type,
- uint8_t opaque_type, uint32_t opaque_id);
+ struct in_addr addr, uint8_t lsa_type,
+ uint8_t opaque_type, uint32_t opaque_id,
+ uint8_t flags);
/* Fetch async message and handle it */
int ospf_apiclient_handle_async(struct ospf_apiclient *oclient);
diff --git a/ospfclient/ospfclient.c b/ospfclient/ospfclient.c
index 3cfee7d573..edf814184a 100644
--- a/ospfclient/ospfclient.c
+++ b/ospfclient/ospfclient.c
@@ -98,9 +98,10 @@ static void lsa_delete(struct thread *t)
printf("Deleting LSA... ");
rc = ospf_apiclient_lsa_delete(oclient, area_id,
- atoi(args[2]), /* lsa type */
- atoi(args[3]), /* opaque type */
- atoi(args[4])); /* opaque ID */
+ atoi(args[2]), /* lsa type */
+ atoi(args[3]), /* opaque type */
+ atoi(args[4]), /* opaque ID */
+ 0); /* send data in withdrawals */
printf("done, return code is = %d\n", rc);
}
diff --git a/ospfclient/ospfclient.py b/ospfclient/ospfclient.py
index 19561145a0..8e3c68445f 100755
--- a/ospfclient/ospfclient.py
+++ b/ospfclient/ospfclient.py
@@ -62,13 +62,16 @@ smsg_info = {
MSG_REGISTER_EVENT: ("REGISTER_EVENT", FMT_LSA_FILTER),
MSG_SYNC_LSDB: ("SYNC_LSDB", FMT_LSA_FILTER),
MSG_ORIGINATE_REQUEST: ("ORIGINATE_REQUEST", ">II" + FMT_LSA_HEADER[1:]),
- MSG_DELETE_REQUEST: ("DELETE_REQUEST", ">IBBxxL"),
+ MSG_DELETE_REQUEST: ("DELETE_REQUEST", ">IBBxBL"),
MSG_SYNC_REACHABLE: ("MSG_SYNC_REACHABLE", ""),
MSG_SYNC_ISM: ("MSG_SYNC_ISM", ""),
MSG_SYNC_NSM: ("MSG_SYNC_NSM", ""),
MSG_SYNC_ROUTER_ID: ("MSG_SYNC_ROUTER_ID", ""),
}
+# OSPF API MSG Delete Flag.
+OSPF_API_DEL_ZERO_LEN_LSA = 0x01 # send withdrawal with no LSA data
+
# --------------------------
# Messages from OSPF daemon.
# --------------------------
@@ -842,7 +845,7 @@ class OspfOpaqueClient(OspfApiClient):
await self._assure_opaque_ready(lsa_type, otype)
await self.msg_send_raises(mt, msg)
- async def delete_opaque_data(self, addr, lsa_type, otype, oid):
+ async def delete_opaque_data(self, addr, lsa_type, otype, oid, flags=0):
"""Delete an instance of opaque data.
Delete an instance of opaque data. This call will register for the given
@@ -854,6 +857,7 @@ class OspfOpaqueClient(OspfApiClient):
otype: (octet) opaque type. Note: the type will be registered if the user
has not explicity done that yet with `register_opaque_data`.
oid: (3 octets) ID of this opaque data
+ flags: (octet) optional flags (e.g., OSPF_API_DEL_ZERO_LEN_LSA, defaults to no flags)
Raises:
See `msg_send_raises`
"""
@@ -862,7 +866,7 @@ class OspfOpaqueClient(OspfApiClient):
mt = MSG_DELETE_REQUEST
await self._assure_opaque_ready(lsa_type, otype)
- mp = struct.pack(msg_fmt[mt], int(addr), lsa_type, otype, oid)
+ mp = struct.pack(msg_fmt[mt], int(addr), lsa_type, otype, flags, oid)
await self.msg_send_raises(mt, mp)
async def register_opaque_data(self, lsa_type, otype, callback=None):
@@ -1115,23 +1119,28 @@ async def async_main(args):
except ValueError:
addr = ip(aval)
oargs = [addr, ltype, int(_s.pop(False)), int(_s.pop(False))]
- assert len(_s) <= 1, "Bad format for action argument"
- try:
- b = bytes.fromhex(_s.pop(False))
- except IndexError:
- b = b""
- logging.info("opaque data is %s octets", len(b))
- # Needs to be multiple of 4 in length
- mod = len(b) % 4
- if mod:
- b += b"\x00" * (4 - mod)
- logging.info("opaque padding to %s octets", len(b))
-
if what.casefold() == "add":
+ try:
+ b = bytes.fromhex(_s.pop(False))
+ except IndexError:
+ b = b""
+ logging.info("opaque data is %s octets", len(b))
+ # Needs to be multiple of 4 in length
+ mod = len(b) % 4
+ if mod:
+ b += b"\x00" * (4 - mod)
+ logging.info("opaque padding to %s octets", len(b))
+
await c.add_opaque_data(*oargs, b)
else:
assert what.casefold().startswith("del")
- await c.delete_opaque_data(*oargs)
+ f = 0
+ if len(_s) >= 1:
+ try:
+ f = int(_s.pop(False))
+ except IndexError:
+ f = 0
+ await c.delete_opaque_data(*oargs, f)
if args.exit:
return 0
except Exception as error:
@@ -1153,7 +1162,9 @@ def main(*args):
ap.add_argument("--server", default="localhost", help="OSPF API server")
ap.add_argument("-v", "--verbose", action="store_true", help="be verbose")
ap.add_argument(
- "actions", nargs="*", help="(ADD|DEL),LSATYPE,[ADDR,],OTYPE,OID,[HEXDATA]"
+ "actions",
+ nargs="*",
+ help="(ADD|DEL),LSATYPE,[ADDR,],OTYPE,OID,[HEXDATA|DEL_FLAG]",
)
args = ap.parse_args()
diff --git a/ospfd/ospf_api.c b/ospfd/ospf_api.c
index 8636db450b..9a134d033c 100644
--- a/ospfd/ospf_api.c
+++ b/ospfd/ospf_api.c
@@ -532,16 +532,17 @@ struct msg *new_msg_originate_request(uint32_t seqnum, struct in_addr ifaddr,
return msg_new(MSG_ORIGINATE_REQUEST, omsg, seqnum, omsglen);
}
-struct msg *new_msg_delete_request(uint32_t seqnum, struct in_addr area_id,
+struct msg *new_msg_delete_request(uint32_t seqnum, struct in_addr addr,
uint8_t lsa_type, uint8_t opaque_type,
- uint32_t opaque_id)
+ uint32_t opaque_id, uint8_t flags)
{
struct msg_delete_request dmsg;
- dmsg.area_id = area_id;
+ dmsg.addr = addr;
dmsg.lsa_type = lsa_type;
dmsg.opaque_type = opaque_type;
dmsg.opaque_id = htonl(opaque_id);
memset(&dmsg.pad, 0, sizeof(dmsg.pad));
+ dmsg.flags = flags;
return msg_new(MSG_DELETE_REQUEST, &dmsg, seqnum,
sizeof(struct msg_delete_request));
diff --git a/ospfd/ospf_api.h b/ospfd/ospf_api.h
index 51c8c52ce5..6f569e962d 100644
--- a/ospfd/ospf_api.h
+++ b/ospfd/ospf_api.h
@@ -185,11 +185,19 @@ struct msg_originate_request {
struct lsa_header data;
};
+
+/* OSPF API MSG Delete Flag. */
+#define OSPF_API_DEL_ZERO_LEN_LSA 0x01 /* send withdrawal with no LSA data */
+
+#define IS_DEL_ZERO_LEN_LSA(x) ((x)->flags & OSPF_API_DEL_ZERO_LEN_LSA)
+
struct msg_delete_request {
- struct in_addr area_id; /* "0.0.0.0" for AS-external opaque LSAs */
+ struct in_addr addr; /* intf IP for link local, area for type 10,
+ "0.0.0.0" for AS-external */
uint8_t lsa_type;
uint8_t opaque_type;
- uint8_t pad[2]; /* padding */
+ uint8_t pad; /* padding */
+ uint8_t flags; /* delete flags */
uint32_t opaque_id;
};
@@ -311,10 +319,9 @@ extern struct msg *new_msg_originate_request(uint32_t seqnum,
struct in_addr ifaddr,
struct in_addr area_id,
struct lsa_header *data);
-extern struct msg *new_msg_delete_request(uint32_t seqnum,
- struct in_addr area_id,
+extern struct msg *new_msg_delete_request(uint32_t seqnum, struct in_addr addr,
uint8_t lsa_type, uint8_t opaque_type,
- uint32_t opaque_id);
+ uint32_t opaque_id, uint8_t flags);
/* Messages sent by OSPF daemon */
extern struct msg *new_msg_reply(uint32_t seqnum, uint8_t rc);
diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c
index f5ed77dab5..0c2ee0c4f8 100644
--- a/ospfd/ospf_apiserver.c
+++ b/ospfd/ospf_apiserver.c
@@ -1924,6 +1924,7 @@ int ospf_apiserver_handle_delete_request(struct ospf_apiserver *apiserv,
struct msg_delete_request *dmsg;
struct ospf_lsa *old;
struct ospf_area *area = NULL;
+ struct ospf_interface *oi = NULL;
struct in_addr id;
int lsa_type, opaque_type;
int rc = 0;
@@ -1938,11 +1939,20 @@ int ospf_apiserver_handle_delete_request(struct ospf_apiserver *apiserv,
/* Lookup area for link-local and area-local opaque LSAs */
switch (dmsg->lsa_type) {
case OSPF_OPAQUE_LINK_LSA:
+ oi = ospf_apiserver_if_lookup_by_addr(dmsg->addr);
+ if (!oi) {
+ zlog_warn("%s: unknown interface %pI4", __func__,
+ &dmsg->addr);
+ rc = OSPF_API_NOSUCHINTERFACE;
+ goto out;
+ }
+ area = oi->area;
+ break;
case OSPF_OPAQUE_AREA_LSA:
- area = ospf_area_lookup_by_area_id(ospf, dmsg->area_id);
+ area = ospf_area_lookup_by_area_id(ospf, dmsg->addr);
if (!area) {
zlog_warn("%s: unknown area %pI4", __func__,
- &dmsg->area_id);
+ &dmsg->addr);
rc = OSPF_API_NOSUCHAREA;
goto out;
}
@@ -1987,6 +1997,11 @@ int ospf_apiserver_handle_delete_request(struct ospf_apiserver *apiserv,
goto out;
}
+ if (IS_DEL_ZERO_LEN_LSA(dmsg)) {
+ /* minimize the size of the withdrawal: */
+ old->opaque_zero_len_delete = 1;
+ }
+
/* Schedule flushing of LSA from LSDB */
/* NB: Multiple scheduling will produce a warning message, but harmless.
*/
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index 0df0072f6d..365f373d2f 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -188,6 +188,7 @@ struct ospf_lsa *ospf_lsa_new(void)
new->refresh_list = -1;
new->vrf_id = VRF_DEFAULT;
new->to_be_acknowledged = 0;
+ new->opaque_zero_len_delete = 0;
return new;
}
diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h
index 97c15d1e3c..1caf8047e4 100644
--- a/ospfd/ospf_lsa.h
+++ b/ospfd/ospf_lsa.h
@@ -123,6 +123,9 @@ struct ospf_lsa {
/*For topo chg detection in HELPER role*/
bool to_be_acknowledged;
+
+ /* send maxage with no data */
+ bool opaque_zero_len_delete;
};
/* OSPF LSA Link Type. */
diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c
index 261d69df33..ab647625fe 100644
--- a/ospfd/ospf_opaque.c
+++ b/ospfd/ospf_opaque.c
@@ -2050,6 +2050,17 @@ void ospf_opaque_lsa_flush_schedule(struct ospf_lsa *lsa0)
goto out;
}
+ if (lsa->opaque_zero_len_delete &&
+ lsa->data->length != htons(sizeof(struct lsa_header))) {
+ /* minimize the size of the withdrawal: */
+ /* increment the sequence number and make len just header */
+ /* and update checksum */
+ lsa->data->ls_seqnum = lsa_seqnum_increment(lsa);
+ lsa->data->length = htons(sizeof(struct lsa_header));
+ lsa->data->checksum = 0;
+ lsa->data->checksum = ospf_lsa_checksum(lsa->data);
+ }
+
/* Delete this lsa from neighbor retransmit-list. */
switch (lsa->data->type) {
case OSPF_OPAQUE_LINK_LSA:
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index 9feb064e96..f9a9aeb1b0 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -495,12 +495,13 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
uint32_t hash_val = 0, mod_val = 0;
uint8_t nh_iter = 0, found = 0;
uint32_t i, num_nbrs = 0;
- pim_addr nh_addr = nexthop->mrib_nexthop_addr;
- pim_addr grp_addr = pim_addr_from_prefix(grp);
if (!pnc || !pnc->nexthop_num || !nexthop)
return 0;
+ pim_addr nh_addr = nexthop->mrib_nexthop_addr;
+ pim_addr grp_addr = pim_addr_from_prefix(grp);
+
memset(&nbrs, 0, sizeof(nbrs));
memset(&ifps, 0, sizeof(ifps));
diff --git a/pimd/pim_tib.c b/pimd/pim_tib.c
index 8f5de3e938..3455e30064 100644
--- a/pimd/pim_tib.c
+++ b/pimd/pim_tib.c
@@ -49,7 +49,8 @@ tib_sg_oil_setup(struct pim_instance *pim, pim_sgaddr sg, struct interface *oif)
if (up) {
memcpy(&nexthop, &up->rpf.source_nexthop,
sizeof(struct pim_nexthop));
- pim_ecmp_nexthop_lookup(pim, &nexthop, vif_source, &grp, 0);
+ (void)pim_ecmp_nexthop_lookup(pim, &nexthop, vif_source, &grp,
+ 0);
if (nexthop.interface)
input_iface_vif_index = pim_if_find_vifindex_by_ifindex(
pim, nexthop.interface->ifindex);
diff --git a/tests/topotests/ospfapi/test_ospf_clientapi.py b/tests/topotests/ospfapi/test_ospf_clientapi.py
index f6928d7cd0..94c8c5c732 100644
--- a/tests/topotests/ospfapi/test_ospf_clientapi.py
+++ b/tests/topotests/ospfapi/test_ospf_clientapi.py
@@ -472,52 +472,70 @@ def _test_opaque_add_del(tgen, apibin):
[
apibin,
"-v",
+ "add,9,10.0.1.1,230,1",
"add,9,10.0.1.1,230,2,00000202",
- "add,10,1.2.3.4,231,1,00010101",
"wait,1",
- "add,10,1.2.3.4,231,2",
- "add,11,232,3,ebadf00d",
+ "add,10,1.2.3.4,231,1",
+ "add,10,1.2.3.4,231,2,0102030405060708",
+ "wait,1",
+ "add,11,232,1",
+ "add,11,232,2,ebadf00d",
"wait,20",
- "del,10,1.2.3.4,231,1",
- "del,10,1.2.3.4,231,2",
+ "del,9,10.0.1.1,230,2,0",
+ "del,10,1.2.3.4,231,2,1",
+ "del,11,232,1,1",
]
)
-
add_input_dict = {
"areas": {
"1.2.3.4": {
"linkLocalOpaqueLsa": [
{
+ "lsId": "230.0.0.1",
+ "advertisedRouter": "192.168.0.1",
+ "sequenceNumber": "80000001",
+ "checksum": "6d5f",
+ },
+ {
"lsId": "230.0.0.2",
"advertisedRouter": "192.168.0.1",
"sequenceNumber": "80000001",
"checksum": "8142",
- }
+ },
],
+ "linkLocalOpaqueLsaCount": 2,
"areaLocalOpaqueLsa": [
{
"lsId": "231.0.0.1",
"advertisedRouter": "192.168.0.1",
"sequenceNumber": "80000001",
- "checksum": "695a",
+ "checksum": "5278",
},
{
"lsId": "231.0.0.2",
"advertisedRouter": "192.168.0.1",
"sequenceNumber": "80000001",
- "checksum": "4881",
+ "checksum": "6d30",
},
],
- }
+ "areaLocalOpaqueLsaCount": 2,
+ },
},
"asExternalOpaqueLsa": [
{
- "lsId": "232.0.0.3",
+ "lsId": "232.0.0.1",
"advertisedRouter": "192.168.0.1",
"sequenceNumber": "80000001",
- "checksum": "c666",
- }
+ "checksum": "5575",
+ },
+ {
+ "lsId": "232.0.0.2",
+ "advertisedRouter": "192.168.0.1",
+ "sequenceNumber": "80000001",
+ "checksum": "d05d",
+ },
],
+ "asExternalOpaqueLsaCount": 2,
}
step("reachable: check for add LSAs")
@@ -537,6 +555,14 @@ def _test_opaque_add_del(tgen, apibin):
"areas": {
"1.2.3.4": [
{
+ "linkStateId": "230.0.0.1",
+ "advertisingRouter": "192.168.0.1",
+ "lsaSeqNumber": "80000001",
+ "checksum": "6d5f",
+ "length": 20,
+ "opaqueDataLength": 0,
+ },
+ {
"linkStateId": "230.0.0.2",
"advertisingRouter": "192.168.0.1",
"lsaSeqNumber": "80000001",
@@ -544,7 +570,7 @@ def _test_opaque_add_del(tgen, apibin):
"length": 24,
"opaqueId": 2,
"opaqueDataLength": 4,
- }
+ },
]
}
}
@@ -557,33 +583,41 @@ def _test_opaque_add_del(tgen, apibin):
"linkStateId": "231.0.0.1",
"advertisingRouter": "192.168.0.1",
"lsaSeqNumber": "80000001",
- "checksum": "695a",
- "length": 24,
- "opaqueDataLength": 4,
+ "checksum": "5278",
+ "length": 20,
+ "opaqueDataLength": 0,
},
{
"linkStateId": "231.0.0.2",
"advertisingRouter": "192.168.0.1",
"lsaSeqNumber": "80000001",
- "checksum": "4881",
- "length": 20,
- "opaqueDataLength": 0,
+ "checksum": "6d30",
+ "length": 28,
+ "opaqueDataLength": 8,
},
- ]
- }
- }
+ ],
+ },
+ },
},
{
"asExternalOpaqueLsa": [
{
- "linkStateId": "232.0.0.3",
+ "linkStateId": "232.0.0.1",
+ "advertisingRouter": "192.168.0.1",
+ "lsaSeqNumber": "80000001",
+ "checksum": "5575",
+ "length": 20,
+ "opaqueDataLength": 0,
+ },
+ {
+ "linkStateId": "232.0.0.2",
"advertisingRouter": "192.168.0.1",
"lsaSeqNumber": "80000001",
- "checksum": "c666",
+ "checksum": "d05d",
"length": 24,
"opaqueDataLength": 4,
- }
- ]
+ },
+ ],
},
]
i = 0
@@ -602,9 +636,16 @@ def _test_opaque_add_del(tgen, apibin):
# Wait for add notification
# RECV: LSA update msg for LSA 232.0.0.3 in area 0.0.0.0 seq 0x80000001 len 24 age 9
- step("reachable: check for API add notifications")
- ls_ids = ["230.0.0.2", "231.0.0.1", "231.0.0.2", "232.0.0.3"]
+ ls_ids = [
+ "230.0.0.1",
+ "230.0.0.2",
+ "231.0.0.1",
+ "231.0.0.2",
+ "232.0.0.1",
+ "232.0.0.2",
+ ]
for ls_id in ls_ids:
+ step("reachable: check for API add notification: %s" % ls_id)
waitfor = "RECV:.*update msg.*LSA {}.*age ([0-9]+)".format(ls_id)
_ = _wait_output(pread, waitfor)
@@ -613,38 +654,54 @@ def _test_opaque_add_del(tgen, apibin):
"1.2.3.4": {
"linkLocalOpaqueLsa": [
{
+ "lsId": "230.0.0.1",
+ "advertisedRouter": "192.168.0.1",
+ "sequenceNumber": "80000001",
+ "checksum": "6d5f",
+ },
+ {
"lsId": "230.0.0.2",
"advertisedRouter": "192.168.0.1",
+ "lsaAge": 3600,
"sequenceNumber": "80000001",
"checksum": "8142",
- }
+ },
],
+ "linkLocalOpaqueLsaCount": 2,
"areaLocalOpaqueLsa": [
{
- "lsaAge": 3600,
"lsId": "231.0.0.1",
"advertisedRouter": "192.168.0.1",
"sequenceNumber": "80000001",
- "checksum": "695a",
+ "checksum": "5278",
},
{
- "lsaAge": 3600,
"lsId": "231.0.0.2",
"advertisedRouter": "192.168.0.1",
- "sequenceNumber": "80000001",
- "checksum": "4881",
+ "lsaAge": 3600,
+ "sequenceNumber": "80000002",
+ "checksum": "4682",
},
],
- }
+ "areaLocalOpaqueLsaCount": 2,
+ },
},
"asExternalOpaqueLsa": [
{
- "lsId": "232.0.0.3",
+ "lsId": "232.0.0.1",
"advertisedRouter": "192.168.0.1",
+ "lsaAge": 3600,
"sequenceNumber": "80000001",
- "checksum": "c666",
- }
+ "checksum": "5575",
+ },
+ {
+ "lsId": "232.0.0.2",
+ "advertisedRouter": "192.168.0.1",
+ "sequenceNumber": "80000001",
+ "checksum": "d05d",
+ },
],
+ "asExternalOpaqueLsaCount": 2,
}
step("reachable: check for explicit withdrawal LSAs")
@@ -652,64 +709,207 @@ def _test_opaque_add_del(tgen, apibin):
assert verify_ospf_database(tgen, r1, del_input_dict, json_cmd) is None
assert verify_ospf_database(tgen, r2, del_input_dict, json_cmd) is None
+ del_detail_input_dict = [
+ {
+ "linkLocalOpaqueLsa": {
+ "areas": {
+ "1.2.3.4": [
+ {
+ "linkStateId": "230.0.0.1",
+ "advertisingRouter": "192.168.0.1",
+ "lsaSeqNumber": "80000001",
+ "checksum": "6d5f",
+ "length": 20,
+ "opaqueDataLength": 0,
+ },
+ {
+ "linkStateId": "230.0.0.2",
+ "advertisingRouter": "192.168.0.1",
+ "lsaAge": 3600,
+ "lsaSeqNumber": "80000001",
+ "checksum": "8142",
+ "length": 24,
+ "opaqueId": 2,
+ "opaqueDataLength": 4,
+ },
+ ]
+ }
+ }
+ },
+ {
+ "areaLocalOpaqueLsa": {
+ "areas": {
+ "1.2.3.4": [
+ {
+ "linkStateId": "231.0.0.1",
+ "advertisingRouter": "192.168.0.1",
+ "lsaSeqNumber": "80000001",
+ "checksum": "5278",
+ "length": 20,
+ "opaqueDataLength": 0,
+ },
+ {
+ "lsaAge": 3600,
+ "linkStateId": "231.0.0.2",
+ "advertisingRouter": "192.168.0.1",
+ "lsaSeqNumber": "80000002",
+ "checksum": "4682",
+ # data removed
+ "length": 20,
+ "opaqueDataLength": 0,
+ },
+ ],
+ },
+ },
+ },
+ {
+ "asExternalOpaqueLsa": [
+ {
+ "linkStateId": "232.0.0.1",
+ "advertisingRouter": "192.168.0.1",
+ "lsaAge": 3600,
+ "lsaSeqNumber": "80000001",
+ "checksum": "5575",
+ "length": 20,
+ "opaqueDataLength": 0,
+ },
+ {
+ "linkStateId": "232.0.0.2",
+ "advertisingRouter": "192.168.0.1",
+ "lsaSeqNumber": "80000001",
+ "checksum": "d05d",
+ "length": 24,
+ "opaqueDataLength": 4,
+ },
+ ],
+ },
+ ]
+ i = 0
+ while i < numcs:
+ step("reachable: check for delete LSA details: %s" % json_cmds[i])
+ assert (
+ verify_ospf_database(tgen, r1, del_detail_input_dict[i], json_cmds[i])
+ is None
+ )
+ assert (
+ verify_ospf_database(tgen, r2, del_detail_input_dict[i], json_cmds[i])
+ is None
+ )
+ i += 1
+
p.terminate()
if p.wait():
comm_error(p)
- del_input_dict = {
- "areas": {
- "1.2.3.4": {
- "linkLocalOpaqueLsa": [
- {
- "lsaAge": 3600,
- "lsId": "230.0.0.2",
- "advertisedRouter": "192.168.0.1",
- "sequenceNumber": "80000001",
- "checksum": "8142",
- }
- ],
- "areaLocalOpaqueLsa": [
- {
- "lsaAge": 3600,
- "lsId": "231.0.0.1",
- "advertisedRouter": "192.168.0.1",
- "sequenceNumber": "80000001",
- "checksum": "695a",
- },
- {
- "lsaAge": 3600,
- "lsId": "231.0.0.2",
- "advertisedRouter": "192.168.0.1",
- "sequenceNumber": "80000001",
- "checksum": "4881",
- },
- ],
+
+ del_detail_input_dict = [
+ {
+ "linkLocalOpaqueLsa": {
+ "areas": {
+ "1.2.3.4": [
+ {
+ "linkStateId": "230.0.0.1",
+ "advertisingRouter": "192.168.0.1",
+ "lsaAge": 3600,
+ "lsaSeqNumber": "80000001",
+ "checksum": "6d5f",
+ "length": 20,
+ "opaqueDataLength": 0,
+ },
+ {
+ "linkStateId": "230.0.0.2",
+ "advertisingRouter": "192.168.0.1",
+ "lsaAge": 3600,
+ "lsaSeqNumber": "80000001",
+ "checksum": "8142",
+ "length": 24,
+ "opaqueId": 2,
+ "opaqueDataLength": 4,
+ },
+ ]
+ }
}
},
- "asExternalOpaqueLsa": [
- {
- "lsaAge": 3600,
- "lsId": "232.0.0.3",
- "advertisedRouter": "192.168.0.1",
- "sequenceNumber": "80000001",
- "checksum": "c666",
- }
- ],
- }
-
- step("reachable: check for implicit withdrawal LSAs")
- json_cmd = "show ip ospf da json"
- assert verify_ospf_database(tgen, r1, del_input_dict, json_cmd) is None
- assert verify_ospf_database(tgen, r2, del_input_dict, json_cmd) is None
+ {
+ "areaLocalOpaqueLsa": {
+ "areas": {
+ "1.2.3.4": [
+ {
+ "lsaAge": 3600,
+ "linkStateId": "231.0.0.1",
+ "advertisingRouter": "192.168.0.1",
+ "lsaSeqNumber": "80000001",
+ "checksum": "5278",
+ "length": 20,
+ "opaqueDataLength": 0,
+ },
+ {
+ "lsaAge": 3600,
+ "linkStateId": "231.0.0.2",
+ "advertisingRouter": "192.168.0.1",
+ "lsaSeqNumber": "80000002",
+ "checksum": "4682",
+ # data removed
+ "length": 20,
+ "opaqueDataLength": 0,
+ },
+ ],
+ },
+ },
+ },
+ {
+ "asExternalOpaqueLsa": [
+ {
+ "linkStateId": "232.0.0.1",
+ "advertisingRouter": "192.168.0.1",
+ "lsaAge": 3600,
+ "lsaSeqNumber": "80000001",
+ "checksum": "5575",
+ "length": 20,
+ "opaqueDataLength": 0,
+ },
+ {
+ "linkStateId": "232.0.0.2",
+ "advertisingRouter": "192.168.0.1",
+ "lsaAge": 3600,
+ "lsaSeqNumber": "80000001",
+ "checksum": "d05d",
+ "length": 24,
+ "opaqueDataLength": 4,
+ },
+ ],
+ },
+ ]
+ i = 0
+ while i < numcs:
+ step(
+ "reachable: check for post API shutdown delete LSA details: %s"
+ % json_cmds[i]
+ )
+ assert (
+ verify_ospf_database(tgen, r1, del_detail_input_dict[i], json_cmds[i])
+ is None
+ )
+ assert (
+ verify_ospf_database(tgen, r2, del_detail_input_dict[i], json_cmds[i])
+ is None
+ )
+ i += 1
# step("reachable: check for flush/age out")
# # Wait for max age notification
# waitfor = "RECV:.*update msg.*LSA {}.*age 3600".format(ls_id)
# _wait_output(pread, waitfor)
-
- step("reachable: check for API delete notifications")
- ls_ids = ["231.0.0.1", "231.0.0.2", "230.0.0.2", "232.0.0.3"]
+ ls_ids = [
+ "230.0.0.2",
+ "231.0.0.2",
+ "232.0.0.1",
+ "230.0.0.1",
+ "231.0.0.1",
+ "232.0.0.2",
+ ]
for ls_id in ls_ids:
- waitfor = "RECV:.*delete msg.*LSA {}.*".format(ls_id)
+ step("reachable: check for API delete notification: %s" % ls_id)
+ waitfor = "RECV:.*delete msg.*LSA {}.*age".format(ls_id)
_ = _wait_output(pread, waitfor)
except Exception:
if p: