mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-06-01 04:09:01 +00:00
Merge pull request #12871 from FRRouting/mergify/bp/dev/8.5/pr-12850
ospfd client api bugfix and refinements (backport #12850)
This commit is contained in:
commit
edf9bec2d1
@ -255,6 +255,16 @@ def nsm_name(state):
|
|||||||
return names.get(state, str(state))
|
return names.get(state, str(state))
|
||||||
|
|
||||||
|
|
||||||
|
class WithNothing:
|
||||||
|
"An object that does nothing when used with `with` statement."
|
||||||
|
|
||||||
|
async def __aenter__(self):
|
||||||
|
return
|
||||||
|
|
||||||
|
async def __aexit__(self, *args, **kwargs):
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
# --------------
|
# --------------
|
||||||
# Client Classes
|
# Client Classes
|
||||||
# --------------
|
# --------------
|
||||||
@ -560,15 +570,17 @@ class OspfOpaqueClient(OspfApiClient):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
server: hostname or IP address of server default is "localhost"
|
server: hostname or IP address of server default is "localhost"
|
||||||
|
wait_ready: if True then wait for OSPF to signal ready, in newer versions
|
||||||
|
FRR ospfd is always ready so this overhead can be skipped.
|
||||||
|
default is False.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
Will raise exceptions for failures with various `socket` modules
|
Will raise exceptions for failures with various `socket` modules
|
||||||
functions such as `socket.socket`, `socket.setsockopt`, `socket.bind`.
|
functions such as `socket.socket`, `socket.setsockopt`, `socket.bind`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, server="localhost"):
|
def __init__(self, server="localhost", wait_ready=False):
|
||||||
handlers = {
|
handlers = {
|
||||||
MSG_READY_NOTIFY: self._ready_msg,
|
|
||||||
MSG_LSA_UPDATE_NOTIFY: self._lsa_change_msg,
|
MSG_LSA_UPDATE_NOTIFY: self._lsa_change_msg,
|
||||||
MSG_LSA_DELETE_NOTIFY: self._lsa_change_msg,
|
MSG_LSA_DELETE_NOTIFY: self._lsa_change_msg,
|
||||||
MSG_NEW_IF: self._if_msg,
|
MSG_NEW_IF: self._if_msg,
|
||||||
@ -578,9 +590,13 @@ class OspfOpaqueClient(OspfApiClient):
|
|||||||
MSG_REACHABLE_CHANGE: self._reachable_msg,
|
MSG_REACHABLE_CHANGE: self._reachable_msg,
|
||||||
MSG_ROUTER_ID_CHANGE: self._router_id_msg,
|
MSG_ROUTER_ID_CHANGE: self._router_id_msg,
|
||||||
}
|
}
|
||||||
|
if wait_ready:
|
||||||
|
handlers[MSG_READY_NOTIFY] = self._ready_msg
|
||||||
|
|
||||||
super().__init__(server, handlers)
|
super().__init__(server, handlers)
|
||||||
|
|
||||||
self.ready_lock = Lock()
|
self.wait_ready = wait_ready
|
||||||
|
self.ready_lock = Lock() if wait_ready else WithNothing()
|
||||||
self.ready_cond = {
|
self.ready_cond = {
|
||||||
LSA_TYPE_OPAQUE_LINK: {},
|
LSA_TYPE_OPAQUE_LINK: {},
|
||||||
LSA_TYPE_OPAQUE_AREA: {},
|
LSA_TYPE_OPAQUE_AREA: {},
|
||||||
@ -617,13 +633,9 @@ class OspfOpaqueClient(OspfApiClient):
|
|||||||
mp = struct.pack(msg_fmt[mt], lsa_type, otype)
|
mp = struct.pack(msg_fmt[mt], lsa_type, otype)
|
||||||
await self.msg_send_raises(mt, mp)
|
await self.msg_send_raises(mt, mp)
|
||||||
|
|
||||||
async def _assure_opaque_ready(self, lsa_type, otype):
|
# If we are not waiting, mark ready for register check
|
||||||
async with self.ready_lock:
|
if not self.wait_ready:
|
||||||
if self.ready_cond[lsa_type].get(otype) is True:
|
self.ready_cond[lsa_type][otype] = True
|
||||||
return
|
|
||||||
|
|
||||||
await self._register_opaque_data(lsa_type, otype)
|
|
||||||
await self.wait_opaque_ready(lsa_type, otype)
|
|
||||||
|
|
||||||
async def _handle_msg_loop(self):
|
async def _handle_msg_loop(self):
|
||||||
try:
|
try:
|
||||||
@ -656,6 +668,8 @@ class OspfOpaqueClient(OspfApiClient):
|
|||||||
return lsa
|
return lsa
|
||||||
|
|
||||||
async def _ready_msg(self, mt, msg, extra, lsa_type, otype, addr):
|
async def _ready_msg(self, mt, msg, extra, lsa_type, otype, addr):
|
||||||
|
assert self.wait_ready
|
||||||
|
|
||||||
if lsa_type == LSA_TYPE_OPAQUE_LINK:
|
if lsa_type == LSA_TYPE_OPAQUE_LINK:
|
||||||
e = "ifaddr {}".format(ip(addr))
|
e = "ifaddr {}".format(ip(addr))
|
||||||
elif lsa_type == LSA_TYPE_OPAQUE_AREA:
|
elif lsa_type == LSA_TYPE_OPAQUE_AREA:
|
||||||
@ -825,6 +839,7 @@ class OspfOpaqueClient(OspfApiClient):
|
|||||||
Raises:
|
Raises:
|
||||||
See `msg_send_raises`
|
See `msg_send_raises`
|
||||||
"""
|
"""
|
||||||
|
assert self.ready_cond.get(lsa_type, {}).get(otype) is True, "Not Registered!"
|
||||||
|
|
||||||
if lsa_type == LSA_TYPE_OPAQUE_LINK:
|
if lsa_type == LSA_TYPE_OPAQUE_LINK:
|
||||||
ifaddr, aid = int(addr), 0
|
ifaddr, aid = int(addr), 0
|
||||||
@ -842,7 +857,6 @@ class OspfOpaqueClient(OspfApiClient):
|
|||||||
*OspfOpaqueClient._opaque_args(lsa_type, otype, oid, data),
|
*OspfOpaqueClient._opaque_args(lsa_type, otype, oid, data),
|
||||||
)
|
)
|
||||||
msg += data
|
msg += data
|
||||||
await self._assure_opaque_ready(lsa_type, otype)
|
|
||||||
await self.msg_send_raises(mt, msg)
|
await self.msg_send_raises(mt, msg)
|
||||||
|
|
||||||
async def delete_opaque_data(self, addr, lsa_type, otype, oid, flags=0):
|
async def delete_opaque_data(self, addr, lsa_type, otype, oid, flags=0):
|
||||||
@ -854,21 +868,31 @@ class OspfOpaqueClient(OspfApiClient):
|
|||||||
Args:
|
Args:
|
||||||
addr: depends on lsa_type, LINK => ifaddr, AREA => area ID, AS => ignored
|
addr: depends on lsa_type, LINK => ifaddr, AREA => area ID, AS => ignored
|
||||||
lsa_type: LSA_TYPE_OPAQUE_{LINK,AREA,AS}
|
lsa_type: LSA_TYPE_OPAQUE_{LINK,AREA,AS}
|
||||||
otype: (octet) opaque type. Note: the type will be registered if the user
|
otype: (octet) opaque type.
|
||||||
has not explicity done that yet with `register_opaque_data`.
|
|
||||||
oid: (3 octets) ID of this 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)
|
flags: (octet) optional flags (e.g., OSPF_API_DEL_ZERO_LEN_LSA, defaults to no flags)
|
||||||
Raises:
|
Raises:
|
||||||
See `msg_send_raises`
|
See `msg_send_raises`
|
||||||
"""
|
"""
|
||||||
if (lsa_type, otype) in self.opaque_change_cb:
|
assert self.ready_cond.get(lsa_type, {}).get(otype) is True, "Not Registered!"
|
||||||
del self.opaque_change_cb[(lsa_type, otype)]
|
|
||||||
|
|
||||||
mt = MSG_DELETE_REQUEST
|
mt = MSG_DELETE_REQUEST
|
||||||
await self._assure_opaque_ready(lsa_type, otype)
|
|
||||||
mp = struct.pack(msg_fmt[mt], int(addr), lsa_type, otype, flags, oid)
|
mp = struct.pack(msg_fmt[mt], int(addr), lsa_type, otype, flags, oid)
|
||||||
await self.msg_send_raises(mt, mp)
|
await self.msg_send_raises(mt, mp)
|
||||||
|
|
||||||
|
async def is_registered(self, lsa_type, otype):
|
||||||
|
"""Determine if an (lsa_type, otype) tuple has been registered with FRR
|
||||||
|
|
||||||
|
This determines if the type has been registered, but not necessarily if it is
|
||||||
|
ready, if that is required use the `wait_opaque_ready` metheod.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
lsa_type: LSA_TYPE_OPAQUE_{LINK,AREA,AS}
|
||||||
|
otype: (octet) opaque type.
|
||||||
|
"""
|
||||||
|
async with self.ready_lock:
|
||||||
|
return self.ready_cond.get(lsa_type, {}).get(otype) is not None
|
||||||
|
|
||||||
async def register_opaque_data(self, lsa_type, otype, callback=None):
|
async def register_opaque_data(self, lsa_type, otype, callback=None):
|
||||||
"""Register intent to advertise opaque data.
|
"""Register intent to advertise opaque data.
|
||||||
|
|
||||||
@ -878,8 +902,7 @@ class OspfOpaqueClient(OspfApiClient):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
lsa_type: LSA_TYPE_OPAQUE_{LINK,AREA,AS}
|
lsa_type: LSA_TYPE_OPAQUE_{LINK,AREA,AS}
|
||||||
otype: (octet) opaque type. Note: the type will be registered if the user
|
otype: (octet) opaque type.
|
||||||
has not explicity done that yet with `register_opaque_data`.
|
|
||||||
callback: if given, callback will be called when changes are received for
|
callback: if given, callback will be called when changes are received for
|
||||||
LSA of the given (lsa_type, otype). The callbacks signature is:
|
LSA of the given (lsa_type, otype). The callbacks signature is:
|
||||||
|
|
||||||
@ -895,6 +918,10 @@ class OspfOpaqueClient(OspfApiClient):
|
|||||||
Raises:
|
Raises:
|
||||||
See `msg_send_raises`
|
See `msg_send_raises`
|
||||||
"""
|
"""
|
||||||
|
assert not await self.is_registered(
|
||||||
|
lsa_type, otype
|
||||||
|
), "Registering registered type"
|
||||||
|
|
||||||
if callback:
|
if callback:
|
||||||
self.opaque_change_cb[(lsa_type, otype)] = callback
|
self.opaque_change_cb[(lsa_type, otype)] = callback
|
||||||
elif (lsa_type, otype) in self.opaque_change_cb:
|
elif (lsa_type, otype) in self.opaque_change_cb:
|
||||||
@ -913,6 +940,8 @@ class OspfOpaqueClient(OspfApiClient):
|
|||||||
if cond is True:
|
if cond is True:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
assert self.wait_ready
|
||||||
|
|
||||||
logging.debug(
|
logging.debug(
|
||||||
"waiting for ready %s opaque-type %s", lsa_typename(lsa_type), otype
|
"waiting for ready %s opaque-type %s", lsa_typename(lsa_type), otype
|
||||||
)
|
)
|
||||||
@ -933,8 +962,7 @@ class OspfOpaqueClient(OspfApiClient):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
lsa_type: LSA_TYPE_OPAQUE_{LINK,AREA,AS}
|
lsa_type: LSA_TYPE_OPAQUE_{LINK,AREA,AS}
|
||||||
otype: (octet) opaque type. Note: the type will be registered if the user
|
otype: (octet) opaque type.
|
||||||
has not explicity done that yet with `register_opaque_data`.
|
|
||||||
callback: if given, callback will be called when changes are received for
|
callback: if given, callback will be called when changes are received for
|
||||||
LSA of the given (lsa_type, otype). The callbacks signature is:
|
LSA of the given (lsa_type, otype). The callbacks signature is:
|
||||||
|
|
||||||
@ -951,17 +979,8 @@ class OspfOpaqueClient(OspfApiClient):
|
|||||||
|
|
||||||
See `msg_send_raises`
|
See `msg_send_raises`
|
||||||
"""
|
"""
|
||||||
if callback:
|
await self.register_opaque_data(lsa_type, otype, callback)
|
||||||
self.opaque_change_cb[(lsa_type, otype)] = callback
|
await self.wait_opaque_ready(lsa_type, otype)
|
||||||
elif (lsa_type, otype) in self.opaque_change_cb:
|
|
||||||
logging.warning(
|
|
||||||
"OSPFCLIENT: register: removing callback for %s opaque-type %s",
|
|
||||||
lsa_typename(lsa_type),
|
|
||||||
otype,
|
|
||||||
)
|
|
||||||
del self.opaque_change_cb[(lsa_type, otype)]
|
|
||||||
|
|
||||||
return await self._assure_opaque_ready(lsa_type, otype)
|
|
||||||
|
|
||||||
async def unregister_opaque_data(self, lsa_type, otype):
|
async def unregister_opaque_data(self, lsa_type, otype):
|
||||||
"""Unregister intent to advertise opaque data.
|
"""Unregister intent to advertise opaque data.
|
||||||
@ -971,11 +990,13 @@ class OspfOpaqueClient(OspfApiClient):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
lsa_type: LSA_TYPE_OPAQUE_{LINK,AREA,AS}
|
lsa_type: LSA_TYPE_OPAQUE_{LINK,AREA,AS}
|
||||||
otype: (octet) opaque type. Note: the type will be registered if the user
|
otype: (octet) opaque type.
|
||||||
has not explicity done that yet with `register_opaque_data`.
|
|
||||||
Raises:
|
Raises:
|
||||||
See `msg_send_raises`
|
See `msg_send_raises`
|
||||||
"""
|
"""
|
||||||
|
assert await self.is_registered(
|
||||||
|
lsa_type, otype
|
||||||
|
), "Unregistering unregistered type"
|
||||||
|
|
||||||
if (lsa_type, otype) in self.opaque_change_cb:
|
if (lsa_type, otype) in self.opaque_change_cb:
|
||||||
del self.opaque_change_cb[(lsa_type, otype)]
|
del self.opaque_change_cb[(lsa_type, otype)]
|
||||||
@ -1081,6 +1102,17 @@ class OspfOpaqueClient(OspfApiClient):
|
|||||||
# ================
|
# ================
|
||||||
# CLI/Script Usage
|
# CLI/Script Usage
|
||||||
# ================
|
# ================
|
||||||
|
def next_action(action_list=None):
|
||||||
|
"Get next action from list or STDIN"
|
||||||
|
if action_list:
|
||||||
|
for action in action_list:
|
||||||
|
yield action
|
||||||
|
else:
|
||||||
|
while True:
|
||||||
|
action = input("")
|
||||||
|
if not action:
|
||||||
|
break
|
||||||
|
yield action.strip()
|
||||||
|
|
||||||
|
|
||||||
async def async_main(args):
|
async def async_main(args):
|
||||||
@ -1099,8 +1131,7 @@ async def async_main(args):
|
|||||||
await c.req_ism_states()
|
await c.req_ism_states()
|
||||||
await c.req_nsm_states()
|
await c.req_nsm_states()
|
||||||
|
|
||||||
if args.actions:
|
for action in next_action(args.actions):
|
||||||
for action in args.actions:
|
|
||||||
_s = action.split(",")
|
_s = action.split(",")
|
||||||
what = _s.pop(False)
|
what = _s.pop(False)
|
||||||
if what.casefold() == "wait":
|
if what.casefold() == "wait":
|
||||||
@ -1119,6 +1150,10 @@ async def async_main(args):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
addr = ip(aval)
|
addr = ip(aval)
|
||||||
oargs = [addr, ltype, int(_s.pop(False)), int(_s.pop(False))]
|
oargs = [addr, ltype, int(_s.pop(False)), int(_s.pop(False))]
|
||||||
|
|
||||||
|
if not await c.is_registered(oargs[1], oargs[2]):
|
||||||
|
await c.register_opaque_data_wait(oargs[1], oargs[2])
|
||||||
|
|
||||||
if what.casefold() == "add":
|
if what.casefold() == "add":
|
||||||
try:
|
try:
|
||||||
b = bytes.fromhex(_s.pop(False))
|
b = bytes.fromhex(_s.pop(False))
|
||||||
@ -1141,7 +1176,7 @@ async def async_main(args):
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
f = 0
|
f = 0
|
||||||
await c.delete_opaque_data(*oargs, f)
|
await c.delete_opaque_data(*oargs, f)
|
||||||
if args.exit:
|
if not args.actions or args.exit:
|
||||||
return 0
|
return 0
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
logging.error("async_main: unexpected error: %s", error, exc_info=True)
|
logging.error("async_main: unexpected error: %s", error, exc_info=True)
|
||||||
@ -1158,19 +1193,23 @@ async def async_main(args):
|
|||||||
|
|
||||||
def main(*args):
|
def main(*args):
|
||||||
ap = argparse.ArgumentParser(args)
|
ap = argparse.ArgumentParser(args)
|
||||||
|
ap.add_argument("--logtag", default="CLIENT", help="tag to identify log messages")
|
||||||
ap.add_argument("--exit", action="store_true", help="Exit after commands")
|
ap.add_argument("--exit", action="store_true", help="Exit after commands")
|
||||||
ap.add_argument("--server", default="localhost", help="OSPF API server")
|
ap.add_argument("--server", default="localhost", help="OSPF API server")
|
||||||
ap.add_argument("-v", "--verbose", action="store_true", help="be verbose")
|
ap.add_argument("-v", "--verbose", action="store_true", help="be verbose")
|
||||||
ap.add_argument(
|
ap.add_argument(
|
||||||
"actions",
|
"actions",
|
||||||
nargs="*",
|
nargs="*",
|
||||||
help="(ADD|DEL),LSATYPE,[ADDR,],OTYPE,OID,[HEXDATA|DEL_FLAG]",
|
help="WAIT,SEC|(ADD|DEL),LSATYPE,[ADDR,],OTYPE,OID,[HEXDATA|DEL_FLAG]",
|
||||||
)
|
)
|
||||||
args = ap.parse_args()
|
args = ap.parse_args()
|
||||||
|
|
||||||
level = logging.DEBUG if args.verbose else logging.INFO
|
level = logging.DEBUG if args.verbose else logging.INFO
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
level=level, format="%(asctime)s %(levelname)s: CLIENT: %(name)s %(message)s"
|
level=level,
|
||||||
|
format="%(asctime)s %(levelname)s: {}: %(name)s %(message)s".format(
|
||||||
|
args.logtag
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
logging.info("ospfclient: starting")
|
logging.info("ospfclient: starting")
|
||||||
|
@ -2593,9 +2593,12 @@ static inline int cmp_route_nodes(struct route_node *orn,
|
|||||||
return 1;
|
return 1;
|
||||||
else if (!nrn)
|
else if (!nrn)
|
||||||
return -1;
|
return -1;
|
||||||
else if (orn->p.u.prefix4.s_addr < nrn->p.u.prefix4.s_addr)
|
|
||||||
|
uint32_t opn = ntohl(orn->p.u.prefix4.s_addr);
|
||||||
|
uint32_t npn = ntohl(nrn->p.u.prefix4.s_addr);
|
||||||
|
if (opn < npn)
|
||||||
return -1;
|
return -1;
|
||||||
else if (orn->p.u.prefix4.s_addr > nrn->p.u.prefix4.s_addr)
|
else if (opn > npn)
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "sockunion.h" /* for inet_aton() */
|
#include "sockunion.h" /* for inet_aton() */
|
||||||
|
#include "printfrr.h"
|
||||||
|
|
||||||
#include "ospfd/ospfd.h"
|
#include "ospfd/ospfd.h"
|
||||||
#include "ospfd/ospf_interface.h"
|
#include "ospfd/ospf_interface.h"
|
||||||
@ -1162,11 +1163,13 @@ void ospf_opaque_config_write_debug(struct vty *vty)
|
|||||||
void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa,
|
void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa,
|
||||||
json_object *json)
|
json_object *json)
|
||||||
{
|
{
|
||||||
|
char buf[128], *bp;
|
||||||
struct lsa_header *lsah = lsa->data;
|
struct lsa_header *lsah = lsa->data;
|
||||||
uint32_t lsid = ntohl(lsah->id.s_addr);
|
uint32_t lsid = ntohl(lsah->id.s_addr);
|
||||||
uint8_t opaque_type = GET_OPAQUE_TYPE(lsid);
|
uint8_t opaque_type = GET_OPAQUE_TYPE(lsid);
|
||||||
uint32_t opaque_id = GET_OPAQUE_ID(lsid);
|
uint32_t opaque_id = GET_OPAQUE_ID(lsid);
|
||||||
struct ospf_opaque_functab *functab;
|
struct ospf_opaque_functab *functab;
|
||||||
|
int len, lenValid;
|
||||||
|
|
||||||
/* Switch output functionality by vty address. */
|
/* Switch output functionality by vty address. */
|
||||||
if (vty != NULL) {
|
if (vty != NULL) {
|
||||||
@ -1185,11 +1188,19 @@ void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa,
|
|||||||
json, "opaqueType",
|
json, "opaqueType",
|
||||||
ospf_opaque_type_name(opaque_type));
|
ospf_opaque_type_name(opaque_type));
|
||||||
json_object_int_add(json, "opaqueId", opaque_id);
|
json_object_int_add(json, "opaqueId", opaque_id);
|
||||||
json_object_int_add(json, "opaqueDataLength",
|
len = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE;
|
||||||
ntohs(lsah->length)
|
json_object_int_add(json, "opaqueDataLength", len);
|
||||||
- OSPF_LSA_HEADER_SIZE);
|
lenValid = VALID_OPAQUE_INFO_LEN(lsah);
|
||||||
json_object_boolean_add(json, "opaqueDataLengthValid",
|
json_object_boolean_add(json, "opaqueDataLengthValid",
|
||||||
VALID_OPAQUE_INFO_LEN(lsah));
|
lenValid);
|
||||||
|
if (lenValid) {
|
||||||
|
bp = asnprintfrr(MTYPE_TMP, buf, sizeof(buf),
|
||||||
|
"%*pHXn", (int)len,
|
||||||
|
(lsah + 1));
|
||||||
|
json_object_string_add(json, "opaqueData", buf);
|
||||||
|
if (bp != buf)
|
||||||
|
XFREE(MTYPE_TMP, bp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
zlog_debug(" Opaque-Type %u (%s)", opaque_type,
|
zlog_debug(" Opaque-Type %u (%s)", opaque_type,
|
||||||
|
@ -363,31 +363,35 @@ void ospf_route_install(struct ospf *ospf, struct route_table *rt)
|
|||||||
|
|
||||||
/* RFC2328 16.1. (4). For "router". */
|
/* RFC2328 16.1. (4). For "router". */
|
||||||
void ospf_intra_add_router(struct route_table *rt, struct vertex *v,
|
void ospf_intra_add_router(struct route_table *rt, struct vertex *v,
|
||||||
struct ospf_area *area, bool add_all)
|
struct ospf_area *area, bool add_only)
|
||||||
{
|
{
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct ospf_route * or ;
|
struct ospf_route * or ;
|
||||||
struct prefix_ipv4 p;
|
struct prefix_ipv4 p;
|
||||||
struct router_lsa *lsa;
|
struct router_lsa *lsa;
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT) {
|
||||||
|
if (!add_only)
|
||||||
zlog_debug("%s: Start", __func__);
|
zlog_debug("%s: Start", __func__);
|
||||||
|
else
|
||||||
|
zlog_debug("%s: REACHRUN: Start", __func__);
|
||||||
|
}
|
||||||
lsa = (struct router_lsa *)v->lsa;
|
lsa = (struct router_lsa *)v->lsa;
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
zlog_debug("%s: LS ID: %pI4", __func__, &lsa->header.id);
|
zlog_debug("%s: LS ID: %pI4", __func__, &lsa->header.id);
|
||||||
|
|
||||||
|
if (!add_only) {
|
||||||
if (!OSPF_IS_AREA_BACKBONE(area))
|
if (!OSPF_IS_AREA_BACKBONE(area))
|
||||||
ospf_vl_up_check(area, lsa->header.id, v);
|
ospf_vl_up_check(area, lsa->header.id, v);
|
||||||
|
|
||||||
if (!CHECK_FLAG(lsa->flags, ROUTER_LSA_SHORTCUT))
|
if (!CHECK_FLAG(lsa->flags, ROUTER_LSA_SHORTCUT))
|
||||||
area->shortcut_capability = 0;
|
area->shortcut_capability = 0;
|
||||||
|
|
||||||
/* If the newly added vertex is an area border router or AS boundary
|
/* If the newly added vertex is an area border router or AS
|
||||||
router, a routing table entry is added whose destination type is
|
boundary router, a routing table entry is added whose
|
||||||
"router". */
|
destination type is "router". */
|
||||||
if (!add_all && !IS_ROUTER_LSA_BORDER(lsa) &&
|
if (!IS_ROUTER_LSA_BORDER(lsa) &&
|
||||||
!IS_ROUTER_LSA_EXTERNAL(lsa)) {
|
!IS_ROUTER_LSA_EXTERNAL(lsa)) {
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
@ -401,6 +405,7 @@ void ospf_intra_add_router(struct route_table *rt, struct vertex *v,
|
|||||||
area->abr_count++;
|
area->abr_count++;
|
||||||
if (IS_ROUTER_LSA_EXTERNAL(lsa))
|
if (IS_ROUTER_LSA_EXTERNAL(lsa))
|
||||||
area->asbr_count++;
|
area->asbr_count++;
|
||||||
|
}
|
||||||
|
|
||||||
/* The Options field found in the associated router-LSA is copied
|
/* The Options field found in the associated router-LSA is copied
|
||||||
into the routing table entry's Optional capabilities field. Call
|
into the routing table entry's Optional capabilities field. Call
|
||||||
@ -448,8 +453,12 @@ void ospf_intra_add_router(struct route_table *rt, struct vertex *v,
|
|||||||
|
|
||||||
listnode_add(rn->info, or);
|
listnode_add(rn->info, or);
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT) {
|
||||||
|
if (!add_only)
|
||||||
zlog_debug("%s: Stop", __func__);
|
zlog_debug("%s: Stop", __func__);
|
||||||
|
else
|
||||||
|
zlog_debug("%s: REACHRUN: Stop", __func__);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RFC2328 16.1. (4). For transit network. */
|
/* RFC2328 16.1. (4). For transit network. */
|
||||||
|
@ -4,7 +4,12 @@ interface r1-eth0
|
|||||||
ip ospf dead-interval 10
|
ip ospf dead-interval 10
|
||||||
ip ospf area 1.2.3.4
|
ip ospf area 1.2.3.4
|
||||||
!
|
!
|
||||||
|
interface r1-eth1
|
||||||
|
ip ospf hello-interval 2
|
||||||
|
ip ospf dead-interval 10
|
||||||
|
ip ospf area 1.2.3.4
|
||||||
|
!
|
||||||
router ospf
|
router ospf
|
||||||
ospf router-id 192.168.0.1
|
ospf router-id 1.0.0.0
|
||||||
capability opaque
|
capability opaque
|
||||||
!
|
!
|
||||||
|
@ -2,3 +2,5 @@
|
|||||||
interface r1-eth0
|
interface r1-eth0
|
||||||
ip address 10.0.1.1/24
|
ip address 10.0.1.1/24
|
||||||
!
|
!
|
||||||
|
interface r1-eth1
|
||||||
|
ip address 10.0.4.1/24
|
||||||
|
@ -10,6 +10,6 @@ interface r2-eth1
|
|||||||
ip ospf area 1.2.3.4
|
ip ospf area 1.2.3.4
|
||||||
!
|
!
|
||||||
router ospf
|
router ospf
|
||||||
ospf router-id 192.168.0.2
|
ospf router-id 2.0.0.0
|
||||||
capability opaque
|
capability opaque
|
||||||
!
|
!
|
||||||
|
@ -10,6 +10,6 @@ interface r3-eth1
|
|||||||
ip ospf area 1.2.3.4
|
ip ospf area 1.2.3.4
|
||||||
!
|
!
|
||||||
router ospf
|
router ospf
|
||||||
ospf router-id 192.168.0.3
|
ospf router-id 3.0.0.0
|
||||||
capability opaque
|
capability opaque
|
||||||
!
|
!
|
||||||
|
@ -4,7 +4,12 @@ interface r4-eth0
|
|||||||
ip ospf dead-interval 10
|
ip ospf dead-interval 10
|
||||||
ip ospf area 1.2.3.4
|
ip ospf area 1.2.3.4
|
||||||
!
|
!
|
||||||
|
interface r4-eth1
|
||||||
|
ip ospf hello-interval 2
|
||||||
|
ip ospf dead-interval 10
|
||||||
|
ip ospf area 1.2.3.4
|
||||||
|
!
|
||||||
router ospf
|
router ospf
|
||||||
ospf router-id 192.168.0.4
|
ospf router-id 4.0.0.0
|
||||||
capability opaque
|
capability opaque
|
||||||
!
|
!
|
||||||
|
@ -2,3 +2,5 @@
|
|||||||
interface r4-eth0
|
interface r4-eth0
|
||||||
ip address 10.0.3.4/24
|
ip address 10.0.3.4/24
|
||||||
!
|
!
|
||||||
|
interface r4-eth1
|
||||||
|
ip address 10.0.4.4/24
|
@ -34,7 +34,7 @@ from datetime import datetime, timedelta
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from lib.common_config import retry, run_frr_cmd, step
|
from lib.common_config import retry, run_frr_cmd, step
|
||||||
from lib.micronet import comm_error
|
from lib.micronet import Timeout, comm_error
|
||||||
from lib.topogen import Topogen, TopoRouter
|
from lib.topogen import Topogen, TopoRouter
|
||||||
from lib.topotest import interface_set_status, json_cmp
|
from lib.topotest import interface_set_status, json_cmp
|
||||||
|
|
||||||
@ -56,15 +56,20 @@ assert os.path.exists(
|
|||||||
# Test Setup
|
# Test Setup
|
||||||
# ----------
|
# ----------
|
||||||
|
|
||||||
|
#
|
||||||
|
# r1 - r2
|
||||||
|
# | |
|
||||||
|
# r4 - r3
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function", name="tgen")
|
@pytest.fixture(scope="function", name="tgen")
|
||||||
def _tgen(request):
|
def _tgen(request):
|
||||||
"Setup/Teardown the environment and provide tgen argument to tests"
|
"Setup/Teardown the environment and provide tgen argument to tests"
|
||||||
nrouters = request.param
|
nrouters = request.param
|
||||||
if nrouters == 1:
|
|
||||||
topodef = {"sw1:": ("r1",)}
|
|
||||||
else:
|
|
||||||
topodef = {f"sw{i}": (f"r{i}", f"r{i+1}") for i in range(1, nrouters)}
|
topodef = {f"sw{i}": (f"r{i}", f"r{i+1}") for i in range(1, nrouters)}
|
||||||
|
if nrouters == 4:
|
||||||
|
topodef["sw4"] = ("r4", "r1")
|
||||||
|
|
||||||
tgen = Topogen(topodef, request.module.__name__)
|
tgen = Topogen(topodef, request.module.__name__)
|
||||||
tgen.start_topology()
|
tgen.start_topology()
|
||||||
@ -107,23 +112,23 @@ def verify_ospf_database(tgen, dut, input_dict, cmd="show ip ospf database json"
|
|||||||
def myreadline(f):
|
def myreadline(f):
|
||||||
buf = b""
|
buf = b""
|
||||||
while True:
|
while True:
|
||||||
# logging.info("READING 1 CHAR")
|
# logging.debug("READING 1 CHAR")
|
||||||
c = f.read(1)
|
c = f.read(1)
|
||||||
if not c:
|
if not c:
|
||||||
return buf if buf else None
|
return buf if buf else None
|
||||||
buf += c
|
buf += c
|
||||||
# logging.info("READ CHAR: '%s'", c)
|
# logging.debug("READ CHAR: '%s'", c)
|
||||||
if c == b"\n":
|
if c == b"\n":
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
|
|
||||||
def _wait_output(p, regex, timeout=120):
|
def _wait_output(p, regex, maxwait=120):
|
||||||
retry_until = datetime.now() + timedelta(seconds=timeout)
|
timeout = Timeout(maxwait)
|
||||||
while datetime.now() < retry_until:
|
while not timeout.is_expired():
|
||||||
# line = p.stdout.readline()
|
# line = p.stdout.readline()
|
||||||
line = myreadline(p.stdout)
|
line = myreadline(p.stdout)
|
||||||
if not line:
|
if not line:
|
||||||
assert None, "Timeout waiting for '{}'".format(regex)
|
assert None, "EOF waiting for '{}'".format(regex)
|
||||||
line = line.decode("utf-8")
|
line = line.decode("utf-8")
|
||||||
line = line.rstrip()
|
line = line.rstrip()
|
||||||
if line:
|
if line:
|
||||||
@ -131,7 +136,9 @@ def _wait_output(p, regex, timeout=120):
|
|||||||
m = re.search(regex, line)
|
m = re.search(regex, line)
|
||||||
if m:
|
if m:
|
||||||
return m
|
return m
|
||||||
assert None, "Failed to get output withint {}s".format(timeout)
|
assert None, "Failed to get output matching '{}' withint {} actual {}s".format(
|
||||||
|
regex, maxwait, timeout.elapsed()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# -----
|
# -----
|
||||||
@ -141,12 +148,13 @@ def _wait_output(p, regex, timeout=120):
|
|||||||
|
|
||||||
def _test_reachability(tgen, testbin):
|
def _test_reachability(tgen, testbin):
|
||||||
waitlist = [
|
waitlist = [
|
||||||
"192.168.0.1,192.168.0.2,192.168.0.4",
|
"1.0.0.0,2.0.0.0,4.0.0.0",
|
||||||
"192.168.0.2,192.168.0.4",
|
"2.0.0.0,4.0.0.0",
|
||||||
"192.168.0.1,192.168.0.2,192.168.0.4",
|
"1.0.0.0,2.0.0.0,4.0.0.0",
|
||||||
]
|
]
|
||||||
r2 = tgen.gears["r2"]
|
r2 = tgen.gears["r2"]
|
||||||
r3 = tgen.gears["r3"]
|
r3 = tgen.gears["r3"]
|
||||||
|
r4 = tgen.gears["r4"]
|
||||||
|
|
||||||
wait_args = [f"--wait={x}" for x in waitlist]
|
wait_args = [f"--wait={x}" for x in waitlist]
|
||||||
|
|
||||||
@ -164,10 +172,12 @@ def _test_reachability(tgen, testbin):
|
|||||||
|
|
||||||
step("reachable: check for modified reachability")
|
step("reachable: check for modified reachability")
|
||||||
interface_set_status(r2, "r2-eth0", False)
|
interface_set_status(r2, "r2-eth0", False)
|
||||||
|
interface_set_status(r4, "r4-eth1", False)
|
||||||
_wait_output(p, "SUCCESS: {}".format(waitlist[1]))
|
_wait_output(p, "SUCCESS: {}".format(waitlist[1]))
|
||||||
|
|
||||||
step("reachable: check for restored reachability")
|
step("reachable: check for restored reachability")
|
||||||
interface_set_status(r2, "r2-eth0", True)
|
interface_set_status(r2, "r2-eth0", True)
|
||||||
|
interface_set_status(r4, "r4-eth1", True)
|
||||||
_wait_output(p, "SUCCESS: {}".format(waitlist[2]))
|
_wait_output(p, "SUCCESS: {}".format(waitlist[2]))
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
logging.error("ERROR: %s", error)
|
logging.error("ERROR: %s", error)
|
||||||
@ -182,16 +192,16 @@ def _test_reachability(tgen, testbin):
|
|||||||
def test_ospf_reachability(tgen):
|
def test_ospf_reachability(tgen):
|
||||||
testbin = os.path.join(TESTDIR, "ctester.py")
|
testbin = os.path.join(TESTDIR, "ctester.py")
|
||||||
rc, o, e = tgen.gears["r2"].net.cmd_status([testbin, "--help"])
|
rc, o, e = tgen.gears["r2"].net.cmd_status([testbin, "--help"])
|
||||||
logging.info("%s --help: rc: %s stdout: '%s' stderr: '%s'", testbin, rc, o, e)
|
logging.debug("%s --help: rc: %s stdout: '%s' stderr: '%s'", testbin, rc, o, e)
|
||||||
_test_reachability(tgen, testbin)
|
_test_reachability(tgen, testbin)
|
||||||
|
|
||||||
|
|
||||||
def _test_router_id(tgen, testbin):
|
def _test_router_id(tgen, testbin):
|
||||||
r1 = tgen.gears["r1"]
|
r1 = tgen.gears["r1"]
|
||||||
waitlist = [
|
waitlist = [
|
||||||
"192.168.0.1",
|
"1.0.0.0",
|
||||||
"1.1.1.1",
|
"1.1.1.1",
|
||||||
"192.168.0.1",
|
"1.0.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
mon_args = [f"--monitor={x}" for x in waitlist]
|
mon_args = [f"--monitor={x}" for x in waitlist]
|
||||||
@ -213,7 +223,7 @@ def _test_router_id(tgen, testbin):
|
|||||||
_wait_output(p, "SUCCESS: {}".format(waitlist[1]))
|
_wait_output(p, "SUCCESS: {}".format(waitlist[1]))
|
||||||
|
|
||||||
step("router id: check for restored router id")
|
step("router id: check for restored router id")
|
||||||
r1.vtysh_multicmd("conf t\nrouter ospf\nospf router-id 192.168.0.1")
|
r1.vtysh_multicmd("conf t\nrouter ospf\nospf router-id 1.0.0.0")
|
||||||
_wait_output(p, "SUCCESS: {}".format(waitlist[2]))
|
_wait_output(p, "SUCCESS: {}".format(waitlist[2]))
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
logging.error("ERROR: %s", error)
|
logging.error("ERROR: %s", error)
|
||||||
@ -228,7 +238,7 @@ def _test_router_id(tgen, testbin):
|
|||||||
def test_ospf_router_id(tgen):
|
def test_ospf_router_id(tgen):
|
||||||
testbin = os.path.join(TESTDIR, "ctester.py")
|
testbin = os.path.join(TESTDIR, "ctester.py")
|
||||||
rc, o, e = tgen.gears["r1"].net.cmd_status([testbin, "--help"])
|
rc, o, e = tgen.gears["r1"].net.cmd_status([testbin, "--help"])
|
||||||
logging.info("%s --help: rc: %s stdout: '%s' stderr: '%s'", testbin, rc, o, e)
|
logging.debug("%s --help: rc: %s stdout: '%s' stderr: '%s'", testbin, rc, o, e)
|
||||||
_test_router_id(tgen, testbin)
|
_test_router_id(tgen, testbin)
|
||||||
|
|
||||||
|
|
||||||
@ -243,13 +253,13 @@ def _test_add_data(tgen, apibin):
|
|||||||
try:
|
try:
|
||||||
p = r1.popen([apibin, "-v", "add,9,10.0.1.1,230,2,00000202"])
|
p = r1.popen([apibin, "-v", "add,9,10.0.1.1,230,2,00000202"])
|
||||||
input_dict = {
|
input_dict = {
|
||||||
"routerId": "192.168.0.1",
|
"routerId": "1.0.0.0",
|
||||||
"areas": {
|
"areas": {
|
||||||
"1.2.3.4": {
|
"1.2.3.4": {
|
||||||
"linkLocalOpaqueLsa": [
|
"linkLocalOpaqueLsa": [
|
||||||
{
|
{
|
||||||
"lsId": "230.0.0.2",
|
"lsId": "230.0.0.2",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"sequenceNumber": "80000001",
|
"sequenceNumber": "80000001",
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -265,7 +275,7 @@ def _test_add_data(tgen, apibin):
|
|||||||
"1.2.3.4": [
|
"1.2.3.4": [
|
||||||
{
|
{
|
||||||
"linkStateId": "230.0.0.2",
|
"linkStateId": "230.0.0.2",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"opaqueData": "00000202",
|
"opaqueData": "00000202",
|
||||||
},
|
},
|
||||||
@ -285,13 +295,13 @@ def _test_add_data(tgen, apibin):
|
|||||||
p = None
|
p = None
|
||||||
p = r1.popen([apibin, "-v", "add,10,1.2.3.4,231,1,00010101"])
|
p = r1.popen([apibin, "-v", "add,10,1.2.3.4,231,1,00010101"])
|
||||||
input_dict = {
|
input_dict = {
|
||||||
"routerId": "192.168.0.1",
|
"routerId": "1.0.0.0",
|
||||||
"areas": {
|
"areas": {
|
||||||
"1.2.3.4": {
|
"1.2.3.4": {
|
||||||
"linkLocalOpaqueLsa": [
|
"linkLocalOpaqueLsa": [
|
||||||
{
|
{
|
||||||
"lsId": "230.0.0.2",
|
"lsId": "230.0.0.2",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"sequenceNumber": "80000001",
|
"sequenceNumber": "80000001",
|
||||||
"lsaAge": 3600,
|
"lsaAge": 3600,
|
||||||
}
|
}
|
||||||
@ -299,7 +309,7 @@ def _test_add_data(tgen, apibin):
|
|||||||
"areaLocalOpaqueLsa": [
|
"areaLocalOpaqueLsa": [
|
||||||
{
|
{
|
||||||
"lsId": "231.0.0.1",
|
"lsId": "231.0.0.1",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"sequenceNumber": "80000001",
|
"sequenceNumber": "80000001",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -315,7 +325,7 @@ def _test_add_data(tgen, apibin):
|
|||||||
"1.2.3.4": [
|
"1.2.3.4": [
|
||||||
{
|
{
|
||||||
"linkStateId": "231.0.0.1",
|
"linkStateId": "231.0.0.1",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"opaqueData": "00010101",
|
"opaqueData": "00010101",
|
||||||
},
|
},
|
||||||
@ -336,13 +346,13 @@ def _test_add_data(tgen, apibin):
|
|||||||
|
|
||||||
p = r1.popen([apibin, "-v", "add,11,232,3,deadbeaf01234567"])
|
p = r1.popen([apibin, "-v", "add,11,232,3,deadbeaf01234567"])
|
||||||
input_dict = {
|
input_dict = {
|
||||||
"routerId": "192.168.0.1",
|
"routerId": "1.0.0.0",
|
||||||
"areas": {
|
"areas": {
|
||||||
"1.2.3.4": {
|
"1.2.3.4": {
|
||||||
"areaLocalOpaqueLsa": [
|
"areaLocalOpaqueLsa": [
|
||||||
{
|
{
|
||||||
"lsId": "231.0.0.1",
|
"lsId": "231.0.0.1",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"sequenceNumber": "80000001",
|
"sequenceNumber": "80000001",
|
||||||
"lsaAge": 3600,
|
"lsaAge": 3600,
|
||||||
},
|
},
|
||||||
@ -352,7 +362,7 @@ def _test_add_data(tgen, apibin):
|
|||||||
"asExternalOpaqueLsa": [
|
"asExternalOpaqueLsa": [
|
||||||
{
|
{
|
||||||
"lsId": "232.0.0.3",
|
"lsId": "232.0.0.3",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"sequenceNumber": "80000001",
|
"sequenceNumber": "80000001",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -364,7 +374,7 @@ def _test_add_data(tgen, apibin):
|
|||||||
"asExternalOpaqueLsa": [
|
"asExternalOpaqueLsa": [
|
||||||
{
|
{
|
||||||
"linkStateId": "232.0.0.3",
|
"linkStateId": "232.0.0.3",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"opaqueData": "deadbeaf01234567",
|
"opaqueData": "deadbeaf01234567",
|
||||||
},
|
},
|
||||||
@ -382,11 +392,11 @@ def _test_add_data(tgen, apibin):
|
|||||||
p = None
|
p = None
|
||||||
|
|
||||||
input_dict = {
|
input_dict = {
|
||||||
"routerId": "192.168.0.1",
|
"routerId": "1.0.0.0",
|
||||||
"asExternalOpaqueLsa": [
|
"asExternalOpaqueLsa": [
|
||||||
{
|
{
|
||||||
"lsId": "232.0.0.3",
|
"lsId": "232.0.0.3",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"sequenceNumber": "80000001",
|
"sequenceNumber": "80000001",
|
||||||
"lsaAge": 3600,
|
"lsaAge": 3600,
|
||||||
},
|
},
|
||||||
@ -400,11 +410,11 @@ def _test_add_data(tgen, apibin):
|
|||||||
# Originate it again
|
# Originate it again
|
||||||
p = r1.popen([apibin, "-v", "add,11,232,3,ebadf00d"])
|
p = r1.popen([apibin, "-v", "add,11,232,3,ebadf00d"])
|
||||||
input_dict = {
|
input_dict = {
|
||||||
"routerId": "192.168.0.1",
|
"routerId": "1.0.0.0",
|
||||||
"asExternalOpaqueLsa": [
|
"asExternalOpaqueLsa": [
|
||||||
{
|
{
|
||||||
"lsId": "232.0.0.3",
|
"lsId": "232.0.0.3",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"sequenceNumber": "80000002",
|
"sequenceNumber": "80000002",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -415,7 +425,7 @@ def _test_add_data(tgen, apibin):
|
|||||||
"asExternalOpaqueLsa": [
|
"asExternalOpaqueLsa": [
|
||||||
{
|
{
|
||||||
"linkStateId": "232.0.0.3",
|
"linkStateId": "232.0.0.3",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaSeqNumber": "80000002",
|
"lsaSeqNumber": "80000002",
|
||||||
"opaqueData": "ebadf00d",
|
"opaqueData": "ebadf00d",
|
||||||
},
|
},
|
||||||
@ -425,6 +435,7 @@ def _test_add_data(tgen, apibin):
|
|||||||
json_cmd = "show ip ospf da opaque-as json"
|
json_cmd = "show ip ospf da opaque-as json"
|
||||||
assert verify_ospf_database(tgen, r1, input_dict, json_cmd) is None
|
assert verify_ospf_database(tgen, r1, input_dict, json_cmd) is None
|
||||||
|
|
||||||
|
logging.debug("sending interrupt to writer api client")
|
||||||
p.send_signal(signal.SIGINT)
|
p.send_signal(signal.SIGINT)
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
p.wait()
|
p.wait()
|
||||||
@ -439,6 +450,7 @@ def _test_add_data(tgen, apibin):
|
|||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
if p:
|
if p:
|
||||||
|
logging.debug("cleanup: sending interrupt to writer api client")
|
||||||
p.terminate()
|
p.terminate()
|
||||||
p.wait()
|
p.wait()
|
||||||
|
|
||||||
@ -447,7 +459,7 @@ def _test_add_data(tgen, apibin):
|
|||||||
def test_ospf_opaque_add_data3(tgen):
|
def test_ospf_opaque_add_data3(tgen):
|
||||||
apibin = os.path.join(CLIENTDIR, "ospfclient.py")
|
apibin = os.path.join(CLIENTDIR, "ospfclient.py")
|
||||||
rc, o, e = tgen.gears["r2"].net.cmd_status([apibin, "--help"])
|
rc, o, e = tgen.gears["r2"].net.cmd_status([apibin, "--help"])
|
||||||
logging.info("%s --help: rc: %s stdout: '%s' stderr: '%s'", apibin, rc, o, e)
|
logging.debug("%s --help: rc: %s stdout: '%s' stderr: '%s'", apibin, rc, o, e)
|
||||||
_test_add_data(tgen, apibin)
|
_test_add_data(tgen, apibin)
|
||||||
|
|
||||||
|
|
||||||
@ -459,10 +471,12 @@ def _test_opaque_add_del(tgen, apibin):
|
|||||||
|
|
||||||
p = None
|
p = None
|
||||||
pread = None
|
pread = None
|
||||||
|
# Log to our stdin, stderr
|
||||||
|
pout = open(os.path.join(r1.net.logdir, "r1/add-del.log"), "a+")
|
||||||
try:
|
try:
|
||||||
step("reachable: check for add notification")
|
step("reachable: check for add notification")
|
||||||
pread = r2.popen(
|
pread = r2.popen(
|
||||||
["/usr/bin/timeout", "120", apibin, "-v"],
|
["/usr/bin/timeout", "120", apibin, "-v", "--logtag=READER", "wait,120"],
|
||||||
encoding=None, # don't buffer
|
encoding=None, # don't buffer
|
||||||
stdin=subprocess.DEVNULL,
|
stdin=subprocess.DEVNULL,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
@ -492,30 +506,30 @@ def _test_opaque_add_del(tgen, apibin):
|
|||||||
"linkLocalOpaqueLsa": [
|
"linkLocalOpaqueLsa": [
|
||||||
{
|
{
|
||||||
"lsId": "230.0.0.1",
|
"lsId": "230.0.0.1",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"sequenceNumber": "80000001",
|
"sequenceNumber": "80000001",
|
||||||
"checksum": "6d5f",
|
"checksum": "76bf",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"lsId": "230.0.0.2",
|
"lsId": "230.0.0.2",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"sequenceNumber": "80000001",
|
"sequenceNumber": "80000001",
|
||||||
"checksum": "8142",
|
"checksum": "8aa2",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"linkLocalOpaqueLsaCount": 2,
|
"linkLocalOpaqueLsaCount": 2,
|
||||||
"areaLocalOpaqueLsa": [
|
"areaLocalOpaqueLsa": [
|
||||||
{
|
{
|
||||||
"lsId": "231.0.0.1",
|
"lsId": "231.0.0.1",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"sequenceNumber": "80000001",
|
"sequenceNumber": "80000001",
|
||||||
"checksum": "5278",
|
"checksum": "5bd8",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"lsId": "231.0.0.2",
|
"lsId": "231.0.0.2",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"sequenceNumber": "80000001",
|
"sequenceNumber": "80000001",
|
||||||
"checksum": "6d30",
|
"checksum": "7690",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"areaLocalOpaqueLsaCount": 2,
|
"areaLocalOpaqueLsaCount": 2,
|
||||||
@ -524,15 +538,15 @@ def _test_opaque_add_del(tgen, apibin):
|
|||||||
"asExternalOpaqueLsa": [
|
"asExternalOpaqueLsa": [
|
||||||
{
|
{
|
||||||
"lsId": "232.0.0.1",
|
"lsId": "232.0.0.1",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"sequenceNumber": "80000001",
|
"sequenceNumber": "80000001",
|
||||||
"checksum": "5575",
|
"checksum": "5ed5",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"lsId": "232.0.0.2",
|
"lsId": "232.0.0.2",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"sequenceNumber": "80000001",
|
"sequenceNumber": "80000001",
|
||||||
"checksum": "d05d",
|
"checksum": "d9bd",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"asExternalOpaqueLsaCount": 2,
|
"asExternalOpaqueLsaCount": 2,
|
||||||
@ -556,17 +570,17 @@ def _test_opaque_add_del(tgen, apibin):
|
|||||||
"1.2.3.4": [
|
"1.2.3.4": [
|
||||||
{
|
{
|
||||||
"linkStateId": "230.0.0.1",
|
"linkStateId": "230.0.0.1",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"checksum": "6d5f",
|
"checksum": "76bf",
|
||||||
"length": 20,
|
"length": 20,
|
||||||
"opaqueDataLength": 0,
|
"opaqueDataLength": 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"linkStateId": "230.0.0.2",
|
"linkStateId": "230.0.0.2",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"checksum": "8142",
|
"checksum": "8aa2",
|
||||||
"length": 24,
|
"length": 24,
|
||||||
"opaqueId": 2,
|
"opaqueId": 2,
|
||||||
"opaqueDataLength": 4,
|
"opaqueDataLength": 4,
|
||||||
@ -581,17 +595,17 @@ def _test_opaque_add_del(tgen, apibin):
|
|||||||
"1.2.3.4": [
|
"1.2.3.4": [
|
||||||
{
|
{
|
||||||
"linkStateId": "231.0.0.1",
|
"linkStateId": "231.0.0.1",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"checksum": "5278",
|
"checksum": "5bd8",
|
||||||
"length": 20,
|
"length": 20,
|
||||||
"opaqueDataLength": 0,
|
"opaqueDataLength": 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"linkStateId": "231.0.0.2",
|
"linkStateId": "231.0.0.2",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"checksum": "6d30",
|
"checksum": "7690",
|
||||||
"length": 28,
|
"length": 28,
|
||||||
"opaqueDataLength": 8,
|
"opaqueDataLength": 8,
|
||||||
},
|
},
|
||||||
@ -603,17 +617,17 @@ def _test_opaque_add_del(tgen, apibin):
|
|||||||
"asExternalOpaqueLsa": [
|
"asExternalOpaqueLsa": [
|
||||||
{
|
{
|
||||||
"linkStateId": "232.0.0.1",
|
"linkStateId": "232.0.0.1",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"checksum": "5575",
|
"checksum": "5ed5",
|
||||||
"length": 20,
|
"length": 20,
|
||||||
"opaqueDataLength": 0,
|
"opaqueDataLength": 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"linkStateId": "232.0.0.2",
|
"linkStateId": "232.0.0.2",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"checksum": "d05d",
|
"checksum": "d9bd",
|
||||||
"length": 24,
|
"length": 24,
|
||||||
"opaqueDataLength": 4,
|
"opaqueDataLength": 4,
|
||||||
},
|
},
|
||||||
@ -655,32 +669,32 @@ def _test_opaque_add_del(tgen, apibin):
|
|||||||
"linkLocalOpaqueLsa": [
|
"linkLocalOpaqueLsa": [
|
||||||
{
|
{
|
||||||
"lsId": "230.0.0.1",
|
"lsId": "230.0.0.1",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"sequenceNumber": "80000001",
|
"sequenceNumber": "80000001",
|
||||||
"checksum": "6d5f",
|
"checksum": "76bf",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"lsId": "230.0.0.2",
|
"lsId": "230.0.0.2",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"lsaAge": 3600,
|
"lsaAge": 3600,
|
||||||
"sequenceNumber": "80000001",
|
"sequenceNumber": "80000001",
|
||||||
"checksum": "8142",
|
"checksum": "8aa2",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"linkLocalOpaqueLsaCount": 2,
|
"linkLocalOpaqueLsaCount": 2,
|
||||||
"areaLocalOpaqueLsa": [
|
"areaLocalOpaqueLsa": [
|
||||||
{
|
{
|
||||||
"lsId": "231.0.0.1",
|
"lsId": "231.0.0.1",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"sequenceNumber": "80000001",
|
"sequenceNumber": "80000001",
|
||||||
"checksum": "5278",
|
"checksum": "5bd8",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"lsId": "231.0.0.2",
|
"lsId": "231.0.0.2",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"lsaAge": 3600,
|
"lsaAge": 3600,
|
||||||
"sequenceNumber": "80000002",
|
"sequenceNumber": "80000002",
|
||||||
"checksum": "4682",
|
"checksum": "4fe2",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"areaLocalOpaqueLsaCount": 2,
|
"areaLocalOpaqueLsaCount": 2,
|
||||||
@ -689,16 +703,16 @@ def _test_opaque_add_del(tgen, apibin):
|
|||||||
"asExternalOpaqueLsa": [
|
"asExternalOpaqueLsa": [
|
||||||
{
|
{
|
||||||
"lsId": "232.0.0.1",
|
"lsId": "232.0.0.1",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"lsaAge": 3600,
|
"lsaAge": 3600,
|
||||||
"sequenceNumber": "80000001",
|
"sequenceNumber": "80000001",
|
||||||
"checksum": "5575",
|
"checksum": "5ed5",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"lsId": "232.0.0.2",
|
"lsId": "232.0.0.2",
|
||||||
"advertisedRouter": "192.168.0.1",
|
"advertisedRouter": "1.0.0.0",
|
||||||
"sequenceNumber": "80000001",
|
"sequenceNumber": "80000001",
|
||||||
"checksum": "d05d",
|
"checksum": "d9bd",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"asExternalOpaqueLsaCount": 2,
|
"asExternalOpaqueLsaCount": 2,
|
||||||
@ -716,18 +730,18 @@ def _test_opaque_add_del(tgen, apibin):
|
|||||||
"1.2.3.4": [
|
"1.2.3.4": [
|
||||||
{
|
{
|
||||||
"linkStateId": "230.0.0.1",
|
"linkStateId": "230.0.0.1",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"checksum": "6d5f",
|
"checksum": "76bf",
|
||||||
"length": 20,
|
"length": 20,
|
||||||
"opaqueDataLength": 0,
|
"opaqueDataLength": 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"linkStateId": "230.0.0.2",
|
"linkStateId": "230.0.0.2",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaAge": 3600,
|
"lsaAge": 3600,
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"checksum": "8142",
|
"checksum": "8aa2",
|
||||||
"length": 24,
|
"length": 24,
|
||||||
"opaqueId": 2,
|
"opaqueId": 2,
|
||||||
"opaqueDataLength": 4,
|
"opaqueDataLength": 4,
|
||||||
@ -742,18 +756,18 @@ def _test_opaque_add_del(tgen, apibin):
|
|||||||
"1.2.3.4": [
|
"1.2.3.4": [
|
||||||
{
|
{
|
||||||
"linkStateId": "231.0.0.1",
|
"linkStateId": "231.0.0.1",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"checksum": "5278",
|
"checksum": "5bd8",
|
||||||
"length": 20,
|
"length": 20,
|
||||||
"opaqueDataLength": 0,
|
"opaqueDataLength": 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"lsaAge": 3600,
|
"lsaAge": 3600,
|
||||||
"linkStateId": "231.0.0.2",
|
"linkStateId": "231.0.0.2",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaSeqNumber": "80000002",
|
"lsaSeqNumber": "80000002",
|
||||||
"checksum": "4682",
|
"checksum": "4fe2",
|
||||||
# data removed
|
# data removed
|
||||||
"length": 20,
|
"length": 20,
|
||||||
"opaqueDataLength": 0,
|
"opaqueDataLength": 0,
|
||||||
@ -766,18 +780,18 @@ def _test_opaque_add_del(tgen, apibin):
|
|||||||
"asExternalOpaqueLsa": [
|
"asExternalOpaqueLsa": [
|
||||||
{
|
{
|
||||||
"linkStateId": "232.0.0.1",
|
"linkStateId": "232.0.0.1",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaAge": 3600,
|
"lsaAge": 3600,
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"checksum": "5575",
|
"checksum": "5ed5",
|
||||||
"length": 20,
|
"length": 20,
|
||||||
"opaqueDataLength": 0,
|
"opaqueDataLength": 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"linkStateId": "232.0.0.2",
|
"linkStateId": "232.0.0.2",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"checksum": "d05d",
|
"checksum": "d9bd",
|
||||||
"length": 24,
|
"length": 24,
|
||||||
"opaqueDataLength": 4,
|
"opaqueDataLength": 4,
|
||||||
},
|
},
|
||||||
@ -808,19 +822,19 @@ def _test_opaque_add_del(tgen, apibin):
|
|||||||
"1.2.3.4": [
|
"1.2.3.4": [
|
||||||
{
|
{
|
||||||
"linkStateId": "230.0.0.1",
|
"linkStateId": "230.0.0.1",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaAge": 3600,
|
"lsaAge": 3600,
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"checksum": "6d5f",
|
"checksum": "76bf",
|
||||||
"length": 20,
|
"length": 20,
|
||||||
"opaqueDataLength": 0,
|
"opaqueDataLength": 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"linkStateId": "230.0.0.2",
|
"linkStateId": "230.0.0.2",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaAge": 3600,
|
"lsaAge": 3600,
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"checksum": "8142",
|
"checksum": "8aa2",
|
||||||
"length": 24,
|
"length": 24,
|
||||||
"opaqueId": 2,
|
"opaqueId": 2,
|
||||||
"opaqueDataLength": 4,
|
"opaqueDataLength": 4,
|
||||||
@ -836,18 +850,18 @@ def _test_opaque_add_del(tgen, apibin):
|
|||||||
{
|
{
|
||||||
"lsaAge": 3600,
|
"lsaAge": 3600,
|
||||||
"linkStateId": "231.0.0.1",
|
"linkStateId": "231.0.0.1",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"checksum": "5278",
|
"checksum": "5bd8",
|
||||||
"length": 20,
|
"length": 20,
|
||||||
"opaqueDataLength": 0,
|
"opaqueDataLength": 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"lsaAge": 3600,
|
"lsaAge": 3600,
|
||||||
"linkStateId": "231.0.0.2",
|
"linkStateId": "231.0.0.2",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaSeqNumber": "80000002",
|
"lsaSeqNumber": "80000002",
|
||||||
"checksum": "4682",
|
"checksum": "4fe2",
|
||||||
# data removed
|
# data removed
|
||||||
"length": 20,
|
"length": 20,
|
||||||
"opaqueDataLength": 0,
|
"opaqueDataLength": 0,
|
||||||
@ -860,19 +874,19 @@ def _test_opaque_add_del(tgen, apibin):
|
|||||||
"asExternalOpaqueLsa": [
|
"asExternalOpaqueLsa": [
|
||||||
{
|
{
|
||||||
"linkStateId": "232.0.0.1",
|
"linkStateId": "232.0.0.1",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaAge": 3600,
|
"lsaAge": 3600,
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"checksum": "5575",
|
"checksum": "5ed5",
|
||||||
"length": 20,
|
"length": 20,
|
||||||
"opaqueDataLength": 0,
|
"opaqueDataLength": 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"linkStateId": "232.0.0.2",
|
"linkStateId": "232.0.0.2",
|
||||||
"advertisingRouter": "192.168.0.1",
|
"advertisingRouter": "1.0.0.0",
|
||||||
"lsaAge": 3600,
|
"lsaAge": 3600,
|
||||||
"lsaSeqNumber": "80000001",
|
"lsaSeqNumber": "80000001",
|
||||||
"checksum": "d05d",
|
"checksum": "d9bd",
|
||||||
"length": 24,
|
"length": 24,
|
||||||
"opaqueDataLength": 4,
|
"opaqueDataLength": 4,
|
||||||
},
|
},
|
||||||
@ -931,7 +945,7 @@ def _test_opaque_add_del(tgen, apibin):
|
|||||||
def test_ospf_opaque_delete_data3(tgen):
|
def test_ospf_opaque_delete_data3(tgen):
|
||||||
apibin = os.path.join(CLIENTDIR, "ospfclient.py")
|
apibin = os.path.join(CLIENTDIR, "ospfclient.py")
|
||||||
rc, o, e = tgen.gears["r2"].net.cmd_status([apibin, "--help"])
|
rc, o, e = tgen.gears["r2"].net.cmd_status([apibin, "--help"])
|
||||||
logging.info("%s --help: rc: %s stdout: '%s' stderr: '%s'", apibin, rc, o, e)
|
logging.debug("%s --help: rc: %s stdout: '%s' stderr: '%s'", apibin, rc, o, e)
|
||||||
_test_opaque_add_del(tgen, apibin)
|
_test_opaque_add_del(tgen, apibin)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user