Ipv6NetworkLayer¶
Package: inet.networklayer.ipv6
compound module Ipv6NetworkLayer
Represents a complete IPv6 network layer (L3), to be used within hosts and routers. It connects to higher-layer protocols (TCP, UDP, …) on top and to the network interfaces below, and bundles the modules that together implement IPv6:
~Ipv6: the core protocol (encapsulation, routing, forwarding, fragmentation);
~Ipv6RoutingTable: the routing table and destination cache;
~Icmpv6: ICMPv6 error messages and echo (ping);
- ~Ipv6NeighbourDiscovery: address autoconfiguration, DAD, neighbour
unreachability detection, and Router Advertisements/Solicitations;
- an IIpv6NodeConfigurator that applies the addresses and routes computed by
the network configurator.
Internal MessageDispatcher submodules route packets between these components and the interfaces by protocol.
Mobile IPv6
When hasMipv6 is set, the layer additionally contains the Mobile IPv6
(RFC 3775) modules: the Mipv6 protocol engine plus its BindingUpdateList and
BindingCache data structures. Mipv6 plugs into Ipv6 through netfilter hooks
and extension-header handlers; no change to the IPv6 core is required. The
node types MobileHost6, HomeAgent6 and CorrespondentNode6 enable it and
select the role via the isMobileNode / isHomeAgent parameters of Mipv6.
Proxy Mobile IPv6
When hasPmipv6 is set, the layer contains the Proxy Mobile IPv6 (RFC 5213)
engine Pmipv6 instead, which implements network-based mobility: the mobile
node runs no mobility software. The node types LocalMobilityAnchor and
MobileAccessGateway enable it and select the role.
:ref:`IPsec <neddoc-inet-networklayer-ipsec-ipsec>`
When hasIpsec is set, the layer additionally contains the IPsec engine and its
SecurityPolicyDatabase and SecurityAssociationDatabase. IPsec plugs into Ipv6
through netfilter hooks (the same dual-stack module the IPv4 layer uses); configure
it via the spdConfig XML parameter of the ipsec submodule.
Usage diagram¶
Inheritance diagram¶
Used in compound modules¶
Name |
Type |
Description |
|---|---|---|
compound module |
An extension of the link layer node base with network layer functionality. Provides support for multiple network protocols, including IPv4 and IPv6. |
Parameters¶
Name |
Type |
Default value |
Description |
|---|---|---|---|
hasMipv6 |
bool |
false |
|
hasPmipv6 |
bool |
false |
|
hasMld |
bool |
false |
|
hasIpsec |
bool |
false |
|
forwarding |
bool |
false |
|
multicastForwarding |
bool |
false |
|
interfaceTableModule |
string |
Properties¶
Name |
Value |
Description |
|---|---|---|
display |
i=block/fork |
Gates¶
Name |
Direction |
Size |
Description |
|---|---|---|---|
ifIn |
input |
||
ifOut |
output |
||
transportIn |
input |
||
transportOut |
output |
Unassigned submodule parameters¶
Name |
Type |
Default value |
Description |
|---|---|---|---|
configurator.displayStringTextFormat |
string |
“” |
Determines the text that is written on top of the submodule, supports displaying pars, watches, and module-specific information |
configurator.interfaceTableModule |
string |
||
configurator.routingTableModule |
string |
||
configurator.networkConfiguratorModule |
string |
“” |
The absolute path to the Ipv6NetworkConfigurator; use “” if there is no configurator |
configurator.configureRoutingTable |
bool |
true |
|
routingTable.displayStringTextFormat |
string |
“{numRoutes} routes\n{numDestCache} destcache entries” |
Determines the text that is written on top of the submodule, supports displaying pars, watches, and module-specific information |
routingTable.interfaceTableModule |
string |
The path to the InterfaceTable module |
|
routingTable.routes |
xml |
xml(“<routingTable/>”) |
|
routingTable.forwarding |
bool |
false |
|
routingTable.isRouter |
bool |
this.forwarding |
|
routingTable.multicastForwarding |
bool |
false |
|
routingTable.useAdminDist |
bool |
false |
Use Cisco-like administrative distances |
routingTable.advManagedFlag |
bool |
false |
“Managed address configuration” (M) flag in RAs |
routingTable.advOtherConfigFlag |
bool |
false |
“Other configuration” (O) flag in RAs |
routingTable.advLinkMtu |
int |
1280 |
MTU option in RAs (1280 = IPv6 minimum MTU, 0 = don’t include) |
routingTable.advCurHopLimit |
int |
30 |
Cur Hop Limit field in RAs (0 = unspecified) |
routingTable.advDefaultLifetime |
double |
-1s |
Router Lifetime in RAs (-1 = auto: 3*maxRtrAdvInterval) |
up.displayStringTextFormat |
string |
“processed {numProcessedPackets} pk ({processedTotalLength})” |
Determines the text that is written on top of the submodule, supports displaying pars, watches, and module-specific information |
up.interfaceTableModule |
string |
Module path to the InterfaceTable module |
|
up.forwardServiceRegistration |
bool |
true |
|
up.forwardProtocolRegistration |
bool |
true |
|
up.interfaceMapping |
object |
{} |
Maps network interface names to connected submodule names (e.g. {“eth0”: “bridging”}), overrides automatically learned dispatching; * overrides all learned network interfaces, ? overrides default |
up.serviceMapping |
object |
{} |
Maps protocols to connected submodule names (e.g. {“ethernetmac”: “bridging”}), overrides automatically learned dispatching; * overrides all learned services, ? overrides default |
up.protocolMapping |
object |
{} |
Maps protocols to connected submodule names (e.g. {“ipv4”: “bridging”}), overrides automatically learned dispatching; * overrides all learned protocols, ? overrides default |
icmpv6.displayStringTextFormat |
string |
“” |
Determines the text that is written on top of the submodule, supports displaying pars, watches, and module-specific information |
icmpv6.interfaceTableModule |
string |
The path to the InterfaceTable module |
|
icmpv6.checksumMode |
string |
“declared” |
|
icmpv6.mldModule |
string |
“” |
Path to the MLD module, or “” if MLD is not enabled; MLD messages are dropped when empty |
lp.displayStringTextFormat |
string |
“processed {numProcessedPackets} pk ({processedTotalLength})” |
Determines the text that is written on top of the submodule, supports displaying pars, watches, and module-specific information |
lp.interfaceTableModule |
string |
Module path to the InterfaceTable module |
|
lp.forwardServiceRegistration |
bool |
true |
|
lp.forwardProtocolRegistration |
bool |
true |
|
lp.interfaceMapping |
object |
{} |
Maps network interface names to connected submodule names (e.g. {“eth0”: “bridging”}), overrides automatically learned dispatching; * overrides all learned network interfaces, ? overrides default |
lp.serviceMapping |
object |
{} |
Maps protocols to connected submodule names (e.g. {“ethernetmac”: “bridging”}), overrides automatically learned dispatching; * overrides all learned services, ? overrides default |
lp.protocolMapping |
object |
{} |
Maps protocols to connected submodule names (e.g. {“ipv4”: “bridging”}), overrides automatically learned dispatching; * overrides all learned protocols, ? overrides default |
neighbourDiscovery.displayStringTextFormat |
string |
“” |
Determines the text that is written on top of the submodule, supports displaying pars, watches, and module-specific information |
neighbourDiscovery.interfaceTableModule |
string |
The path to the InterfaceTable module |
|
neighbourDiscovery.checksumMode |
string |
“declared” |
|
neighbourDiscovery.icmpv6Module |
string |
||
neighbourDiscovery.mipv6Module |
string |
||
neighbourDiscovery.routingTableModule |
string |
||
neighbourDiscovery.minIntervalBetweenRAs |
double |
200s |
RFC 4861: MinRtrAdvInterval (0.33 * MaxRtrAdvInterval) |
neighbourDiscovery.maxIntervalBetweenRAs |
double |
600s |
RFC 4861: MaxRtrAdvInterval |
neighbourDiscovery.advReachableTime |
double |
3600s |
advertised reachable time in RAs; hosts use it as base for NUD |
neighbourDiscovery.dupAddrDetectTransmits |
int |
1 |
RFC 4862 Section 5.1: number of NS sent for DAD (0 = disable DAD) |
neighbourDiscovery.optimisticDad |
bool |
false |
RFC 4429 Optimistic DAD: if true, an autoconfigured address may be used as a source address while DAD is still in progress; if false (RFC 4862), packets that would use it are deferred until DAD completes |
neighbourDiscovery.detectL2Movement |
bool |
true |
if true (default), (re)start Router Discovery (send Router Solicitations) whenever an interface associates at the link layer (e.g. a wireless handover to a new access point); lets a mobile node detect movement and obtain a new care-of address immediately, instead of relying on frequent unsolicited Router Advertisements (cf. MIPv6 fast RAs). Set to false to restore the legacy behaviour (movement detected only from periodic Router Advertisements) |
neighbourDiscovery.retransTimer |
double |
1s |
RFC 4861 Section 10: delay between retransmitted NS messages |
neighbourDiscovery.baseReachableTime |
double |
30s |
RFC 4861 Section 10: base value for computing random ReachableTime |
neighbourDiscovery.routerBootupTime |
double |
uniform(0s, 0.3s) |
random startup delay before a router assigns its link-local address; routers boot faster than hosts so that RAs are available by the time hosts solicit |
neighbourDiscovery.hostBootupTime |
double |
uniform(0.4s, 1s) |
random startup delay before a host assigns its link-local address |
ipv6.displayStringTextFormat |
string |
“{ipv6StatusText}” |
Determines the text that is written on top of the submodule, supports displaying pars, watches, and module-specific information |
ipv6.interfaceTableModule |
string |
The path to the InterfaceTable module |
|
ipv6.routingTableModule |
string |
||
ipv6.ipv6NeighbourDiscoveryModule |
string |
||
ipv6.icmpv6Module |
string |
||
ipv6.procDelay |
double |
0s |
|
ipv6.sendRedirects |
bool |
true |
RFC 4861 Section 8.2: when a router forwards a packet back out the interface it arrived on, send the source an ICMPv6 Redirect. Disable on wireless multi-hop / ad-hoc networks (e.g. MANET routing), where the geographic next hop is not directly reachable by the source, so redirects are useless and trigger a storm. |
ipsec.displayStringTextFormat |
string |
“IN: ACCEPT: {inAccept} DROP: {inDrop} BYPASS: {inBypass}\n OUT: PROTECT: {outProtect} DROP: {outDrop} BYPASS: {outBypass}” |
Determines the text that is written on top of the submodule, supports displaying pars, watches, and module-specific information |
ipsec.interfaceTableModule |
string |
||
ipsec.spdModule |
string |
“^.spd” |
|
ipsec.sadModule |
string |
“^.sad” |
|
ipsec.spdConfig |
xml |
||
ipsec.defaultProtection |
string |
“” |
If not “”: value to use where <Protection> element is absent from the configuration |
ipsec.defaultEspMode |
string |
“” |
If not “”: value to use where <EspMode> element is absent from the configuration |
ipsec.defaultEncryptionAlg |
string |
“” |
If not “”: value to use where <EncryptionAlg> element is absent from the configuration |
ipsec.defaultAuthenticationAlg |
string |
“” |
If not “”: value to use where <defaultAuthenticationAlg> element is absent from the configuration |
ipsec.defaultMaxTfcPadLength |
int |
0 |
Value to use where <MaxTfcPadLength> element is absent from the configuration |
ipsec.ahProtectOutDelay |
double |
0.0s |
|
ipsec.ahProtectInDelay |
double |
0.0s |
|
ipsec.espProtectOutDelay |
double |
0.0s |
|
ipsec.espProtectInDelay |
double |
0.0s |
|
spd.displayStringTextFormat |
string |
“entries: {numEntries}” |
Determines the text that is written on top of the submodule, supports displaying pars, watches, and module-specific information |
sad.displayStringTextFormat |
string |
“entries: {numEntries}” |
Determines the text that is written on top of the submodule, supports displaying pars, watches, and module-specific information |
mipv6.displayStringTextFormat |
string |
“” |
Determines the text that is written on top of the submodule, supports displaying pars, watches, and module-specific information |
mipv6.interfaceTableModule |
string |
The path to the InterfaceTable module |
|
mipv6.ipv6NeighbourDiscoveryModule |
string |
||
mipv6.bindingUpdateListModule |
string |
||
mipv6.bindingCacheModule |
string |
||
mipv6.isHomeAgent |
bool |
||
mipv6.isMobileNode |
bool |
||
mipv6.maxHaBindingLifeTime |
double |
3600s |
max binding lifetime for HA registration |
mipv6.maxRrBindingLifeTime |
double |
420s |
max binding lifetime for CN (route optimization) |
mipv6.useRouteOptimization |
bool |
true |
whether a mobile node route-optimizes with correspondent nodes (RFC 3775); if false, their traffic always uses the bidirectional home-agent tunnel |
buList.displayStringTextFormat |
string |
“” |
Determines the text that is written on top of the submodule, supports displaying pars, watches, and module-specific information |
bindingCache.displayStringTextFormat |
string |
“” |
Determines the text that is written on top of the submodule, supports displaying pars, watches, and module-specific information |
pmipv6.displayStringTextFormat |
string |
“” |
Determines the text that is written on top of the submodule, supports displaying pars, watches, and module-specific information |
pmipv6.interfaceTableModule |
string |
path to the InterfaceTable module |
|
pmipv6.ipv6NeighbourDiscoveryModule |
string |
path to the Ipv6NeighbourDiscovery module |
|
pmipv6.isLocalMobilityAnchor |
bool |
false |
(the IPv6 routing table is resolved automatically) |
pmipv6.isMobileAccessGateway |
bool |
false |
|
pmipv6.localMobilityAnchorAddress |
string |
“” |
MAG: the address of the LMA to register mobile nodes with |
pmipv6.mobileNodeProfiles |
xml |
xml(“<mobileNodes/>”) |
MAG: mobile-node policy profiles, one per access interface, e.g. <mobileNodes> <mobileNode accessInterface=”wlan0” id=”mn1@example.com” homeNetworkPrefix=”2001:db8:1::” prefixLength=”64”/> </mobileNodes> (accessInterface may be omitted to match any access interface) |
pmipv6.bindingLifetime |
double |
3600s |
lifetime requested in Proxy Binding Updates |
pmipv6.homeNetworkPrefixAdvValidLifetime |
double |
3600s |
MAG: valid lifetime of the advertised home network prefix |
pmipv6.homeNetworkPrefixAdvPreferredLifetime |
double |
1800s |
MAG: preferred lifetime of the advertised home network prefix |
mld.displayStringTextFormat |
string |
“” |
Determines the text that is written on top of the submodule, supports displaying pars, watches, and module-specific information |
mld.interfaceTableModule |
string |
path to the InterfaceTable module |
|
mld.routingTableModule |
string |
path to the Ipv6RoutingTable module |
|
mld.checksumMode |
string |
“declared” |
how the ICMPv6 checksum is handled |
mld.enabled |
bool |
true |
when false, MLD is inert on this node (see above) |
mld.unsolicitedReportInterval |
double |
10s |
host: delay before the repeated Report after a join |
mld.robustnessVariable |
int |
2 |
loss tolerance; only supplies the defaults of the three params marked (RV) below |
mld.queryInterval |
double |
125s |
querier: interval between periodic General Queries |
mld.queryResponseInterval |
double |
10s |
querier: max delay a host may wait before answering a General Query |
mld.multicastListenerInterval |
double |
(robustnessVariable * queryInterval) + queryResponseInterval |
querier: how long a group stays “has listeners” without a new Report (RV) |
mld.startupQueryInterval |
double |
queryInterval / 4 |
querier: interval between the initial General Queries at startup |
mld.startupQueryCount |
int |
robustnessVariable |
querier: number of General Queries sent at startup (RV) |
mld.lastListenerQueryInterval |
double |
1s |
querier: interval between the group-specific Queries sent after a Done |
mld.lastListenerQueryCount |
int |
robustnessVariable |
querier: number of group-specific Queries sent after a Done (RV) |
Source code¶
//
// Represents a complete IPv6 network layer (L3), to be used within hosts and
// routers. It connects to higher-layer protocols (TCP, UDP, ...) on top and to
// the network interfaces below, and bundles the modules that together implement
// IPv6:
//
// - ~Ipv6: the core protocol (encapsulation, routing, forwarding, fragmentation);
// - ~Ipv6RoutingTable: the routing table and destination cache;
// - ~Icmpv6: ICMPv6 error messages and echo (ping);
// - ~Ipv6NeighbourDiscovery: address autoconfiguration, DAD, neighbour
// unreachability detection, and Router Advertisements/Solicitations;
// - an ~IIpv6NodeConfigurator that applies the addresses and routes computed by
// the network configurator.
//
// Internal ~MessageDispatcher submodules route packets between these components
// and the interfaces by protocol.
//
// <b>Mobile IPv6</b>
//
// When `hasMipv6` is set, the layer additionally contains the Mobile IPv6
// (RFC 3775) modules: the ~Mipv6 protocol engine plus its ~BindingUpdateList and
// ~BindingCache data structures. ~Mipv6 plugs into ~Ipv6 through netfilter hooks
// and extension-header handlers; no change to the IPv6 core is required. The
// node types ~MobileHost6, ~HomeAgent6 and ~CorrespondentNode6 enable it and
// select the role via the `isMobileNode` / `isHomeAgent` parameters of ~Mipv6.
//
// <b>Proxy Mobile IPv6</b>
//
// When `hasPmipv6` is set, the layer contains the Proxy Mobile IPv6 (RFC 5213)
// engine ~Pmipv6 instead, which implements network-based mobility: the mobile
// node runs no mobility software. The node types ~LocalMobilityAnchor and
// ~MobileAccessGateway enable it and select the role.
//
// <b>IPsec</b>
//
// When `hasIpsec` is set, the layer additionally contains the ~IPsec engine and its
// ~SecurityPolicyDatabase and ~SecurityAssociationDatabase. ~IPsec plugs into ~Ipv6
// through netfilter hooks (the same dual-stack module the IPv4 layer uses); configure
// it via the `spdConfig` XML parameter of the `ipsec` submodule.
//
module Ipv6NetworkLayer like INetworkLayer
{
parameters:
bool hasMipv6 = default(false);
bool hasPmipv6 = default(false);
bool hasMld = default(false);
bool hasIpsec = default(false);
bool forwarding = default(false);
bool multicastForwarding = default(false);
*.mipv6Module = hasMipv6 ? absPath(".mipv6") : "";
*.mldModule = hasMld ? absPath(".mld") : "";
string interfaceTableModule;
*.forwarding = this.forwarding;
*.multicastForwarding = this.multicastForwarding;
*.interfaceTableModule = default(absPath(this.interfaceTableModule));
*.routingTableModule = default(absPath(".routingTable"));
*.ipv6NeighbourDiscoveryModule = default(absPath(".neighbourDiscovery"));
*.icmpv6Module = default(absPath(".icmpv6"));
*.bindingUpdateListModule = default(absPath(".buList"));
*.bindingCacheModule = default(absPath(".bindingCache"));
@display("i=block/fork");
gates:
input ifIn @labels(INetworkHeader);
output ifOut @labels(INetworkHeader);
input transportIn @labels(Ipv6ControlInfo/down);
output transportOut @labels(Ipv6ControlInfo/up);
submodules:
configurator: <default("Ipv6NodeConfigurator")> like IIpv6NodeConfigurator if typename != "" {
parameters:
@display("p=100,50;is=s");
}
routingTable: Ipv6RoutingTable {
parameters:
@display("p=100,100;is=s");
}
up: MessageDispatcher {
parameters:
@display("p=550,100;b=600,5");
}
icmpv6: Icmpv6 {
parameters:
@display("p=700,200");
}
lp: MessageDispatcher {
parameters:
@display("p=550,300;b=600,5");
}
neighbourDiscovery: Ipv6NeighbourDiscovery {
parameters:
@display("p=400,400");
}
// TODO rename to ip
ipv6: Ipv6 {
parameters:
@display("p=550,400");
}
ipsec: IPsec if hasIpsec {
parameters:
networkProtocolModule = "^.ipv6";
networkProtocol = "ipv6";
@display("p=300,500");
}
spd: SecurityPolicyDatabase if hasIpsec {
parameters:
@display("p=160,460;is=s");
}
sad: SecurityAssociationDatabase if hasIpsec {
parameters:
@display("p=160,540;is=s");
}
mipv6: Mipv6 if hasMipv6 {
parameters:
@display("p=700,500");
}
buList: BindingUpdateList if hasMipv6 {
parameters:
@display("p=850,450");
}
bindingCache: BindingCache if hasMipv6 {
parameters:
@display("p=850,550");
}
pmipv6: Pmipv6 if hasPmipv6 {
parameters:
@display("p=700,500");
}
mld: <default("Mldv1")> like IMld if hasMld {
parameters:
@display("p=800,200");
}
connections allowunconnected: // FIXME remove 'nocheck'!
transportIn --> { @display("m=n"); } --> up.in++;
transportOut <-- { @display("m=n"); } <-- up.out++;
up.out++ --> lp.in++;
up.in++ <-- lp.out++;
up.out++ --> icmpv6.transportIn;
up.in++ <-- icmpv6.transportOut;
icmpv6.ipv6Out --> lp.in++;
icmpv6.ipv6In <-- lp.out++;
lp.out++ --> ipv6.transportIn;
lp.in++ <-- ipv6.transportOut;
neighbourDiscovery.ipv6Out --> ipv6.ndIn;
neighbourDiscovery.ipv6In <-- ipv6.ndOut;
mipv6.fromIPv6 <-- lp.out++ if hasMipv6;
mipv6.toIPv6 --> lp.in++ if hasMipv6;
pmipv6.fromIPv6 <-- lp.out++ if hasPmipv6;
pmipv6.toIPv6 --> lp.in++ if hasPmipv6;
mld.ipIn <-- lp.out++ if hasMld;
mld.ipOut --> lp.in++ if hasMld;
ipv6.queueOut --> { @display("m=s"); } --> ifOut;
ipv6.queueIn <-- { @display("m=s"); } <-- ifIn;
}