Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions src/inet/networklayer/icmpv6/Ipv6NeighbourDiscovery.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2489,6 +2489,7 @@ void Ipv6NeighbourDiscovery::processRaPrefixInfoForAddrAutoConf(const Ipv6NdPref

// changed structure of code below, 12.9.07 - CB
bool isPrefixAssignedToInterface = false;
int assignedAddrIndex = -1;
bool returnedHome = false; // 4.9.07 - CB

for (int i = 0; i < ie->getProtocolData<Ipv6InterfaceData>()->getNumAddresses(); i++) {
Expand Down Expand Up @@ -2516,11 +2517,49 @@ void Ipv6NeighbourDiscovery::processRaPrefixInfoForAddrAutoConf(const Ipv6NdPref
returnedHome = true;
else {
isPrefixAssignedToInterface = true;
assignedAddrIndex = i;
EV_INFO << "The received Prefix is already assigned to the interface" << endl; // Zarrar Yousaf 19.07.07
break;
}
}
}

/*e) If the advertised prefix is equal to the prefix of an address
configured by stateless autoconfiguration in the list, the preferred
lifetime of the address is reset to the Preferred Lifetime in the
received advertisement. The specific action to perform for the valid
lifetime of the address depends on the Valid Lifetime in the received
advertisement and the remaining time to the valid lifetime expiration
of the previously autoconfigured address.*/
if (isPrefixAssignedToInterface) {
auto *ipv6Data = ie->getProtocolDataForUpdate<Ipv6InterfaceData>();
simtime_t expiryTime = ipv6Data->getAddressExpiryTime(assignedAddrIndex);
// An address with an infinite valid lifetime was not autoconfigured from a
// Prefix Information option, so step (e) does not speak about it.
if (expiryTime != SIMTIME_ZERO) {
// RFC 4862 Section 5.5.3 (e) writes the remaining valid lifetime of the
// address as RemainingLifetime, and caps how far an unauthenticated
// advertisement may shorten it. Without that cap a single forged
// advertisement carrying short valid lifetimes could expire every
// address of a node; a legitimate advertisement, which the router
// repeats, always passes the first case and takes effect immediately.
const simtime_t twoHours = 7200;
simtime_t remainingLifetime = expiryTime - simTime();
simtime_t newValidLifetime;

if (validLifetime > twoHours || validLifetime > remainingLifetime)
newValidLifetime = validLifetime; // (e)(1)
else if (remainingLifetime <= twoHours)
newValidLifetime = remainingLifetime; // (e)(2), the advertisement is not authenticated
else
newValidLifetime = twoHours; // (e)(3)

EV_INFO << "Prefix already assigned to the interface, refreshing lifetimes: valid "
<< newValidLifetime << ", preferred " << preferredLifetime << endl;
ipv6Data->updateMatchingAddressExpiryTimes(prefix, prefixLength,
simTime() + newValidLifetime, simTime() + preferredLifetime);
}
}
/*d) If the prefix advertised does not match the prefix of an address already
in the list, and the Valid Lifetime is not 0, form an address (and add
it to the list) by combining the advertised prefix with the link's
Expand Down
6 changes: 6 additions & 0 deletions src/inet/networklayer/ipv6/Ipv6InterfaceData.cc
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,12 @@ Ipv6InterfaceData::AddressType Ipv6InterfaceData::getAddressType(int i) const
return addresses[i].addrType;
}

simtime_t Ipv6InterfaceData::getAddressExpiryTime(int i) const
{
ASSERT(i >= 0 && i < (int)addresses.size());
return addresses[i].expiryTime;
}

Ipv6InterfaceData::AddressType Ipv6InterfaceData::getAddressType(const Ipv6Address& addr) const
{
return getAddressType(findAddress(addr));
Expand Down
6 changes: 6 additions & 0 deletions src/inet/networklayer/ipv6/Ipv6InterfaceData.h
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,12 @@ class INET_API Ipv6InterfaceData : public InterfaceProtocolData
*/
AddressType getAddressType(int i) const;

/**
* Returns the time at which the valid lifetime of the ith address of the
* interface expires, or zero if that lifetime is infinite.
*/
simtime_t getAddressExpiryTime(int i) const;

/**
* Returns the address type (HoA, CoA) of the provided address of the interface.
*/
Expand Down
78 changes: 78 additions & 0 deletions tests/module/Ipv6_prefix_lifetime_refresh.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
%description:
Tests that a repeated Prefix Information option refreshes the lifetimes of the
address the host already holds from that prefix (RFC 4862 Section 5.5.3 step e).

The router advertises a prefix whose valid lifetime (20 s) and preferred
lifetime (10 s) are much shorter than the 60 s run, and re-advertises it every
4 s to 6 s. The host forms one address from the prefix and must then keep it
alive from the repeated advertisements, instead of forming a second address or
letting the first one lapse at the lifetime the first advertisement carried.

%#--------------------------------------------------------------------------------------------------------------
%file: test.ned
import inet.networklayer.configurator.ipv6.Ipv6NetworkConfigurator;
import inet.node.ipv6.Router6;
import inet.node.ipv6.StandardHost6;
import ned.DatarateChannel;

network PrefixLifetimeRefreshNetwork
{
types:
channel ethline extends DatarateChannel
{
delay = 0.1us;
datarate = 100Mbps;
}
submodules:
configurator: Ipv6NetworkConfigurator;
router: Router6;
host: StandardHost6;
connections:
host.ethg++ <--> ethline <--> router.ethg++;
}
%#--------------------------------------------------------------------------------------------------------------
%file: config.xml
<config>
<interface among="host router" prefix="aaaa:1::/64" advValidLifetime="20" advPreferredLifetime="10"/>
</config>
%#--------------------------------------------------------------------------------------------------------------
%inifile: omnetpp.ini
[General]
record-vector-results = false
ned-path = ../../../../src
network = PrefixLifetimeRefreshNetwork
sim-time-limit = 60s
cmdenv-express-mode = false
cmdenv-log-prefix = "%C: "

**.ipv6.configurator.networkConfiguratorModule = "configurator"
*.configurator.assignAddressesToHosts = false
*.configurator.config = xmldoc("config.xml")

# Advertise far more often than the advertised lifetimes, so that the address
# would lapse many times over if the advertisements did not refresh it.
**.neighbourDiscovery.minIntervalBetweenRAs = 4s
**.neighbourDiscovery.maxIntervalBetweenRAs = 6s

# Ethernet NIC configuration
**.eth[*].queue.typename = "EthernetQosQueue"
**.eth[*].queue.dataQueue.typename = "DropTailQueue"
**.eth[*].queue.dataQueue.packetCapacity = 10

%#--------------------------------------------------------------------------------------------------------------
%subst: /omnetpp:://
%#--------------------------------------------------------------------------------------------------------------
%contains: stdout
PrefixLifetimeRefreshNetwork.host.ipv6.neighbourDiscovery: DAD completed for address aaaa:1::
%#--------------------------------------------------------------------------------------------------------------
%contains: stdout
PrefixLifetimeRefreshNetwork.host.ipv6.neighbourDiscovery: Prefix already assigned to the interface, refreshing lifetimes: valid 20, preferred 10
%#--------------------------------------------------------------------------------------------------------------
%postrun-command: grep -c "Assigning new address to: eth0" test.out > test_newaddr.out || true
%contains: test_newaddr.out
1
%#--------------------------------------------------------------------------------------------------------------
%postrun-command: grep "undisposed object:" test.out > test_undisposed.out || true
%not-contains: test_undisposed.out
undisposed object: (
%#--------------------------------------------------------------------------------------------------------------