]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/sd-network/network-util.c
30b3d041408328b785cd369c3edcdd5b648642a8
[thirdparty/systemd.git] / src / libsystemd / sd-network / network-util.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "sd-network.h"
4
5 #include "alloc-util.h"
6 #include "network-util.h"
7 #include "string-table.h"
8 #include "string-util.h"
9 #include "strv.h"
10
11 bool network_is_online(void) {
12 _cleanup_free_ char *online_state = NULL;
13 LinkOnlineState state;
14 int r;
15
16 r = sd_network_get_online_state(&online_state);
17 if (r < 0)
18 state = _LINK_ONLINE_STATE_INVALID;
19 else
20 state = link_online_state_from_string(online_state);
21
22 if (state >= LINK_ONLINE_STATE_PARTIAL)
23 return true;
24 else if (state < 0) {
25 _cleanup_free_ char *carrier_state = NULL, *addr_state = NULL;
26
27 r = sd_network_get_carrier_state(&carrier_state);
28 if (r < 0) /* if we don't know anything, we consider the system online */
29 return true;
30
31 r = sd_network_get_address_state(&addr_state);
32 if (r < 0) /* if we don't know anything, we consider the system online */
33 return true;
34
35 /* we don't know the online state for certain, so make an educated guess */
36 if (STR_IN_SET(carrier_state, "degraded-carrier", "carrier") &&
37 STR_IN_SET(addr_state, "routable", "degraded"))
38 return true;
39 }
40
41 return false;
42 }
43
44 static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
45 [LINK_OPERSTATE_MISSING] = "missing",
46 [LINK_OPERSTATE_OFF] = "off",
47 [LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
48 [LINK_OPERSTATE_DORMANT] = "dormant",
49 [LINK_OPERSTATE_DEGRADED_CARRIER] = "degraded-carrier",
50 [LINK_OPERSTATE_CARRIER] = "carrier",
51 [LINK_OPERSTATE_DEGRADED] = "degraded",
52 [LINK_OPERSTATE_ENSLAVED] = "enslaved",
53 [LINK_OPERSTATE_ROUTABLE] = "routable",
54 };
55
56 DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);
57
58 static const char* const link_carrier_state_table[_LINK_CARRIER_STATE_MAX] = {
59 [LINK_CARRIER_STATE_OFF] = "off",
60 [LINK_CARRIER_STATE_NO_CARRIER] = "no-carrier",
61 [LINK_CARRIER_STATE_DORMANT] = "dormant",
62 [LINK_CARRIER_STATE_DEGRADED_CARRIER] = "degraded-carrier",
63 [LINK_CARRIER_STATE_CARRIER] = "carrier",
64 [LINK_CARRIER_STATE_ENSLAVED] = "enslaved",
65 };
66
67 DEFINE_STRING_TABLE_LOOKUP(link_carrier_state, LinkCarrierState);
68
69 static const char* const link_required_address_family_table[_ADDRESS_FAMILY_MAX] = {
70 [ADDRESS_FAMILY_NO] = "any",
71 [ADDRESS_FAMILY_IPV4] = "ipv4",
72 [ADDRESS_FAMILY_IPV6] = "ipv6",
73 [ADDRESS_FAMILY_YES] = "both",
74 };
75
76 DEFINE_STRING_TABLE_LOOKUP(link_required_address_family, AddressFamily);
77
78 static const char* const link_address_state_table[_LINK_ADDRESS_STATE_MAX] = {
79 [LINK_ADDRESS_STATE_OFF] = "off",
80 [LINK_ADDRESS_STATE_DEGRADED] = "degraded",
81 [LINK_ADDRESS_STATE_ROUTABLE] = "routable",
82 };
83
84 DEFINE_STRING_TABLE_LOOKUP(link_address_state, LinkAddressState);
85
86 static const char *const link_online_state_table[_LINK_ONLINE_STATE_MAX] = {
87 [LINK_ONLINE_STATE_OFFLINE] = "offline",
88 [LINK_ONLINE_STATE_PARTIAL] = "partial",
89 [LINK_ONLINE_STATE_ONLINE] = "online",
90 };
91
92 DEFINE_STRING_TABLE_LOOKUP(link_online_state, LinkOnlineState);
93
94 int parse_operational_state_range(const char *s, LinkOperationalStateRange *ret) {
95 LinkOperationalStateRange range = LINK_OPERSTATE_RANGE_INVALID;
96 _cleanup_free_ char *buf = NULL;
97 const char *p;
98
99 assert(s);
100 assert(ret);
101
102 /* allowed formats: "min", "min:", "min:max", ":max" */
103
104 if (isempty(s) || streq(s, ":"))
105 return -EINVAL;
106
107 p = strchr(s, ':');
108 if (!p || isempty(p + 1))
109 range.max = LINK_OPERSTATE_ROUTABLE;
110 else {
111 range.max = link_operstate_from_string(p + 1);
112 if (range.max < 0)
113 return -EINVAL;
114 }
115
116 if (p) {
117 buf = strndup(s, p - s);
118 if (!buf)
119 return -ENOMEM;
120
121 s = buf;
122 }
123
124 if (isempty(s))
125 range.min = LINK_OPERSTATE_MISSING;
126 else {
127 range.min = link_operstate_from_string(s);
128 if (range.min < 0)
129 return -EINVAL;
130 }
131
132 if (!operational_state_range_is_valid(&range))
133 return -EINVAL;
134
135 *ret = range;
136 return 0;
137 }
138
139 int network_link_get_operational_state(int ifindex, LinkOperationalState *ret) {
140 _cleanup_free_ char *str = NULL;
141 LinkOperationalState s;
142 int r;
143
144 assert(ifindex > 0);
145 assert(ret);
146
147 r = sd_network_link_get_operational_state(ifindex, &str);
148 if (r < 0)
149 return r;
150
151 s = link_operstate_from_string(str);
152 if (s < 0)
153 return s;
154
155 *ret = s;
156 return 0;
157 }