]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
04473969 PF |
2 | #pragma once |
3 | ||
4 | /*** | |
810adae9 | 5 | Copyright © 2017 Intel Corporation. All rights reserved. |
04473969 PF |
6 | ***/ |
7 | ||
6a6d27bc SS |
8 | #include <netinet/icmp6.h> |
9 | ||
04473969 PF |
10 | #include "sd-radv.h" |
11 | ||
04473969 | 12 | #include "list.h" |
6e8f5e4c | 13 | #include "ndisc-protocol.h" |
5977b71f | 14 | #include "network-common.h" |
04473969 | 15 | #include "sparse-endian.h" |
7003b114 | 16 | #include "time-util.h" |
04473969 | 17 | |
e786c2e5 YW |
18 | /* RFC 4861 section 6.2.1. |
19 | * MaxRtrAdvInterval | |
20 | * The maximum time allowed between sending unsolicited multicast Router Advertisements from the | |
21 | * interface, in seconds. MUST be no less than 4 seconds and no greater than 1800 seconds. | |
22 | * Default: 600 seconds */ | |
80477557 YW |
23 | #define RADV_MIN_MAX_TIMEOUT_USEC (4 * USEC_PER_SEC) |
24 | #define RADV_MAX_MAX_TIMEOUT_USEC (1800 * USEC_PER_SEC) | |
03ec10fd | 25 | #define RADV_DEFAULT_MAX_TIMEOUT_USEC (600 * USEC_PER_SEC) |
e786c2e5 YW |
26 | /* RFC 4861 section 6.2.1. |
27 | * MinRtrAdvInterval | |
28 | * The minimum time allowed between sending unsolicited multicast Router Advertisements from the | |
29 | * interface, in seconds. MUST be no less than 3 seconds and no greater than .75 * MaxRtrAdvInterval. | |
30 | * Default: 0.33 * MaxRtrAdvInterval If MaxRtrAdvInterval >= 9 seconds; otherwise, the Default is | |
31 | * MaxRtrAdvInterval (Note, this should be a typo. We use 0.75 * MaxRtrAdvInterval). */ | |
80477557 | 32 | #define RADV_MIN_MIN_TIMEOUT_USEC (3 * USEC_PER_SEC) |
72db0a71 YW |
33 | /* RFC 4861 section 6.2.4. |
34 | * AdvDefaultLifetime | |
35 | * The value to be placed in the Router Lifetime field of Router Advertisements sent from the interface, | |
36 | * in seconds. MUST be either zero or between MaxRtrAdvInterval and 9000 seconds. A value of zero | |
37 | * indicates that the router is not to be used as a default router. These limits may be overridden by | |
38 | * specific documents that describe how IPv6 operates over different link layers. For instance, in a | |
39 | * point-to-point link the peers may have enough information about the number and status of devices at | |
40 | * the other end so that advertisements are needed less frequently. | |
41 | * Default: 3 * MaxRtrAdvInterval */ | |
80477557 | 42 | #define RADV_MIN_ROUTER_LIFETIME_USEC RADV_MIN_MAX_TIMEOUT_USEC |
09457670 | 43 | #define RADV_MAX_ROUTER_LIFETIME_USEC (9000 * USEC_PER_SEC) |
72db0a71 | 44 | #define RADV_DEFAULT_ROUTER_LIFETIME_USEC (3 * RADV_DEFAULT_MAX_TIMEOUT_USEC) |
d951507d YW |
45 | /* draft-ietf-6man-slaac-renum-02 section 4.1.1. |
46 | * AdvPreferredLifetime: max(AdvDefaultLifetime, 3 * MaxRtrAdvInterval) | |
47 | * AdvValidLifetime: 2 * AdvPreferredLifetime */ | |
48 | #define RADV_DEFAULT_PREFERRED_LIFETIME_USEC CONST_MAX(RADV_DEFAULT_ROUTER_LIFETIME_USEC, 3 * RADV_DEFAULT_MAX_TIMEOUT_USEC) | |
49 | #define RADV_DEFAULT_VALID_LIFETIME_USEC (2 * RADV_DEFAULT_PREFERRED_LIFETIME_USEC) | |
e786c2e5 YW |
50 | /* RFC 4861 section 10. |
51 | * MAX_INITIAL_RTR_ADVERT_INTERVAL 16 seconds | |
52 | * MAX_INITIAL_RTR_ADVERTISEMENTS 3 transmissions | |
53 | * MAX_FINAL_RTR_ADVERTISEMENTS 3 transmissions | |
54 | * MIN_DELAY_BETWEEN_RAS 3 seconds | |
55 | * MAX_RA_DELAY_TIME .5 seconds */ | |
d6fc0d67 YW |
56 | #define RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC (16 * USEC_PER_SEC) |
57 | #define RADV_MAX_INITIAL_RTR_ADVERTISEMENTS 3 | |
58 | #define RADV_MAX_FINAL_RTR_ADVERTISEMENTS 3 | |
59 | #define RADV_MIN_DELAY_BETWEEN_RAS 3 | |
60 | #define RADV_MAX_RA_DELAY_TIME_USEC (500 * USEC_PER_MSEC) | |
1925f829 SS |
61 | /* From RFC 8781 section 4.1 |
62 | * By default, the value of the Scaled Lifetime field SHOULD be set to the lesser of 3 x MaxRtrAdvInterval */ | |
63 | #define RADV_DEFAULT_PRE64_LIFETIME_USEC (3 * RADV_DEFAULT_MAX_TIMEOUT_USEC) | |
204fb681 | 64 | |
d6fc0d67 YW |
65 | #define RADV_OPT_ROUTE_INFORMATION 24 |
66 | #define RADV_OPT_RDNSS 25 | |
67 | #define RADV_OPT_DNSSL 31 | |
1925f829 SS |
68 | /* Pref64 option type (RFC8781, section 4) */ |
69 | #define RADV_OPT_PREF64 38 | |
e9c6da38 | 70 | |
6a6d27bc SS |
71 | /* rfc6275 7.4 Neighbor Discovery Home Agent Lifetime. |
72 | * The default value is the same as the Router Lifetime | |
73 | * The maximum value corresponds to 18.2 hours. value of 0 MUST NOT be used.*/ | |
74 | #define RADV_MAX_HOME_AGENT_LIFETIME_USEC (65535 * USEC_PER_SEC) | |
75 | ||
204f99d2 | 76 | enum RAdvState { |
d6fc0d67 YW |
77 | RADV_STATE_IDLE = 0, |
78 | RADV_STATE_ADVERTISING = 1, | |
204f99d2 PF |
79 | }; |
80 | typedef enum RAdvState RAdvState; | |
81 | ||
e9c6da38 PF |
82 | struct sd_radv_opt_dns { |
83 | uint8_t type; | |
84 | uint8_t length; | |
85 | uint16_t reserved; | |
86 | be32_t lifetime; | |
87 | } _packed_; | |
88 | ||
204f99d2 PF |
89 | struct sd_radv { |
90 | unsigned n_ref; | |
91 | RAdvState state; | |
92 | ||
93 | int ifindex; | |
61a9fa8f | 94 | char *ifname; |
204f99d2 PF |
95 | |
96 | sd_event *event; | |
97 | int event_priority; | |
98 | ||
99 | struct ether_addr mac_addr; | |
100 | uint8_t hop_limit; | |
101 | uint8_t flags; | |
102 | uint32_t mtu; | |
fdc4c67c | 103 | uint32_t retransmit_msec; |
7003b114 | 104 | usec_t lifetime_usec; /* timespan */ |
204f99d2 | 105 | |
77baf5ae | 106 | int fd; |
204fb681 | 107 | unsigned ra_sent; |
88d5a3db | 108 | sd_event_source *recv_event_source; |
204fb681 PF |
109 | sd_event_source *timeout_event_source; |
110 | ||
204f99d2 PF |
111 | unsigned n_prefixes; |
112 | LIST_HEAD(sd_radv_prefix, prefixes); | |
e9c6da38 | 113 | |
203d4df5 SS |
114 | unsigned n_route_prefixes; |
115 | LIST_HEAD(sd_radv_route_prefix, route_prefixes); | |
116 | ||
1925f829 SS |
117 | unsigned n_pref64_prefixes; |
118 | LIST_HEAD(sd_radv_pref64_prefix, pref64_prefixes); | |
119 | ||
e9c6da38 PF |
120 | size_t n_rdnss; |
121 | struct sd_radv_opt_dns *rdnss; | |
e965d6ab | 122 | struct sd_radv_opt_dns *dnssl; |
6a6d27bc SS |
123 | |
124 | /* Mobile IPv6 extension: Home Agent Info. */ | |
125 | struct nd_opt_home_agent_info home_agent; | |
204f99d2 PF |
126 | }; |
127 | ||
e27b9aba ZJS |
128 | #define radv_prefix_opt__contents { \ |
129 | uint8_t type; \ | |
130 | uint8_t length; \ | |
131 | uint8_t prefixlen; \ | |
132 | uint8_t flags; \ | |
95e104e0 YW |
133 | be32_t lifetime_valid; \ |
134 | be32_t lifetime_preferred; \ | |
e27b9aba ZJS |
135 | uint32_t reserved; \ |
136 | struct in6_addr in6_addr; \ | |
137 | } | |
138 | ||
139 | struct radv_prefix_opt radv_prefix_opt__contents; | |
140 | ||
141 | /* We need the opt substructure to be packed, because we use it in send(). But | |
142 | * if we use _packed_, this means that the structure cannot be used directly in | |
143 | * normal code in general, because the fields might not be properly aligned. | |
144 | * But in this particular case, the structure is defined in a way that gives | |
145 | * proper alignment, even without the explicit _packed_ attribute. To appease | |
146 | * the compiler we use the "unpacked" structure, but we also verify that | |
147 | * structure contains no holes, so offsets are the same when _packed_ is used. | |
148 | */ | |
149 | struct radv_prefix_opt__packed radv_prefix_opt__contents _packed_; | |
150 | assert_cc(sizeof(struct radv_prefix_opt) == sizeof(struct radv_prefix_opt__packed)); | |
151 | ||
04473969 PF |
152 | struct sd_radv_prefix { |
153 | unsigned n_ref; | |
154 | ||
e27b9aba | 155 | struct radv_prefix_opt opt; |
04473969 PF |
156 | |
157 | LIST_FIELDS(struct sd_radv_prefix, prefix); | |
d601b566 | 158 | |
95e104e0 YW |
159 | /* These are timespans, NOT points in time. */ |
160 | usec_t lifetime_valid_usec; | |
161 | usec_t lifetime_preferred_usec; | |
162 | /* These are points in time specified with clock_boottime_or_monotonic(), NOT timespans. */ | |
d601b566 PF |
163 | usec_t valid_until; |
164 | usec_t preferred_until; | |
04473969 PF |
165 | }; |
166 | ||
203d4df5 SS |
167 | #define radv_route_prefix_opt__contents { \ |
168 | uint8_t type; \ | |
169 | uint8_t length; \ | |
170 | uint8_t prefixlen; \ | |
171 | uint8_t flags_reserved; \ | |
172 | be32_t lifetime; \ | |
173 | struct in6_addr in6_addr; \ | |
174 | } | |
175 | ||
176 | struct radv_route_prefix_opt radv_route_prefix_opt__contents; | |
177 | ||
178 | struct radv_route_prefix_opt__packed radv_route_prefix_opt__contents _packed_; | |
179 | assert_cc(sizeof(struct radv_route_prefix_opt) == sizeof(struct radv_route_prefix_opt__packed)); | |
180 | ||
181 | struct sd_radv_route_prefix { | |
182 | unsigned n_ref; | |
183 | ||
184 | struct radv_route_prefix_opt opt; | |
185 | ||
186 | LIST_FIELDS(struct sd_radv_route_prefix, prefix); | |
95e104e0 YW |
187 | |
188 | /* This is a timespan, NOT a point in time. */ | |
189 | usec_t lifetime_usec; | |
190 | /* This is a point in time specified with clock_boottime_or_monotonic(), NOT a timespan. */ | |
191 | usec_t valid_until; | |
203d4df5 SS |
192 | }; |
193 | ||
1925f829 SS |
194 | struct sd_radv_pref64_prefix { |
195 | unsigned n_ref; | |
196 | ||
6e8f5e4c | 197 | struct nd_opt_prefix64_info opt; |
1925f829 SS |
198 | |
199 | struct in6_addr in6_addr; | |
200 | uint8_t prefixlen; | |
201 | ||
202 | usec_t lifetime_usec; | |
203 | ||
204 | LIST_FIELDS(struct sd_radv_pref64_prefix, prefix); | |
205 | }; | |
206 | ||
a0c2541b | 207 | #define log_radv_errno(radv, error, fmt, ...) \ |
00dd6d77 | 208 | log_interface_prefix_full_errno( \ |
a0c2541b | 209 | "RADV: ", \ |
5977b71f | 210 | sd_radv, radv, \ |
a0c2541b ZJS |
211 | error, fmt, ##__VA_ARGS__) |
212 | #define log_radv(radv, fmt, ...) \ | |
00dd6d77 ZJS |
213 | log_interface_prefix_full_errno_zerook( \ |
214 | "RADV: ", \ | |
5977b71f | 215 | sd_radv, radv, \ |
00dd6d77 | 216 | 0, fmt, ##__VA_ARGS__) |