Browse code

Revert "Add improvements to RA in systemd"

This reverts commit 704cd8cb2d13578de0a894516cedf8b35f870085.

Change-Id: I7291e16f8310a604da7ba6b72b18b7f50783ec01
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/3854
Reviewed-by: Anish Swaminathan <anishs@vmware.com>
Tested-by: Anish Swaminathan <anishs@vmware.com>

Vinay Kulkarni authored on 2017/09/23 09:14:04
Showing 2 changed files
1 1
deleted file mode 100644
... ...
@@ -1,1452 +0,0 @@
1
-Backports the following commits from systemd 234:
2
-
3
-ce905cb44620e979862e63743133d354c90d28df icmp6-util: Bind Router Advertisement socket
4
-9dab3e066bb5dfeefa28854ab7f95648eaf0d75d sd-radv: Receive Router Solicitations
5
-d0d6045f658ac3e043235aee68a540650e0f98e0 sd-radv: Send Router Advertisments
6
-dd39628ac19c691917aeeb01babaef411f146039 sd-radv: Implement Router Advertisement timeout handling
7
-938c9ff7d374086b996d6a9a484f88ebd94731a3 sd-radv: Add Router Advertisement functionality
8
-b076a89bb331b91a7cafcd77fb3c13484805b24f sd-radv: Add Router Advertisement prefix handling
9
-1e4a54de3a79a0ba764e482122e381398eaf3e25 icmp6-util: Move multicast address definitions
10
-42a7accc3dec5350f0e88ffa145a55293b6fd0e9 sd-ndisc.c: Move Router Solicitation sending after timer computaion
11
-7b72b034e7c406209dfc55643b79ec0cb2636e4f sd-ndisc: Implement Router Solicitation backoff method
12
-33261358b2a16d895d7beb5b34ebdacadb56cb56 sd-ndisc: Reset counter for sent Router Solicitations (#5874)
13
-b40e6a51d55531314666e866d7f9813fce385023 networkd: RFC compliant autonomous prefix handling (#5636)
14
-
15
- Makefile.am                             |   3 +
16
- src/libsystemd-network/icmp6-util.c     | 117 ++++++++++-
17
- src/libsystemd-network/icmp6-util.h     |  13 ++
18
- src/libsystemd-network/ndisc-internal.h |   7 +-
19
- src/libsystemd-network/radv-internal.h  |  88 +++++++++
20
- src/libsystemd-network/sd-ndisc.c       | 184 ++++++++---------
21
- src/libsystemd-network/sd-radv.c        | 653 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22
- src/libsystemd-network/test-ndisc-rs.c  |  15 ++
23
- src/network/networkd-ndisc.c            |  30 ++-
24
- src/systemd/sd-radv.h                   |  81 ++++++++
25
- 10 files changed, 1086 insertions(+), 105 deletions(-)
26
- create mode 100644 src/libsystemd-network/radv-internal.h
27
- create mode 100644 src/libsystemd-network/sd-radv.c
28
- create mode 100644 src/systemd/sd-radv.h
29
-
30
-diff -rupN systemd-base/Makefile.am systemd/Makefile.am
31
-+++ systemd/Makefile.am	2017-09-18 14:58:25.561666434 -0700
32
-@@ -3629,6 +3629,7 @@ libsystemd_network_la_SOURCES = \
33
- 	src/systemd/sd-ipv4ll.h \
34
- 	src/systemd/sd-ipv4acd.h \
35
- 	src/systemd/sd-ndisc.h \
36
-+	src/systemd/sd-radv.h \
37
- 	src/systemd/sd-dhcp6-client.h \
38
- 	src/systemd/sd-dhcp6-lease.h \
39
- 	src/systemd/sd-lldp.h \
40
-@@ -3652,6 +3653,8 @@ libsystemd_network_la_SOURCES = \
41
- 	src/libsystemd-network/ndisc-internal.h \
42
- 	src/libsystemd-network/ndisc-router.h \
43
- 	src/libsystemd-network/ndisc-router.c \
44
-+	src/libsystemd-network/sd-radv.c \
45
-+	src/libsystemd-network/radv-internal.h \
46
- 	src/libsystemd-network/icmp6-util.h \
47
- 	src/libsystemd-network/icmp6-util.c \
48
- 	src/libsystemd-network/sd-dhcp6-client.c \
49
-diff -rupN systemd-base/src/libsystemd-network/icmp6-util.c systemd/src/libsystemd-network/icmp6-util.c
50
-+++ systemd/src/libsystemd-network/icmp6-util.c	2017-09-18 15:06:31.020575497 -0700
51
-@@ -32,6 +32,7 @@
52
- #include "fd-util.h"
53
- #include "icmp6-util.h"
54
- #include "socket-util.h"
55
-+#include "in-addr-util.h"
56
- 
57
- #define IN6ADDR_ALL_ROUTERS_MULTICAST_INIT \
58
-         { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
59
-@@ -41,12 +42,9 @@
60
-         { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
61
-               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }
62
- 
63
--int icmp6_bind_router_solicitation(int index) {
64
--        struct icmp6_filter filter = { };
65
--        struct ipv6_mreq mreq = {
66
--                .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
67
--                .ipv6mr_interface = index,
68
--        };
69
-+static int icmp6_bind_router_message(const struct icmp6_filter *filter,
70
-+                                     const struct ipv6_mreq *mreq) {
71
-+        int index = mreq->ipv6mr_interface;
72
-         _cleanup_close_ int s = -1;
73
-         char ifname[IF_NAMESIZE] = "";
74
-         static const int zero = 0, one = 1, hops = 255;
75
-@@ -56,9 +54,11 @@ int icmp6_bind_router_solicitation(int i
76
-         if (s < 0)
77
-                 return -errno;
78
- 
79
--        ICMP6_FILTER_SETBLOCKALL(&filter);
80
--        ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
81
--        r = setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof(filter));
82
-+        r = setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, filter, sizeof(*filter));
83
-+        if (r < 0)
84
-+                return -errno;
85
-+
86
-+        r = setsockopt(s, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq, sizeof(*mreq));
87
-         if (r < 0)
88
-                 return -errno;
89
- 
90
-@@ -78,7 +78,7 @@ int icmp6_bind_router_solicitation(int i
91
-         if (r < 0)
92
-                 return -errno;
93
- 
94
--        r = setsockopt(s, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
95
-+        r = setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, sizeof(hops));
96
-         if (r < 0)
97
-                 return -errno;
98
- 
99
-@@ -102,6 +102,32 @@ int icmp6_bind_router_solicitation(int i
100
-         return r;
101
- }
102
- 
103
-+int icmp6_bind_router_solicitation(int index) {
104
-+        struct icmp6_filter filter = {};
105
-+        struct ipv6_mreq mreq = {
106
-+                .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
107
-+                .ipv6mr_interface = index,
108
-+        };
109
-+
110
-+        ICMP6_FILTER_SETBLOCKALL(&filter);
111
-+        ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
112
-+
113
-+        return icmp6_bind_router_message(&filter, &mreq);
114
-+}
115
-+
116
-+int icmp6_bind_router_advertisement(int index) {
117
-+        struct icmp6_filter filter = {};
118
-+        struct ipv6_mreq mreq = {
119
-+                .ipv6mr_multiaddr = IN6ADDR_ALL_ROUTERS_MULTICAST_INIT,
120
-+                .ipv6mr_interface = index,
121
-+        };
122
-+
123
-+        ICMP6_FILTER_SETBLOCKALL(&filter);
124
-+        ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
125
-+
126
-+        return icmp6_bind_router_message(&filter, &mreq);
127
-+}
128
-+
129
- int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
130
-         struct sockaddr_in6 dst = {
131
-                 .sin6_family = AF_INET6,
132
-@@ -139,3 +165,74 @@ int icmp6_send_router_solicitation(int s
133
- 
134
-         return 0;
135
- }
136
-+
137
-+int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
138
-+                  triple_timestamp *timestamp) {
139
-+        union {
140
-+                struct cmsghdr cmsghdr;
141
-+                uint8_t buf[CMSG_SPACE(sizeof(int)) + /* ttl */
142
-+                            CMSG_SPACE(sizeof(struct timeval))];
143
-+        } control = {};
144
-+        struct iovec iov = {};
145
-+        union sockaddr_union sa = {};
146
-+        struct msghdr msg = {
147
-+                .msg_name = &sa.sa,
148
-+                .msg_namelen = sizeof(sa),
149
-+                .msg_iov = &iov,
150
-+                .msg_iovlen = 1,
151
-+                .msg_control = &control,
152
-+                .msg_controllen = sizeof(control),
153
-+        };
154
-+        struct cmsghdr *cmsg;
155
-+        ssize_t len;
156
-+
157
-+        iov.iov_base = buffer;
158
-+        iov.iov_len = size;
159
-+
160
-+        len = recvmsg(fd, &msg, MSG_DONTWAIT);
161
-+        if (len < 0) {
162
-+                if (errno == EAGAIN || errno == EINTR)
163
-+                        return 0;
164
-+
165
-+                return -errno;
166
-+        }
167
-+
168
-+        if ((size_t) len != size)
169
-+                return -EINVAL;
170
-+
171
-+        if (msg.msg_namelen == sizeof(struct sockaddr_in6) &&
172
-+            sa.in6.sin6_family == AF_INET6)  {
173
-+
174
-+                *dst = sa.in6.sin6_addr;
175
-+                if (in_addr_is_link_local(AF_INET6, (union in_addr_union*) dst) <= 0)
176
-+                        return -EADDRNOTAVAIL;
177
-+
178
-+        } else if (msg.msg_namelen > 0)
179
-+                return -EPFNOSUPPORT;
180
-+
181
-+        /* namelen == 0 only happens when running the test-suite over a socketpair */
182
-+
183
-+        assert(!(msg.msg_flags & MSG_CTRUNC));
184
-+        assert(!(msg.msg_flags & MSG_TRUNC));
185
-+
186
-+        CMSG_FOREACH(cmsg, &msg) {
187
-+                if (cmsg->cmsg_level == SOL_IPV6 &&
188
-+                    cmsg->cmsg_type == IPV6_HOPLIMIT &&
189
-+                    cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
190
-+                        int hops = *(int*) CMSG_DATA(cmsg);
191
-+
192
-+                        if (hops != 255)
193
-+                                return -EMULTIHOP;
194
-+                }
195
-+
196
-+                if (cmsg->cmsg_level == SOL_SOCKET &&
197
-+                    cmsg->cmsg_type == SO_TIMESTAMP &&
198
-+                    cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
199
-+                        triple_timestamp_from_realtime(timestamp, timeval_load((struct timeval*) CMSG_DATA(cmsg)));
200
-+        }
201
-+
202
-+        if (!triple_timestamp_is_set(timestamp))
203
-+                triple_timestamp_get(timestamp);
204
-+
205
-+        return 0;
206
-+}
207
-diff -rupN systemd-base/src/libsystemd-network/icmp6-util.h systemd/src/libsystemd-network/icmp6-util.h
208
-+++ systemd/src/libsystemd-network/icmp6-util.h	2017-09-18 15:06:31.020575497 -0700
209
-@@ -21,5 +21,18 @@
210
- 
211
- #include <net/ethernet.h>
212
- 
213
-+#include "time-util.h"
214
-+
215
-+#define IN6ADDR_ALL_ROUTERS_MULTICAST_INIT \
216
-+        { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
217
-+              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 } } }
218
-+
219
-+#define IN6ADDR_ALL_NODES_MULTICAST_INIT \
220
-+        { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
221
-+              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }
222
-+
223
- int icmp6_bind_router_solicitation(int index);
224
-+int icmp6_bind_router_advertisement(int index);
225
- int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr);
226
-+int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
227
-+                  triple_timestamp *timestamp);
228
-diff -rupN systemd-base/src/libsystemd-network/ndisc-internal.h systemd/src/libsystemd-network/ndisc-internal.h
229
-+++ systemd/src/libsystemd-network/ndisc-internal.h	2017-09-18 14:55:04.905317356 -0700
230
-@@ -23,6 +23,10 @@
231
- 
232
- #include "sd-ndisc.h"
233
- 
234
-+#define NDISC_ROUTER_SOLICITATION_INTERVAL (4U * USEC_PER_SEC)
235
-+#define NDISC_MAX_ROUTER_SOLICITATION_INTERVAL (3600U * USEC_PER_SEC)
236
-+#define NDISC_MAX_ROUTER_SOLICITATIONS 3U
237
-+
238
- struct sd_ndisc {
239
-         unsigned n_ref;
240
- 
241
-@@ -38,8 +42,9 @@ struct sd_ndisc {
242
- 
243
-         sd_event_source *recv_event_source;
244
-         sd_event_source *timeout_event_source;
245
-+        sd_event_source *timeout_no_ra;
246
- 
247
--        unsigned nd_sent;
248
-+        usec_t retransmit_time;
249
- 
250
-         sd_ndisc_callback_t callback;
251
-         void *userdata;
252
-diff -rupN systemd-base/src/libsystemd-network/radv-internal.h systemd/src/libsystemd-network/radv-internal.h
253
-+++ systemd/src/libsystemd-network/radv-internal.h	2017-09-18 15:00:40.022354604 -0700
254
-@@ -0,0 +1,88 @@
255
-+#pragma once
256
-+
257
-+/***
258
-+  This file is part of systemd.
259
-+
260
-+  Copyright (C) 2017 Intel Corporation. All rights reserved.
261
-+
262
-+  systemd is free software; you can redistribute it and/or modify it
263
-+  under the terms of the GNU Lesser General Public License as published by
264
-+  the Free Software Foundation; either version 2.1 of the License, or
265
-+  (at your option) any later version.
266
-+
267
-+  systemd is distributed in the hope that it will be useful, but
268
-+  WITHOUT ANY WARRANTY; without even the implied warranty of
269
-+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
270
-+  Lesser General Public License for more details.
271
-+
272
-+  You should have received a copy of the GNU Lesser General Public License
273
-+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
274
-+***/
275
-+
276
-+#include "sd-radv.h"
277
-+
278
-+#include "log.h"
279
-+#include "list.h"
280
-+#include "sparse-endian.h"
281
-+
282
-+#define SD_RADV_DEFAULT_MIN_TIMEOUT_USEC        (200*USEC_PER_SEC)
283
-+#define SD_RADV_DEFAULT_MAX_TIMEOUT_USEC        (600*USEC_PER_SEC)
284
-+assert_cc(SD_RADV_DEFAULT_MIN_TIMEOUT_USEC <= SD_RADV_DEFAULT_MAX_TIMEOUT_USEC)
285
-+
286
-+#define SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC (16*USEC_PER_SEC)
287
-+#define SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS  3
288
-+#define SD_RADV_MAX_FINAL_RTR_ADVERTISEMENTS    3
289
-+#define SD_RADV_MIN_DELAY_BETWEEN_RAS           3
290
-+#define SD_RADV_MAX_RA_DELAY_TIME_USEC          (500*USEC_PER_MSEC)
291
-+
292
-+enum RAdvState {
293
-+        SD_RADV_STATE_IDLE                      = 0,
294
-+        SD_RADV_STATE_ADVERTISING               = 1,
295
-+};
296
-+typedef enum RAdvState RAdvState;
297
-+
298
-+struct sd_radv {
299
-+        unsigned n_ref;
300
-+        RAdvState state;
301
-+
302
-+        int ifindex;
303
-+
304
-+        sd_event *event;
305
-+        int event_priority;
306
-+
307
-+        struct ether_addr mac_addr;
308
-+        uint8_t hop_limit;
309
-+        uint8_t flags;
310
-+        uint32_t mtu;
311
-+        uint16_t lifetime;
312
-+
313
-+        int fd;
314
-+        unsigned ra_sent;
315
-+        sd_event_source *recv_event_source;
316
-+        sd_event_source *timeout_event_source;
317
-+
318
-+        unsigned n_prefixes;
319
-+        LIST_HEAD(sd_radv_prefix, prefixes);
320
-+};
321
-+
322
-+struct sd_radv_prefix {
323
-+        unsigned n_ref;
324
-+
325
-+        struct {
326
-+                uint8_t type;
327
-+                uint8_t length;
328
-+                uint8_t prefixlen;
329
-+                uint8_t flags;
330
-+                be32_t valid_lifetime;
331
-+                be32_t preferred_lifetime;
332
-+                uint32_t reserved;
333
-+                struct in6_addr in6_addr;
334
-+        } _packed_ opt;
335
-+
336
-+        LIST_FIELDS(struct sd_radv_prefix, prefix);
337
-+};
338
-+
339
-+#define log_radv_full(level, error, fmt, ...) log_internal(level, error, __FILE__, __LINE__, __func__, "RADV: " fmt, ##__VA_ARGS__)
340
-+#define log_radv_errno(error, fmt, ...) log_radv_full(LOG_DEBUG, error, fmt, ##__VA_ARGS__)
341
-+#define log_radv_warning_errno(error, fmt, ...) log_radv_full(LOG_WARNING, error, fmt, ##__VA_ARGS__)
342
-+#define log_radv(fmt, ...) log_radv_errno(0, fmt, ##__VA_ARGS__)
343
-diff -rupN systemd-base/src/libsystemd-network/sd-ndisc.c systemd/src/libsystemd-network/sd-ndisc.c
344
-+++ systemd/src/libsystemd-network/sd-ndisc.c	2017-09-18 15:00:40.038396204 -0700
345
-@@ -28,12 +28,12 @@
346
- #include "in-addr-util.h"
347
- #include "ndisc-internal.h"
348
- #include "ndisc-router.h"
349
-+#include "random-util.h"
350
- #include "socket-util.h"
351
- #include "string-util.h"
352
- #include "util.h"
353
- 
354
--#define NDISC_ROUTER_SOLICITATION_INTERVAL (4U * USEC_PER_SEC)
355
--#define NDISC_MAX_ROUTER_SOLICITATIONS 3U
356
-+#define NDISC_TIMEOUT_NO_RA_USEC (NDISC_ROUTER_SOLICITATION_INTERVAL * NDISC_MAX_ROUTER_SOLICITATIONS)
357
- 
358
- static void ndisc_callback(sd_ndisc *ndisc, sd_ndisc_event event, sd_ndisc_router *rt) {
359
-         assert(ndisc);
360
-@@ -129,6 +129,8 @@ static int ndisc_reset(sd_ndisc *nd) {
361
-         assert(nd);
362
- 
363
-         nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source);
364
-+        nd->timeout_no_ra = sd_event_source_unref(nd->timeout_no_ra);
365
-+        nd->retransmit_time = 0;
366
-         nd->recv_event_source = sd_event_source_unref(nd->recv_event_source);
367
-         nd->fd = safe_close(nd->fd);
368
- 
369
-@@ -221,23 +223,9 @@ static int ndisc_handle_datagram(sd_ndis
370
- static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
371
-         _cleanup_(sd_ndisc_router_unrefp) sd_ndisc_router *rt = NULL;
372
-         sd_ndisc *nd = userdata;
373
--        union {
374
--                struct cmsghdr cmsghdr;
375
--                uint8_t buf[CMSG_SPACE(sizeof(int)) + /* ttl */
376
--                            CMSG_SPACE(sizeof(struct timeval))];
377
--        } control = {};
378
--        struct iovec iov = {};
379
--        union sockaddr_union sa = {};
380
--        struct msghdr msg = {
381
--                .msg_name = &sa.sa,
382
--                .msg_namelen = sizeof(sa),
383
--                .msg_iov = &iov,
384
--                .msg_iovlen = 1,
385
--                .msg_control = &control,
386
--                .msg_controllen = sizeof(control),
387
--        };
388
--        struct cmsghdr *cmsg;
389
--        ssize_t len, buflen;
390
-+        ssize_t buflen;
391
-+        int r;
392
-+        _cleanup_free_ char *addr = NULL;
393
- 
394
-         assert(s);
395
-         assert(nd);
396
-@@ -251,110 +239,90 @@ static int ndisc_recv(sd_event_source *s
397
-         if (!rt)
398
-                 return -ENOMEM;
399
- 
400
--        iov.iov_base = NDISC_ROUTER_RAW(rt);
401
--        iov.iov_len = rt->raw_size;
402
--
403
--        len = recvmsg(fd, &msg, MSG_DONTWAIT);
404
--        if (len < 0) {
405
--                if (errno == EAGAIN || errno == EINTR)
406
--                        return 0;
407
--
408
--                return log_ndisc_errno(errno, "Could not receive message from ICMPv6 socket: %m");
409
--        }
410
--
411
--        if ((size_t) len != rt->raw_size) {
412
--                log_ndisc("Packet size mismatch.");
413
--                return -EINVAL;
414
--        }
415
--
416
--        if (msg.msg_namelen == sizeof(struct sockaddr_in6) &&
417
--            sa.in6.sin6_family == AF_INET6)  {
418
--
419
--                if (in_addr_is_link_local(AF_INET6, (union in_addr_union*) &sa.in6.sin6_addr) <= 0) {
420
--                        _cleanup_free_ char *addr = NULL;
421
--
422
--                        (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &sa.in6.sin6_addr, &addr);
423
--                        log_ndisc("Received RA from non-link-local address %s. Ignoring.", strna(addr));
424
--                        return 0;
425
--                }
426
--
427
--                rt->address = sa.in6.sin6_addr;
428
--
429
--        } else if (msg.msg_namelen > 0) {
430
--                log_ndisc("Received invalid source address size from ICMPv6 socket: %zu bytes", (size_t) msg.msg_namelen);
431
--                return -EINVAL;
432
--        }
433
--
434
--        /* namelen == 0 only happens when running the test-suite over a socketpair */
435
--
436
--        assert(!(msg.msg_flags & MSG_CTRUNC));
437
--        assert(!(msg.msg_flags & MSG_TRUNC));
438
--
439
--        CMSG_FOREACH(cmsg, &msg) {
440
--                if (cmsg->cmsg_level == SOL_IPV6 &&
441
--                    cmsg->cmsg_type == IPV6_HOPLIMIT &&
442
--                    cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
443
--                        int hops = *(int*) CMSG_DATA(cmsg);
444
--
445
--                        if (hops != 255) {
446
--                                log_ndisc("Received RA with invalid hop limit %d. Ignoring.", hops);
447
--                                return 0;
448
--                        }
449
-+        r = icmp6_receive(fd, NDISC_ROUTER_RAW(rt), rt->raw_size, &rt->address,
450
-+                     &rt->timestamp);
451
-+        if (r < 0) {
452
-+                switch (r) {
453
-+                case -EADDRNOTAVAIL:
454
-+                        (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &rt->address, &addr);
455
-+                        log_ndisc("Received RA from non-link-local address %s. Ignoring", addr);
456
-+                        break;
457
-+
458
-+                case -EMULTIHOP:
459
-+                        log_ndisc("Received RA with invalid hop limit. Ignoring.");
460
-+                        break;
461
-+
462
-+                case -EPFNOSUPPORT:
463
-+                        log_ndisc("Received invalid source address from ICMPv6 socket.");
464
-+                        break;
465
-                 }
466
- 
467
--                if (cmsg->cmsg_level == SOL_SOCKET &&
468
--                    cmsg->cmsg_type == SO_TIMESTAMP &&
469
--                    cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
470
--                        triple_timestamp_from_realtime(&rt->timestamp, timeval_load((struct timeval*) CMSG_DATA(cmsg)));
471
-+                return 0;
472
-         }
473
- 
474
--        if (!triple_timestamp_is_set(&rt->timestamp))
475
--                triple_timestamp_get(&rt->timestamp);
476
--
477
-         nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source);
478
- 
479
-         return ndisc_handle_datagram(nd, rt);
480
- }
481
- 
482
-+static usec_t ndisc_timeout_compute_random(usec_t val) {
483
-+        /* compute a time that is random within ±10% of the given value */
484
-+        return val - val / 10 +
485
-+                (random_u64() % (2 * USEC_PER_SEC)) * val / 10 / USEC_PER_SEC;
486
-+}
487
-+
488
- static int ndisc_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
489
-         sd_ndisc *nd = userdata;
490
--        usec_t time_now, next_timeout;
491
-+        usec_t time_now;
492
-         int r;
493
-+        char time_string[FORMAT_TIMESPAN_MAX];
494
- 
495
-         assert(s);
496
-         assert(nd);
497
-         assert(nd->event);
498
- 
499
--        if (nd->nd_sent >= NDISC_MAX_ROUTER_SOLICITATIONS) {
500
--                nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source);
501
--                ndisc_callback(nd, SD_NDISC_EVENT_TIMEOUT, NULL);
502
--                return 0;
503
-+        assert_se(sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now) >= 0);
504
-+
505
-+        nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source);
506
-+
507
-+        if (!nd->retransmit_time)
508
-+                nd->retransmit_time = ndisc_timeout_compute_random(NDISC_ROUTER_SOLICITATION_INTERVAL);
509
-+        else {
510
-+                if (nd->retransmit_time > NDISC_MAX_ROUTER_SOLICITATION_INTERVAL / 2)
511
-+                        nd->retransmit_time = ndisc_timeout_compute_random(NDISC_MAX_ROUTER_SOLICITATION_INTERVAL);
512
-+                else
513
-+                        nd->retransmit_time += ndisc_timeout_compute_random(nd->retransmit_time);
514
-         }
515
- 
516
--        r = icmp6_send_router_solicitation(nd->fd, &nd->mac_addr);
517
--        if (r < 0) {
518
--                log_ndisc_errno(r, "Error sending Router Solicitation: %m");
519
-+        r = sd_event_add_time(nd->event, &nd->timeout_event_source,
520
-+                              clock_boottime_or_monotonic(),
521
-+                              time_now + nd->retransmit_time,
522
-+                              10 * USEC_PER_MSEC, ndisc_timeout, nd);
523
-+        if (r < 0)
524
-                 goto fail;
525
--        }
526
- 
527
--        log_ndisc("Sent Router Solicitation");
528
--        nd->nd_sent++;
529
-+        r = sd_event_source_set_priority(nd->timeout_event_source, nd->event_priority);
530
-+        if (r < 0)
531
-+                goto fail;
532
- 
533
--        assert_se(sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now) >= 0);
534
--        next_timeout = time_now + NDISC_ROUTER_SOLICITATION_INTERVAL;
535
-+        (void) sd_event_source_set_description(nd->timeout_event_source, "ndisc-timeout-no-ra");
536
- 
537
--        r = sd_event_source_set_time(nd->timeout_event_source, next_timeout);
538
-+        r = sd_event_source_set_enabled(nd->timeout_event_source, SD_EVENT_ONESHOT);
539
-         if (r < 0) {
540
--                log_ndisc_errno(r, "Error updating timer: %m");
541
-+                log_ndisc_errno(r, "Error reenabling timer: %m");
542
-                 goto fail;
543
-         }
544
- 
545
--        r = sd_event_source_set_enabled(nd->timeout_event_source, SD_EVENT_ONESHOT);
546
-+        r = icmp6_send_router_solicitation(nd->fd, &nd->mac_addr);
547
-         if (r < 0) {
548
--                log_ndisc_errno(r, "Error reenabling timer: %m");
549
-+                log_ndisc_errno(r, "Error sending Router Solicitation: %m");
550
-                 goto fail;
551
-         }
552
- 
553
-+        log_ndisc("Sent Router Solicitation, next solicitation in %s",
554
-+                  format_timespan(time_string, FORMAT_TIMESPAN_MAX,
555
-+                                  nd->retransmit_time, USEC_PER_SEC));
556
-+
557
-         return 0;
558
- 
559
- fail:
560
-@@ -362,6 +330,20 @@ fail:
561
-         return 0;
562
- }
563
- 
564
-+static int ndisc_timeout_no_ra(sd_event_source *s, uint64_t usec, void *userdata) {
565
-+        sd_ndisc *nd = userdata;
566
-+
567
-+        assert(s);
568
-+        assert(nd);
569
-+
570
-+        log_ndisc("No RA received before link confirmation timeout");
571
-+
572
-+        nd->timeout_no_ra = sd_event_source_unref(nd->timeout_no_ra);
573
-+        ndisc_callback(nd, SD_NDISC_EVENT_TIMEOUT, NULL);
574
-+
575
-+        return 0;
576
-+}
577
-+
578
- _public_ int sd_ndisc_stop(sd_ndisc *nd) {
579
-         assert_return(nd, -EINVAL);
580
- 
581
-@@ -376,6 +358,7 @@ _public_ int sd_ndisc_stop(sd_ndisc *nd)
582
- 
583
- _public_ int sd_ndisc_start(sd_ndisc *nd) {
584
-         int r;
585
-+        usec_t time_now;
586
- 
587
-         assert_return(nd, -EINVAL);
588
-         assert_return(nd->event, -EINVAL);
589
-@@ -387,6 +370,10 @@ _public_ int sd_ndisc_start(sd_ndisc *nd
590
-         assert(!nd->recv_event_source);
591
-         assert(!nd->timeout_event_source);
592
- 
593
-+        r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now);
594
-+        if (r < 0)
595
-+                goto fail;
596
-+
597
-         nd->fd = icmp6_bind_router_solicitation(nd->ifindex);
598
-         if (nd->fd < 0)
599
-                 return nd->fd;
600
-@@ -411,6 +398,19 @@ _public_ int sd_ndisc_start(sd_ndisc *nd
601
- 
602
-         (void) sd_event_source_set_description(nd->timeout_event_source, "ndisc-timeout");
603
- 
604
-+        r = sd_event_add_time(nd->event, &nd->timeout_no_ra,
605
-+                              clock_boottime_or_monotonic(),
606
-+                              time_now + NDISC_TIMEOUT_NO_RA_USEC,
607
-+                              10 * USEC_PER_MSEC, ndisc_timeout_no_ra, nd);
608
-+        if (r < 0)
609
-+                goto fail;
610
-+
611
-+        r = sd_event_source_set_priority(nd->timeout_no_ra, nd->event_priority);
612
-+        if (r < 0)
613
-+                goto fail;
614
-+
615
-+        (void) sd_event_source_set_description(nd->timeout_no_ra, "ndisc-timeout-no-ra");
616
-+
617
-         log_ndisc("Started IPv6 Router Solicitation client");
618
-         return 1;
619
- 
620
-diff -rupN systemd-base/src/libsystemd-network/sd-radv.c systemd/src/libsystemd-network/sd-radv.c
621
-+++ systemd/src/libsystemd-network/sd-radv.c	2017-09-18 15:00:40.022354604 -0700
622
-@@ -0,0 +1,653 @@
623
-+/***
624
-+  This file is part of systemd.
625
-+
626
-+  Copyright (C) 2017 Intel Corporation. All rights reserved.
627
-+
628
-+  systemd is free software; you can redistribute it and/or modify it
629
-+  under the terms of the GNU Lesser General Public License as published by
630
-+  the Free Software Foundation; either version 2.1 of the License, or
631
-+  (at your option) any later version.
632
-+
633
-+  systemd is distributed in the hope that it will be useful, but
634
-+  WITHOUT ANY WARRANTY; without even the implied warranty of
635
-+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
636
-+  Lesser General Public License for more details.
637
-+
638
-+  You should have received a copy of the GNU Lesser General Public License
639
-+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
640
-+***/
641
-+
642
-+#include <netinet/icmp6.h>
643
-+#include <netinet/in.h>
644
-+#include <arpa/inet.h>
645
-+#include <linux/in6.h>
646
-+
647
-+#include "sd-radv.h"
648
-+
649
-+#include "macro.h"
650
-+#include "alloc-util.h"
651
-+#include "fd-util.h"
652
-+#include "icmp6-util.h"
653
-+#include "in-addr-util.h"
654
-+#include "radv-internal.h"
655
-+#include "socket-util.h"
656
-+#include "string-util.h"
657
-+#include "util.h"
658
-+#include "random-util.h"
659
-+
660
-+_public_ int sd_radv_new(sd_radv **ret) {
661
-+        _cleanup_(sd_radv_unrefp) sd_radv *ra = NULL;
662
-+
663
-+        assert_return(ret, -EINVAL);
664
-+
665
-+        ra = new0(sd_radv, 1);
666
-+        if (!ra)
667
-+                return -ENOMEM;
668
-+
669
-+        ra->n_ref = 1;
670
-+        ra->fd = -1;
671
-+
672
-+        LIST_HEAD_INIT(ra->prefixes);
673
-+
674
-+        *ret = ra;
675
-+        ra = NULL;
676
-+
677
-+        return 0;
678
-+}
679
-+
680
-+_public_ int sd_radv_attach_event(sd_radv *ra, sd_event *event, int64_t priority) {
681
-+        int r;
682
-+
683
-+        assert_return(ra, -EINVAL);
684
-+        assert_return(!ra->event, -EBUSY);
685
-+
686
-+        if (event)
687
-+                ra->event = sd_event_ref(event);
688
-+        else {
689
-+                r = sd_event_default(&ra->event);
690
-+                if (r < 0)
691
-+                        return 0;
692
-+        }
693
-+
694
-+        ra->event_priority = priority;
695
-+
696
-+        return 0;
697
-+}
698
-+
699
-+_public_ int sd_radv_detach_event(sd_radv *ra) {
700
-+
701
-+        assert_return(ra, -EINVAL);
702
-+
703
-+        ra->event = sd_event_unref(ra->event);
704
-+        return 0;
705
-+}
706
-+
707
-+_public_ sd_event *sd_radv_get_event(sd_radv *ra) {
708
-+        assert_return(ra, NULL);
709
-+
710
-+        return ra->event;
711
-+}
712
-+
713
-+static void radv_reset(sd_radv *ra) {
714
-+
715
-+        ra->timeout_event_source =
716
-+                sd_event_source_unref(ra->timeout_event_source);
717
-+
718
-+        ra->recv_event_source =
719
-+                sd_event_source_unref(ra->recv_event_source);
720
-+
721
-+        ra->ra_sent = 0;
722
-+}
723
-+
724
-+_public_ sd_radv *sd_radv_ref(sd_radv *ra) {
725
-+        if (!ra)
726
-+                return NULL;
727
-+
728
-+        assert(ra->n_ref > 0);
729
-+        ra->n_ref++;
730
-+
731
-+        return ra;
732
-+}
733
-+
734
-+_public_ sd_radv *sd_radv_unref(sd_radv *ra) {
735
-+        if (!ra)
736
-+                return NULL;
737
-+
738
-+        assert(ra->n_ref > 0);
739
-+        ra->n_ref--;
740
-+
741
-+        if (ra->n_ref > 0)
742
-+                return NULL;
743
-+
744
-+        while (ra->prefixes) {
745
-+                sd_radv_prefix *p = ra->prefixes;
746
-+
747
-+                LIST_REMOVE(prefix, ra->prefixes, p);
748
-+                sd_radv_prefix_unref(p);
749
-+        }
750
-+
751
-+        radv_reset(ra);
752
-+
753
-+        sd_radv_detach_event(ra);
754
-+        return mfree(ra);
755
-+}
756
-+
757
-+static int radv_send(sd_radv *ra, const struct in6_addr *dst,
758
-+                     const uint32_t router_lifetime) {
759
-+        static const struct ether_addr mac_zero = {};
760
-+        sd_radv_prefix *p;
761
-+        struct sockaddr_in6 dst_addr = {
762
-+                .sin6_family = AF_INET6,
763
-+                .sin6_addr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
764
-+        };
765
-+        struct nd_router_advert adv = {};
766
-+        struct {
767
-+                struct nd_opt_hdr opthdr;
768
-+                struct ether_addr slladdr;
769
-+        } _packed_ opt_mac = {
770
-+                .opthdr = {
771
-+                        .nd_opt_type = ND_OPT_SOURCE_LINKADDR,
772
-+                        .nd_opt_len = (sizeof(struct nd_opt_hdr) +
773
-+                                       sizeof(struct ether_addr) - 1) /8 + 1,
774
-+                },
775
-+        };
776
-+        struct nd_opt_mtu opt_mtu =  {
777
-+                .nd_opt_mtu_type = ND_OPT_MTU,
778
-+                .nd_opt_mtu_len = 1,
779
-+        };
780
-+        /* Reserve iov space for RA header, linkaddr, MTU + N prefixes */
781
-+        struct iovec iov[3 + ra->n_prefixes];
782
-+        struct msghdr msg = {
783
-+                .msg_name = &dst_addr,
784
-+                .msg_namelen = sizeof(dst_addr),
785
-+                .msg_iov = iov,
786
-+        };
787
-+
788
-+        if (dst && !in_addr_is_null(AF_INET6, (union in_addr_union*) dst))
789
-+                dst_addr.sin6_addr = *dst;
790
-+
791
-+        adv.nd_ra_type = ND_ROUTER_ADVERT;
792
-+        adv.nd_ra_curhoplimit = ra->hop_limit;
793
-+        adv.nd_ra_flags_reserved = ra->flags;
794
-+        adv.nd_ra_router_lifetime = htobe16(router_lifetime);
795
-+        iov[msg.msg_iovlen].iov_base = &adv;
796
-+        iov[msg.msg_iovlen].iov_len = sizeof(adv);
797
-+        msg.msg_iovlen++;
798
-+
799
-+        /* MAC address is optional, either because the link does not use L2
800
-+           addresses or load sharing is desired. See RFC 4861, Section 4.2 */
801
-+        if (memcmp(&mac_zero, &ra->mac_addr, sizeof(mac_zero))) {
802
-+                opt_mac.slladdr = ra->mac_addr;
803
-+                iov[msg.msg_iovlen].iov_base = &opt_mac;
804
-+                iov[msg.msg_iovlen].iov_len = sizeof(opt_mac);
805
-+                msg.msg_iovlen++;
806
-+        }
807
-+
808
-+        if (ra->mtu) {
809
-+                opt_mtu.nd_opt_mtu_mtu = htobe32(ra->mtu);
810
-+                iov[msg.msg_iovlen].iov_base = &opt_mtu;
811
-+                iov[msg.msg_iovlen].iov_len = sizeof(opt_mtu);
812
-+                msg.msg_iovlen++;
813
-+        }
814
-+
815
-+        LIST_FOREACH(prefix, p, ra->prefixes) {
816
-+                iov[msg.msg_iovlen].iov_base = &p->opt;
817
-+                iov[msg.msg_iovlen].iov_len = sizeof(p->opt);
818
-+                msg.msg_iovlen++;
819
-+        }
820
-+
821
-+        if (sendmsg(ra->fd, &msg, 0) < 0)
822
-+                return -errno;
823
-+
824
-+        return 0;
825
-+}
826
-+
827
-+static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
828
-+        sd_radv *ra = userdata;
829
-+        _cleanup_free_ char *addr = NULL;
830
-+        struct in6_addr src;
831
-+        triple_timestamp timestamp;
832
-+        int r;
833
-+        ssize_t buflen;
834
-+        _cleanup_free_ char *buf = NULL;
835
-+
836
-+        assert(s);
837
-+        assert(ra);
838
-+        assert(ra->event);
839
-+
840
-+        buflen = next_datagram_size_fd(fd);
841
-+
842
-+        if ((unsigned) buflen < sizeof(struct nd_router_solicit))
843
-+                return log_radv("Too short packet received");
844
-+
845
-+        buf = new0(char, buflen);
846
-+        if (!buf)
847
-+                return 0;
848
-+
849
-+        r = icmp6_receive(fd, buf, buflen, &src, &timestamp);
850
-+        if (r < 0) {
851
-+                switch (r) {
852
-+                case -EADDRNOTAVAIL:
853
-+                        (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &src, &addr);
854
-+                        log_radv("Received RS from non-link-local address %s. Ignoring", addr);
855
-+                        break;
856
-+
857
-+                case -EMULTIHOP:
858
-+                        log_radv("Received RS with invalid hop limit. Ignoring.");
859
-+                        break;
860
-+
861
-+                case -EPFNOSUPPORT:
862
-+                        log_radv("Received invalid source address from ICMPv6 socket. Ignoring.");
863
-+                        break;
864
-+
865
-+                default:
866
-+                        log_radv_warning_errno(r, "Error receiving from ICMPv6 socket: %m");
867
-+                        break;
868
-+                }
869
-+
870
-+                return 0;
871
-+        }
872
-+
873
-+        (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &src, &addr);
874
-+
875
-+        r = radv_send(ra, &src, ra->lifetime);
876
-+        if (r < 0)
877
-+                log_radv_warning_errno(r, "Unable to send solicited Router Advertisment to %s: %m", addr);
878
-+        else
879
-+                log_radv("Sent solicited Router Advertisement to %s", addr);
880
-+
881
-+        return 0;
882
-+}
883
-+
884
-+static usec_t radv_compute_timeout(usec_t min, usec_t max) {
885
-+        assert_return(min <= max, SD_RADV_DEFAULT_MIN_TIMEOUT_USEC);
886
-+
887
-+        return min + (random_u32() % (max - min));
888
-+}
889
-+
890
-+static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
891
-+        int r;
892
-+        sd_radv *ra = userdata;
893
-+        usec_t min_timeout = SD_RADV_DEFAULT_MIN_TIMEOUT_USEC;
894
-+        usec_t max_timeout = SD_RADV_DEFAULT_MAX_TIMEOUT_USEC;
895
-+        usec_t time_now, timeout;
896
-+        char time_string[FORMAT_TIMESPAN_MAX];
897
-+
898
-+        assert(s);
899
-+        assert(ra);
900
-+        assert(ra->event);
901
-+
902
-+        ra->timeout_event_source = sd_event_source_unref(ra->timeout_event_source);
903
-+
904
-+        r = sd_event_now(ra->event, clock_boottime_or_monotonic(), &time_now);
905
-+        if (r < 0)
906
-+                goto fail;
907
-+
908
-+        r = radv_send(ra, NULL, ra->lifetime);
909
-+        if (r < 0)
910
-+                log_radv_warning_errno(r, "Unable to send Router Advertisement: %m");
911
-+
912
-+        /* RFC 4861, Section 6.2.4, sending initial Router Advertisements */
913
-+        if (ra->ra_sent < SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS) {
914
-+                max_timeout = SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC;
915
-+                min_timeout = SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC / 3;
916
-+        }
917
-+
918
-+        timeout = radv_compute_timeout(min_timeout, max_timeout);
919
-+
920
-+        log_radv("Next Router Advertisement in %s",
921
-+                 format_timespan(time_string, FORMAT_TIMESPAN_MAX,
922
-+                                 timeout, USEC_PER_SEC));
923
-+
924
-+        r = sd_event_add_time(ra->event, &ra->timeout_event_source,
925
-+                              clock_boottime_or_monotonic(),
926
-+                              time_now + timeout, MSEC_PER_SEC,
927
-+                              radv_timeout, ra);
928
-+        if (r < 0)
929
-+                goto fail;
930
-+
931
-+        r = sd_event_source_set_priority(ra->timeout_event_source,
932
-+                                         ra->event_priority);
933
-+        if (r < 0)
934
-+                goto fail;
935
-+
936
-+        r = sd_event_source_set_description(ra->timeout_event_source,
937
-+                                            "radv-timeout");
938
-+        if (r < 0)
939
-+                goto fail;
940
-+
941
-+        ra->ra_sent++;
942
-+
943
-+fail:
944
-+        if (r < 0)
945
-+                sd_radv_stop(ra);
946
-+
947
-+        return 0;
948
-+}
949
-+
950
-+_public_ int sd_radv_stop(sd_radv *ra) {
951
-+        int r;
952
-+
953
-+        assert_return(ra, -EINVAL);
954
-+
955
-+        log_radv("Stopping IPv6 Router Advertisement daemon");
956
-+
957
-+        /* RFC 4861, Section 6.2.5, send at least one Router Advertisement
958
-+           with zero lifetime  */
959
-+        r = radv_send(ra, NULL, 0);
960
-+        if (r < 0)
961
-+                log_radv_warning_errno(r, "Unable to send last Router Advertisement with router lifetime set to zero: %m");
962
-+
963
-+        radv_reset(ra);
964
-+        ra->fd = safe_close(ra->fd);
965
-+        ra->state = SD_RADV_STATE_IDLE;
966
-+
967
-+        return 0;
968
-+}
969
-+
970
-+_public_ int sd_radv_start(sd_radv *ra) {
971
-+        int r = 0;
972
-+
973
-+        assert_return(ra, -EINVAL);
974
-+        assert_return(ra->event, -EINVAL);
975
-+        assert_return(ra->ifindex > 0, -EINVAL);
976
-+
977
-+        if (ra->state != SD_RADV_STATE_IDLE)
978
-+                return 0;
979
-+
980
-+        r = sd_event_add_time(ra->event, &ra->timeout_event_source,
981
-+                              clock_boottime_or_monotonic(), 0, 0,
982
-+                              radv_timeout, ra);
983
-+        if (r < 0)
984
-+                goto fail;
985
-+
986
-+        r = sd_event_source_set_priority(ra->timeout_event_source,
987
-+                                         ra->event_priority);
988
-+        if (r < 0)
989
-+                goto fail;
990
-+
991
-+        (void) sd_event_source_set_description(ra->timeout_event_source,
992
-+                                               "radv-timeout");
993
-+
994
-+        r = icmp6_bind_router_advertisement(ra->ifindex);
995
-+        if (r < 0)
996
-+                goto fail;
997
-+
998
-+        ra->fd = r;
999
-+
1000
-+        r = sd_event_add_io(ra->event, &ra->recv_event_source, ra->fd, EPOLLIN, radv_recv, ra);
1001
-+        if (r < 0)
1002
-+                goto fail;
1003
-+
1004
-+        r = sd_event_source_set_priority(ra->recv_event_source, ra->event_priority);
1005
-+        if (r < 0)
1006
-+                goto fail;
1007
-+
1008
-+        (void) sd_event_source_set_description(ra->recv_event_source, "radv-receive-message");
1009
-+
1010
-+        ra->state = SD_RADV_STATE_ADVERTISING;
1011
-+
1012
-+        log_radv("Started IPv6 Router Advertisement daemon");
1013
-+
1014
-+        return 0;
1015
-+
1016
-+ fail:
1017
-+        radv_reset(ra);
1018
-+
1019
-+        return r;
1020
-+}
1021
-+
1022
-+_public_ int sd_radv_set_ifindex(sd_radv *ra, int ifindex) {
1023
-+        assert_return(ra, -EINVAL);
1024
-+        assert_return(ifindex >= -1, -EINVAL);
1025
-+
1026
-+        if (ra->state != SD_RADV_STATE_IDLE)
1027
-+                return -EBUSY;
1028
-+
1029
-+        ra->ifindex = ifindex;
1030
-+
1031
-+        return 0;
1032
-+}
1033
-+
1034
-+_public_ int sd_radv_set_mac(sd_radv *ra, const struct ether_addr *mac_addr) {
1035
-+        assert_return(ra, -EINVAL);
1036
-+
1037
-+        if (ra->state != SD_RADV_STATE_IDLE)
1038
-+                return -EBUSY;
1039
-+
1040
-+        if (mac_addr)
1041
-+                ra->mac_addr = *mac_addr;
1042
-+        else
1043
-+                zero(ra->mac_addr);
1044
-+
1045
-+        return 0;
1046
-+}
1047
-+
1048
-+_public_ int sd_radv_set_mtu(sd_radv *ra, uint32_t mtu) {
1049
-+        assert_return(ra, -EINVAL);
1050
-+        assert_return(mtu >= 1280, -EINVAL);
1051
-+
1052
-+        if (ra->state != SD_RADV_STATE_IDLE)
1053
-+                return -EBUSY;
1054
-+
1055
-+        ra->mtu = mtu;
1056
-+
1057
-+        return 0;
1058
-+}
1059
-+
1060
-+_public_ int sd_radv_set_hop_limit(sd_radv *ra, uint8_t hop_limit) {
1061
-+        assert_return(ra, -EINVAL);
1062
-+
1063
-+        if (ra->state != SD_RADV_STATE_IDLE)
1064
-+                return -EBUSY;
1065
-+
1066
-+        ra->hop_limit = hop_limit;
1067
-+
1068
-+        return 0;
1069
-+}
1070
-+
1071
-+_public_ int sd_radv_set_router_lifetime(sd_radv *ra, uint32_t router_lifetime) {
1072
-+        assert_return(ra, -EINVAL);
1073
-+
1074
-+        if (ra->state != SD_RADV_STATE_IDLE)
1075
-+                return -EBUSY;
1076
-+
1077
-+        /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the
1078
-+           preference value MUST be set to (00) by the sender..." */
1079
-+        if (router_lifetime == 0 &&
1080
-+            (ra->flags & (0x3 << 3)) != (SD_NDISC_PREFERENCE_MEDIUM << 3))
1081
-+                return -ETIME;
1082
-+
1083
-+        ra->lifetime = router_lifetime;
1084
-+
1085
-+        return 0;
1086
-+}
1087
-+
1088
-+_public_ int sd_radv_set_managed_information(sd_radv *ra, int managed) {
1089
-+        assert_return(ra, -EINVAL);
1090
-+
1091
-+        if (ra->state != SD_RADV_STATE_IDLE)
1092
-+                return -EBUSY;
1093
-+
1094
-+        SET_FLAG(ra->flags, ND_RA_FLAG_MANAGED, managed);
1095
-+
1096
-+        return 0;
1097
-+}
1098
-+
1099
-+_public_ int sd_radv_set_other_information(sd_radv *ra, int other) {
1100
-+        assert_return(ra, -EINVAL);
1101
-+
1102
-+        if (ra->state != SD_RADV_STATE_IDLE)
1103
-+                return -EBUSY;
1104
-+
1105
-+        SET_FLAG(ra->flags, ND_RA_FLAG_OTHER, other);
1106
-+
1107
-+        return 0;
1108
-+}
1109
-+
1110
-+_public_ int sd_radv_set_preference(sd_radv *ra, unsigned preference) {
1111
-+        int r = 0;
1112
-+
1113
-+        assert_return(ra, -EINVAL);
1114
-+        assert_return(IN_SET(preference,
1115
-+                             SD_NDISC_PREFERENCE_LOW,
1116
-+                             SD_NDISC_PREFERENCE_MEDIUM,
1117
-+                             SD_NDISC_PREFERENCE_HIGH), -EINVAL);
1118
-+
1119
-+        ra->flags = (ra->flags & ~(0x3 << 3)) | (preference << 3);
1120
-+
1121
-+        return r;
1122
-+}
1123
-+
1124
-+_public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p) {
1125
-+        sd_radv_prefix *cur;
1126
-+        _cleanup_free_ char *addr_p = NULL;
1127
-+
1128
-+        assert_return(ra, -EINVAL);
1129
-+
1130
-+        if (!p)
1131
-+                return -EINVAL;
1132
-+
1133
-+        LIST_FOREACH(prefix, cur, ra->prefixes) {
1134
-+                int r;
1135
-+
1136
-+                r = in_addr_prefix_intersect(AF_INET6,
1137
-+                                             (union in_addr_union*) &cur->opt.in6_addr,
1138
-+                                             cur->opt.prefixlen,
1139
-+                                             (union in_addr_union*) &p->opt.in6_addr,
1140
-+                                             p->opt.prefixlen);
1141
-+                if (r > 0) {
1142
-+                        _cleanup_free_ char *addr_cur = NULL;
1143
-+
1144
-+                        (void) in_addr_to_string(AF_INET6,
1145
-+                                                 (union in_addr_union*) &cur->opt.in6_addr,
1146
-+                                                 &addr_cur);
1147
-+                        (void) in_addr_to_string(AF_INET6,
1148
-+                                                 (union in_addr_union*) &p->opt.in6_addr,
1149
-+                                                 &addr_p);
1150
-+
1151
-+                        log_radv("IPv6 prefix %s/%u already configured, ignoring %s/%u",
1152
-+                                 addr_cur, cur->opt.prefixlen,
1153
-+                                 addr_p, p->opt.prefixlen);
1154
-+
1155
-+                        return -EEXIST;
1156
-+                }
1157
-+        }
1158
-+
1159
-+        p = sd_radv_prefix_ref(p);
1160
-+
1161
-+        LIST_APPEND(prefix, ra->prefixes, p);
1162
-+
1163
-+        ra->n_prefixes++;
1164
-+
1165
-+        (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &p->opt.in6_addr, &addr_p);
1166
-+        log_radv("Added prefix %s/%d", addr_p, p->opt.prefixlen);
1167
-+
1168
-+        return 0;
1169
-+}
1170
-+
1171
-+_public_ int sd_radv_prefix_new(sd_radv_prefix **ret) {
1172
-+        _cleanup_(sd_radv_prefix_unrefp) sd_radv_prefix *p = NULL;
1173
-+
1174
-+        assert_return(ret, -EINVAL);
1175
-+
1176
-+        p = new0(sd_radv_prefix, 1);
1177
-+        if (!p)
1178
-+                return -ENOMEM;
1179
-+
1180
-+        p->n_ref = 1;
1181
-+
1182
-+        p->opt.type = ND_OPT_PREFIX_INFORMATION;
1183
-+        p->opt.length = (sizeof(p->opt) - 1) /8 + 1;
1184
-+
1185
-+        p->opt.prefixlen = 64;
1186
-+
1187
-+        /* RFC 4861, Section 6.2.1 */
1188
-+        SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_ONLINK, true);
1189
-+        SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_AUTO, true);
1190
-+        p->opt.preferred_lifetime = htobe32(604800);
1191
-+        p->opt.valid_lifetime = htobe32(2592000);
1192
-+
1193
-+        LIST_INIT(prefix, p);
1194
-+
1195
-+        *ret = p;
1196
-+        p = NULL;
1197
-+
1198
-+        return 0;
1199
-+}
1200
-+
1201
-+_public_ sd_radv_prefix *sd_radv_prefix_ref(sd_radv_prefix *p) {
1202
-+        if (!p)
1203
-+                return NULL;
1204
-+
1205
-+        assert(p->n_ref > 0);
1206
-+        p->n_ref++;
1207
-+
1208
-+        return p;
1209
-+}
1210
-+
1211
-+_public_ sd_radv_prefix *sd_radv_prefix_unref(sd_radv_prefix *p) {
1212
-+        if (!p)
1213
-+                return NULL;
1214
-+
1215
-+        assert(p->n_ref > 0);
1216
-+        p->n_ref--;
1217
-+
1218
-+        if (p->n_ref > 0)
1219
-+                return NULL;
1220
-+
1221
-+        return mfree(p);
1222
-+}
1223
-+
1224
-+_public_ int sd_radv_prefix_set_prefix(sd_radv_prefix *p, struct in6_addr *in6_addr,
1225
-+                                       unsigned char prefixlen) {
1226
-+        assert_return(p, -EINVAL);
1227
-+        assert_return(in6_addr, -EINVAL);
1228
-+
1229
-+        if (prefixlen < 3 || prefixlen > 128)
1230
-+                return -EINVAL;
1231
-+
1232
-+        if (prefixlen > 64)
1233
-+                /* unusual but allowed, log it */
1234
-+                log_radv("Unusual prefix length %d greater than 64", prefixlen);
1235
-+
1236
-+        p->opt.in6_addr = *in6_addr;
1237
-+        p->opt.prefixlen = prefixlen;
1238
-+
1239
-+        return 0;
1240
-+}
1241
-+
1242
-+_public_ int sd_radv_prefix_set_onlink(sd_radv_prefix *p, int onlink) {
1243
-+        assert_return(p, -EINVAL);
1244
-+
1245
-+        SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_ONLINK, onlink);
1246
-+
1247
-+        return 0;
1248
-+}
1249
-+
1250
-+_public_ int sd_radv_prefix_set_address_autoconfiguration(sd_radv_prefix *p,
1251
-+                                                          int address_autoconfiguration) {
1252
-+        assert_return(p, -EINVAL);
1253
-+
1254
-+        SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_AUTO, address_autoconfiguration);
1255
-+
1256
-+        return 0;
1257
-+}
1258
-+
1259
-+_public_ int sd_radv_prefix_set_valid_lifetime(sd_radv_prefix *p,
1260
-+                                               uint32_t valid_lifetime) {
1261
-+        assert_return(p, -EINVAL);
1262
-+
1263
-+        p->opt.valid_lifetime = htobe32(valid_lifetime);
1264
-+
1265
-+        return 0;
1266
-+}
1267
-+
1268
-+_public_ int sd_radv_prefix_set_preferred_lifetime(sd_radv_prefix *p,
1269
-+                                                   uint32_t preferred_lifetime) {
1270
-+        assert_return(p, -EINVAL);
1271
-+
1272
-+        p->opt.preferred_lifetime = htobe32(preferred_lifetime);
1273
-+
1274
-+        return 0;
1275
-+}
1276
-diff -rupN systemd-base/src/libsystemd-network/test-ndisc-rs.c systemd/src/libsystemd-network/test-ndisc-rs.c
1277
-+++ systemd/src/libsystemd-network/test-ndisc-rs.c	2017-09-18 15:07:09.099322638 -0700
1278
-@@ -193,6 +193,21 @@ int icmp6_bind_router_solicitation(int i
1279
-         return test_fd[0];
1280
- }
1281
- 
1282
-+int icmp6_bind_router_advertisement(int index) {
1283
-+
1284
-+        return -ENOSYS;
1285
-+}
1286
-+
1287
-+int icmp6_receive(int fd, void *iov_base, size_t iov_len,
1288
-+                  struct in6_addr *dst, triple_timestamp *timestamp) {
1289
-+        assert (read (fd, iov_base, iov_len) == (ssize_t)iov_len);
1290
-+
1291
-+        if (timestamp)
1292
-+                triple_timestamp_get(timestamp);
1293
-+
1294
-+        return 0;
1295
-+}
1296
-+
1297
- static int send_ra(uint8_t flags) {
1298
-         uint8_t advertisement[] = {
1299
-                 0x86, 0x00, 0xde, 0x83, 0x40, 0xc0, 0x00, 0xb4,
1300
-diff -rupN systemd-base/src/network/networkd-ndisc.c systemd/src/network/networkd-ndisc.c
1301
-+++ systemd/src/network/networkd-ndisc.c	2017-09-18 14:39:40.690643380 -0700
1302
-@@ -27,6 +27,7 @@
1303
- 
1304
- #define NDISC_DNSSL_MAX 64U
1305
- #define NDISC_RDNSS_MAX 64U
1306
-+#define NDISC_PREFIX_LFT_MIN 7200U
1307
- 
1308
- static int ndisc_netlink_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
1309
-         _cleanup_link_unref_ Link *link = userdata;
1310
-@@ -152,13 +153,21 @@ static void ndisc_router_process_default
1311
- 
1312
- static void ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *rt) {
1313
-         _cleanup_address_free_ Address *address = NULL;
1314
--        uint32_t lifetime_valid, lifetime_preferred;
1315
-+        Address *existing_address;
1316
-+        uint32_t lifetime_valid, lifetime_preferred, lifetime_remaining;
1317
-+        usec_t time_now;
1318
-         unsigned prefixlen;
1319
-         int r;
1320
- 
1321
-         assert(link);
1322
-         assert(rt);
1323
- 
1324
-+        r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
1325
-+        if (r < 0) {
1326
-+                log_link_warning_errno(link, r, "Failed to get RA timestamp: %m");
1327
-+                return;
1328
-+        }
1329
-+
1330
-         r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen);
1331
-         if (r < 0) {
1332
-                 log_link_error_errno(link, r, "Failed to get prefix length: %m");
1333
-@@ -207,7 +216,24 @@ static void ndisc_router_process_autonom
1334
-         address->prefixlen = prefixlen;
1335
-         address->flags = IFA_F_NOPREFIXROUTE|IFA_F_MANAGETEMPADDR;
1336
-         address->cinfo.ifa_prefered = lifetime_preferred;
1337
--        address->cinfo.ifa_valid = lifetime_valid;
1338
-+
1339
-+        /* see RFC4862 section 5.5.3.e */
1340
-+        r = address_get(link, address->family, &address->in_addr, address->prefixlen, &existing_address);
1341
-+        if (r > 0) {
1342
-+                lifetime_remaining = existing_address->cinfo.tstamp / 100 + existing_address->cinfo.ifa_valid - time_now / USEC_PER_SEC;
1343
-+                if (lifetime_valid > NDISC_PREFIX_LFT_MIN || lifetime_valid > lifetime_remaining)
1344
-+                        address->cinfo.ifa_valid = lifetime_valid;
1345
-+                else if (lifetime_remaining <= NDISC_PREFIX_LFT_MIN)
1346
-+                        address->cinfo.ifa_valid = lifetime_remaining;
1347
-+                else
1348
-+                        address->cinfo.ifa_valid = NDISC_PREFIX_LFT_MIN;
1349
-+        } else if (lifetime_valid > 0)
1350
-+                address->cinfo.ifa_valid = lifetime_valid;
1351
-+        else
1352
-+                return; /* see RFC4862 section 5.5.3.d */
1353
-+
1354
-+        if (address->cinfo.ifa_valid == 0)
1355
-+                return;
1356
- 
1357
-         r = address_configure(address, link, ndisc_netlink_handler, true);
1358
-         if (r < 0) {
1359
-diff -rupN systemd-base/src/systemd/sd-radv.h systemd/src/systemd/sd-radv.h
1360
-+++ systemd/src/systemd/sd-radv.h	2017-09-18 14:58:44.807575602 -0700
1361
-@@ -0,0 +1,81 @@
1362
-+#ifndef foosdradvfoo
1363
-+#define foosdradvfoo
1364
-+
1365
-+/***
1366
-+  This file is part of systemd.
1367
-+
1368
-+  Copyright (C) 2017 Intel Corporation. All rights reserved.
1369
-+
1370
-+  systemd is free software; you can redistribute it and/or modify it
1371
-+  under the terms of the GNU Lesser General Public License as published by
1372
-+  the Free Software Foundation; either version 2.1 of the License, or
1373
-+  (at your option) any later version.
1374
-+
1375
-+  systemd is distributed in the hope that it will be useful, but
1376
-+  WITHOUT ANY WARRANTY; without even the implied warranty of
1377
-+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1378
-+  Lesser General Public License for more details.
1379
-+
1380
-+  You should have received a copy of the GNU Lesser General Public License
1381
-+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
1382
-+***/
1383
-+
1384
-+#include <inttypes.h>
1385
-+#include <net/ethernet.h>
1386
-+#include <netinet/in.h>
1387
-+#include <sys/types.h>
1388
-+
1389
-+#include "sd-ndisc.h"
1390
-+
1391
-+#include "sd-event.h"
1392
-+
1393
-+#include "_sd-common.h"
1394
-+
1395
-+_SD_BEGIN_DECLARATIONS;
1396
-+
1397
-+typedef struct sd_radv sd_radv;
1398
-+typedef struct sd_radv_prefix sd_radv_prefix;
1399
-+
1400
-+/* Router Advertisment */
1401
-+int sd_radv_new(sd_radv **ret);
1402
-+sd_radv *sd_radv_ref(sd_radv *ra);
1403
-+sd_radv *sd_radv_unref(sd_radv *ra);
1404
-+
1405
-+int sd_radv_attach_event(sd_radv *ra, sd_event *event, int64_t priority);
1406
-+int sd_radv_detach_event(sd_radv *nd);
1407
-+sd_event *sd_radv_get_event(sd_radv *ra);
1408
-+
1409
-+int sd_radv_start(sd_radv *ra);
1410
-+int sd_radv_stop(sd_radv *ra);
1411
-+
1412
-+int sd_radv_set_ifindex(sd_radv *ra, int interface_index);
1413
-+int sd_radv_set_mac(sd_radv *ra, const struct ether_addr *mac_addr);
1414
-+int sd_radv_set_mtu(sd_radv *ra, uint32_t mtu);
1415
-+int sd_radv_set_hop_limit(sd_radv *ra, uint8_t hop_limit);
1416
-+int sd_radv_set_router_lifetime(sd_radv *ra, uint32_t router_lifetime);
1417
-+int sd_radv_set_managed_information(sd_radv *ra, int managed);
1418
-+int sd_radv_set_other_information(sd_radv *ra, int other);
1419
-+int sd_radv_set_preference(sd_radv *ra, unsigned preference);
1420
-+int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p);
1421
-+
1422
-+/* Advertised prefixes */
1423
-+int sd_radv_prefix_new(sd_radv_prefix **ret);
1424
-+sd_radv_prefix *sd_radv_prefix_ref(sd_radv_prefix *ra);
1425
-+sd_radv_prefix *sd_radv_prefix_unref(sd_radv_prefix *ra);
1426
-+
1427
-+int sd_radv_prefix_set_prefix(sd_radv_prefix *p, struct in6_addr *in6_addr,
1428
-+                              unsigned char prefixlen);
1429
-+int sd_radv_prefix_set_onlink(sd_radv_prefix *p, int onlink);
1430
-+int sd_radv_prefix_set_address_autoconfiguration(sd_radv_prefix *p,
1431
-+                                                 int address_autoconfiguration);
1432
-+int sd_radv_prefix_set_valid_lifetime(sd_radv_prefix *p,
1433
-+                                      uint32_t valid_lifetime);
1434
-+int sd_radv_prefix_set_preferred_lifetime(sd_radv_prefix *p,
1435
-+                                          uint32_t preferred_lifetime);
1436
-+
1437
-+_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_radv, sd_radv_unref);
1438
-+_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_radv_prefix, sd_radv_prefix_unref);
1439
-+
1440
-+_SD_END_DECLARATIONS;
1441
-+
1442
-+#endif
... ...
@@ -1,7 +1,7 @@
1 1
 Summary:          Systemd-233
