core: don't postpone configuring onlink ECMP routes
Also add some code comments.
Fixes: 7a844ecba9
('netns: fix configuring onlink routes for ECMP routes')
This commit is contained in:
@@ -105,7 +105,19 @@ typedef struct {
|
|||||||
/* Calling nm_netns_ip_route_ecmp_register() will ensure that the tracked
|
/* Calling nm_netns_ip_route_ecmp_register() will ensure that the tracked
|
||||||
* entry is non-dirty. This can be used to remove stale entries. */
|
* entry is non-dirty. This can be used to remove stale entries. */
|
||||||
bool dirty : 1;
|
bool dirty : 1;
|
||||||
|
|
||||||
|
/* This flag is set during nm_netns_ip_route_ecmp_register(), when first tracking the
|
||||||
|
* route. It is cleared on the next nm_netns_ip_route_ecmp_commit(). It thus only
|
||||||
|
* exists for a short time, to know during a commit that the route is new and
|
||||||
|
* we need to do something special. */
|
||||||
bool is_new : 1;
|
bool is_new : 1;
|
||||||
|
|
||||||
|
/* The entry is ready to be configured. This exists, because the nexthop of
|
||||||
|
* a route must be reachable directly (being onlink). That is, we may need
|
||||||
|
* to add a direct, single-hop route to the gateway, which is done by
|
||||||
|
* the NML3Cfg of that interface. Since the NML3Cfg calls nm_netns_ip_route_ecmp_commit()
|
||||||
|
* and only adds the direct route afterwards, the ECMP route may not be ready
|
||||||
|
* right away, but only upon seeing the entry a second time. */
|
||||||
bool is_ready : 1;
|
bool is_ready : 1;
|
||||||
} EcmpTrackObj;
|
} EcmpTrackObj;
|
||||||
|
|
||||||
@@ -631,7 +643,6 @@ nm_netns_ip_route_ecmp_commit(NMNetns *self,
|
|||||||
EcmpTrackObj *track_obj_safe;
|
EcmpTrackObj *track_obj_safe;
|
||||||
EcmpTrackEcmpid *track_ecmpid;
|
EcmpTrackEcmpid *track_ecmpid;
|
||||||
const NMPObject *route_obj;
|
const NMPObject *route_obj;
|
||||||
const NMPlatformIP4Route *route;
|
|
||||||
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
||||||
gboolean already_notified = FALSE;
|
gboolean already_notified = FALSE;
|
||||||
|
|
||||||
@@ -662,6 +673,9 @@ nm_netns_ip_route_ecmp_commit(NMNetns *self,
|
|||||||
track_obj->is_ready = FALSE;
|
track_obj->is_ready = FALSE;
|
||||||
}
|
}
|
||||||
if (track_obj->is_new) {
|
if (track_obj->is_new) {
|
||||||
|
const NMPlatformIP4Route *route =
|
||||||
|
NMP_OBJECT_CAST_IP4_ROUTE(track_ecmpid->merged_obj);
|
||||||
|
|
||||||
/* This is a new route entry that was just added. Upon first
|
/* This is a new route entry that was just added. Upon first
|
||||||
* addition, the route is not yet ready for configuration,
|
* addition, the route is not yet ready for configuration,
|
||||||
* because we need to make sure that the gateway is reachable
|
* because we need to make sure that the gateway is reachable
|
||||||
@@ -673,7 +687,11 @@ nm_netns_ip_route_ecmp_commit(NMNetns *self,
|
|||||||
* after l3cfg configured that route. We achieve that by
|
* after l3cfg configured that route. We achieve that by
|
||||||
* scheduling another idle commit on "l3cfg". */
|
* scheduling another idle commit on "l3cfg". */
|
||||||
track_obj->is_new = FALSE;
|
track_obj->is_new = FALSE;
|
||||||
if (c_list_length_is(&track_ecmpid->ecmpid_lst_head, 1)) {
|
if (route && route->gateway == 0) {
|
||||||
|
/* This route is onlink. We don't need to configure an onlink route
|
||||||
|
* to the gateway, and the route is immediately ready for configuration. */
|
||||||
|
track_obj->is_ready = TRUE;
|
||||||
|
} else if (c_list_length_is(&track_ecmpid->ecmpid_lst_head, 1)) {
|
||||||
/* This route has no merge partner and ends up being a
|
/* This route has no merge partner and ends up being a
|
||||||
* single hop route. It will be returned and configured by
|
* single hop route. It will be returned and configured by
|
||||||
* the calling "l3cfg".
|
* the calling "l3cfg".
|
||||||
@@ -683,7 +701,15 @@ nm_netns_ip_route_ecmp_commit(NMNetns *self,
|
|||||||
* don't need to schedule an idle commit. */
|
* don't need to schedule an idle commit. */
|
||||||
track_obj->is_ready = TRUE;
|
track_obj->is_ready = TRUE;
|
||||||
} else {
|
} else {
|
||||||
|
/* This is a new route which has a gateway. We need for the "l3cfg"
|
||||||
|
* to first configure the onlink route. It's not yet ready for configuration.
|
||||||
|
*
|
||||||
|
* Instead, schedule an idle commit to make sure we get called back
|
||||||
|
* again, and then (upon seeing the entry the second time) the onlink
|
||||||
|
* route is already configured and we will be ready. */
|
||||||
if (!already_notified) {
|
if (!already_notified) {
|
||||||
|
/* Some micro optimization with already_notified to avoid calling
|
||||||
|
* schedule unnecessarily. */
|
||||||
already_notified = TRUE;
|
already_notified = TRUE;
|
||||||
nm_l3cfg_commit_on_idle_schedule(l3cfg, NM_L3_CFG_COMMIT_TYPE_AUTO);
|
nm_l3cfg_commit_on_idle_schedule(l3cfg, NM_L3_CFG_COMMIT_TYPE_AUTO);
|
||||||
}
|
}
|
||||||
@@ -720,6 +746,7 @@ nm_netns_ip_route_ecmp_commit(NMNetns *self,
|
|||||||
c_list_for_each_entry (track_obj,
|
c_list_for_each_entry (track_obj,
|
||||||
&l3cfg->internal_netns.ecmp_track_ifindex_lst_head,
|
&l3cfg->internal_netns.ecmp_track_ifindex_lst_head,
|
||||||
ifindex_lst) {
|
ifindex_lst) {
|
||||||
|
const NMPlatformIP4Route *route;
|
||||||
EcmpTrackObj *track_obj2;
|
EcmpTrackObj *track_obj2;
|
||||||
nm_auto_nmpobj const NMPObject *obj_del = NULL;
|
nm_auto_nmpobj const NMPObject *obj_del = NULL;
|
||||||
gboolean changed;
|
gboolean changed;
|
||||||
|
Reference in New Issue
Block a user