summary refs log tree commit diff
path: root/src/libnm-platform
diff options
context:
space:
mode:
Diffstat (limited to 'src/libnm-platform')
-rw-r--r--src/libnm-platform/nm-linux-platform.c59
-rw-r--r--src/libnm-platform/nmp-object.c42
-rw-r--r--src/libnm-platform/nmp-object.h14
3 files changed, 71 insertions, 44 deletions
diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c
index eb7c671b..b798d12d 100644
--- a/src/libnm-platform/nm-linux-platform.c
+++ b/src/libnm-platform/nm-linux-platform.c
@@ -711,6 +711,9 @@ wait_for_nl_response_to_string(WaitForNlResponseResult seq_result,
     case WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_UNKNOWN:
         nm_strbuf_append_str(&buf, &buf_size, "failure");
         break;
+    case WAIT_FOR_NL_RESPONSE_RESULT_FAILED_RESYNC:
+        nm_strbuf_append_str(&buf, &buf_size, "failed-resync");
+        break;
     default:
         if (seq_result < 0) {
             nm_strbuf_append(&buf,
@@ -7893,20 +7896,25 @@ do_change_link(NMPlatform           *platform,
     WaitForNlResponseResult     seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN;
     gs_free char               *errmsg     = NULL;
     char                        s_buf[256];
-    int                         result          = 0;
-    NMLogLevel                  log_level       = LOGL_DEBUG;
-    const char                 *log_result      = "failure";
-    const char                 *log_detail      = "";
+    int                         result;
+    NMLogLevel                  log_level;
+    const char                 *log_detail;
     gs_free char               *log_detail_free = NULL;
     const NMPObject            *obj_cache;
 
     if (!nm_platform_netns_push(platform, &netns)) {
         log_level  = LOGL_ERR;
         log_detail = ", failure to change network namespace";
+        result     = -NME_UNSPEC;
         goto out;
     }
 
 retry:
+    result     = -NME_UNSPEC;
+    log_level  = LOGL_WARN;
+    log_detail = "";
+    nm_clear_g_free(&log_detail_free);
+
     nle = _netlink_send_nlmsg_rtnl(platform, nlmsg, &seq_result, &errmsg);
     if (nle < 0) {
         log_level = LOGL_ERR;
@@ -7924,53 +7932,54 @@ retry:
 
     nm_assert(seq_result);
 
-    if (NM_IN_SET(-((int) seq_result), EOPNOTSUPP) && nlmsg_hdr(nlmsg)->nlmsg_type == RTM_NEWLINK) {
+    if (NM_IN_SET(seq_result, WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK, -EEXIST, -EADDRINUSE)) {
+        log_level = LOGL_DEBUG;
+        result    = 0;
+    } else if (NM_IN_SET(seq_result, -EOPNOTSUPP) && nlmsg_hdr(nlmsg)->nlmsg_type == RTM_NEWLINK) {
         nlmsg_hdr(nlmsg)->nlmsg_type = RTM_SETLINK;
-        goto retry;
-    }
 
-    if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK) {
-        log_result = "success";
-    } else if (NM_IN_SET(-((int) seq_result), EEXIST, EADDRINUSE)) {
-        /* */
-    } else if (NM_IN_SET(-((int) seq_result), ESRCH, ENOENT)) {
+        log_level  = LOGL_INFO;
+        log_detail = ", will try SETLINK instead of NEWLINK";
+        result     = -EAGAIN;
+    } else if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_FAILED_RESYNC) {
+        log_level  = LOGL_INFO;
+        log_detail = ", due to lost synchronization";
+        result     = -EAGAIN;
+    } else if (NM_IN_SET(seq_result, -ESRCH, -ENOENT)) {
         log_detail = ", firmware not found";
         result     = -NME_PL_NO_FIRMWARE;
-    } else if (NM_IN_SET(-((int) seq_result), ERANGE)
-               && change_link_type == CHANGE_LINK_TYPE_SET_MTU) {
+    } else if (NM_IN_SET(seq_result, -ERANGE) && change_link_type == CHANGE_LINK_TYPE_SET_MTU) {
         log_detail = ", setting MTU to requested size is not possible";
         result     = -NME_PL_CANT_SET_MTU;
-    } else if (NM_IN_SET(-((int) seq_result), ENFILE)
-               && change_link_type == CHANGE_LINK_TYPE_SET_ADDRESS
+    } else if (NM_IN_SET(seq_result, -ENFILE) && change_link_type == CHANGE_LINK_TYPE_SET_ADDRESS
                && (obj_cache = nmp_cache_lookup_link(nm_platform_get_cache(platform), ifindex))
                && obj_cache->link.l_address.len == data->set_address.length
                && memcmp(obj_cache->link.l_address.data,
                          data->set_address.address,
                          data->set_address.length)
                       == 0) {
-        /* workaround ENFILE which may be wrongly returned (bgo #770456).
+        /* work around ENFILE which may be wrongly returned (bgo #770456).
          * If the MAC address is as expected, assume success? */
-        log_result = "success";
         log_detail = " (assume success changing address)";
         result     = 0;
-    } else if (NM_IN_SET(-((int) seq_result), ENODEV)) {
+    } else if (NM_IN_SET(seq_result, -ENODEV)) {
         log_level = LOGL_DEBUG;
         result    = -NME_PL_NOT_FOUND;
-    } else if (-((int) seq_result) == EAFNOSUPPORT) {
+    } else if (seq_result == -EAFNOSUPPORT) {
         log_level = LOGL_DEBUG;
         result    = -NME_PL_OPNOTSUPP;
-    } else {
-        log_level = LOGL_WARN;
-        result    = -NME_UNSPEC;
     }
 
 out:
     _NMLOG(log_level,
-           "do-change-link[%d]: %s changing link: %s%s",
+           "do-change-link[%d]: %s%s",
            ifindex,
-           log_result,
            wait_for_nl_response_to_string(seq_result, errmsg, s_buf, sizeof(s_buf)),
            log_detail);
+
+    if (result == -EAGAIN)
+        goto retry;
+
     return result;
 }
 
diff --git a/src/libnm-platform/nmp-object.c b/src/libnm-platform/nmp-object.c
index 6609a7d5..db7bd314 100644
--- a/src/libnm-platform/nmp-object.c
+++ b/src/libnm-platform/nmp-object.c
@@ -2204,19 +2204,23 @@ nmp_lookup_init_route_by_weak_id(NMPLookup *lookup, const NMPObject *obj)
     switch (NMP_OBJECT_GET_TYPE(obj)) {
     case NMP_OBJECT_TYPE_IP4_ROUTE:
         r4 = NMP_OBJECT_CAST_IP4_ROUTE(obj);
-        return nmp_lookup_init_ip4_route_by_weak_id(lookup,
-                                                    r4->network,
-                                                    r4->plen,
-                                                    r4->metric,
-                                                    r4->tos);
+        return nmp_lookup_init_ip4_route_by_weak_id(
+            lookup,
+            nm_platform_route_table_uncoerce(r4->table_coerced, TRUE),
+            r4->network,
+            r4->plen,
+            r4->metric,
+            r4->tos);
     case NMP_OBJECT_TYPE_IP6_ROUTE:
         r6 = NMP_OBJECT_CAST_IP6_ROUTE(obj);
-        return nmp_lookup_init_ip6_route_by_weak_id(lookup,
-                                                    &r6->network,
-                                                    r6->plen,
-                                                    r6->metric,
-                                                    &r6->src,
-                                                    r6->src_plen);
+        return nmp_lookup_init_ip6_route_by_weak_id(
+            lookup,
+            nm_platform_route_table_uncoerce(r6->table_coerced, TRUE),
+            &r6->network,
+            r6->plen,
+            r6->metric,
+            &r6->src,
+            r6->src_plen);
     default:
         nm_assert_not_reached();
         return NULL;
@@ -2225,6 +2229,7 @@ nmp_lookup_init_route_by_weak_id(NMPLookup *lookup, const NMPObject *obj)
 
 const NMPLookup *
 nmp_lookup_init_ip4_route_by_weak_id(NMPLookup *lookup,
+                                     guint32    route_table,
                                      in_addr_t  network,
                                      guint      plen,
                                      guint32    metric,
@@ -2235,9 +2240,10 @@ nmp_lookup_init_ip4_route_by_weak_id(NMPLookup *lookup,
     nm_assert(lookup);
 
     o = _nmp_object_stackinit_from_type(&lookup->selector_obj, NMP_OBJECT_TYPE_IP4_ROUTE);
-    o->ip4_route.ifindex = 1;
-    o->ip4_route.plen    = plen;
-    o->ip4_route.metric  = metric;
+    o->ip4_route.ifindex       = 1;
+    o->ip4_route.plen          = plen;
+    o->ip4_route.table_coerced = nm_platform_route_table_coerce(route_table);
+    o->ip4_route.metric        = metric;
     if (network)
         o->ip4_route.network = network;
     o->ip4_route.tos      = tos;
@@ -2247,6 +2253,7 @@ nmp_lookup_init_ip4_route_by_weak_id(NMPLookup *lookup,
 
 const NMPLookup *
 nmp_lookup_init_ip6_route_by_weak_id(NMPLookup             *lookup,
+                                     guint32                route_table,
                                      const struct in6_addr *network,
                                      guint                  plen,
                                      guint32                metric,
@@ -2258,9 +2265,10 @@ nmp_lookup_init_ip6_route_by_weak_id(NMPLookup             *lookup,
     nm_assert(lookup);
 
     o = _nmp_object_stackinit_from_type(&lookup->selector_obj, NMP_OBJECT_TYPE_IP6_ROUTE);
-    o->ip6_route.ifindex = 1;
-    o->ip6_route.plen    = plen;
-    o->ip6_route.metric  = metric;
+    o->ip6_route.ifindex       = 1;
+    o->ip6_route.plen          = plen;
+    o->ip6_route.table_coerced = nm_platform_route_table_coerce(route_table);
+    o->ip6_route.metric        = metric;
     if (network)
         o->ip6_route.network = *network;
     if (src)
diff --git a/src/libnm-platform/nmp-object.h b/src/libnm-platform/nmp-object.h
index 4958404a..25156fe2 100644
--- a/src/libnm-platform/nmp-object.h
+++ b/src/libnm-platform/nmp-object.h
@@ -811,11 +811,13 @@ nmp_lookup_init_object_by_ifindex(NMPLookup *lookup, NMPObjectType obj_type, int
 const NMPLookup *nmp_lookup_init_route_default(NMPLookup *lookup, NMPObjectType obj_type);
 const NMPLookup *nmp_lookup_init_route_by_weak_id(NMPLookup *lookup, const NMPObject *obj);
 const NMPLookup *nmp_lookup_init_ip4_route_by_weak_id(NMPLookup *lookup,
+                                                      guint32    route_table,
                                                       in_addr_t  network,
                                                       guint      plen,
                                                       guint32    metric,
                                                       guint8     tos);
 const NMPLookup *nmp_lookup_init_ip6_route_by_weak_id(NMPLookup             *lookup,
+                                                      guint32                route_table,
                                                       const struct in6_addr *network,
                                                       guint                  plen,
                                                       guint32                metric,
@@ -1074,6 +1076,7 @@ nm_platform_lookup_route_default_clone(NMPlatform            *platform,
 
 static inline const NMDedupMultiHeadEntry *
 nm_platform_lookup_ip4_route_by_weak_id(NMPlatform *platform,
+                                        guint32     route_table,
                                         in_addr_t   network,
                                         guint       plen,
                                         guint32     metric,
@@ -1081,12 +1084,13 @@ nm_platform_lookup_ip4_route_by_weak_id(NMPlatform *platform,
 {
     NMPLookup lookup;
 
-    nmp_lookup_init_ip4_route_by_weak_id(&lookup, network, plen, metric, tos);
+    nmp_lookup_init_ip4_route_by_weak_id(&lookup, route_table, network, plen, metric, tos);
     return nm_platform_lookup(platform, &lookup);
 }
 
 static inline const NMDedupMultiHeadEntry *
 nm_platform_lookup_ip6_route_by_weak_id(NMPlatform            *platform,
+                                        guint32                route_table,
                                         const struct in6_addr *network,
                                         guint                  plen,
                                         guint32                metric,
@@ -1095,7 +1099,13 @@ nm_platform_lookup_ip6_route_by_weak_id(NMPlatform            *platform,
 {
     NMPLookup lookup;
 
-    nmp_lookup_init_ip6_route_by_weak_id(&lookup, network, plen, metric, src, src_plen);
+    nmp_lookup_init_ip6_route_by_weak_id(&lookup,
+                                         route_table,
+                                         network,
+                                         plen,
+                                         metric,
+                                         src,
+                                         src_plen);
     return nm_platform_lookup(platform, &lookup);
 }