b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen/***
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen This file is part of systemd.
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen Copyright 2013-2014 Tom Gundersen <teg@jklm.no>
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen systemd is free software; you can redistribute it and/or modify it
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen under the terms of the GNU Lesser General Public License as published by
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen the Free Software Foundation; either version 2.1 of the License, or
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen (at your option) any later version.
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen systemd is distributed in the hope that it will be useful, but
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen Lesser General Public License for more details.
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen You should have received a copy of the GNU Lesser General Public License
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen***/
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen#include <netinet/ether.h>
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen#include <linux/if.h>
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen#include "network-internal.h"
cf0fbc49e67b55f8d346fc94de28c90113505297Thomas Hindoe Paaboel Andersen#include "networkd-link.h"
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersenstatic int ipv4ll_address_lost(Link *link) {
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen _cleanup_address_free_ Address *address = NULL;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen _cleanup_route_free_ Route *route = NULL;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen struct in_addr addr;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen int r;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen assert(link);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen link->ipv4ll_route = false;
920b52e4909d9dc812817fd8b82f83ca23a11c91Thomas Hindoe Paaboel Andersen link->ipv4ll_address = false;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (r < 0)
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return 0;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering log_link_debug(link, "IPv4 link-local release %u.%u.%u.%u", ADDRESS_FMT_VAL(addr));
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
f0213e3796b4dd66e546e2de4d677db319f9171bTom Gundersen r = address_new(&address);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (r < 0) {
e53fc357a9bb9d0a5362ccc4246d598cb0febd5eLennart Poettering log_link_error_errno(link, r, "Could not allocate address: %m");
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return r;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen }
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen address->family = AF_INET;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen address->in_addr.in = addr;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen address->prefixlen = 16;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen address->scope = RT_SCOPE_LINK;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
91b5f997316ddc77d26f9a7a5e24c335484586bdTom Gundersen address_remove(address, link, &link_address_remove_handler);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
ed9e361a8a798f9fee353b5c7e0e23308e0d329fTom Gundersen r = route_new(&route);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (r < 0) {
e53fc357a9bb9d0a5362ccc4246d598cb0febd5eLennart Poettering log_link_error_errno(link, r, "Could not allocate route: %m");
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return r;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen }
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen route->family = AF_INET;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen route->scope = RT_SCOPE_LINK;
86655331bc28887def7998d321b14ef8fccbeaf9Tom Gundersen route->priority = IPV4LL_ROUTE_METRIC;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
91b5f997316ddc77d26f9a7a5e24c335484586bdTom Gundersen route_remove(route, link, &link_route_remove_handler);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
8012cd391932d58b44332df106d426a360faf0a6Tom Gundersen link_check_ready(link);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return 0;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen}
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersenstatic int ipv4ll_route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen _cleanup_link_unref_ Link *link = userdata;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen int r;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen assert(link);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen assert(!link->ipv4ll_route);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_netlink_message_get_errno(m);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (r < 0 && r != -EEXIST) {
e53fc357a9bb9d0a5362ccc4246d598cb0febd5eLennart Poettering log_link_error_errno(link, r, "could not set ipv4ll route: %m");
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen link_enter_failed(link);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen }
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen link->ipv4ll_route = true;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (link->ipv4ll_address == true)
8012cd391932d58b44332df106d426a360faf0a6Tom Gundersen link_check_ready(link);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return 1;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen}
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersenstatic int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen _cleanup_link_unref_ Link *link = userdata;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen int r;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen assert(link);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen assert(!link->ipv4ll_address);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_netlink_message_get_errno(m);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (r < 0 && r != -EEXIST) {
e53fc357a9bb9d0a5362ccc4246d598cb0febd5eLennart Poettering log_link_error_errno(link, r, "could not set ipv4ll address: %m");
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen link_enter_failed(link);
45af44d47da6933b260c734ad9ff721f63f80a4dTom Gundersen } else if (r >= 0)
200a0868fcdf7b95f3d8d1fda3aa2aef48d84fddTom Gundersen manager_rtnl_process_address(rtnl, m, link->manager);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen link->ipv4ll_address = true;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (link->ipv4ll_route == true)
8012cd391932d58b44332df106d426a360faf0a6Tom Gundersen link_check_ready(link);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return 1;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen}
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersenstatic int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen _cleanup_address_free_ Address *ll_addr = NULL;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen _cleanup_route_free_ Route *route = NULL;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen struct in_addr address;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen int r;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen assert(ll);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen assert(link);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen r = sd_ipv4ll_get_address(ll, &address);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (r == -ENOENT)
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return 0;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen else if (r < 0)
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return r;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering log_link_debug(link, "IPv4 link-local claim %u.%u.%u.%u",
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen ADDRESS_FMT_VAL(address));
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
f0213e3796b4dd66e546e2de4d677db319f9171bTom Gundersen r = address_new(&ll_addr);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (r < 0)
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return r;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen ll_addr->family = AF_INET;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen ll_addr->in_addr.in = address;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen ll_addr->prefixlen = 16;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen ll_addr->scope = RT_SCOPE_LINK;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
6666907869fb3bc7fe6a6025540db5b887c7a78bTom Gundersen r = address_configure(ll_addr, link, ipv4ll_address_handler, false);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (r < 0)
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return r;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen link->ipv4ll_address = false;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
ed9e361a8a798f9fee353b5c7e0e23308e0d329fTom Gundersen r = route_new(&route);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (r < 0)
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return r;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen route->family = AF_INET;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen route->scope = RT_SCOPE_LINK;
ed9e361a8a798f9fee353b5c7e0e23308e0d329fTom Gundersen route->protocol = RTPROT_STATIC;
86655331bc28887def7998d321b14ef8fccbeaf9Tom Gundersen route->priority = IPV4LL_ROUTE_METRIC;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen r = route_configure(route, link, ipv4ll_route_handler);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (r < 0)
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return r;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen link->ipv4ll_route = false;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return 0;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen}
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersenstatic void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen Link *link = userdata;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen int r;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen assert(link);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen assert(link->network);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen assert(link->manager);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen switch(event) {
be19c5b5e0c0f78b8429b126936fa15856550a23David Herrmann case SD_IPV4LL_EVENT_STOP:
be19c5b5e0c0f78b8429b126936fa15856550a23David Herrmann case SD_IPV4LL_EVENT_CONFLICT:
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen r = ipv4ll_address_lost(link);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (r < 0) {
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen link_enter_failed(link);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen }
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen break;
be19c5b5e0c0f78b8429b126936fa15856550a23David Herrmann case SD_IPV4LL_EVENT_BIND:
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen r = ipv4ll_address_claimed(ll, link);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (r < 0) {
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen link_enter_failed(link);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen }
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen break;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen default:
b45e4eb679ad0c9a77c4fe6e404c8842d4097fdbTom Gundersen log_link_warning(link, "IPv4 link-local unknown event: %d", event);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen break;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen }
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen}
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersenint ipv4ll_configure(Link *link) {
dbe81cbd2a93088236a2e4e41eeb33378940f7b9Martin Pitt uint64_t seed;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen int r;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen assert(link);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen assert(link->network);
e0ee46f29028e291eb67f435aff1b6202d75d9d6Lennart Poettering assert(link->network->link_local & ADDRESS_FAMILY_IPV4);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
0bc70f1d9c5453ba614ec0ed041dc30b9cd52071Tom Gundersen if (!link->ipv4ll) {
0bc70f1d9c5453ba614ec0ed041dc30b9cd52071Tom Gundersen r = sd_ipv4ll_new(&link->ipv4ll);
0bc70f1d9c5453ba614ec0ed041dc30b9cd52071Tom Gundersen if (r < 0)
0bc70f1d9c5453ba614ec0ed041dc30b9cd52071Tom Gundersen return r;
0bc70f1d9c5453ba614ec0ed041dc30b9cd52071Tom Gundersen }
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (link->udev_device) {
dbe81cbd2a93088236a2e4e41eeb33378940f7b9Martin Pitt r = net_get_unique_predictable_data(link->udev_device, &seed);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (r >= 0) {
e3dca0089b7b50e2ec21409d1292727921d06102Tom Gundersen assert_cc(sizeof(unsigned) <= 8);
e3dca0089b7b50e2ec21409d1292727921d06102Tom Gundersen
dbe81cbd2a93088236a2e4e41eeb33378940f7b9Martin Pitt r = sd_ipv4ll_set_address_seed(link->ipv4ll, (unsigned)seed);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (r < 0)
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return r;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen }
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen }
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (r < 0)
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return r;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (r < 0)
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return r;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (r < 0)
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return r;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen if (r < 0)
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return r;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen return 0;
b22d8a00f48f3c5fc4510b4acd3e1a43e731e592Tom Gundersen}