@@ -176,6 +176,40 @@ static void connected_update(struct interface *ifp, struct connected *ifc)
176
176
connected_announce (ifp , ifc );
177
177
}
178
178
179
+ /*
180
+ * This function goes through and handles the deletion of a kernel route that happened
181
+ * to be the exact same as the connected route, so that the connected route wins.
182
+ * This can happen during processing if we happen to receive events in a slightly
183
+ * unexpected order. This is similiar to code in the other direction where if we
184
+ * have a kernel route don't install it if it perfectly matches a connected route.
185
+ */
186
+ static void connected_remove_kernel_for_connected (afi_t afi , safi_t safi , struct zebra_vrf * zvrf ,
187
+ struct prefix * p , struct nexthop * nh )
188
+ {
189
+ struct route_node * rn ;
190
+ struct route_entry * re ;
191
+ rib_dest_t * dest ;
192
+ struct route_table * table = zebra_vrf_table (afi , SAFI_UNICAST , zvrf -> vrf -> vrf_id );
193
+
194
+ rn = route_node_match (table , p );
195
+ if (!rn )
196
+ return ;
197
+
198
+ if (!prefix_same (& rn -> p , p ))
199
+ return ;
200
+
201
+ dest = rib_dest_from_rnode (rn );
202
+ if (!dest || !dest -> selected_fib )
203
+ return ;
204
+
205
+ re = dest -> selected_fib ;
206
+ if (re -> type != ZEBRA_ROUTE_KERNEL )
207
+ return ;
208
+
209
+ rib_delete (afi , SAFI_UNICAST , zvrf -> vrf -> vrf_id , ZEBRA_ROUTE_KERNEL , 0 , 0 , p , NULL , nh , 0 ,
210
+ zvrf -> table_id , 0 , 0 , false);
211
+ }
212
+
179
213
/* Called from if_up(). */
180
214
void connected_up (struct interface * ifp , struct connected * ifc )
181
215
{
@@ -284,10 +318,13 @@ void connected_up(struct interface *ifp, struct connected *ifc)
284
318
}
285
319
286
320
if (!CHECK_FLAG (ifc -> flags , ZEBRA_IFA_NOPREFIXROUTE )) {
321
+ connected_remove_kernel_for_connected (afi , SAFI_UNICAST , zvrf , & p , & nh );
322
+
287
323
rib_add (afi , SAFI_UNICAST , zvrf -> vrf -> vrf_id ,
288
324
ZEBRA_ROUTE_CONNECT , 0 , flags , & p , NULL , & nh , 0 ,
289
325
zvrf -> table_id , metric , 0 , 0 , 0 , false);
290
326
327
+ connected_remove_kernel_for_connected (afi , SAFI_MULTICAST , zvrf , & p , & nh );
291
328
rib_add (afi , SAFI_MULTICAST , zvrf -> vrf -> vrf_id ,
292
329
ZEBRA_ROUTE_CONNECT , 0 , flags , & p , NULL , & nh , 0 ,
293
330
zvrf -> table_id , metric , 0 , 0 , 0 , false);
0 commit comments