Skip to content

Commit

Permalink
isisd: When the ISIS types of the routers do not match on a P2P link,…
Browse files Browse the repository at this point in the history
… the neighbor status remains UP

Test Scenario:
RouterA and RouterB are in the same routing domain and have configured a P2P link. RouterA is configured with "is-type level-1" while RouterB is configured with "is-type level-1-2". They establish a level-1 UP neighborship. In this scenario, we expect that when RouterB's configuration is switched to "is-type level-2-only", the neighborship status on both RouterA and RouterB would be non-UP. However, RouterB still shows the neighbor as UP.

Upon receiving a P2P Hello packet, the function "process_p2p_hello" is invoked. According to the ISO/IEC 10589 protocol specification, section 8.2.5.2 a) and tables 5 and 7, if the "iih->circ_type" of the neighbor's hello packet does not match one's own "circuit->is_type," we may choose to take no action.
When establishing a neighborship for the first time, the neighbor's status can remain in the "Initializing" state. However, if the neighborship has already been established and one's own "circuit->is_type" changes, the neighbor's UP status cannot be reset. Therefore, when processing P2P Hello packets, we should be cognizant of changes in our own link adjacency type.

Signed-off-by: zhou-run <zhou.run@h3c.com>
  • Loading branch information
zhou-run committed Aug 7, 2024
1 parent 64112ed commit 55422f1
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 1 deletion.
3 changes: 2 additions & 1 deletion isisd/isis_pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,8 @@ static int process_p2p_hello(struct iih_info *iih)
return ISIS_OK;
}
}
if (!adj || adj->level != iih->calculated_type) {
if (!adj || adj->level != iih->calculated_type ||
!(iih->circuit->is_type & iih->circ_type)) {
if (!adj) {
adj = isis_new_adj(iih->sys_id, NULL,
iih->calculated_type, iih->circuit);
Expand Down
134 changes: 134 additions & 0 deletions tests/topotests/isis_topo1/test_isis_topo1.py
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,140 @@ def test_isis_hello_padding_during_adjacency_formation():
result = check_last_iih_packet_for_padding(r1, expect_padding=False)
assert result is True, result

def test_isis_neighbor_state():
"Check that the neighbor states remain normal when the ISIS type is switched."

tgen = get_topogen()
# Don't run this test if we have any failure.
if tgen.routers_have_failure():
pytest.skip(tgen.errors)

logger.info("Checking 'show isis neighbor json'")

# Establish a P2P link
# When the IS-IS type of r3 is set to level-1-2 and the IS-IS type of r5 is set to level-1,
# it is expected that all neighbors exist and are in the Up state
r3 = tgen.gears["r3"]
r3.vtysh_cmd(
"""
configure
interface r3-eth1
isis network point-to-point
end
"""
)
r5 = tgen.gears["r5"]
r5.vtysh_cmd(
"""
configure
interface r5-eth0
isis network point-to-point
end
"""
)
result = _check_isis_neighbor_json("r3", "r5", True, "Up")
assert result is True, result
result = _check_isis_neighbor_json("r5", "r3", True, "Up")
assert result is True, result

# Remove the configuration that affects the switch of IS-IS type.
# Configure the IS-IS type of r3 to transition from level-1-2 to level-2-only,
# while maintaining the IS-IS type of r5 as level-1.
# In this scenario,
# the expectation is that some neighbors do not exist or are in the Initializing state
r3.vtysh_cmd(
"""
configure
router isis 1
no redistribute ipv4 connected level-1
no redistribute ipv6 connected level-1
is-type level-2-only
interface r3-eth1
isis circuit-type level-2-only
end
"""
)
result = _check_isis_neighbor_json("r3", "r5", False, "Initializing")
assert result is True, result
result = _check_isis_neighbor_json("r5", "r3", False, "Initializing")
assert result is True, result

# Restore to initial configuration
r3.vtysh_cmd(
"""
configure
router isis 1
no is-type
redistribute ipv4 connected level-1
redistribute ipv6 connected level-1
interface r3-eth1
isis circuit-type level-1
no isis network point-to-point
end
"""
)
r5.vtysh_cmd(
"""
configure
interface r5-eth0
no isis network point-to-point
end
"""
)
result = _check_isis_neighbor_json("r3", "r5", True, "Up")
assert result is True, result
result = _check_isis_neighbor_json("r5", "r3", True, "Up")
assert result is True, result


def _check_isis_neighbor_json(self, neighbor, neighbor_expected, neighbor_state_expected):
tgen = get_topogen()
router = tgen.gears[self]
logger.info(f"check_isis_neighbor_json {router}")

result = _check_isis_neighbor_exist(self, neighbor)
if result == True:
return _check_isis_neighbor_state(self, neighbor, neighbor_state_expected)
elif neighbor_expected == True:
return "{} with expected neighbor {} got none ".format(
router.name, neighbor
)
else:
return True

@retry(retry_timeout=5)
def _check_isis_neighbor_exist(self, neighbor):
tgen = get_topogen()
router = tgen.gears[self]
logger.info(f"check_isis_neighbor_exist {router}")
isis_neightor_output = router.vtysh_cmd(
"show isis neighbor {} json".format(neighbor)
)

neighbor_json = json.loads(isis_neightor_output)
if "state" not in neighbor_json["areas"][0]["circuits"][0]["interface"]:
return "The neighbor {} of router {} has not been learned yet ".format(
neighbor, router.name
)

return True

@retry(retry_timeout=5)
def _check_isis_neighbor_state(self, neighbor, neighbor_state_expected):
tgen = get_topogen()
router = tgen.gears[self]
logger.info(f"check_isis_neighbor_state {router}")
isis_neightor_output = router.vtysh_cmd(
"show isis neighbor {} json".format(neighbor)
)

neighbor_json = json.loads(isis_neightor_output)
neighbor_state = neighbor_json["areas"][0]["circuits"][0]["interface"]["state"]
if neighbor_state == neighbor_state_expected:
return True
return "{} peer with expected neighbor_state {} got {} ".format(
router.name, neighbor_state_expected, neighbor_state
)

@retry(retry_timeout=5)
def check_last_iih_packet_for_padding(router, expect_padding):
Expand Down

0 comments on commit 55422f1

Please sign in to comment.