11#!/usr/bin/env python3
2- """
3- OSPF Basic
2+ """OSPF Basic
3+
4+ Verifies basic OSPF functionality by configuring two routers (R1 and R2)
5+ with OSPF on their interconnecting link. The test ensures OSPF
6+ neighbors are established, routes are exchanged between the routers, and
7+ end-to-end connectivity is achieved.
8+
9+ An end-device (HOST) is connected to R2 on an interface without OSPF enabled.
10+ This verifies that OSPF status information remains accessible when a router
11+ has non-OSPF interfaces.
412
5- Very basic OSPF test just test that OSPF sends HELLO packets between the DUTs
6- and that they exchange routes, ending with a simple connectivity check.
713"""
814
15+ # TODO: Remove HOST node once Infamy supports unconnected ports in topologies
16+
917import infamy
1018import infamy .route as route
1119from infamy .util import until , parallel
1220
21+
1322def config_target1 (target , data , link ):
1423 target .put_config_dict ("ietf-interfaces" , {
1524 "interfaces" : {
@@ -30,8 +39,8 @@ def config_target1(target, data, link):
3039 "ipv4" : {
3140 "forwarding" : True ,
3241 "address" : [{
33- "ip" : "192.168.50.1" ,
34- "prefix-length" : 24
42+ "ip" : "192.168.50.1" ,
43+ "prefix-length" : 24
3544 }]
3645 }
3746 },
@@ -40,8 +49,8 @@ def config_target1(target, data, link):
4049 "enabled" : True ,
4150 "ipv4" : {
4251 "address" : [{
43- "ip" : "192.168.100.1" ,
44- "prefix-length" : 32
52+ "ip" : "192.168.100.1" ,
53+ "prefix-length" : 32
4554 }]
4655 }
4756 }
@@ -56,38 +65,34 @@ def config_target1(target, data, link):
5665 target .put_config_dict ("ietf-routing" , {
5766 "routing" : {
5867 "control-plane-protocols" : {
59- "control-plane-protocol" : [
60- {
61- "type" : "infix-routing:static" ,
62- "name" : "default" ,
63- "static-routes" : {
64- "ipv4" : {
65- "route" : [{
66- "destination-prefix" : "192.168.33.1/32" ,
67- "next-hop" : {
68- "special-next-hop" : "blackhole"
69- }
70- }]
71- }
68+ "control-plane-protocol" : [{
69+ "type" : "infix-routing:static" ,
70+ "name" : "default" ,
71+ "static-routes" : {
72+ "ipv4" : {
73+ "route" : [{
74+ "destination-prefix" : "192.168.33.1/32" ,
75+ "next-hop" : {
76+ "special-next-hop" : "blackhole"
77+ }
78+ }]
7279 }
73- },
74- {
80+ }
81+ }, {
7582 "type" : "infix-routing:ospfv2" ,
7683 "name" : "default" ,
7784 "ospf" : {
7885 "redistribute" : {
7986 "redistribute" : [{
8087 "protocol" : "static"
81- },
82- {
88+ }, {
8389 "protocol" : "connected"
8490 }]
8591 },
8692 "areas" : {
8793 "area" : [{
8894 "area-id" : "0.0.0.0" ,
89- "interfaces" :
90- {
95+ "interfaces" : {
9196 "interface" : [{
9297 "enabled" : True ,
9398 "name" : link ,
@@ -103,35 +108,43 @@ def config_target1(target, data, link):
103108 }
104109 })
105110
106- def config_target2 (target , link ):
111+
112+ def config_target2 (target , link , data ):
107113 target .put_config_dict ("ietf-interfaces" , {
108- "interfaces" : {
109- "interface" : [
110- {
111- "name" : link ,
112- "enabled" : True ,
113- "ipv4" : {
114- "forwarding" : True ,
115- "address" : [{
116- "ip" : "192.168.50.2" ,
117- "prefix-length" : 24
118- }]
119- }
120- },
121- {
122- "name" : "lo" ,
123- "enabled" : True ,
124- "forwarding" : True ,
125- "ipv4" : {
126- "address" : [{
127- "ip" : "192.168.200.1" ,
128- "prefix-length" : 32
129- }]
130- }
131- }
132- ]
133- }
134- })
114+ "interfaces" : {
115+ "interface" : [{
116+ "name" : link ,
117+ "enabled" : True ,
118+ "ipv4" : {
119+ "forwarding" : True ,
120+ "address" : [{
121+ "ip" : "192.168.50.2" ,
122+ "prefix-length" : 24
123+ }]
124+ }
125+ }, {
126+ "name" : data ,
127+ "enabled" : True ,
128+ "ipv4" : {
129+ "forwarding" : True ,
130+ "address" : [{
131+ "ip" : "192.168.60.1" ,
132+ "prefix-length" : 24
133+ }]
134+ }
135+ }, {
136+ "name" : "lo" ,
137+ "enabled" : True ,
138+ "forwarding" : True ,
139+ "ipv4" : {
140+ "address" : [{
141+ "ip" : "192.168.200.1" ,
142+ "prefix-length" : 32
143+ }]
144+ }
145+ }]
146+ }
147+ })
135148
136149 target .put_config_dict ("ietf-system" , {
137150 "system" : {
@@ -141,8 +154,7 @@ def config_target2(target, link):
141154 target .put_config_dict ("ietf-routing" , {
142155 "routing" : {
143156 "control-plane-protocols" : {
144- "control-plane-protocol" : [
145- {
157+ "control-plane-protocol" : [{
146158 "type" : "infix-routing:ospfv2" ,
147159 "name" : "default" ,
148160 "ospf" : {
@@ -154,7 +166,7 @@ def config_target2(target, link):
154166 "areas" : {
155167 "area" : [{
156168 "area-id" : "0.0.0.0" ,
157- "interfaces" :{
169+ "interfaces" : {
158170 "interface" : [{
159171 "enabled" : True ,
160172 "name" : link ,
@@ -165,31 +177,61 @@ def config_target2(target, link):
165177 }]
166178 }
167179 }
168- }
169- ]
180+ }]
170181 }
171182 }
172183 })
173184
185+
186+ def config_host (target , link ):
187+ target .put_config_dict ("ietf-interfaces" , {
188+ "interfaces" : {
189+ "interface" : [{
190+ "name" : link ,
191+ "enabled" : True ,
192+ "ipv4" : {
193+ "address" : [{
194+ "ip" : "192.168.60.2" ,
195+ "prefix-length" : 24
196+ }]
197+ }
198+ }]
199+ }
200+ })
201+
202+ target .put_config_dict ("ietf-system" , {
203+ "system" : {
204+ "hostname" : "HOST"
205+ }
206+ })
207+
208+
174209with infamy .Test () as test :
175210 with test .step ("Set up topology and attach to target DUTs" ):
176211 env = infamy .Env ()
177212 R1 = env .attach ("R1" , "mgmt" )
178213 R2 = env .attach ("R2" , "mgmt" )
214+ HOST = env .attach ("HOST" , "mgmt" )
179215
180216 with test .step ("Configure targets" ):
181217 _ , R1data = env .ltop .xlate ("R1" , "data" )
182218 _ , R2link = env .ltop .xlate ("R2" , "link" )
183- _ , R1link = env .ltop .xlate ("R1" , "link" )
219+ _ , R1link = env .ltop .xlate ("R1" , "link" )
220+ _ , R2data = env .ltop .xlate ("R2" , "data" )
221+ _ , HOSTlink = env .ltop .xlate ("HOST" , "link" )
184222
185223 parallel (config_target1 (R1 , R1data , R1link ),
186- config_target2 (R2 , R2link ))
224+ config_target2 (R2 , R2link , R2data ),
225+ config_host (HOST , HOSTlink ))
187226 with test .step ("Wait for OSPF routes" ):
188- print ("Waiting for OSPF routes.." )
189227 until (lambda : route .ipv4_route_exist (R1 , "192.168.200.1/32" , proto = "ietf-ospf:ospfv2" ), attempts = 200 )
190228 until (lambda : route .ipv4_route_exist (R2 , "192.168.100.1/32" , proto = "ietf-ospf:ospfv2" ), attempts = 200 )
191229 until (lambda : route .ipv4_route_exist (R2 , "192.168.33.1/32" , proto = "ietf-ospf:ospfv2" ), attempts = 200 )
192230
231+ with test .step ("Verify R2 OSPF neighbors with non-OSPF interface" ):
232+ # Regression test for #1169
233+ assert route .ospf_has_neighbors (R2 )
234+
193235 with test .step ("Test connectivity from PC:data to 192.168.200.1" ):
194236 _ , hport0 = env .ltop .xlate ("PC" , "data" )
195237 with infamy .IsolatedMacVlan (hport0 ) as ns0 :
0 commit comments