1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include "network-util.h"
5 #include "networkd-forward.h"
8 typedef enum NetworkConfigSource
{
9 NETWORK_CONFIG_SOURCE_FOREIGN
, /* configured by kernel */
10 NETWORK_CONFIG_SOURCE_STATIC
,
11 NETWORK_CONFIG_SOURCE_IPV4LL
,
12 NETWORK_CONFIG_SOURCE_DHCP4
,
13 NETWORK_CONFIG_SOURCE_DHCP6
,
14 NETWORK_CONFIG_SOURCE_DHCP_PD
,
15 NETWORK_CONFIG_SOURCE_NDISC
,
16 NETWORK_CONFIG_SOURCE_RUNTIME
, /* through D-Bus method */
17 _NETWORK_CONFIG_SOURCE_MAX
,
18 _NETWORK_CONFIG_SOURCE_INVALID
= -EINVAL
,
19 } NetworkConfigSource
;
21 typedef enum NetworkConfigState
{
22 NETWORK_CONFIG_STATE_REQUESTING
= 1 << 0, /* request is queued */
23 NETWORK_CONFIG_STATE_CONFIGURING
= 1 << 1, /* e.g. address_configure() is called, but no response is received yet */
24 NETWORK_CONFIG_STATE_CONFIGURED
= 1 << 2, /* e.g. address_configure() is called and received a response from kernel.
25 * Note that address may not be ready yet, so please use address_is_ready()
26 * to check whether the address can be usable or not. */
27 NETWORK_CONFIG_STATE_MARKED
= 1 << 3, /* used GC'ing the old config */
28 NETWORK_CONFIG_STATE_REMOVING
= 1 << 4, /* e.g. address_remove() is called, but no response is received yet */
31 static inline usec_t
sec_to_usec(uint32_t sec
, usec_t timestamp_usec
) {
34 sec
== UINT32_MAX
? USEC_INFINITY
:
35 usec_add(timestamp_usec
, sec
* USEC_PER_SEC
);
38 static inline usec_t
sec16_to_usec(uint16_t sec
, usec_t timestamp_usec
) {
39 return sec_to_usec(sec
== UINT16_MAX
? UINT32_MAX
: (uint32_t) sec
, timestamp_usec
);
42 static inline uint32_t usec_to_sec(usec_t usec
, usec_t now_usec
) {
43 return MIN(DIV_ROUND_UP(usec_sub_unsigned(usec
, now_usec
), USEC_PER_SEC
), UINT32_MAX
);
46 CONFIG_PARSER_PROTOTYPE(config_parse_link_local_address_family
);
47 CONFIG_PARSER_PROTOTYPE(config_parse_ip_masquerade
);
48 CONFIG_PARSER_PROTOTYPE(config_parse_mud_url
);
50 const char* network_config_source_to_string(NetworkConfigSource s
) _const_
;
51 NetworkConfigSource
network_config_source_from_string(const char* s
) _pure_
;
53 int network_config_state_to_string_alloc(NetworkConfigState s
, char **ret
);
55 #define DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(type, name) \
56 static inline void name##_update_state( \
58 NetworkConfigState mask, \
59 NetworkConfigState value) { \
63 t->state = (t->state & ~mask) | (value & mask); \
65 static inline bool name##_exists(const type *t) { \
68 if ((t->state & (NETWORK_CONFIG_STATE_CONFIGURING | \
69 NETWORK_CONFIG_STATE_CONFIGURED)) == 0) \
70 return false; /* Not assigned yet. */ \
71 if (FLAGS_SET(t->state, NETWORK_CONFIG_STATE_REMOVING)) \
72 return false; /* Already removing. */ \
75 static inline void name##_enter_requesting(type *t) { \
76 name##_update_state(t, \
77 NETWORK_CONFIG_STATE_REQUESTING, \
78 NETWORK_CONFIG_STATE_REQUESTING); \
80 static inline void name##_cancel_requesting(type *t) { \
81 name##_update_state(t, \
82 NETWORK_CONFIG_STATE_REQUESTING, \
85 static inline bool name##_is_requesting(const type *t) { \
87 return FLAGS_SET(t->state, NETWORK_CONFIG_STATE_REQUESTING); \
89 static inline void name##_enter_configuring(type *t) { \
90 name##_update_state(t, \
91 NETWORK_CONFIG_STATE_REQUESTING | \
92 NETWORK_CONFIG_STATE_CONFIGURING | \
93 NETWORK_CONFIG_STATE_REMOVING, \
94 NETWORK_CONFIG_STATE_CONFIGURING); \
96 static inline void name##_enter_configured(type *t) { \
97 name##_update_state(t, \
98 NETWORK_CONFIG_STATE_CONFIGURING | \
99 NETWORK_CONFIG_STATE_CONFIGURED, \
100 NETWORK_CONFIG_STATE_CONFIGURED); \
102 static inline void name##_mark(type *t) { \
103 name##_update_state(t, \
104 NETWORK_CONFIG_STATE_MARKED, \
105 NETWORK_CONFIG_STATE_MARKED); \
107 static inline void name##_unmark(type *t) { \
108 name##_update_state(t, NETWORK_CONFIG_STATE_MARKED, 0); \
110 static inline bool name##_is_marked(const type *t) { \
112 return FLAGS_SET(t->state, NETWORK_CONFIG_STATE_MARKED); \
114 static inline void name##_enter_removing(type *t) { \
115 name##_update_state(t, \
116 NETWORK_CONFIG_STATE_MARKED | \
117 NETWORK_CONFIG_STATE_REMOVING, \
118 NETWORK_CONFIG_STATE_REMOVING); \
120 static inline void name##_enter_removed(type *t) { \
121 name##_update_state(t, \
122 NETWORK_CONFIG_STATE_CONFIGURED | \
123 NETWORK_CONFIG_STATE_REMOVING, \
127 const char* address_family_to_string(AddressFamily b
) _const_
;
128 AddressFamily
address_family_from_string(const char *s
) _pure_
;
130 AddressFamily
link_local_address_family_from_string(const char *s
) _pure_
;
132 const char* routing_policy_rule_address_family_to_string(AddressFamily b
) _const_
;
133 AddressFamily
routing_policy_rule_address_family_from_string(const char *s
) _pure_
;
135 const char* nexthop_address_family_to_string(AddressFamily b
) _const_
;
136 AddressFamily
nexthop_address_family_from_string(const char *s
) _pure_
;
138 const char* duplicate_address_detection_address_family_to_string(AddressFamily b
) _const_
;
139 AddressFamily
duplicate_address_detection_address_family_from_string(const char *s
) _pure_
;
141 AddressFamily
dhcp_deprecated_address_family_from_string(const char *s
) _pure_
;
143 const char* dhcp_lease_server_type_to_string(sd_dhcp_lease_server_type_t t
) _const_
;
144 sd_dhcp_lease_server_type_t
dhcp_lease_server_type_from_string(const char *s
) _pure_
;
146 bool link_should_mark_config(Link
*link
, bool only_static
, NetworkConfigSource source
, uint8_t protocol
);
148 #define _log_link_message_full_errno(link, link_u, message, error_msg, length, level, level_u, error, error_u, format, ...) \
150 Link *link_u = (link); \
151 int level_u = (level); \
152 int error_u = (error); \
155 const char *error_msg = NULL; \
157 length = sd_netlink_message_read_string(message, NLMSGERR_ATTR_MSG, &error_msg); \
159 error_msg && length > 0 ? \
160 log_link_full_errno(link_u, level_u, error_u, format ": %s%s %m", ##__VA_ARGS__, \
161 error_msg, error_msg[length - 1] == '.' ? "" : ".") : \
162 log_link_full_errno(link_u, level_u, error_u, format ": %m", ##__VA_ARGS__); \
166 #define log_link_message_full_errno(link, message, level, error, format, ...) \
167 _log_link_message_full_errno(link, UNIQ_T(lnk, UNIQ), message, UNIQ_T(emsg, UNIQ), UNIQ_T(len, UNIQ), level, UNIQ_T(lvl, UNIQ), error, UNIQ_T(err, UNIQ), format, ##__VA_ARGS__)
169 #define log_link_message_error_errno(link, m, err, fmt, ...) log_link_message_full_errno(link, m, LOG_ERR, err, fmt, ##__VA_ARGS__)
170 #define log_link_message_warning_errno(link, m, err, fmt, ...) log_link_message_full_errno(link, m, LOG_WARNING, err, fmt, ##__VA_ARGS__)
171 #define log_link_message_notice_errno(link, m, err, fmt, ...) log_link_message_full_errno(link, m, LOG_NOTICE, err, fmt, ##__VA_ARGS__)
172 #define log_link_message_info_errno(link, m, err, fmt, ...) log_link_message_full_errno(link, m, LOG_INFO, err, fmt, ##__VA_ARGS__)
173 #define log_link_message_debug_errno(link, m, err, fmt, ...) log_link_message_full_errno(link, m, LOG_DEBUG, err, fmt, ##__VA_ARGS__)
174 #define log_message_full_errno(m, level, err, fmt, ...) log_link_message_full_errno(NULL, m, level, err, fmt, ##__VA_ARGS__)
175 #define log_message_error_errno(m, err, fmt, ...) log_message_full_errno(m, LOG_ERR, err, fmt, ##__VA_ARGS__)
176 #define log_message_warning_errno(m, err, fmt, ...) log_message_full_errno(m, LOG_WARNING, err, fmt, ##__VA_ARGS__)
177 #define log_message_notice_errno(m, err, fmt, ...) log_message_full_errno(m, LOG_NOTICE, err, fmt, ##__VA_ARGS__)
178 #define log_message_info_errno(m, err, fmt, ...) log_message_full_errno(m, LOG_INFO, err, fmt, ##__VA_ARGS__)
179 #define log_message_debug_errno(m, err, fmt, ...) log_message_full_errno(m, LOG_DEBUG, err, fmt, ##__VA_ARGS__)