summaryrefslogtreecommitdiffstats
path: root/src/network/networkd-address.h
blob: fc6f33b0f9c09e5ddcfa8fdd916f95e88d472e69 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once

#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>

#include "conf-parser.h"
#include "firewall-util.h"
#include "hash-funcs.h"
#include "in-addr-util.h"
#include "network-util.h"
#include "networkd-address-generation.h"
#include "networkd-link.h"
#include "networkd-util.h"
#include "time-util.h"

typedef struct Address Address;
typedef struct Manager Manager;
typedef struct Network Network;
typedef struct Request Request;
typedef int (*address_ready_callback_t)(Address *address);
typedef int (*address_netlink_handler_t)(
                sd_netlink *rtnl,
                sd_netlink_message *m,
                Request *req,
                Link *link,
                Address *address);

struct Address {
        Link *link;
        Network *network;
        ConfigSection *section;
        NetworkConfigSource source;
        NetworkConfigState state;
        union in_addr_union provider; /* DHCP server or router address */

        unsigned n_ref;

        int family;
        unsigned char prefixlen;
        unsigned char scope;
        uint32_t flags;
        uint32_t route_metric; /* route metric for prefix route */
        char *label, *netlabel;

        int set_broadcast;
        struct in_addr broadcast;

        union in_addr_union in_addr;
        union in_addr_union in_addr_peer;

        /* These are absolute points in time, and NOT timespans/durations.
         * Must be specified with clock_boottime_or_monotonic(). */
        usec_t lifetime_valid_usec;
        usec_t lifetime_preferred_usec;

        bool scope_set:1;
        bool ip_masquerade_done:1;
        bool requested_as_null:1;
        bool used_by_dhcp_server:1;

        /* duplicate_address_detection is only used by static or IPv4 dynamic addresses.
         * To control DAD for IPv6 dynamic addresses, set IFA_F_NODAD to flags. */
        AddressFamily duplicate_address_detection;

        /* Used by address generator. */
        IPv6Token *token;

        /* Called when address become ready */
        address_ready_callback_t callback;

        NFTSetContext nft_set_context;
};

void log_address_debug(const Address *address, const char *str, const Link *link);

const char* format_lifetime(char *buf, size_t l, usec_t lifetime_usec) _warn_unused_result_;
/* Note: the lifetime of the compound literal is the immediately surrounding block,
 * see C11 §6.5.2.5, and
 * https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks */
#define FORMAT_LIFETIME(lifetime) \
        format_lifetime((char[FORMAT_TIMESPAN_MAX+STRLEN("for ")]){}, FORMAT_TIMESPAN_MAX+STRLEN("for "), lifetime)

int address_flags_to_string_alloc(uint32_t flags, int family, char **ret);

void link_get_address_states(
                Link *link,
                LinkAddressState *ret_ipv4,
                LinkAddressState *ret_ipv6,
                LinkAddressState *ret_all);

void address_hash_func(const Address *a, struct siphash *state);
int address_compare_func(const Address *a1, const Address *a2);
extern const struct hash_ops address_hash_ops;

bool address_can_update(const Address *existing, const Address *requesting);

Address* address_ref(Address *address);
Address* address_unref(Address *address);

int address_new(Address **ret);
int address_new_static(Network *network, const char *filename, unsigned section_line, Address **ret);
int address_get(Link *link, const Address *in, Address **ret);
int address_get_harder(Link *link, const Address *in, Address **ret);
int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);
int address_remove(Address *address, Link *link);
int address_remove_and_cancel(Address *address, Link *link);
int address_dup(const Address *src, Address **ret);
bool address_is_ready(const Address *a);
bool link_check_addresses_ready(Link *link, NetworkConfigSource source);

DEFINE_SECTION_CLEANUP_FUNCTIONS(Address, address_unref);

int link_drop_static_addresses(Link *link);
int link_drop_foreign_addresses(Link *link);
int link_drop_ipv6ll_addresses(Link *link);
void link_foreignize_addresses(Link *link);
bool link_address_is_dynamic(const Link *link, const Address *address);

int link_get_address_full(
                Link *link,
                int family,
                const union in_addr_union *address,
                const union in_addr_union *peer, /* optional, can be NULL */
                unsigned char prefixlen,         /* optional, can be 0 */
                Address **ret);
static inline int link_get_address(Link *link, int family, const union in_addr_union *address, Address **ret) {
        return link_get_address_full(link, family, address, NULL, 0, ret);
}
static inline int link_get_ipv6_address(Link *link, const struct in6_addr *address, Address **ret) {
        assert(address);
        return link_get_address(link, AF_INET6, &(union in_addr_union) { .in6 = *address }, ret);
}
int manager_get_address_full(
                Manager *manager,
                int family,
                const union in_addr_union *address,
                const union in_addr_union *peer,
                unsigned char prefixlen,
                Address **ret);
static inline int manager_get_address(Manager *manager, int family, const union in_addr_union *address, Address **ret) {
        return manager_get_address_full(manager, family, address, NULL, 0, ret);
}

int link_request_address(
                Link *link,
                const Address *address,
                unsigned *message_counter,
                address_netlink_handler_t netlink_handler,
                Request **ret);
int link_request_static_address(Link *link, const Address *address);
int link_request_static_addresses(Link *link);

int manager_rtnl_process_address(sd_netlink *nl, sd_netlink_message *message, Manager *m);

int address_section_verify(Address *address);
int network_drop_invalid_addresses(Network *network);

DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(Address, address);

void link_mark_addresses(Link *link, NetworkConfigSource source);

typedef enum AddressConfParserType {
        ADDRESS_ADDRESS,
        ADDRESS_PEER,
        ADDRESS_BROADCAST,
        ADDRESS_LABEL,
        ADDRESS_PREFERRED_LIFETIME,
        ADDRESS_HOME_ADDRESS,
        ADDRESS_MANAGE_TEMPORARY_ADDRESS,
        ADDRESS_PREFIX_ROUTE,
        ADDRESS_ADD_PREFIX_ROUTE,
        ADDRESS_AUTO_JOIN,
        ADDRESS_DAD,
        ADDRESS_SCOPE,
        ADDRESS_ROUTE_METRIC,
        ADDRESS_NET_LABEL,
        ADDRESS_NFT_SET,
        _ADDRESS_CONF_PARSER_MAX,
        _ADDRESS_CONF_PARSER_INVALID = -EINVAL,
} AddressConfParserType;

CONFIG_PARSER_PROTOTYPE(config_parse_address_section);