2 2
 Name:             systemd
3 3
 Version:          233
4
-Release:          9%{?dist}
4
+Release:          8%{?dist}
5 5
 License:          LGPLv2+ and GPLv2+ and MIT
6 6
 URL:              http://www.freedesktop.org/wiki/Software/systemd/
7 7
 Group:            System Environment/Security
... ...
@@ -25,7 +25,6 @@ Patch7:           systemd-233-CVE-2017-9217.patch
25 25
 Patch8:           systemd-233-CVE-2017-9445-dns-oob.patch
26 26
 Patch9:           systemd-233-CVE-2017-1000082-1.patch
27 27
 Patch10:          systemd-233-CVE-2017-1000082-2.patch
28
-Patch11:          systemd-233-ra-improvements.patch
29 28
 
30 29
 Requires:         Linux-PAM
31 30
 Requires:         libcap
... ...
@@ -90,7 +89,6 @@ sed -i "/xlocale.h/d" src/basic/parse-util.c
90 90
 %patch8 -p1
91 91
 %patch9 -p1
92 92
 %patch10 -p1
93
-%patch11 -p1
94 93
 
95 94
 sed -i "s#\#DefaultTasksMax=512#DefaultTasksMax=infinity#g" src/core/system.conf
96 95
 
... ...
@@ -239,8 +237,6 @@ rm -rf %{buildroot}/*
239 239
 %files lang -f %{name}.lang
240 240
 
241 241
 %changelog
242
-*    Mon Sep 18 2017 Anish Swaminathan <anishs@vmware.com>  233-9
243
--    Backport router solicitation backoff from systemd 234
244 242
 *    Fri Sep 15 2017 Anish Swaminathan <anishs@vmware.com>  233-8
245 243
 -    Move network file to systemd package
246 244
 *    Tue Aug 15 2017 Alexey Makhalov <amakhalov@vmware.com> 233-7