Skip to content

Commit 5ff6f6c

Browse files
committed
examples/bgpv4: add BgpAndOspfv3 (BGP over an OSPFv3 IGP, IPv6)
BGP/OSPFv3 interoperation over IPv6: two autonomous systems, each running OSPFv3 as its IGP, with eBGP between the ASes and an iBGP full mesh inside each, and no route redistribution. OSPFv3 distributes the intra-AS prefixes and resolves the (i)BGP next hops; BGP carries the inter-AS prefixes (MP-BGP, RFC 4760). hostA pinging hostB succeeds only once both protocols have converged. This is the IPv6 counterpart of the IPv4 BgpAndOspf example. Includes a tplx fingerprint test (OSPFv3 packets have no serializer, so the ~tNl/~tND ingredients cannot be used here).
1 parent 731ffd2 commit 5ff6f6c

7 files changed

Lines changed: 288 additions & 0 deletions

File tree

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//
2+
// Copyright (C) 2026 OpenSim Ltd.
3+
//
4+
// SPDX-License-Identifier: LGPL-3.0-or-later
5+
//
6+
7+
package inet.examples.bgpv4.BgpAndOspfv3;
8+
9+
import inet.networklayer.configurator.ipv6.Ipv6NetworkConfigurator;
10+
import inet.node.ethernet.Eth100M;
11+
import inet.node.ospfv3.Ospfv3Router;
12+
import inet.node.ipv6.StandardHost6;
13+
14+
//
15+
// BGP / OSPFv3 interoperation over IPv6.
16+
//
17+
// Two autonomous systems, each running OSPFv3 as its interior gateway protocol
18+
// (IGP). The three routers of each AS form an iBGP full mesh; the two border
19+
// routers (rA3, rB1) peer over eBGP. There is NO mutual route redistribution:
20+
// OSPFv3 carries the intra-AS prefixes and resolves the (i)BGP next hops, while
21+
// BGP carries the inter-AS prefixes -- the classic BGP-over-an-IGP arrangement.
22+
//
23+
// hostA -- rA1 -- rA2 -- rA3 ==eBGP== rB1 -- rB2 -- rB3 -- hostB
24+
// \_______ AS 65001 _______/ \____ AS 65002 ____/
25+
// (OSPFv3 + iBGP mesh) (OSPFv3 + iBGP mesh)
26+
//
27+
// OSPFv3 is load-bearing: rA1 and rA3 are not adjacent, so their iBGP session
28+
// and the next-hop resolution for the routes they exchange rely on the OSPFv3
29+
// route through rA2 (and symmetrically in AS 65002).
30+
//
31+
network BgpAndOspfv3
32+
{
33+
submodules:
34+
configurator: Ipv6NetworkConfigurator {
35+
parameters:
36+
@display("p=100,100;is=s");
37+
config = xmldoc("Ipv6Config.xml");
38+
// on-link (direct) + host default routes only; intra-AS routes come
39+
// from OSPFv3 and inter-AS routes from BGP
40+
addRemoteRoutes = false;
41+
}
42+
rA1: Ospfv3Router { @display("p=250,200"); }
43+
rA2: Ospfv3Router { @display("p=370,200"); }
44+
rA3: Ospfv3Router { @display("p=490,200"); }
45+
rB1: Ospfv3Router { @display("p=650,200"); }
46+
rB2: Ospfv3Router { @display("p=770,200"); }
47+
rB3: Ospfv3Router { @display("p=890,200"); }
48+
hostA: StandardHost6 { @display("p=250,320;i=device/pc"); }
49+
hostB: StandardHost6 { @display("p=890,320;i=device/pc"); }
50+
connections:
51+
hostA.ethg++ <--> Eth100M <--> rA1.ethg++;
52+
rA1.ethg++ <--> Eth100M <--> rA2.ethg++;
53+
rA2.ethg++ <--> Eth100M <--> rA3.ethg++;
54+
rA3.ethg++ <--> Eth100M <--> rB1.ethg++; // inter-AS (eBGP) link
55+
rB1.ethg++ <--> Eth100M <--> rB2.ethg++;
56+
rB2.ethg++ <--> Eth100M <--> rB3.ethg++;
57+
rB3.ethg++ <--> Eth100M <--> hostB.ethg++;
58+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0" encoding="ISO-8859-1"?>
2+
<BGPConfig>
3+
4+
<TimerParams>
5+
<connectRetryTime> 120 </connectRetryTime>
6+
<holdTime> 180 </holdTime>
7+
<keepAliveTime> 60 </keepAliveTime>
8+
<startDelay> 1 </startDelay>
9+
</TimerParams>
10+
11+
<!-- AS 65001: rA1, rA2, rA3 form an iBGP full mesh (created automatically from
12+
the Router list). rA1 originates hostA's subnet. rA3 is the eBGP border. -->
13+
<AS id="65001">
14+
<Router interAddr="2001:db8:1:12::1"> <!-- rA1 -->
15+
<Network address="2001:db8:1:1::"/> <!-- the subnet behind rA1 (hostA) -->
16+
</Router>
17+
<Router interAddr="2001:db8:1:12::2"/> <!-- rA2 -->
18+
<Router interAddr="2001:db8:1:23::3"/> <!-- rA3 (border) -->
19+
</AS>
20+
21+
<!-- AS 65002: rB1, rB2, rB3 iBGP full mesh. rB3 originates hostB's subnet.
22+
rB1 is the eBGP border. -->
23+
<AS id="65002">
24+
<Router interAddr="2001:db8:2:12::1"/> <!-- rB1 (border) -->
25+
<Router interAddr="2001:db8:2:12::2"/> <!-- rB2 -->
26+
<Router interAddr="2001:db8:2:23::3"> <!-- rB3 -->
27+
<Network address="2001:db8:2:3::"/> <!-- the subnet behind rB3 (hostB) -->
28+
</Router>
29+
</AS>
30+
31+
<!-- eBGP session over the inter-AS link rA3 <-> rB1 -->
32+
<Session id="1">
33+
<Router exterAddr="2001:db8:0:ab::a"/> <!-- rA3 -->
34+
<Router exterAddr="2001:db8:0:ab::b"/> <!-- rB1 -->
35+
</Session>
36+
37+
</BGPConfig>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<config>
2+
<!-- Explicit IPv6 addresses so they match the OSPFv3 and BGP configurations.
3+
The configurator runs with addRemoteRoutes=false: it adds the on-link
4+
(direct) routes and the host default routes, but no multi-hop routes -
5+
those come from OSPFv3 (intra-AS) and BGP (inter-AS). -->
6+
7+
<!-- AS 65001 -->
8+
<interface hosts="hostA" address="2001:db8:1:1::100"/>
9+
<interface hosts="rA1" towards="hostA" address="2001:db8:1:1::1"/>
10+
11+
<interface hosts="rA1" towards="rA2" address="2001:db8:1:12::1"/>
12+
<interface hosts="rA2" towards="rA1" address="2001:db8:1:12::2"/>
13+
14+
<interface hosts="rA2" towards="rA3" address="2001:db8:1:23::2"/>
15+
<interface hosts="rA3" towards="rA2" address="2001:db8:1:23::3"/>
16+
17+
<!-- inter-AS (eBGP) link -->
18+
<interface hosts="rA3" towards="rB1" address="2001:db8:0:ab::a"/>
19+
<interface hosts="rB1" towards="rA3" address="2001:db8:0:ab::b"/>
20+
21+
<!-- AS 65002 -->
22+
<interface hosts="rB1" towards="rB2" address="2001:db8:2:12::1"/>
23+
<interface hosts="rB2" towards="rB1" address="2001:db8:2:12::2"/>
24+
25+
<interface hosts="rB2" towards="rB3" address="2001:db8:2:23::2"/>
26+
<interface hosts="rB3" towards="rB2" address="2001:db8:2:23::3"/>
27+
28+
<interface hosts="rB3" towards="hostB" address="2001:db8:2:3::3"/>
29+
<interface hosts="hostB" address="2001:db8:2:3::100"/>
30+
</config>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<Devices>
2+
<!-- OSPFv3 runs as the IGP inside each AS, on the intra-AS interfaces only.
3+
The inter-AS link rA3<->rB1 (eth1 on rA3, eth0 on rB1) is left out of
4+
OSPFv3; it carries the eBGP session instead. Interface IPv6 addresses are
5+
assigned by the Ipv6NetworkConfigurator, not here. Single area 0.0.0.0. -->
6+
7+
<!-- ===================== AS 65001 ===================== -->
8+
<Router id="rA1">
9+
<Routing6><OSPFv3><Process id="100" af="IPv6"><RouterID>1.1.1.1</RouterID></Process></OSPFv3></Routing6>
10+
<Interfaces>
11+
<Interface name="eth0"><Process id="100"><Instance AF="IPv6"><InterfaceType>Broadcast</InterfaceType><Area>0.0.0.0</Area></Instance></Process></Interface>
12+
<Interface name="eth1"><Process id="100"><Instance AF="IPv6"><InterfaceType>Broadcast</InterfaceType><Area>0.0.0.0</Area></Instance></Process></Interface>
13+
</Interfaces>
14+
</Router>
15+
<Router id="rA2">
16+
<Routing6><OSPFv3><Process id="100" af="IPv6"><RouterID>1.1.1.2</RouterID></Process></OSPFv3></Routing6>
17+
<Interfaces>
18+
<Interface name="eth0"><Process id="100"><Instance AF="IPv6"><InterfaceType>Broadcast</InterfaceType><Area>0.0.0.0</Area></Instance></Process></Interface>
19+
<Interface name="eth1"><Process id="100"><Instance AF="IPv6"><InterfaceType>Broadcast</InterfaceType><Area>0.0.0.0</Area></Instance></Process></Interface>
20+
</Interfaces>
21+
</Router>
22+
<Router id="rA3">
23+
<Routing6><OSPFv3><Process id="100" af="IPv6"><RouterID>1.1.1.3</RouterID></Process></OSPFv3></Routing6>
24+
<Interfaces>
25+
<Interface name="eth0"><Process id="100"><Instance AF="IPv6"><InterfaceType>Broadcast</InterfaceType><Area>0.0.0.0</Area></Instance></Process></Interface>
26+
</Interfaces>
27+
</Router>
28+
29+
<!-- ===================== AS 65002 ===================== -->
30+
<Router id="rB1">
31+
<Routing6><OSPFv3><Process id="100" af="IPv6"><RouterID>2.2.2.1</RouterID></Process></OSPFv3></Routing6>
32+
<Interfaces>
33+
<Interface name="eth1"><Process id="100"><Instance AF="IPv6"><InterfaceType>Broadcast</InterfaceType><Area>0.0.0.0</Area></Instance></Process></Interface>
34+
</Interfaces>
35+
</Router>
36+
<Router id="rB2">
37+
<Routing6><OSPFv3><Process id="100" af="IPv6"><RouterID>2.2.2.2</RouterID></Process></OSPFv3></Routing6>
38+
<Interfaces>
39+
<Interface name="eth0"><Process id="100"><Instance AF="IPv6"><InterfaceType>Broadcast</InterfaceType><Area>0.0.0.0</Area></Instance></Process></Interface>
40+
<Interface name="eth1"><Process id="100"><Instance AF="IPv6"><InterfaceType>Broadcast</InterfaceType><Area>0.0.0.0</Area></Instance></Process></Interface>
41+
</Interfaces>
42+
</Router>
43+
<Router id="rB3">
44+
<Routing6><OSPFv3><Process id="100" af="IPv6"><RouterID>2.2.2.3</RouterID></Process></OSPFv3></Routing6>
45+
<Interfaces>
46+
<Interface name="eth0"><Process id="100"><Instance AF="IPv6"><InterfaceType>Broadcast</InterfaceType><Area>0.0.0.0</Area></Instance></Process></Interface>
47+
<Interface name="eth1"><Process id="100"><Instance AF="IPv6"><InterfaceType>Broadcast</InterfaceType><Area>0.0.0.0</Area></Instance></Process></Interface>
48+
</Interfaces>
49+
</Router>
50+
</Devices>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# BgpAndOspfv3 — BGP over an OSPFv3 IGP (IPv6)
2+
3+
BGP and OSPFv3 interoperating over IPv6: two autonomous systems, each running **OSPFv3** as
4+
its interior gateway protocol (IGP), with **eBGP** between the ASes and a full **iBGP** mesh
5+
inside each. This is the IPv6 counterpart of the IPv4 `BgpAndOspf` example, in the
6+
"BGP over an IGP" arrangement (the way transit ASes are actually built), **without any route
7+
redistribution** between the two protocols.
8+
9+
```
10+
hostA --- rA1 --- rA2 --- rA3 ==eBGP== rB1 --- rB2 --- rB3 --- hostB
11+
\________ AS 65001 ________/ \____ AS 65002 ____/
12+
OSPFv3 + iBGP mesh OSPFv3 + iBGP mesh
13+
```
14+
15+
- AS 65001 = {rA1, rA2, rA3}, AS 65002 = {rB1, rB2, rB3}; rA3 and rB1 are the border routers.
16+
- `hostA` (`2001:db8:1:1::/64`) sits behind rA1; `hostB` (`2001:db8:2:3::/64`) behind rB3.
17+
18+
## What it demonstrates
19+
20+
- **OSPFv3 is the IGP**: it distributes the intra-AS prefixes and, crucially, resolves the
21+
(i)BGP next hops. rA1 and rA3 are *not* adjacent, so their iBGP session and the next-hop
22+
resolution for the routes they exchange go through rA2 via OSPFv3 (symmetrically in AS 65002).
23+
- **BGP carries the inter-AS prefixes** over IPv6 (MP-BGP, RFC 4760): rA1 originates hostA's
24+
subnet, rB3 originates hostB's; the border routers re-advertise across the eBGP link with
25+
`nextHopSelf` so the far AS resolves the next hop through its own OSPFv3.
26+
- **No redistribution**: OSPFv3 and BGP run side by side and both install IPv6 routes into the
27+
same table; reachability composes. (`bgp.ospfRoutingModule = ""` because `ospf` here is
28+
`Ospfv3`, not the IPv4 `Ospfv2` that BGP's redistribution hooks expect.)
29+
- **End-to-end check**: `hostA` pinging `hostB` succeeds only once OSPFv3 has converged
30+
(intra-AS reachability + next-hop resolution) **and** BGP has exchanged the inter-AS
31+
prefixes — there are no static inter-AS routes.
32+
33+
## Configs
34+
35+
- `General` — the full interop scenario above.
36+
- `OspfOnly` — BGP disabled; `hostA` pings rA3's far interface, reachable only via the OSPFv3
37+
route through rA2. A quick check that OSPFv3 alone provides multi-hop intra-AS IPv6 routing.
38+
39+
## Notes / addressing
40+
41+
- Addresses are assigned by the `Ipv6NetworkConfigurator` (`Ipv6Config.xml`); OSPFv3 runs on
42+
those addresses (no `<IPv6Address>` in `Ospfv3Config.xml`). The configurator runs with
43+
`addRemoteRoutes = false`, so it provides only the on-link and host-default routes — intra-AS
44+
routes come from OSPFv3, inter-AS routes from BGP.
45+
- OSPFv3 is configured on the intra-AS interfaces only; the inter-AS link rA3↔rB1 carries the
46+
eBGP session and is left out of OSPFv3.
47+
- Because OSPFv3 converges relatively slowly (default hello/dead intervals), the iBGP sessions
48+
to non-adjacent peers are *deferred* until OSPFv3 installs a route to the peer; the ping
49+
therefore starts at t=70s, after convergence.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
[General]
2+
network = BgpAndOspfv3
3+
sim-time-limit = 100s
4+
5+
**.ipv6.configurator.networkConfiguratorModule = "configurator"
6+
7+
# IPv6-only routers (no IPv4 stack/configurator)
8+
*.r*.hasIpv4 = false
9+
10+
# ---- OSPFv3 (IGP) configuration, per router; intra-AS interfaces only ----
11+
**.rA1.ospf.ospfv3Splitter.ospfv3RoutingConfig = xmldoc("Ospfv3Config.xml", "Devices/Router[@id='rA1']/Routing6/OSPFv3")
12+
**.rA1.ospf.ospfv3Splitter.ospfv3IntConfig = xmldoc("Ospfv3Config.xml", "Devices/Router[@id='rA1']/Interfaces")
13+
**.rA2.ospf.ospfv3Splitter.ospfv3RoutingConfig = xmldoc("Ospfv3Config.xml", "Devices/Router[@id='rA2']/Routing6/OSPFv3")
14+
**.rA2.ospf.ospfv3Splitter.ospfv3IntConfig = xmldoc("Ospfv3Config.xml", "Devices/Router[@id='rA2']/Interfaces")
15+
**.rA3.ospf.ospfv3Splitter.ospfv3RoutingConfig = xmldoc("Ospfv3Config.xml", "Devices/Router[@id='rA3']/Routing6/OSPFv3")
16+
**.rA3.ospf.ospfv3Splitter.ospfv3IntConfig = xmldoc("Ospfv3Config.xml", "Devices/Router[@id='rA3']/Interfaces")
17+
**.rB1.ospf.ospfv3Splitter.ospfv3RoutingConfig = xmldoc("Ospfv3Config.xml", "Devices/Router[@id='rB1']/Routing6/OSPFv3")
18+
**.rB1.ospf.ospfv3Splitter.ospfv3IntConfig = xmldoc("Ospfv3Config.xml", "Devices/Router[@id='rB1']/Interfaces")
19+
**.rB2.ospf.ospfv3Splitter.ospfv3RoutingConfig = xmldoc("Ospfv3Config.xml", "Devices/Router[@id='rB2']/Routing6/OSPFv3")
20+
**.rB2.ospf.ospfv3Splitter.ospfv3IntConfig = xmldoc("Ospfv3Config.xml", "Devices/Router[@id='rB2']/Interfaces")
21+
**.rB3.ospf.ospfv3Splitter.ospfv3RoutingConfig = xmldoc("Ospfv3Config.xml", "Devices/Router[@id='rB3']/Routing6/OSPFv3")
22+
**.rB3.ospf.ospfv3Splitter.ospfv3IntConfig = xmldoc("Ospfv3Config.xml", "Devices/Router[@id='rB3']/Interfaces")
23+
24+
# ---- BGP over IPv6 (MP-BGP) ----
25+
*.r*.hasBgp = true
26+
*.r*.bgp.addressFamily = "ipv6"
27+
*.r*.bgp.routingTableModule = "^.ipv6.routingTable"
28+
*.r*.bgp.bgpConfig = xmldoc("BgpConfig6.xml")
29+
# ospf here is OSPFv3 (not ospfv2::Ospfv2), and there is no redistribution, so
30+
# BGP must not try to bind to it
31+
*.r*.bgp.ospfRoutingModule = ""
32+
*.rA1.bgp.routerId = "1.1.1.1"
33+
*.rA2.bgp.routerId = "1.1.1.2"
34+
*.rA3.bgp.routerId = "1.1.1.3"
35+
*.rB1.bgp.routerId = "2.2.2.1"
36+
*.rB2.bgp.routerId = "2.2.2.2"
37+
*.rB3.bgp.routerId = "2.2.2.3"
38+
# border routers advertise themselves as next hop into their AS, so the internal
39+
# routers resolve the BGP next hop via OSPFv3
40+
*.rA3.bgp.nextHopSelf = true
41+
*.rB1.bgp.nextHopSelf = true
42+
43+
# end-to-end check: hostA pings hostB. This only succeeds once OSPFv3 has
44+
# converged (intra-AS reachability + next-hop resolution) AND BGP has exchanged
45+
# the inter-AS prefixes.
46+
*.hostA.numApps = 1
47+
*.hostA.app[0].typename = "PingApp"
48+
*.hostA.app[0].destAddr = "2001:db8:2:3::100" # hostB (inter-AS, via BGP)
49+
# OSPFv3 converges and the (deferred) iBGP sessions come up around t=51s, then BGP
50+
# exchanges the inter-AS prefixes; start pinging after that
51+
*.hostA.app[0].startTime = 70s
52+
*.hostA.app[0].sendInterval = 1s
53+
54+
# -----------------------------------------------------------------------------
55+
# OSPFv3 only (no BGP): verifies that OSPFv3 provides multi-hop intra-AS IPv6
56+
# reachability. hostA pings rA3's far (rA2-facing) address, which rA1 can only
57+
# reach via the OSPFv3 route through rA2.
58+
# -----------------------------------------------------------------------------
59+
[Config OspfOnly]
60+
description = "OSPFv3 IGP only, no BGP - intra-AS IPv6 routing"
61+
*.r*.hasBgp = false
62+
*.hostA.app[0].destAddr = "2001:db8:1:23::3" # rA3 (intra-AS, via OSPFv3)
63+
*.hostA.app[0].startTime = 55s # after OSPFv3 has converged

tests/fingerprint/examples.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
/examples/bgpv4/BgpAndOspf/, -f omnetpp.ini -c General -r 0, 1000s, 1e22-36e3/tplx;2b66-00b2/~tNl;430e-7064/~tND;de89-afd7/tyf, PASS, ospf EthernetMac Ipv4
3333
/examples/bgpv4/BgpAndOspfSimple/, -f omnetpp.ini -c General -r 0, 1000s, dc15-38aa/tplx;dacd-0cbd/~tNl;46d3-bcb3/~tND;8a59-2347/tyf, PASS, ospf EthernetMac Ipv4
3434
/examples/bgpv4/BgpIpv6Basic/, -f omnetpp.ini -c General -r 0, 30s, 7ed5-3294/tplx;8d57-7c0c/~tNl;d6e7-ba7e/~tND;2e97-8771/tyf, PASS, EthernetMac Ipv6
35+
/examples/bgpv4/BgpAndOspfv3/, -f omnetpp.ini -c General -r 0, 100s, 8421-4b2f/tplx, PASS, ospf EthernetMac Ipv6
3536

3637
/examples/clock/, -f omnetpp.ini -c General -r 0, 10ms, 35c3-8325/tplx;0000-0000/~tNl;0000-0000/~tND;a4b7-bff5/tyf, PASS,
3738

0 commit comments

Comments
 (0)