mirror of
https://github.com/espressif/openthread.git
synced 2026-10-21 15:08:19 +00:00
[border-router] accept RA initiated from the infra interface (#6348)
Accept RA initiated from the infra interface so that we can detect the existence of another RA daemon which is working on the same infra interface. Also enhance the test_single_border_router.py test script to make it more readable.
This commit is contained in:
@@ -249,9 +249,6 @@ void RoutingManager::RecvIcmp6Message(uint32_t aInfraIfIndex,
|
|||||||
VerifyOrExit(aInfraIfIndex == mInfraIfIndex, error = kErrorDrop);
|
VerifyOrExit(aInfraIfIndex == mInfraIfIndex, error = kErrorDrop);
|
||||||
infraLinkLocalAddr = static_cast<const Ip6::Address *>(&mInfraIfLinkLocalAddress);
|
infraLinkLocalAddr = static_cast<const Ip6::Address *>(&mInfraIfLinkLocalAddress);
|
||||||
|
|
||||||
// Drop any ICMPv6 messages sent from myself.
|
|
||||||
VerifyOrExit(infraLinkLocalAddr != nullptr && aSrcAddress != *infraLinkLocalAddr, error = kErrorDrop);
|
|
||||||
|
|
||||||
VerifyOrExit(aBuffer != nullptr && aBufferLength >= sizeof(*icmp6Header), error = kErrorParse);
|
VerifyOrExit(aBuffer != nullptr && aBufferLength >= sizeof(*icmp6Header), error = kErrorParse);
|
||||||
|
|
||||||
icmp6Header = reinterpret_cast<const Ip6::Icmp::Header *>(aBuffer);
|
icmp6Header = reinterpret_cast<const Ip6::Icmp::Header *>(aBuffer);
|
||||||
@@ -262,6 +259,8 @@ void RoutingManager::RecvIcmp6Message(uint32_t aInfraIfIndex,
|
|||||||
HandleRouterAdvertisement(aSrcAddress, aBuffer, aBufferLength);
|
HandleRouterAdvertisement(aSrcAddress, aBuffer, aBufferLength);
|
||||||
break;
|
break;
|
||||||
case Ip6::Icmp::Header::kTypeRouterSolicit:
|
case Ip6::Icmp::Header::kTypeRouterSolicit:
|
||||||
|
// Drop Router Solicitations initiated from infra interface.
|
||||||
|
VerifyOrExit(aSrcAddress != *infraLinkLocalAddr, error = kErrorDrop);
|
||||||
HandleRouterSolicit(aSrcAddress, aBuffer, aBufferLength);
|
HandleRouterSolicit(aSrcAddress, aBuffer, aBufferLength);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -637,6 +636,8 @@ void RoutingManager::StartRoutingPolicyEvaluationDelay(void)
|
|||||||
// between 0 and kMaxRtrSolicitationDelay.
|
// between 0 and kMaxRtrSolicitationDelay.
|
||||||
void RoutingManager::StartRouterSolicitationDelay(void)
|
void RoutingManager::StartRouterSolicitationDelay(void)
|
||||||
{
|
{
|
||||||
|
OT_ASSERT(mAdvertisedOnLinkPrefix == nullptr);
|
||||||
|
|
||||||
uint32_t randomDelay;
|
uint32_t randomDelay;
|
||||||
|
|
||||||
mRouterSolicitCount = 0;
|
mRouterSolicitCount = 0;
|
||||||
@@ -993,10 +994,12 @@ bool RoutingManager::UpdateDiscoveredPrefixes(const RouterAdv::PrefixInfoOption
|
|||||||
|
|
||||||
if (!IsValidOnLinkPrefix(aPio, aManagedAddrConfig))
|
if (!IsValidOnLinkPrefix(aPio, aManagedAddrConfig))
|
||||||
{
|
{
|
||||||
otLogInfoBr("ignore invalid prefix in PIO: %s", prefix.ToString().AsCString());
|
otLogInfoBr("ignore invalid on-link prefix in PIO: %s", prefix.ToString().AsCString());
|
||||||
ExitNow();
|
ExitNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VerifyOrExit(mAdvertisedOnLinkPrefix == nullptr || prefix != *mAdvertisedOnLinkPrefix);
|
||||||
|
|
||||||
otLogInfoBr("discovered on-link prefix (%s, %u seconds) from interface %u", prefix.ToString().AsCString(),
|
otLogInfoBr("discovered on-link prefix (%s, %u seconds) from interface %u", prefix.ToString().AsCString(),
|
||||||
aPio.GetValidLifetime(), mInfraIfIndex);
|
aPio.GetValidLifetime(), mInfraIfIndex);
|
||||||
|
|
||||||
@@ -1020,11 +1023,20 @@ bool RoutingManager::UpdateDiscoveredPrefixes(const RouterAdv::RouteInfoOption &
|
|||||||
|
|
||||||
if (!IsValidOmrPrefix(prefix))
|
if (!IsValidOmrPrefix(prefix))
|
||||||
{
|
{
|
||||||
otLogInfoBr("ignore invalid prefix in RIO: %s", prefix.ToString().AsCString());
|
otLogInfoBr("ignore invalid OMR prefix in RIO: %s", prefix.ToString().AsCString());
|
||||||
ExitNow();
|
ExitNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore the OMR prefix in current Thread Network.
|
// Ignore OMR prefixes advertised by ourselves or in current Thread Network Data.
|
||||||
|
// The `mAdvertisedOmrPrefixes` and the OMR prefix set in Network Data should eventually
|
||||||
|
// be equal, but there is time that they are not synchronized immediately:
|
||||||
|
// 1. Network Data could contain more OMR prefixes than `mAdvertisedOmrPrefixes` because
|
||||||
|
// we added random delay before Evaluating routing policy when Network Data is changed.
|
||||||
|
// 2. `mAdvertisedOmrPrefixes` could contain more OMR prefixes than Network Data because
|
||||||
|
// it takes time to sync a new OMR prefix into Network Data (multicast loopback RA
|
||||||
|
// messages are usually faster than Thread Network Data propagation).
|
||||||
|
// They are the reasons why we need both the checks.
|
||||||
|
VerifyOrExit(!ContainsPrefix(prefix, mAdvertisedOmrPrefixes, mAdvertisedOmrPrefixNum));
|
||||||
VerifyOrExit(!NetworkDataContainsOmrPrefix(prefix));
|
VerifyOrExit(!NetworkDataContainsOmrPrefix(prefix));
|
||||||
|
|
||||||
otLogInfoBr("discovered OMR prefix (%s, %u seconds) from interface %u", prefix.ToString().AsCString(),
|
otLogInfoBr("discovered OMR prefix (%s, %u seconds) from interface %u", prefix.ToString().AsCString(),
|
||||||
@@ -1080,9 +1092,12 @@ bool RoutingManager::InvalidateDiscoveredPrefixes(const Ip6::Prefix *aPrefix, bo
|
|||||||
{
|
{
|
||||||
mDiscoveredPrefixInvalidTimer.Stop();
|
mDiscoveredPrefixInvalidTimer.Stop();
|
||||||
|
|
||||||
// There are no valid on-link prefixes on infra link now, start Router Solicitation
|
if (mAdvertisedOnLinkPrefix == nullptr)
|
||||||
// To find out more on-link prefixes or timeout to advertise my local on-link prefix.
|
{
|
||||||
StartRouterSolicitationDelay();
|
// There are no valid on-link prefixes on infra link now, start Router Solicitation
|
||||||
|
// To find out more on-link prefixes or timeout to advertise my local on-link prefix.
|
||||||
|
StartRouterSolicitationDelay();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,16 +39,14 @@ import thread_cert
|
|||||||
# Topology:
|
# Topology:
|
||||||
# ----------------(eth)--------------------
|
# ----------------(eth)--------------------
|
||||||
# | |
|
# | |
|
||||||
# BR1 (Leader) HOST
|
# BR (Leader) HOST
|
||||||
# |
|
# |
|
||||||
# ROUTER1
|
# ROUTER
|
||||||
#
|
#
|
||||||
|
|
||||||
BR1 = 1
|
BR = 1
|
||||||
ROUTER1 = 2
|
ROUTER = 2
|
||||||
HOST = 4
|
HOST = 3
|
||||||
|
|
||||||
CHANNEL1 = 18
|
|
||||||
|
|
||||||
# The two prefixes are set small enough that a random-generated OMR prefix is
|
# The two prefixes are set small enough that a random-generated OMR prefix is
|
||||||
# very likely greater than them. So that the duckhorn BR will remove the random-generated one.
|
# very likely greater than them. So that the duckhorn BR will remove the random-generated one.
|
||||||
@@ -60,20 +58,17 @@ class SingleBorderRouter(thread_cert.TestCase):
|
|||||||
USE_MESSAGE_FACTORY = False
|
USE_MESSAGE_FACTORY = False
|
||||||
|
|
||||||
TOPOLOGY = {
|
TOPOLOGY = {
|
||||||
BR1: {
|
BR: {
|
||||||
'name': 'BR_1',
|
'name': 'BR',
|
||||||
'allowlist': [ROUTER1],
|
'allowlist': [ROUTER],
|
||||||
'is_otbr': True,
|
'is_otbr': True,
|
||||||
'version': '1.2',
|
'version': '1.2',
|
||||||
'channel': CHANNEL1,
|
|
||||||
'router_selection_jitter': 2,
|
|
||||||
},
|
},
|
||||||
ROUTER1: {
|
ROUTER: {
|
||||||
'name': 'Router_1',
|
'name': 'Router',
|
||||||
'allowlist': [BR1],
|
'allowlist': [BR],
|
||||||
'version': '1.2',
|
'version': '1.2',
|
||||||
'channel': CHANNEL1,
|
'router_selection_jitter': 1,
|
||||||
'router_selection_jitter': 2,
|
|
||||||
},
|
},
|
||||||
HOST: {
|
HOST: {
|
||||||
'name': 'Host',
|
'name': 'Host',
|
||||||
@@ -82,16 +77,20 @@ class SingleBorderRouter(thread_cert.TestCase):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def test(self):
|
def test(self):
|
||||||
self.nodes[HOST].start(start_radvd=False)
|
br = self.nodes[BR]
|
||||||
|
router = self.nodes[ROUTER]
|
||||||
|
host = self.nodes[HOST]
|
||||||
|
|
||||||
|
host.start(start_radvd=False)
|
||||||
self.simulator.go(5)
|
self.simulator.go(5)
|
||||||
|
|
||||||
self.nodes[BR1].start()
|
br.start()
|
||||||
self.simulator.go(5)
|
self.simulator.go(5)
|
||||||
self.assertEqual('leader', self.nodes[BR1].get_state())
|
self.assertEqual('leader', br.get_state())
|
||||||
|
|
||||||
self.nodes[ROUTER1].start()
|
router.start()
|
||||||
self.simulator.go(5)
|
self.simulator.go(5)
|
||||||
self.assertEqual('router', self.nodes[ROUTER1].get_state())
|
self.assertEqual('router', router.get_state())
|
||||||
|
|
||||||
#
|
#
|
||||||
# Case 1. There is no OMR prefix or on-link prefix.
|
# Case 1. There is no OMR prefix or on-link prefix.
|
||||||
@@ -100,30 +99,29 @@ class SingleBorderRouter(thread_cert.TestCase):
|
|||||||
self.simulator.go(10)
|
self.simulator.go(10)
|
||||||
self.collect_ipaddrs()
|
self.collect_ipaddrs()
|
||||||
|
|
||||||
logging.info("BR1 addrs: %r", self.nodes[BR1].get_addrs())
|
logging.info("BR addrs: %r", br.get_addrs())
|
||||||
logging.info("ROUTER1 addrs: %r", self.nodes[ROUTER1].get_addrs())
|
logging.info("ROUTER addrs: %r", router.get_addrs())
|
||||||
logging.info("HOST addrs: %r", self.nodes[HOST].get_addrs())
|
logging.info("HOST addrs: %r", host.get_addrs())
|
||||||
|
|
||||||
self.assertTrue(len(self.nodes[BR1].get_prefixes()) == 1)
|
self.assertEqual(len(br.get_prefixes()), 1)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_prefixes()) == 1)
|
self.assertEqual(len(router.get_prefixes()), 1)
|
||||||
self.assertTrue(len(self.nodes[BR1].get_routes()) == 1)
|
self.assertEqual(len(br.get_routes()), 1)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_routes()) == 1)
|
self.assertEqual(len(router.get_routes()), 1)
|
||||||
|
|
||||||
omr_prefix = self.nodes[BR1].get_prefixes()[0]
|
omr_prefix = br.get_prefixes()[0]
|
||||||
external_route = self.nodes[BR1].get_routes()[0]
|
external_route = br.get_routes()[0]
|
||||||
|
|
||||||
self.assertTrue(len(self.nodes[BR1].get_ip6_address(config.ADDRESS_TYPE.OMR)) == 1)
|
self.assertEqual(len(br.get_ip6_address(config.ADDRESS_TYPE.OMR)), 1)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.OMR)) == 1)
|
self.assertEqual(len(router.get_ip6_address(config.ADDRESS_TYPE.OMR)), 1)
|
||||||
self.assertTrue(len(self.nodes[HOST].get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)) == 1)
|
self.assertEqual(len(host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)), 1)
|
||||||
|
|
||||||
br1_omr_address = self.nodes[BR1].get_ip6_address(config.ADDRESS_TYPE.OMR)[0]
|
br1_omr_address = br.get_ip6_address(config.ADDRESS_TYPE.OMR)[0]
|
||||||
router1_omr_address = self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.OMR)[0]
|
router1_omr_address = router.get_ip6_address(config.ADDRESS_TYPE.OMR)[0]
|
||||||
host_ula_address = self.nodes[HOST].get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0]
|
host_ula_address = host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0]
|
||||||
|
|
||||||
# Router1 can ping to/from the Host on infra link.
|
# Router1 can ping to/from the Host on infra link.
|
||||||
self.assertTrue(self.nodes[ROUTER1].ping(self.nodes[HOST].get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0]))
|
self.assertTrue(router.ping(host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0]))
|
||||||
self.assertTrue(self.nodes[HOST].ping(self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.OMR)[0],
|
self.assertTrue(host.ping(router.get_ip6_address(config.ADDRESS_TYPE.OMR)[0], backbone=True))
|
||||||
backbone=True))
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Case 2. User adds smaller on-mesh prefix.
|
# Case 2. User adds smaller on-mesh prefix.
|
||||||
@@ -132,195 +130,205 @@ class SingleBorderRouter(thread_cert.TestCase):
|
|||||||
# is removed.
|
# is removed.
|
||||||
#
|
#
|
||||||
|
|
||||||
self.nodes[BR1].add_prefix(ON_MESH_PREFIX1)
|
br.add_prefix(ON_MESH_PREFIX1)
|
||||||
self.nodes[BR1].add_prefix(ON_MESH_PREFIX2)
|
br.add_prefix(ON_MESH_PREFIX2)
|
||||||
self.nodes[BR1].register_netdata()
|
br.register_netdata()
|
||||||
|
|
||||||
self.simulator.go(10)
|
self.simulator.go(10)
|
||||||
self.collect_ipaddrs()
|
self.collect_ipaddrs()
|
||||||
|
|
||||||
logging.info("BR1 addrs: %r", self.nodes[BR1].get_addrs())
|
logging.info("BR addrs: %r", br.get_addrs())
|
||||||
logging.info("ROUTER1 addrs: %r", self.nodes[ROUTER1].get_addrs())
|
logging.info("ROUTER addrs: %r", router.get_addrs())
|
||||||
logging.info("HOST addrs: %r", self.nodes[HOST].get_addrs())
|
logging.info("HOST addrs: %r", host.get_addrs())
|
||||||
|
|
||||||
self.assertGreaterEqual(len(self.nodes[HOST].get_addrs()), 2)
|
self.assertGreaterEqual(len(host.get_addrs()), 2)
|
||||||
|
|
||||||
self.assertTrue(len(self.nodes[BR1].get_prefixes()) == 2)
|
self.assertEqual(len(br.get_prefixes()), 2)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_prefixes()) == 2)
|
self.assertEqual(len(router.get_prefixes()), 2)
|
||||||
self.assertTrue(len(self.nodes[BR1].get_routes()) == 1)
|
self.assertEqual(len(br.get_routes()), 1)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_routes()) == 1)
|
self.assertEqual(len(router.get_routes()), 1)
|
||||||
|
|
||||||
self.assertTrue(len(self.nodes[BR1].get_ip6_address(config.ADDRESS_TYPE.OMR)) == 2)
|
self.assertEqual(len(br.get_ip6_address(config.ADDRESS_TYPE.OMR)), 2)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.OMR)) == 2)
|
self.assertEqual(len(router.get_ip6_address(config.ADDRESS_TYPE.OMR)), 2)
|
||||||
self.assertTrue(len(self.nodes[HOST].get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)) == 1)
|
self.assertEqual(len(host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)), 1)
|
||||||
|
|
||||||
# Router1 can ping to/from the Host on infra link.
|
# Router1 can ping to/from the Host on infra link.
|
||||||
self.assertTrue(self.nodes[ROUTER1].ping(self.nodes[HOST].get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0]))
|
self.assertTrue(router.ping(host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0]))
|
||||||
self.assertTrue(self.nodes[HOST].ping(self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.OMR)[0],
|
self.assertTrue(host.ping(router.get_ip6_address(config.ADDRESS_TYPE.OMR)[0], backbone=True))
|
||||||
backbone=True))
|
self.assertTrue(host.ping(router.get_ip6_address(config.ADDRESS_TYPE.OMR)[1], backbone=True))
|
||||||
self.assertTrue(self.nodes[HOST].ping(self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.OMR)[1],
|
|
||||||
backbone=True))
|
|
||||||
|
|
||||||
# Remove user prefixes, should re-register local OMR prefix.
|
# Remove user prefixes, should re-register local OMR prefix.
|
||||||
self.nodes[BR1].remove_prefix(ON_MESH_PREFIX1)
|
br.remove_prefix(ON_MESH_PREFIX1)
|
||||||
self.nodes[BR1].remove_prefix(ON_MESH_PREFIX2)
|
br.remove_prefix(ON_MESH_PREFIX2)
|
||||||
self.nodes[BR1].register_netdata()
|
br.register_netdata()
|
||||||
|
|
||||||
self.simulator.go(10)
|
self.simulator.go(10)
|
||||||
self.collect_ipaddrs()
|
self.collect_ipaddrs()
|
||||||
|
|
||||||
logging.info("BR1 addrs: %r", self.nodes[BR1].get_addrs())
|
logging.info("BR addrs: %r", br.get_addrs())
|
||||||
logging.info("ROUTER1 addrs: %r", self.nodes[ROUTER1].get_addrs())
|
logging.info("ROUTER addrs: %r", router.get_addrs())
|
||||||
logging.info("HOST addrs: %r", self.nodes[HOST].get_addrs())
|
logging.info("HOST addrs: %r", host.get_addrs())
|
||||||
|
|
||||||
self.assertTrue(len(self.nodes[BR1].get_prefixes()) == 1)
|
self.assertEqual(len(br.get_prefixes()), 1)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_prefixes()) == 1)
|
self.assertEqual(len(router.get_prefixes()), 1)
|
||||||
self.assertTrue(len(self.nodes[BR1].get_routes()) == 1)
|
self.assertEqual(len(br.get_routes()), 1)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_routes()) == 1)
|
self.assertEqual(len(router.get_routes()), 1)
|
||||||
|
|
||||||
# The same local OMR and on-link prefix should be re-register.
|
# The same local OMR and on-link prefix should be re-register.
|
||||||
self.assertEqual(omr_prefix, self.nodes[BR1].get_prefixes()[0])
|
self.assertEqual(br.get_prefixes(), [omr_prefix])
|
||||||
self.assertEqual(omr_prefix, self.nodes[ROUTER1].get_prefixes()[0])
|
self.assertEqual(router.get_prefixes(), [omr_prefix])
|
||||||
self.assertEqual(external_route, self.nodes[BR1].get_routes()[0])
|
self.assertEqual(br.get_routes(), [external_route])
|
||||||
self.assertEqual(external_route, self.nodes[ROUTER1].get_routes()[0])
|
self.assertEqual(router.get_routes(), [external_route])
|
||||||
|
|
||||||
self.assertTrue(len(self.nodes[BR1].get_ip6_address(config.ADDRESS_TYPE.OMR)) == 1)
|
self.assertEqual(len(br.get_ip6_address(config.ADDRESS_TYPE.OMR)), 1)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.OMR)) == 1)
|
self.assertEqual(len(router.get_ip6_address(config.ADDRESS_TYPE.OMR)), 1)
|
||||||
self.assertTrue(len(self.nodes[HOST].get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)) == 1)
|
self.assertEqual(len(host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)), 1)
|
||||||
|
|
||||||
self.assertEqual(br1_omr_address, self.nodes[BR1].get_ip6_address(config.ADDRESS_TYPE.OMR)[0])
|
self.assertEqual(br.get_ip6_address(config.ADDRESS_TYPE.OMR), [br1_omr_address])
|
||||||
self.assertEqual(router1_omr_address, self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.OMR)[0])
|
self.assertEqual(router.get_ip6_address(config.ADDRESS_TYPE.OMR), [router1_omr_address])
|
||||||
self.assertEqual(host_ula_address, self.nodes[HOST].get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0])
|
self.assertEqual(host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA), [host_ula_address])
|
||||||
|
|
||||||
# Router1 can ping to/from the Host on infra link.
|
# Router1 can ping to/from the Host on infra link.
|
||||||
self.assertTrue(self.nodes[ROUTER1].ping(self.nodes[HOST].get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0]))
|
self.assertTrue(router.ping(host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0]))
|
||||||
self.assertTrue(self.nodes[HOST].ping(self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.OMR)[0],
|
self.assertTrue(host.ping(router.get_ip6_address(config.ADDRESS_TYPE.OMR)[0], backbone=True))
|
||||||
backbone=True))
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Case 3. OMR and on-link prefixes should be removed when Border Routing is
|
# Case 3. OMR and on-link prefixes should be removed when Border Routing is
|
||||||
# explicitly disabled and added when Border Routing is enabled again.
|
# explicitly disabled and added when Border Routing is enabled again.
|
||||||
#
|
#
|
||||||
|
|
||||||
self.nodes[BR1].disable_br()
|
br.disable_br()
|
||||||
|
|
||||||
self.simulator.go(10)
|
self.simulator.go(10)
|
||||||
self.collect_ipaddrs()
|
self.collect_ipaddrs()
|
||||||
|
|
||||||
logging.info("BR1 addrs: %r", self.nodes[BR1].get_addrs())
|
logging.info("BR addrs: %r", br.get_addrs())
|
||||||
logging.info("ROUTER1 addrs: %r", self.nodes[ROUTER1].get_addrs())
|
logging.info("ROUTER addrs: %r", router.get_addrs())
|
||||||
logging.info("HOST addrs: %r", self.nodes[HOST].get_addrs())
|
logging.info("HOST addrs: %r", host.get_addrs())
|
||||||
|
|
||||||
self.assertTrue(len(self.nodes[BR1].get_prefixes()) == 0)
|
self.assertEqual(len(br.get_prefixes()), 0)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_prefixes()) == 0)
|
self.assertEqual(len(router.get_prefixes()), 0)
|
||||||
self.assertTrue(len(self.nodes[BR1].get_routes()) == 0)
|
self.assertEqual(len(br.get_routes()), 0)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_routes()) == 0)
|
self.assertEqual(len(router.get_routes()), 0)
|
||||||
self.assertTrue(len(self.nodes[BR1].get_ip6_address(config.ADDRESS_TYPE.OMR)) == 0)
|
self.assertEqual(len(br.get_ip6_address(config.ADDRESS_TYPE.OMR)), 0)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.OMR)) == 0)
|
self.assertEqual(len(router.get_ip6_address(config.ADDRESS_TYPE.OMR)), 0)
|
||||||
|
|
||||||
# Per RFC 4862, the host will not immediately remove the ULA address, but deprecate it.
|
# Per RFC 4862, the host will not immediately remove the ULA address, but deprecate it.
|
||||||
self.assertTrue(len(self.nodes[HOST].get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)) == 1)
|
self.assertEqual(len(host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)), 1)
|
||||||
|
|
||||||
self.nodes[BR1].enable_br()
|
br.enable_br()
|
||||||
|
|
||||||
# It takes around 10 seconds to start sending RA messages.
|
# It takes around 10 seconds to start sending RA messages.
|
||||||
self.simulator.go(15)
|
self.simulator.go(15)
|
||||||
self.collect_ipaddrs()
|
self.collect_ipaddrs()
|
||||||
|
|
||||||
logging.info("BR1 addrs: %r", self.nodes[BR1].get_addrs())
|
logging.info("BR addrs: %r", br.get_addrs())
|
||||||
logging.info("ROUTER1 addrs: %r", self.nodes[ROUTER1].get_addrs())
|
logging.info("ROUTER addrs: %r", router.get_addrs())
|
||||||
logging.info("HOST addrs: %r", self.nodes[HOST].get_addrs())
|
logging.info("HOST addrs: %r", host.get_addrs())
|
||||||
|
|
||||||
self.assertTrue(len(self.nodes[BR1].get_prefixes()) == 1)
|
self.assertEqual(len(br.get_prefixes()), 1)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_prefixes()) == 1)
|
self.assertEqual(len(router.get_prefixes()), 1)
|
||||||
self.assertTrue(len(self.nodes[BR1].get_routes()) == 1)
|
self.assertEqual(len(br.get_routes()), 1)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_routes()) == 1)
|
self.assertEqual(len(router.get_routes()), 1)
|
||||||
|
|
||||||
# The same local OMR and on-link prefix should be re-registered.
|
# The same local OMR and on-link prefix should be re-registered.
|
||||||
self.assertEqual(omr_prefix, self.nodes[BR1].get_prefixes()[0])
|
self.assertEqual(br.get_prefixes(), [omr_prefix])
|
||||||
self.assertEqual(omr_prefix, self.nodes[ROUTER1].get_prefixes()[0])
|
self.assertEqual(router.get_prefixes(), [omr_prefix])
|
||||||
self.assertEqual(external_route, self.nodes[BR1].get_routes()[0])
|
self.assertEqual(br.get_routes(), [external_route])
|
||||||
self.assertEqual(external_route, self.nodes[ROUTER1].get_routes()[0])
|
self.assertEqual(router.get_routes(), [external_route])
|
||||||
|
|
||||||
self.assertTrue(len(self.nodes[BR1].get_ip6_address(config.ADDRESS_TYPE.OMR)) == 1)
|
self.assertEqual(len(br.get_ip6_address(config.ADDRESS_TYPE.OMR)), 1)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.OMR)) == 1)
|
self.assertEqual(len(router.get_ip6_address(config.ADDRESS_TYPE.OMR)), 1)
|
||||||
self.assertTrue(len(self.nodes[HOST].get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)) == 1)
|
self.assertEqual(len(host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)), 1)
|
||||||
|
|
||||||
self.assertEqual(br1_omr_address, self.nodes[BR1].get_ip6_address(config.ADDRESS_TYPE.OMR)[0])
|
self.assertEqual(br.get_ip6_address(config.ADDRESS_TYPE.OMR), [br1_omr_address])
|
||||||
self.assertEqual(router1_omr_address, self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.OMR)[0])
|
self.assertEqual(router.get_ip6_address(config.ADDRESS_TYPE.OMR), [router1_omr_address])
|
||||||
self.assertEqual(host_ula_address, self.nodes[HOST].get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0])
|
self.assertEqual(host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA), [host_ula_address])
|
||||||
|
|
||||||
# Router1 can ping to/from the Host on infra link.
|
# Router1 can ping to/from the Host on infra link.
|
||||||
self.assertTrue(self.nodes[ROUTER1].ping(self.nodes[HOST].get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0]))
|
self.assertTrue(router.ping(host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0]))
|
||||||
self.assertTrue(self.nodes[HOST].ping(self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.OMR)[0],
|
self.assertTrue(host.ping(router.get_ip6_address(config.ADDRESS_TYPE.OMR)[0], backbone=True))
|
||||||
backbone=True))
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Case 4. The Routing Manager should be stopped if the infra interface went down.
|
# Case 4. The Routing Manager should be stopped if the infra interface went down.
|
||||||
#
|
#
|
||||||
|
|
||||||
self.nodes[BR1].disable_ether()
|
br.disable_ether()
|
||||||
|
|
||||||
self.simulator.go(10)
|
self.simulator.go(10)
|
||||||
self.collect_ipaddrs()
|
self.collect_ipaddrs()
|
||||||
|
|
||||||
logging.info("BR1 addrs: %r", self.nodes[BR1].get_addrs())
|
logging.info("BR addrs: %r", br.get_addrs())
|
||||||
logging.info("ROUTER1 addrs: %r", self.nodes[ROUTER1].get_addrs())
|
logging.info("ROUTER addrs: %r", router.get_addrs())
|
||||||
logging.info("HOST addrs: %r", self.nodes[HOST].get_addrs())
|
logging.info("HOST addrs: %r", host.get_addrs())
|
||||||
|
|
||||||
self.assertTrue(len(self.nodes[BR1].get_prefixes()) == 0)
|
self.assertEqual(len(br.get_prefixes()), 0)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_prefixes()) == 0)
|
self.assertEqual(len(router.get_prefixes()), 0)
|
||||||
self.assertTrue(len(self.nodes[BR1].get_routes()) == 0)
|
self.assertEqual(len(br.get_routes()), 0)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_routes()) == 0)
|
self.assertEqual(len(router.get_routes()), 0)
|
||||||
self.assertTrue(len(self.nodes[BR1].get_ip6_address(config.ADDRESS_TYPE.OMR)) == 0)
|
self.assertEqual(len(br.get_ip6_address(config.ADDRESS_TYPE.OMR)), 0)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.OMR)) == 0)
|
self.assertEqual(len(router.get_ip6_address(config.ADDRESS_TYPE.OMR)), 0)
|
||||||
|
|
||||||
self.nodes[BR1].enable_ether()
|
br.enable_ether()
|
||||||
|
|
||||||
# It takes around 10 seconds to start sending RA messages.
|
# It takes around 10 seconds to start sending RA messages.
|
||||||
self.simulator.go(15)
|
self.simulator.go(15)
|
||||||
self.collect_ipaddrs()
|
self.collect_ipaddrs()
|
||||||
|
|
||||||
logging.info("BR1 addrs: %r", self.nodes[BR1].get_addrs())
|
logging.info("BR addrs: %r", br.get_addrs())
|
||||||
logging.info("ROUTER1 addrs: %r", self.nodes[ROUTER1].get_addrs())
|
logging.info("ROUTER addrs: %r", router.get_addrs())
|
||||||
logging.info("HOST addrs: %r", self.nodes[HOST].get_addrs())
|
logging.info("HOST addrs: %r", host.get_addrs())
|
||||||
|
|
||||||
self.assertTrue(len(self.nodes[BR1].get_prefixes()) == 1)
|
self.assertEqual(len(br.get_prefixes()), 1)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_prefixes()) == 1)
|
self.assertEqual(len(router.get_prefixes()), 1)
|
||||||
self.assertTrue(len(self.nodes[BR1].get_routes()) == 1)
|
self.assertEqual(len(br.get_routes()), 1)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_routes()) == 1)
|
self.assertEqual(len(router.get_routes()), 1)
|
||||||
|
|
||||||
# The same local OMR and on-link prefix should be re-registered.
|
# The same local OMR and on-link prefix should be re-registered.
|
||||||
self.assertEqual(omr_prefix, self.nodes[BR1].get_prefixes()[0])
|
self.assertEqual(br.get_prefixes(), [omr_prefix])
|
||||||
self.assertEqual(omr_prefix, self.nodes[ROUTER1].get_prefixes()[0])
|
self.assertEqual(router.get_prefixes(), [omr_prefix])
|
||||||
self.assertEqual(external_route, self.nodes[BR1].get_routes()[0])
|
self.assertEqual(br.get_routes(), [external_route])
|
||||||
self.assertEqual(external_route, self.nodes[ROUTER1].get_routes()[0])
|
self.assertEqual(router.get_routes(), [external_route])
|
||||||
|
|
||||||
self.assertTrue(len(self.nodes[BR1].get_ip6_address(config.ADDRESS_TYPE.OMR)) == 1)
|
self.assertEqual(len(br.get_ip6_address(config.ADDRESS_TYPE.OMR)), 1)
|
||||||
self.assertTrue(len(self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.OMR)) == 1)
|
self.assertEqual(len(router.get_ip6_address(config.ADDRESS_TYPE.OMR)), 1)
|
||||||
self.assertTrue(len(self.nodes[HOST].get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)) == 1)
|
self.assertEqual(len(host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)), 1)
|
||||||
|
|
||||||
self.assertEqual(br1_omr_address, self.nodes[BR1].get_ip6_address(config.ADDRESS_TYPE.OMR)[0])
|
self.assertEqual(br.get_ip6_address(config.ADDRESS_TYPE.OMR), [br1_omr_address])
|
||||||
self.assertEqual(router1_omr_address, self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.OMR)[0])
|
self.assertEqual(router.get_ip6_address(config.ADDRESS_TYPE.OMR), [router1_omr_address])
|
||||||
self.assertEqual(host_ula_address, self.nodes[HOST].get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0])
|
self.assertEqual(host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA), [host_ula_address])
|
||||||
|
|
||||||
# Router1 can ping to/from the Host on infra link.
|
# Router1 can ping to/from the Host on infra link.
|
||||||
self.assertTrue(self.nodes[ROUTER1].ping(self.nodes[HOST].get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0]))
|
self.assertTrue(router.ping(host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0]))
|
||||||
self.assertTrue(self.nodes[HOST].ping(self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.OMR)[0],
|
self.assertTrue(host.ping(router.get_ip6_address(config.ADDRESS_TYPE.OMR)[0], backbone=True))
|
||||||
backbone=True))
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Case 5. Test if the linux host is still reachable if rejoin the network.
|
# Case 5. Test if the linux host is still reachable if rejoin the network.
|
||||||
#
|
#
|
||||||
|
|
||||||
self.nodes[HOST].disable_ether()
|
host.disable_ether()
|
||||||
self.simulator.go(10)
|
self.simulator.go(10)
|
||||||
self.nodes[HOST].enable_ether()
|
host.enable_ether()
|
||||||
self.simulator.go(10)
|
self.simulator.go(10)
|
||||||
|
|
||||||
self.assertTrue(self.nodes[ROUTER1].ping(self.nodes[HOST].get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0]))
|
self.assertTrue(router.ping(host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0]))
|
||||||
self.assertTrue(self.nodes[HOST].ping(self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.OMR)[0],
|
self.assertTrue(host.ping(router.get_ip6_address(config.ADDRESS_TYPE.OMR)[0], backbone=True))
|
||||||
backbone=True))
|
|
||||||
|
#
|
||||||
|
# Case 6. Test if the Border Router will remove the on-link prefix when
|
||||||
|
# another RA daemon is started on the same infra interface.
|
||||||
|
#
|
||||||
|
|
||||||
|
br.start_radvd_service(prefix=config.ONLINK_GUA_PREFIX, slaac=True)
|
||||||
|
self.simulator.go(5)
|
||||||
|
|
||||||
|
self.assertEqual(len(br.get_routes()), 1)
|
||||||
|
self.assertTrue(br.get_routes()[0].startswith(config.ONLINK_GUA_PREFIX.split('::/')[0]))
|
||||||
|
self.assertEqual(len(router.get_routes()), 1)
|
||||||
|
self.assertTrue(router.get_routes()[0].startswith(config.ONLINK_GUA_PREFIX.split('::/')[0]))
|
||||||
|
|
||||||
|
self.assertTrue(router.ping(host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_GUA)[0]))
|
||||||
|
self.assertTrue(host.ping(router.get_ip6_address(config.ADDRESS_TYPE.OMR)[0], backbone=True))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ ALL_NETWORK_BBRS_ADDRESS = 'ff32:40:fd00:db8:0:0:0:3'
|
|||||||
ALL_DOMAIN_BBRS_ADDRESS = 'ff32:40:fd00:7d03:7d03:7d03:0:3'
|
ALL_DOMAIN_BBRS_ADDRESS = 'ff32:40:fd00:7d03:7d03:7d03:0:3'
|
||||||
ALL_DOMAIN_BBRS_ADDRESS_ALTER = 'ff32:40:fd00:7d04:7d04:7d04:0:3'
|
ALL_DOMAIN_BBRS_ADDRESS_ALTER = 'ff32:40:fd00:7d04:7d04:7d04:0:3'
|
||||||
|
|
||||||
ONLINK_PREFIX = 'fd00:dead:face::/64'
|
ONLINK_GUA_PREFIX = '2021::/64'
|
||||||
|
|
||||||
# Any address starts with 'fd' are considered on-link address.
|
# Any address starts with 'fd' are considered on-link address.
|
||||||
ONLINK_PREFIX_REGEX_PATTERN = '^fd'
|
ONLINK_PREFIX_REGEX_PATTERN = '^fd'
|
||||||
@@ -113,6 +113,7 @@ class ADDRESS_TYPE(Enum):
|
|||||||
BACKBONE_GUA = 'BACKBONE_GUA'
|
BACKBONE_GUA = 'BACKBONE_GUA'
|
||||||
OMR = 'OMR'
|
OMR = 'OMR'
|
||||||
ONLINK_ULA = 'ONLINK_ULA'
|
ONLINK_ULA = 'ONLINK_ULA'
|
||||||
|
ONLINK_GUA = 'ONLINK_GUA'
|
||||||
|
|
||||||
|
|
||||||
RSSI = {
|
RSSI = {
|
||||||
|
|||||||
@@ -2670,7 +2670,7 @@ class LinuxHost():
|
|||||||
return resp_count
|
return resp_count
|
||||||
|
|
||||||
def _getBackboneGua(self) -> Optional[str]:
|
def _getBackboneGua(self) -> Optional[str]:
|
||||||
for addr in self.get_addrs():
|
for addr in self.get_ether_addrs():
|
||||||
if re.match(config.BACKBONE_PREFIX_REGEX_PATTERN, addr, re.I):
|
if re.match(config.BACKBONE_PREFIX_REGEX_PATTERN, addr, re.I):
|
||||||
return addr
|
return addr
|
||||||
|
|
||||||
@@ -2680,12 +2680,19 @@ class LinuxHost():
|
|||||||
""" Returns the ULA addresses autoconfigured on the infra link.
|
""" Returns the ULA addresses autoconfigured on the infra link.
|
||||||
"""
|
"""
|
||||||
addrs = []
|
addrs = []
|
||||||
for addr in self.get_addrs():
|
for addr in self.get_ether_addrs():
|
||||||
if re.match(config.ONLINK_PREFIX_REGEX_PATTERN, addr, re.I):
|
if re.match(config.ONLINK_PREFIX_REGEX_PATTERN, addr, re.I):
|
||||||
addrs.append(addr)
|
addrs.append(addr)
|
||||||
|
|
||||||
return addrs
|
return addrs
|
||||||
|
|
||||||
|
def _getInfraGua(self) -> Optional[str]:
|
||||||
|
""" Returns the GUA addresses autoconfigured on the infra link.
|
||||||
|
"""
|
||||||
|
|
||||||
|
gua_prefix = config.ONLINK_GUA_PREFIX.split('::/')[0]
|
||||||
|
return [addr for addr in self.get_ether_addrs() if addr.startswith(gua_prefix)]
|
||||||
|
|
||||||
def ping(self, *args, **kwargs):
|
def ping(self, *args, **kwargs):
|
||||||
backbone = kwargs.pop('backbone', False)
|
backbone = kwargs.pop('backbone', False)
|
||||||
if backbone:
|
if backbone:
|
||||||
@@ -2768,6 +2775,31 @@ class LinuxHost():
|
|||||||
service['addresses'] = addresses
|
service['addresses'] = addresses
|
||||||
return service if service['addresses'] else None
|
return service if service['addresses'] else None
|
||||||
|
|
||||||
|
def start_radvd_service(self, prefix, slaac):
|
||||||
|
self.bash("""cat >/etc/radvd.conf <<EOF
|
||||||
|
interface eth0
|
||||||
|
{
|
||||||
|
AdvSendAdvert on;
|
||||||
|
|
||||||
|
MinRtrAdvInterval 3;
|
||||||
|
MaxRtrAdvInterval 30;
|
||||||
|
AdvDefaultPreference low;
|
||||||
|
|
||||||
|
prefix %s
|
||||||
|
{
|
||||||
|
AdvOnLink on;
|
||||||
|
AdvAutonomous %s;
|
||||||
|
AdvRouterAddr off;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
EOF
|
||||||
|
""" % (prefix, 'on' if slaac else 'off'))
|
||||||
|
self.bash('service radvd start')
|
||||||
|
self.bash('service radvd status') # Make sure radvd service is running
|
||||||
|
|
||||||
|
def stop_radvd_service(self):
|
||||||
|
self.bash('service radvd stop')
|
||||||
|
|
||||||
|
|
||||||
class OtbrNode(LinuxHost, NodeImpl, OtbrDocker):
|
class OtbrNode(LinuxHost, NodeImpl, OtbrDocker):
|
||||||
is_otbr = True
|
is_otbr = True
|
||||||
@@ -2796,12 +2828,12 @@ class HostNode(LinuxHost, OtbrDocker):
|
|||||||
def start(self, start_radvd=True, prefix=config.DOMAIN_PREFIX, slaac=False):
|
def start(self, start_radvd=True, prefix=config.DOMAIN_PREFIX, slaac=False):
|
||||||
self._setup_sysctl()
|
self._setup_sysctl()
|
||||||
if start_radvd:
|
if start_radvd:
|
||||||
self._service_radvd_start(prefix, slaac)
|
self.start_radvd_service(prefix, slaac)
|
||||||
else:
|
else:
|
||||||
self._service_radvd_stop()
|
self.stop_radvd_service()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self._service_radvd_stop()
|
self.stop_radvd_service()
|
||||||
|
|
||||||
def get_addrs(self) -> List[str]:
|
def get_addrs(self) -> List[str]:
|
||||||
return self.get_ether_addrs()
|
return self.get_ether_addrs()
|
||||||
@@ -2829,39 +2861,15 @@ class HostNode(LinuxHost, OtbrDocker):
|
|||||||
Returns:
|
Returns:
|
||||||
IPv6 address string.
|
IPv6 address string.
|
||||||
"""
|
"""
|
||||||
assert address_type in [config.ADDRESS_TYPE.BACKBONE_GUA, config.ADDRESS_TYPE.ONLINK_ULA]
|
|
||||||
|
|
||||||
if address_type == config.ADDRESS_TYPE.BACKBONE_GUA:
|
if address_type == config.ADDRESS_TYPE.BACKBONE_GUA:
|
||||||
return self._getBackboneGua()
|
return self._getBackboneGua()
|
||||||
if address_type == config.ADDRESS_TYPE.ONLINK_ULA:
|
elif address_type == config.ADDRESS_TYPE.ONLINK_ULA:
|
||||||
return self._getInfraUla()
|
return self._getInfraUla()
|
||||||
|
elif address_type == config.ADDRESS_TYPE.ONLINK_GUA:
|
||||||
|
return self._getInfraGua()
|
||||||
else:
|
else:
|
||||||
return None
|
raise ValueError(f'unsupported address type: {address_type}')
|
||||||
|
|
||||||
def _service_radvd_start(self, prefix, slaac):
|
|
||||||
self.bash("""cat >/etc/radvd.conf <<EOF
|
|
||||||
interface eth0
|
|
||||||
{
|
|
||||||
AdvSendAdvert on;
|
|
||||||
|
|
||||||
MinRtrAdvInterval 3;
|
|
||||||
MaxRtrAdvInterval 30;
|
|
||||||
AdvDefaultPreference low;
|
|
||||||
|
|
||||||
prefix %s
|
|
||||||
{
|
|
||||||
AdvOnLink on;
|
|
||||||
AdvAutonomous %s;
|
|
||||||
AdvRouterAddr off;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
EOF
|
|
||||||
""" % (prefix, 'on' if slaac else 'off'))
|
|
||||||
self.bash('service radvd start')
|
|
||||||
self.bash('service radvd status') # Make sure radvd service is running
|
|
||||||
|
|
||||||
def _service_radvd_stop(self):
|
|
||||||
self.bash('service radvd stop')
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
Reference in New Issue
Block a user