@@ -105,6 +105,139 @@ def teardown_module(_mod):
105
105
tgen .stop_topology ()
106
106
107
107
108
+ def test_v6_rtadv ():
109
+ tgen = get_topogen ()
110
+
111
+ # Get the initial interface state and RA interval before making any changes
112
+ interface_output = tgen .gears ["r1" ].vtysh_cmd ("show interface r1-eth200 json" )
113
+ interface_data = json .loads (interface_output )
114
+
115
+ # Check if the interface exists and get its current state
116
+ interface_section = interface_data .get ("r1-eth200" , {})
117
+ if not interface_section :
118
+ logger .error ("Interface r1-eth200 not found. Test cannot continue." )
119
+ return
120
+
121
+ # Get the RA interval
122
+ ra_interval = interface_section .get ("ndRouterAdvertisementsIntervalSecs" )
123
+ if ra_interval is None :
124
+ # If RA interval isn't found, log a message and exit the test
125
+ logger .error (
126
+ "Could not find RA interval (ndRouterAdvertisementsIntervalSecs) in interface configuration. Test cannot continue."
127
+ )
128
+ return
129
+
130
+ logger .info (f"Using RA interval of { ra_interval } seconds" )
131
+
132
+ # Function to get current RA state - returns the router advertisement sent count
133
+ def _get_ra_state ():
134
+ output = tgen .gears ["r1" ].vtysh_cmd ("show interface r1-eth200 json" )
135
+ data = json .loads (output )
136
+ return data .get ("r1-eth200" , {}).get ("ndRouterAdvertisementsSent" )
137
+
138
+ logger .info ("Shutdown r1-eth200" )
139
+ tgen .gears ["r1" ].vtysh_cmd (
140
+ """
141
+ configure terminal
142
+ interface r1-eth200
143
+ shutdown
144
+ """
145
+ )
146
+
147
+ # Verify interface is down before proceeding
148
+ def _check_interface_down ():
149
+ output = tgen .gears ["r1" ].vtysh_cmd ("show interface r1-eth200 json" )
150
+ return True if '"administrativeStatus":"down"' in output else False
151
+
152
+ _ , result = topotest .run_and_expect (_check_interface_down , True , count = 10 , wait = 15 )
153
+ assert result is True , "Interface r1-eth200 did not go down after shutdown command"
154
+
155
+ # Take snapshots for RA status when interface is down
156
+ ra_sent_count1 = _get_ra_state ()
157
+
158
+ if ra_sent_count1 is None :
159
+ logger .error ("Could not get RA sent count. Test cannot continue." )
160
+ return
161
+
162
+ # We need to wait for at least ra_interval + buffer time(1 sec) to avoid
163
+ # situation where any event was delayed or due to any processing delay
164
+ logger .info (f"Waiting another { ra_interval + 1 } seconds for RA timer..." )
165
+ sleep (ra_interval + 1 )
166
+ ra_sent_count2 = _get_ra_state ()
167
+
168
+ # Verify RA sent count didn't change when interface is down
169
+ assert (
170
+ ra_sent_count1 == ra_sent_count2
171
+ ), f"RA sent count should not have changed when interface is down: was { ra_sent_count1 } , now { ra_sent_count2 } "
172
+
173
+ logger .info ("Do no shutdown for r1-eth200" )
174
+ tgen .gears ["r1" ].vtysh_cmd (
175
+ """
176
+ configure terminal
177
+ interface r1-eth200
178
+ no shutdown
179
+ """
180
+ )
181
+
182
+ # Verify interface is up before proceeding
183
+ def _check_interface_up ():
184
+ output = tgen .gears ["r1" ].vtysh_cmd ("show interface r1-eth200 json" )
185
+ return True if '"administrativeStatus":"up"' in output else False
186
+
187
+ _ , result = topotest .run_and_expect (_check_interface_up , True , count = 10 , wait = 15 )
188
+ assert result is True , "Interface r1-eth200 did not go up after no shutdown command"
189
+
190
+ # Take snapshots for RA status when interface is up
191
+ ra_sent_count1 = _get_ra_state ()
192
+
193
+ # We need to wait for at least ra_interval + buffer time(1 sec)
194
+ logger .info (f"Waiting another { ra_interval + 1 } seconds for RA timer..." )
195
+ sleep (ra_interval + 1 )
196
+ ra_sent_count2 = _get_ra_state ()
197
+
198
+ # Verify RA sent count changed when interface is up (RAs should be sent)
199
+ assert (
200
+ ra_sent_count1 != ra_sent_count2
201
+ ), f"RA sent count should have changed when interface is up: was { ra_sent_count1 } , still { ra_sent_count2 } "
202
+
203
+ logger .info ("Remove r1-eth200" )
204
+ existing_config = tgen .gears ["r1" ].vtysh_cmd ("show interface r1-eth200" )
205
+ tgen .gears ["r1" ].cmd (
206
+ """
207
+ sudo ip link set dev r1-eth200 down
208
+ """
209
+ )
210
+
211
+ # Verify interface is down after ip link set down
212
+ _ , result = topotest .run_and_expect (_check_interface_down , True , count = 10 , wait = 15 )
213
+ assert result is True , "Interface r1-eth200 did not go down after ip link set down"
214
+
215
+ # Get current RA sent count
216
+ ra_sent_count1 = _get_ra_state ()
217
+
218
+ # Wait for the RA interval
219
+ logger .info (f"Waiting { ra_interval + 1 } seconds for RA timer..." )
220
+ sleep (ra_interval + 1 )
221
+
222
+ # Get second RA sent count
223
+ ra_sent_count2 = _get_ra_state ()
224
+
225
+ # Verify counts are the same when interface is down
226
+ assert (
227
+ ra_sent_count1 == ra_sent_count2
228
+ ), f"RA sent count changed from { ra_sent_count1 } to { ra_sent_count2 } within { ra_interval + 1 } seconds while interface is down"
229
+
230
+ tgen .gears ["r1" ].cmd (
231
+ """
232
+ sudo ip link set dev r1-eth200 up
233
+ """
234
+ )
235
+
236
+ # Verify interface is up after ip link set up
237
+ _ , result = topotest .run_and_expect (_check_interface_up , True , count = 10 , wait = 15 )
238
+ assert result is True , "Interface r1-eth200 did not go up after ip link set up"
239
+
240
+
108
241
def test_bgp_route_cleanup ():
109
242
failures = 0
110
243
net = get_topogen ().net
0 commit comments