summaryrefslogtreecommitdiff
path: root/src/libsystemd-network/radv-internal.h
blob: ef566ed8ec2fa65dac9d1655dd1753c75e1e302f (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
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once

/***
  Copyright © 2017 Intel Corporation. All rights reserved.
***/

#include "sd-radv.h"

#include "list.h"
#include "network-common.h"
#include "sparse-endian.h"

assert_cc(SD_RADV_DEFAULT_MIN_TIMEOUT_USEC <= SD_RADV_DEFAULT_MAX_TIMEOUT_USEC);

#define SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC (16*USEC_PER_SEC)
#define SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS  3
#define SD_RADV_MAX_FINAL_RTR_ADVERTISEMENTS    3
#define SD_RADV_MIN_DELAY_BETWEEN_RAS           3
#define SD_RADV_MAX_RA_DELAY_TIME_USEC          (500*USEC_PER_MSEC)

#define SD_RADV_OPT_ROUTE_INFORMATION           24
#define SD_RADV_OPT_RDNSS                       25
#define SD_RADV_OPT_DNSSL                       31

enum RAdvState {
        SD_RADV_STATE_IDLE                      = 0,
        SD_RADV_STATE_ADVERTISING               = 1,
};
typedef enum RAdvState RAdvState;

struct sd_radv_opt_dns {
        uint8_t type;
        uint8_t length;
        uint16_t reserved;
        be32_t lifetime;
} _packed_;

struct sd_radv {
        unsigned n_ref;
        RAdvState state;

        int ifindex;
        char *ifname;

        sd_event *event;
        int event_priority;

        struct ether_addr mac_addr;
        uint8_t hop_limit;
        uint8_t flags;
        uint32_t mtu;
        uint16_t lifetime;

        int fd;
        unsigned ra_sent;
        sd_event_source *recv_event_source;
        sd_event_source *timeout_event_source;

        unsigned n_prefixes;
        LIST_HEAD(sd_radv_prefix, prefixes);

        unsigned n_route_prefixes;
        LIST_HEAD(sd_radv_route_prefix, route_prefixes);

        size_t n_rdnss;
        struct sd_radv_opt_dns *rdnss;
        struct sd_radv_opt_dns *dnssl;
};

#define radv_prefix_opt__contents {             \
        uint8_t type;                           \
        uint8_t length;                         \
        uint8_t prefixlen;                      \
        uint8_t flags;                          \
        be32_t valid_lifetime;                  \
        be32_t preferred_lifetime;              \
        uint32_t reserved;                      \
        struct in6_addr in6_addr;               \
}

struct radv_prefix_opt radv_prefix_opt__contents;

/* We need the opt substructure to be packed, because we use it in send(). But
 * if we use _packed_, this means that the structure cannot be used directly in
 * normal code in general, because the fields might not be properly aligned.
 * But in this particular case, the structure is defined in a way that gives
 * proper alignment, even without the explicit _packed_ attribute. To appease
 * the compiler we use the "unpacked" structure, but we also verify that
 * structure contains no holes, so offsets are the same when _packed_ is used.
 */
struct radv_prefix_opt__packed radv_prefix_opt__contents _packed_;
assert_cc(sizeof(struct radv_prefix_opt) == sizeof(struct radv_prefix_opt__packed));

struct sd_radv_prefix {
        unsigned n_ref;

        struct radv_prefix_opt opt;

        LIST_FIELDS(struct sd_radv_prefix, prefix);

        usec_t valid_until;
        usec_t preferred_until;
};

#define radv_route_prefix_opt__contents {       \
        uint8_t type;                           \
        uint8_t length;                         \
        uint8_t prefixlen;                      \
        uint8_t flags_reserved;                 \
        be32_t  lifetime;                       \
        struct in6_addr in6_addr;               \
}

struct radv_route_prefix_opt radv_route_prefix_opt__contents;

struct radv_route_prefix_opt__packed radv_route_prefix_opt__contents _packed_;
assert_cc(sizeof(struct radv_route_prefix_opt) == sizeof(struct radv_route_prefix_opt__packed));

struct sd_radv_route_prefix {
        unsigned n_ref;

        struct radv_route_prefix_opt opt;

        LIST_FIELDS(struct sd_radv_route_prefix, prefix);
};

#define log_radv_errno(radv, error, fmt, ...)           \
        log_interface_prefix_full_errno(                \
                "RADV: ",                               \
                sd_radv, radv,                          \
                error, fmt, ##__VA_ARGS__)
#define log_radv(radv, fmt, ...)                        \
        log_interface_prefix_full_errno_zerook(         \
                "RADV: ",                               \
                sd_radv, radv,                          \
                0, fmt, ##__VA_ARGS__)