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>
| 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, ×tamp); |
|
| 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 |