]> git.proxmox.com Git - systemd.git/blob - src/network/wait-online/link.c
New upstream version 242
[systemd.git] / src / network / wait-online / link.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include "sd-network.h"
4
5 #include "alloc-util.h"
6 #include "hashmap.h"
7 #include "link.h"
8 #include "manager.h"
9 #include "string-util.h"
10
11 int link_new(Manager *m, Link **ret, int ifindex, const char *ifname) {
12 _cleanup_(link_freep) Link *l = NULL;
13 _cleanup_free_ char *n = NULL;
14 int r;
15
16 assert(m);
17 assert(ifindex > 0);
18
19 r = hashmap_ensure_allocated(&m->links, NULL);
20 if (r < 0)
21 return r;
22
23 r = hashmap_ensure_allocated(&m->links_by_name, &string_hash_ops);
24 if (r < 0)
25 return r;
26
27 n = strdup(ifname);
28 if (!n)
29 return -ENOMEM;
30
31 l = new(Link, 1);
32 if (!l)
33 return -ENOMEM;
34
35 *l = (Link) {
36 .manager = m,
37 .ifname = TAKE_PTR(n),
38 .ifindex = ifindex,
39 .required_operstate = LINK_OPERSTATE_DEGRADED,
40 };
41
42 r = hashmap_put(m->links_by_name, l->ifname, l);
43 if (r < 0)
44 return r;
45
46 r = hashmap_put(m->links, INT_TO_PTR(ifindex), l);
47 if (r < 0)
48 return r;
49
50 if (ret)
51 *ret = l;
52
53 TAKE_PTR(l);
54 return 0;
55 }
56
57 Link *link_free(Link *l) {
58
59 if (!l)
60 return NULL;
61
62 if (l->manager) {
63 hashmap_remove(l->manager->links, INT_TO_PTR(l->ifindex));
64 hashmap_remove(l->manager->links_by_name, l->ifname);
65 }
66
67 free(l->state);
68 free(l->ifname);
69 return mfree(l);
70 }
71
72 int link_update_rtnl(Link *l, sd_netlink_message *m) {
73 const char *ifname;
74 int r;
75
76 assert(l);
77 assert(l->manager);
78 assert(m);
79
80 r = sd_rtnl_message_link_get_flags(m, &l->flags);
81 if (r < 0)
82 return r;
83
84 r = sd_netlink_message_read_string(m, IFLA_IFNAME, &ifname);
85 if (r < 0)
86 return r;
87
88 if (!streq(l->ifname, ifname)) {
89 char *new_ifname;
90
91 new_ifname = strdup(ifname);
92 if (!new_ifname)
93 return -ENOMEM;
94
95 assert_se(hashmap_remove(l->manager->links_by_name, l->ifname) == l);
96 free_and_replace(l->ifname, new_ifname);
97
98 r = hashmap_put(l->manager->links_by_name, l->ifname, l);
99 if (r < 0)
100 return r;
101 }
102
103 return 0;
104 }
105
106 int link_update_monitor(Link *l) {
107 _cleanup_free_ char *operstate = NULL, *required_operstate = NULL, *state = NULL;
108 LinkOperationalState s;
109 int r, ret = 0;
110
111 assert(l);
112 assert(l->ifname);
113
114 r = sd_network_link_get_required_for_online(l->ifindex);
115 if (r < 0)
116 ret = log_link_debug_errno(l, r, "Failed to determine whether the link is required for online or not, "
117 "ignoring: %m");
118 else
119 l->required_for_online = r > 0;
120
121 r = sd_network_link_get_required_operstate_for_online(l->ifindex, &required_operstate);
122 if (r < 0)
123 ret = log_link_debug_errno(l, r, "Failed to get required operational state, ignoring: %m");
124 else {
125 s = link_operstate_from_string(required_operstate);
126 if (s < 0)
127 ret = log_link_debug_errno(l, SYNTHETIC_ERRNO(EINVAL),
128 "Failed to parse required operational state, ignoring: %m");
129 else
130 l->required_operstate = s;
131 }
132
133 r = sd_network_link_get_operational_state(l->ifindex, &operstate);
134 if (r < 0)
135 ret = log_link_debug_errno(l, r, "Failed to get operational state, ignoring: %m");
136 else {
137 s = link_operstate_from_string(operstate);
138 if (s < 0)
139 ret = log_link_debug_errno(l, SYNTHETIC_ERRNO(EINVAL),
140 "Failed to parse operational state, ignoring: %m");
141 else
142 l->operational_state = s;
143 }
144
145 r = sd_network_link_get_setup_state(l->ifindex, &state);
146 if (r < 0)
147 ret = log_link_debug_errno(l, r, "Failed to get setup state, ignoring: %m");
148 else
149 free_and_replace(l->state, state);
150
151 return ret;
152 }