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