mirror of
https://git.yoctoproject.org/poky
synced 2026-04-10 23:02:25 +02:00
systemd: Add fix for systemd-networkd crash during free
We are observing systemd-network service crash during link down while freeing link->ifname pointer Backtrace: (gdb) bt 0 __GI_abort () at abort.c:107 1 0x0000007f861d32b4 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7f8628d500 "%s\n") at ../sysdeps/posix/libc_fatal.c:155 2 0x0000007f861da51c in malloc_printerr (str=str@entry=0x7f86289070 "free(): invalid next size (fast)") at malloc.c:5347 3 0x0000007f861dbd58 in _int_free (av=0x7f862c9a28 <main_arena>, p=0x558aa28eb0, have_lock=0) at malloc.c:4249 4 0x0000005569249cf0 in link_free (link=0x558aa1c0d0) at ../git/src/network/networkd-link.c:715 5 link_unref (p=0x558aa1c0d0) at ../git/src/network/networkd-link.c:734 6 0x000000556920f34c in manager_rtnl_process_link (rtnl=<optimized out>, message=0x558aa2a430, userdata=0x558a9fc630) While checking upstream code change with regards to link->ifname memory allocation and free, we found below PR which also fixes random systemd-networkd crash: https://github.com/systemd/systemd/pull/19631 https://github.com/systemd/systemd/issues/19629 (From OE-Core rev: adca61c61d84f022fdedd2d616e7c2df00661af8) Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> Signed-off-by: Ranjitsinh Rathod <ranjitsinhrathod1991@gmail.com> Signed-off-by: Steve Sakoman <steve@sakoman.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
committed by
Richard Purdie
parent
3d5a3e009a
commit
f3452bf993
@@ -0,0 +1,78 @@
|
||||
From 1f25c71d9d0b5fe6cf383c347dcebc2443a99fe1 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||
Date: Tue, 1 Sep 2020 12:42:35 +0200
|
||||
Subject: [PATCH] basic: pass allocation info for ordered_set_new() and
|
||||
introduce ordered_set_ensure_put()
|
||||
|
||||
Upstream-Status: Backport [https://github.com/systemd/systemd-stable/commit/1f25c71d9d0b5fe6cf383c347dcebc2443a99fe1]
|
||||
Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
|
||||
|
||||
---
|
||||
src/basic/ordered-set.c | 21 +++++++++++++++++++++
|
||||
src/basic/ordered-set.h | 18 +++++++-----------
|
||||
2 files changed, 28 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/basic/ordered-set.c b/src/basic/ordered-set.c
|
||||
index 7fdb47e064..fb82c17b5a 100644
|
||||
--- a/src/basic/ordered-set.c
|
||||
+++ b/src/basic/ordered-set.c
|
||||
@@ -4,6 +4,27 @@
|
||||
#include "ordered-set.h"
|
||||
#include "strv.h"
|
||||
|
||||
+int _ordered_set_ensure_allocated(OrderedSet **s, const struct hash_ops *ops HASHMAP_DEBUG_PARAMS) {
|
||||
+ if (*s)
|
||||
+ return 0;
|
||||
+
|
||||
+ *s = _ordered_set_new(ops HASHMAP_DEBUG_PASS_ARGS);
|
||||
+ if (!*s)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int _ordered_set_ensure_put(OrderedSet **s, const struct hash_ops *ops, void *p HASHMAP_DEBUG_PARAMS) {
|
||||
+ int r;
|
||||
+
|
||||
+ r = _ordered_set_ensure_allocated(s, ops HASHMAP_DEBUG_PASS_ARGS);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ return ordered_set_put(*s, p);
|
||||
+}
|
||||
+
|
||||
int ordered_set_consume(OrderedSet *s, void *p) {
|
||||
int r;
|
||||
|
||||
diff --git a/src/basic/ordered-set.h b/src/basic/ordered-set.h
|
||||
index a42a57eb49..2c241a808b 100644
|
||||
--- a/src/basic/ordered-set.h
|
||||
+++ b/src/basic/ordered-set.h
|
||||
@@ -7,20 +7,16 @@
|
||||
|
||||
typedef struct OrderedSet OrderedSet;
|
||||
|
||||
-static inline OrderedSet* ordered_set_new(const struct hash_ops *ops) {
|
||||
- return (OrderedSet*) ordered_hashmap_new(ops);
|
||||
+static inline OrderedSet* _ordered_set_new(const struct hash_ops *ops HASHMAP_DEBUG_PARAMS) {
|
||||
+ return (OrderedSet*) internal_ordered_hashmap_new(ops HASHMAP_DEBUG_PASS_ARGS);
|
||||
}
|
||||
+#define ordered_set_new(ops) _ordered_set_new(ops HASHMAP_DEBUG_SRC_ARGS)
|
||||
|
||||
-static inline int ordered_set_ensure_allocated(OrderedSet **s, const struct hash_ops *ops) {
|
||||
- if (*s)
|
||||
- return 0;
|
||||
+int _ordered_set_ensure_allocated(OrderedSet **s, const struct hash_ops *ops HASHMAP_DEBUG_PARAMS);
|
||||
+#define ordered_set_ensure_allocated(s, ops) _ordered_set_ensure_allocated(s, ops HASHMAP_DEBUG_SRC_ARGS)
|
||||
|
||||
- *s = ordered_set_new(ops);
|
||||
- if (!*s)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
+int _ordered_set_ensure_put(OrderedSet **s, const struct hash_ops *ops, void *p HASHMAP_DEBUG_PARAMS);
|
||||
+#define ordered_set_ensure_put(s, hash_ops, key) _ordered_set_ensure_put(s, hash_ops, key HASHMAP_DEBUG_SRC_ARGS)
|
||||
|
||||
static inline OrderedSet* ordered_set_free(OrderedSet *s) {
|
||||
return (OrderedSet*) ordered_hashmap_free((OrderedHashmap*) s);
|
||||
@@ -0,0 +1,35 @@
|
||||
From d38a6476aad3f2cc80a2a4bc11f3898cc06a70f5 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Mon, 26 Apr 2021 23:52:40 +0900
|
||||
Subject: [PATCH] ordered-set: introduce
|
||||
ordered_set_clear/free_with_destructor()
|
||||
|
||||
Upstream-Status: Backport [https://github.com/systemd/systemd-stable/commit/d38a6476aad3f2cc80a2a4bc11f3898cc06a70f5]
|
||||
Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
|
||||
|
||||
---
|
||||
src/basic/ordered-set.h | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/src/basic/ordered-set.h b/src/basic/ordered-set.h
|
||||
index a377f20b1f..64df41766f 100644
|
||||
--- a/src/basic/ordered-set.h
|
||||
+++ b/src/basic/ordered-set.h
|
||||
@@ -63,6 +63,17 @@ void ordered_set_print(FILE *f, const char *field, OrderedSet *s);
|
||||
#define ORDERED_SET_FOREACH(e, s, i) \
|
||||
for ((i) = ITERATOR_FIRST; ordered_set_iterate((s), &(i), (void**)&(e)); )
|
||||
|
||||
+#define ordered_set_clear_with_destructor(s, f) \
|
||||
+ ({ \
|
||||
+ OrderedSet *_s = (s); \
|
||||
+ void *_item; \
|
||||
+ while ((_item = ordered_set_steal_first(_s))) \
|
||||
+ f(_item); \
|
||||
+ _s; \
|
||||
+ })
|
||||
+#define ordered_set_free_with_destructor(s, f) \
|
||||
+ ordered_set_free(ordered_set_clear_with_destructor(s, f))
|
||||
+
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedSet*, ordered_set_free);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedSet*, ordered_set_free_free);
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
From 19d9a5adf0c1a6b5a243eea0390f6f6526d569de Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Fri, 7 May 2021 15:39:16 +0900
|
||||
Subject: [PATCH] network: add skeleton of request queue
|
||||
|
||||
This will be used in later commits.
|
||||
|
||||
Upstream-Status: Backport [https://github.com/systemd/systemd-stable/commit/19d9a5adf0c1a6b5a243eea0390f6f6526d569de]
|
||||
Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
|
||||
|
||||
---
|
||||
src/network/meson.build | 2 +
|
||||
src/network/networkd-link.c | 20 +++++-
|
||||
src/network/networkd-manager.c | 7 ++
|
||||
src/network/networkd-manager.h | 2 +
|
||||
src/network/networkd-queue.c | 121 +++++++++++++++++++++++++++++++++
|
||||
src/network/networkd-queue.h | 42 ++++++++++++
|
||||
6 files changed, 192 insertions(+), 2 deletions(-)
|
||||
create mode 100644 src/network/networkd-queue.c
|
||||
create mode 100644 src/network/networkd-queue.h
|
||||
|
||||
diff --git a/src/network/meson.build b/src/network/meson.build
|
||||
index 4fca3106dc..a8b9232e64 100644
|
||||
--- a/src/network/meson.build
|
||||
+++ b/src/network/meson.build
|
||||
@@ -105,6 +105,8 @@ sources = files('''
|
||||
networkd-network.h
|
||||
networkd-nexthop.c
|
||||
networkd-nexthop.h
|
||||
+ networkd-queue.c
|
||||
+ networkd-queue.h
|
||||
networkd-route.c
|
||||
networkd-route.h
|
||||
networkd-routing-policy-rule.c
|
||||
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
|
||||
index 34359b2541..2f33305a27 100644
|
||||
--- a/src/network/networkd-link.c
|
||||
+++ b/src/network/networkd-link.c
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-ndisc.h"
|
||||
#include "networkd-neighbor.h"
|
||||
+#include "networkd-queue.h"
|
||||
#include "networkd-radv.h"
|
||||
#include "networkd-routing-policy-rule.h"
|
||||
#include "networkd-wifi.h"
|
||||
|
||||
@@ -2232,6 +2244,8 @@ static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool for
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
+ link_drop_requests(link);
|
||||
+
|
||||
r = link_drop_config(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -2664,6 +2678,8 @@ static int link_carrier_lost(Link *link) {
|
||||
return r;
|
||||
}
|
||||
|
||||
+ link_drop_requests(link);
|
||||
+
|
||||
r = link_drop_config(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
|
||||
index 562ce5ca54..fd576169a9 100644
|
||||
--- a/src/network/networkd-manager.c
|
||||
+++ b/src/network/networkd-manager.c
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "networkd-manager-bus.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-network-bus.h"
|
||||
+#include "networkd-queue.h"
|
||||
#include "networkd-speed-meter.h"
|
||||
#include "ordered-set.h"
|
||||
#include "path-util.h"
|
||||
@@ -406,6 +407,10 @@ int manager_new(Manager **ret) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
+ r = sd_event_add_post(m->event, NULL, manager_process_requests, m);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
r = manager_connect_rtnl(m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -446,6 +451,8 @@ Manager* manager_free(Manager *m) {
|
||||
|
||||
free(m->state_file);
|
||||
|
||||
+ m->request_queue = ordered_set_free_with_destructor(m->request_queue, request_free);
|
||||
+
|
||||
while ((a = hashmap_first_key(m->dhcp6_prefixes)))
|
||||
(void) dhcp6_prefix_remove(m, a);
|
||||
m->dhcp6_prefixes = hashmap_free(m->dhcp6_prefixes);
|
||||
diff --git a/src/network/networkd-manager.h b/src/network/networkd-manager.h
|
||||
index 301b97c1a1..26e8802871 100644
|
||||
--- a/src/network/networkd-manager.h
|
||||
+++ b/src/network/networkd-manager.h
|
||||
@@ -91,6 +91,8 @@ struct Manager {
|
||||
usec_t speed_meter_usec_old;
|
||||
|
||||
bool dhcp4_prefix_root_cannot_set_table;
|
||||
+
|
||||
+ OrderedSet *request_queue;
|
||||
};
|
||||
|
||||
int manager_new(Manager **ret);
|
||||
diff --git a/src/network/networkd-queue.c b/src/network/networkd-queue.c
|
||||
new file mode 100644
|
||||
index 0000000000..24bb2c845d
|
||||
--- /dev/null
|
||||
+++ b/src/network/networkd-queue.c
|
||||
@@ -0,0 +1,121 @@
|
||||
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
+
|
||||
+#include "networkd-address.h"
|
||||
+#include "networkd-manager.h"
|
||||
+#include "networkd-neighbor.h"
|
||||
+#include "networkd-nexthop.h"
|
||||
+#include "networkd-route.h"
|
||||
+#include "networkd-routing-policy-rule.h"
|
||||
+#include "networkd-queue.h"
|
||||
+
|
||||
+static void request_free_object(RequestType type, void *object) {
|
||||
+ switch(type) {
|
||||
+ default:
|
||||
+ assert_not_reached("invalid request type.");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+Request *request_free(Request *req) {
|
||||
+ if (!req)
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (req->on_free)
|
||||
+ req->on_free(req);
|
||||
+ if (req->consume_object)
|
||||
+ request_free_object(req->type, req->object);
|
||||
+ if (req->link && req->link->manager)
|
||||
+ ordered_set_remove(req->link->manager->request_queue, req);
|
||||
+ link_unref(req->link);
|
||||
+
|
||||
+ return mfree(req);
|
||||
+}
|
||||
+
|
||||
+DEFINE_TRIVIAL_CLEANUP_FUNC(Request*, request_free);
|
||||
+
|
||||
+void request_drop(Request *req) {
|
||||
+ if (req->message_counter)
|
||||
+ (*req->message_counter)--;
|
||||
+
|
||||
+ request_free(req);
|
||||
+}
|
||||
+
|
||||
+int link_queue_request(
|
||||
+ Link *link,
|
||||
+ RequestType type,
|
||||
+ void *object,
|
||||
+ bool consume_object,
|
||||
+ unsigned *message_counter,
|
||||
+ link_netlink_message_handler_t netlink_handler,
|
||||
+ Request **ret) {
|
||||
+
|
||||
+ _cleanup_(request_freep) Request *req = NULL;
|
||||
+ int r;
|
||||
+
|
||||
+ assert(link);
|
||||
+ assert(link->manager);
|
||||
+ assert(type >= 0 && type < _REQUEST_TYPE_MAX);
|
||||
+ assert(object);
|
||||
+ assert(netlink_handler);
|
||||
+
|
||||
+ req = new(Request, 1);
|
||||
+ if (!req) {
|
||||
+ if (consume_object)
|
||||
+ request_free_object(type, object);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ *req = (Request) {
|
||||
+ .link = link,
|
||||
+ .type = type,
|
||||
+ .object = object,
|
||||
+ .consume_object = consume_object,
|
||||
+ .message_counter = message_counter,
|
||||
+ .netlink_handler = netlink_handler,
|
||||
+ };
|
||||
+
|
||||
+ link_ref(link);
|
||||
+
|
||||
+ r = ordered_set_ensure_put(&link->manager->request_queue, NULL, req);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ if (req->message_counter)
|
||||
+ (*req->message_counter)++;
|
||||
+
|
||||
+ if (ret)
|
||||
+ *ret = req;
|
||||
+
|
||||
+ TAKE_PTR(req);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int manager_process_requests(sd_event_source *s, void *userdata) {
|
||||
+ Manager *manager = userdata;
|
||||
+ int r;
|
||||
+
|
||||
+ assert(manager);
|
||||
+
|
||||
+ for (;;) {
|
||||
+ bool processed = false;
|
||||
+ Request *req;
|
||||
+ Iterator i;
|
||||
+ ORDERED_SET_FOREACH(req, manager->request_queue, i) {
|
||||
+ switch(req->type) {
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (r < 0)
|
||||
+ link_enter_failed(req->link);
|
||||
+ if (r > 0) {
|
||||
+ ordered_set_remove(manager->request_queue, req);
|
||||
+ request_free(req);
|
||||
+ processed = true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!processed)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/src/network/networkd-queue.h b/src/network/networkd-queue.h
|
||||
new file mode 100644
|
||||
index 0000000000..4558ae548f
|
||||
--- /dev/null
|
||||
+++ b/src/network/networkd-queue.h
|
||||
@@ -0,0 +1,42 @@
|
||||
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
+#pragma once
|
||||
+
|
||||
+#include "sd-event.h"
|
||||
+
|
||||
+#include "networkd-link.h"
|
||||
+
|
||||
+typedef struct Request Request;
|
||||
+
|
||||
+typedef int (*request_after_configure_handler_t)(Request*, void*);
|
||||
+typedef void (*request_on_free_handler_t)(Request*);
|
||||
+
|
||||
+typedef enum RequestType {
|
||||
+ _REQUEST_TYPE_MAX,
|
||||
+ _REQUEST_TYPE_INVALID = -EINVAL,
|
||||
+} RequestType;
|
||||
+
|
||||
+typedef struct Request {
|
||||
+ Link *link;
|
||||
+ RequestType type;
|
||||
+ bool consume_object;
|
||||
+ void *object;
|
||||
+ void *userdata;
|
||||
+ unsigned *message_counter;
|
||||
+ link_netlink_message_handler_t netlink_handler;
|
||||
+ request_after_configure_handler_t after_configure;
|
||||
+ request_on_free_handler_t on_free;
|
||||
+} Request;
|
||||
+
|
||||
+Request *request_free(Request *req);
|
||||
+void request_drop(Request *req);
|
||||
+
|
||||
+int link_queue_request(
|
||||
+ Link *link,
|
||||
+ RequestType type,
|
||||
+ void *object,
|
||||
+ bool consume_object,
|
||||
+ unsigned *message_counter,
|
||||
+ link_netlink_message_handler_t netlink_handler,
|
||||
+ Request **ret);
|
||||
+
|
||||
+int manager_process_requests(sd_event_source *s, void *userdata);
|
||||
@@ -0,0 +1,50 @@
|
||||
From 56001f023305ea99329e27141d6e6067596491a9 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Mon, 17 May 2021 15:32:57 +0900
|
||||
Subject: [PATCH] network: also drop requests when link enters linger state
|
||||
|
||||
Otherwise, if link is removed, several references to the link in remain
|
||||
exist in requests.
|
||||
|
||||
Upstream-Status: Backport [https://github.com/systemd/systemd-stable/commit/56001f023305ea99329e27141d6e6067596491a9]
|
||||
Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
|
||||
|
||||
---
|
||||
src/network/networkd-link.c | 24 +++++++++++++-----------
|
||||
1 file changed, 13 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
|
||||
index 67d01ac44d..b56c232eca 100644
|
||||
--- a/src/network/networkd-link.c
|
||||
+++ b/src/network/networkd-link.c
|
||||
@@ -1771,6 +1771,18 @@ static void link_drop_from_master(Link *link, NetDev *netdev) {
|
||||
link_unref(set_remove(master->slaves, link));
|
||||
}
|
||||
|
||||
+static void link_drop_requests(Link *link) {
|
||||
+ Request *req;
|
||||
+ Iterator i;
|
||||
+
|
||||
+ assert(link);
|
||||
+ assert(link->manager);
|
||||
+
|
||||
+ ORDERED_SET_FOREACH(req, link->manager->request_queue, i)
|
||||
+ if (req->link == link)
|
||||
+ request_drop(req);
|
||||
+}
|
||||
+
|
||||
void link_drop(Link *link) {
|
||||
if (!link)
|
||||
return;
|
||||
@@ -1782,6 +1793,8 @@ void link_drop(Link *link) {
|
||||
/* Drop all references from other links and manager. Note that async netlink calls may have
|
||||
* references to the link, and they will be dropped when we receive replies. */
|
||||
|
||||
+ link_drop_requests(link);
|
||||
+
|
||||
link_free_carrier_maps(link);
|
||||
|
||||
if (link->network) {
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@@ -0,0 +1,278 @@
|
||||
From cc2d7efc5ca09a7de4bec55e80476986839a655c Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Fri, 14 May 2021 15:58:15 +0900
|
||||
Subject: [PATCH] network: fix Link reference counter issue
|
||||
|
||||
Previously, when link_new() fails, `link_unref()` was called, so,
|
||||
`Manager::links` may become dirty.
|
||||
This introduces `link_drop_or_unref()` and it will be called on
|
||||
failure.
|
||||
|
||||
Upstream-Status: Backport [https://github.com/systemd/systemd-stable/commit/cc2d7efc5ca09a7de4bec55e80476986839a655c]
|
||||
Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
|
||||
|
||||
---
|
||||
src/network/networkd-link.c | 240 ++++++++++++++++++------------------
|
||||
1 file changed, 122 insertions(+), 118 deletions(-)
|
||||
|
||||
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
|
||||
index b56c232eca..d493afda4c 100644
|
||||
--- a/src/network/networkd-link.c
|
||||
+++ b/src/network/networkd-link.c
|
||||
@@ -540,109 +540,6 @@ static int link_update_flags(Link *link,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
|
||||
- _cleanup_(link_unrefp) Link *link = NULL;
|
||||
- uint16_t type;
|
||||
- const char *ifname, *kind = NULL;
|
||||
- int r, ifindex;
|
||||
- unsigned short iftype;
|
||||
-
|
||||
- assert(manager);
|
||||
- assert(message);
|
||||
- assert(ret);
|
||||
-
|
||||
- /* check for link kind */
|
||||
- r = sd_netlink_message_enter_container(message, IFLA_LINKINFO);
|
||||
- if (r == 0) {
|
||||
- (void) sd_netlink_message_read_string(message, IFLA_INFO_KIND, &kind);
|
||||
- r = sd_netlink_message_exit_container(message);
|
||||
- if (r < 0)
|
||||
- return r;
|
||||
- }
|
||||
-
|
||||
- r = sd_netlink_message_get_type(message, &type);
|
||||
- if (r < 0)
|
||||
- return r;
|
||||
- else if (type != RTM_NEWLINK)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
|
||||
- if (r < 0)
|
||||
- return r;
|
||||
- else if (ifindex <= 0)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- r = sd_rtnl_message_link_get_type(message, &iftype);
|
||||
- if (r < 0)
|
||||
- return r;
|
||||
-
|
||||
- r = sd_netlink_message_read_string(message, IFLA_IFNAME, &ifname);
|
||||
- if (r < 0)
|
||||
- return r;
|
||||
-
|
||||
- link = new(Link, 1);
|
||||
- if (!link)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- *link = (Link) {
|
||||
- .n_ref = 1,
|
||||
- .manager = manager,
|
||||
- .state = LINK_STATE_PENDING,
|
||||
- .ifindex = ifindex,
|
||||
- .iftype = iftype,
|
||||
-
|
||||
- .n_dns = (unsigned) -1,
|
||||
- .dns_default_route = -1,
|
||||
- .llmnr = _RESOLVE_SUPPORT_INVALID,
|
||||
- .mdns = _RESOLVE_SUPPORT_INVALID,
|
||||
- .dnssec_mode = _DNSSEC_MODE_INVALID,
|
||||
- .dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID,
|
||||
- };
|
||||
-
|
||||
- link->ifname = strdup(ifname);
|
||||
- if (!link->ifname)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- if (kind) {
|
||||
- link->kind = strdup(kind);
|
||||
- if (!link->kind)
|
||||
- return -ENOMEM;
|
||||
- }
|
||||
-
|
||||
- r = sd_netlink_message_read_u32(message, IFLA_MASTER, (uint32_t *)&link->master_ifindex);
|
||||
- if (r < 0)
|
||||
- log_link_debug_errno(link, r, "New device has no master, continuing without");
|
||||
-
|
||||
- r = sd_netlink_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
|
||||
- if (r < 0)
|
||||
- log_link_debug_errno(link, r, "MAC address not found for new device, continuing without");
|
||||
-
|
||||
- if (asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex) < 0)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- if (asprintf(&link->lease_file, "/run/systemd/netif/leases/%d", link->ifindex) < 0)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- if (asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d", link->ifindex) < 0)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- r = hashmap_ensure_allocated(&manager->links, NULL);
|
||||
- if (r < 0)
|
||||
- return r;
|
||||
-
|
||||
- r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
|
||||
- if (r < 0)
|
||||
- return r;
|
||||
-
|
||||
- r = link_update_flags(link, message, false);
|
||||
- if (r < 0)
|
||||
- return r;
|
||||
-
|
||||
- *ret = TAKE_PTR(link);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
void link_ntp_settings_clear(Link *link) {
|
||||
link->ntp = strv_free(link->ntp);
|
||||
}
|
||||
@@ -2030,9 +1927,9 @@ static void link_drop_requests(Link *lin
|
||||
request_drop(req);
|
||||
}
|
||||
|
||||
-void link_drop(Link *link) {
|
||||
+Link *link_drop(Link *link) {
|
||||
if (!link)
|
||||
- return;
|
||||
+ return NULL;
|
||||
|
||||
assert(link->manager);
|
||||
|
||||
@@ -2057,7 +1954,7 @@ void link_drop(Link *link) {
|
||||
|
||||
/* The following must be called at last. */
|
||||
assert_se(hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)) == link);
|
||||
- link_unref(link);
|
||||
+ return link_unref(link);
|
||||
}
|
||||
|
||||
static int link_joined(Link *link) {
|
||||
@@ -3295,6 +3192,112 @@ ipv4ll_address_fail:
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+static Link *link_drop_or_unref(Link *link) {
|
||||
+ if (!link)
|
||||
+ return NULL;
|
||||
+ if (!link->manager)
|
||||
+ return link_unref(link);
|
||||
+ return link_drop(link);
|
||||
+}
|
||||
+
|
||||
+DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_drop_or_unref);
|
||||
+
|
||||
+static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
|
||||
+ _cleanup_(link_drop_or_unrefp) Link *link = NULL;
|
||||
+ uint16_t type;
|
||||
+ _cleanup_free_ char *ifname = NULL, *kind = NULL;
|
||||
+ int r, ifindex;
|
||||
+ unsigned short iftype;
|
||||
+
|
||||
+ assert(manager);
|
||||
+ assert(message);
|
||||
+ assert(ret);
|
||||
+
|
||||
+ r = sd_netlink_message_get_type(message, &type);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+ else if (type != RTM_NEWLINK)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+ else if (ifindex <= 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ r = sd_rtnl_message_link_get_type(message, &iftype);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ r = sd_netlink_message_read_string_strdup(message, IFLA_IFNAME, &ifname);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ /* check for link kind */
|
||||
+ r = sd_netlink_message_enter_container(message, IFLA_LINKINFO);
|
||||
+ if (r >= 0) {
|
||||
+ (void) sd_netlink_message_read_string_strdup(message, IFLA_INFO_KIND, &kind);
|
||||
+ r = sd_netlink_message_exit_container(message);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+ }
|
||||
+
|
||||
+ link = new(Link, 1);
|
||||
+ if (!link)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ *link = (Link) {
|
||||
+ .n_ref = 1,
|
||||
+ .state = LINK_STATE_PENDING,
|
||||
+ .ifindex = ifindex,
|
||||
+ .iftype = iftype,
|
||||
+ .ifname = TAKE_PTR(ifname),
|
||||
+ .kind = TAKE_PTR(kind),
|
||||
+
|
||||
+ .n_dns = (unsigned) -1,
|
||||
+ .dns_default_route = -1,
|
||||
+ .llmnr = _RESOLVE_SUPPORT_INVALID,
|
||||
+ .mdns = _RESOLVE_SUPPORT_INVALID,
|
||||
+ .dnssec_mode = _DNSSEC_MODE_INVALID,
|
||||
+ .dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID,
|
||||
+ };
|
||||
+
|
||||
+ r = hashmap_ensure_allocated(&manager->links, NULL);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ link->manager = manager;
|
||||
+
|
||||
+ r = sd_netlink_message_read_u32(message, IFLA_MASTER, (uint32_t*) &link->master_ifindex);
|
||||
+ if (r < 0)
|
||||
+ log_link_debug_errno(link, r, "New device has no master, continuing without");
|
||||
+
|
||||
+ r = sd_netlink_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
|
||||
+ if (r < 0)
|
||||
+ log_link_debug_errno(link, r, "MAC address not found for new device, continuing without");
|
||||
+
|
||||
+ if (asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex) < 0)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ if (asprintf(&link->lease_file, "/run/systemd/netif/leases/%d", link->ifindex) < 0)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ if (asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d", link->ifindex) < 0)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ r = link_update_flags(link, message, false);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ *ret = TAKE_PTR(link);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
int link_add(Manager *m, sd_netlink_message *message, Link **ret) {
|
||||
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
|
||||
|
||||
--- a/src/network/networkd-link.h 2021-09-02 18:04:16.900542857 +0530
|
||||
+++ b/src/network/networkd-link.h 2021-09-02 18:18:56.776571563 +0530
|
||||
@@ -175,7 +175,7 @@ DEFINE_TRIVIAL_DESTRUCTOR(link_netlink_d
|
||||
|
||||
int link_get(Manager *m, int ifindex, Link **ret);
|
||||
int link_add(Manager *manager, sd_netlink_message *message, Link **ret);
|
||||
-void link_drop(Link *link);
|
||||
+Link *link_drop(Link *link);
|
||||
|
||||
int link_down(Link *link, link_netlink_message_handler_t callback);
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
From 63130eb36dc51e4fd50716c585f98ebe456ca7cf Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Mon, 17 May 2021 15:40:15 +0900
|
||||
Subject: [PATCH] network: merge link_drop() and link_detach_from_manager()
|
||||
|
||||
link_detach_from_manager() is only called by link_drop(). It is not
|
||||
necessary to split such tiny function.
|
||||
|
||||
Upstream-Status: Backport [https://github.com/systemd/systemd-stable/commit/63130eb36dc51e4fd50716c585f98ebe456ca7cf]
|
||||
Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
|
||||
|
||||
---
|
||||
src/network/networkd-link.c | 27 ++++++++++++---------------
|
||||
1 file changed, 12 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
|
||||
index 9d30e16b0a..67d01ac44d 100644
|
||||
--- a/src/network/networkd-link.c
|
||||
+++ b/src/network/networkd-link.c
|
||||
@@ -2019,24 +2019,17 @@ static void link_drop_from_master(Link *link, NetDev *netdev) {
|
||||
link_unref(set_remove(master->slaves, link));
|
||||
}
|
||||
|
||||
-static void link_detach_from_manager(Link *link) {
|
||||
- if (!link || !link->manager)
|
||||
- return;
|
||||
-
|
||||
- link_unref(set_remove(link->manager->links_requesting_uuid, link));
|
||||
- link_clean(link);
|
||||
-
|
||||
- /* The following must be called at last. */
|
||||
- assert_se(hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)) == link);
|
||||
- link_unref(link);
|
||||
-}
|
||||
-
|
||||
void link_drop(Link *link) {
|
||||
- if (!link || link->state == LINK_STATE_LINGER)
|
||||
+ if (!link)
|
||||
return;
|
||||
|
||||
+ assert(link->manager);
|
||||
+
|
||||
link_set_state(link, LINK_STATE_LINGER);
|
||||
|
||||
+ /* Drop all references from other links and manager. Note that async netlink calls may have
|
||||
+ * references to the link, and they will be dropped when we receive replies. */
|
||||
+
|
||||
link_free_carrier_maps(link);
|
||||
|
||||
if (link->network) {
|
||||
@@ -2044,10 +2037,14 @@ void link_drop(Link *link) {
|
||||
link_drop_from_master(link, link->network->bond);
|
||||
}
|
||||
|
||||
- log_link_debug(link, "Link removed");
|
||||
+ link_unref(set_remove(link->manager->links_requesting_uuid, link));
|
||||
|
||||
(void) unlink(link->state_file);
|
||||
- link_detach_from_manager(link);
|
||||
+ link_clean(link);
|
||||
+
|
||||
+ /* The following must be called at last. */
|
||||
+ assert_se(hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)) == link);
|
||||
+ link_unref(link);
|
||||
}
|
||||
|
||||
static int link_joined(Link *link) {
|
||||
@@ -22,6 +22,12 @@ SRC_URI += "file://touchscreen.rules \
|
||||
file://0003-implment-systemd-sysv-install-for-OE.patch \
|
||||
file://CVE-2021-33910.patch \
|
||||
file://CVE-2020-13529.patch \
|
||||
file://basic-pass-allocation-info-for-ordered-set-new-and-introd.patch \
|
||||
file://introduce-ordered_set_clear-free-with-destructor.patch \
|
||||
file://network-add-skeleton-of-request-queue.patch \
|
||||
file://network-merge-link_drop-and-link_detach_from_manager.patch \
|
||||
file://network-also-drop-requests-when-link-enters-linger-state.patch \
|
||||
file://network-fix-Link-reference-counter-issue.patch \
|
||||
"
|
||||
|
||||
# patches needed by musl
|
||||
|
||||
Reference in New Issue
Block a user