networkd-ipv4ll.c revision d0d6a4cd70477970812bff0a37e70f66208d7c14
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering/***
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering This file is part of systemd.
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering Copyright 2013-2014 Tom Gundersen <teg@jklm.no>
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering systemd is free software; you can redistribute it and/or modify it
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering under the terms of the GNU Lesser General Public License as published by
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering (at your option) any later version.
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering systemd is distributed in the hope that it will be useful, but
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering Lesser General Public License for more details.
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering You should have received a copy of the GNU Lesser General Public License
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering***/
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering#include <netinet/ether.h>
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering#include <linux/if.h>
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering#include "networkd-link.h"
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering#include "network-internal.h"
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersenstatic int ipv4ll_address_lost(Link *link) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_address_free_ Address *address = NULL;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_route_free_ Route *route = NULL;
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen struct in_addr addr;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering int r;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering assert(link);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering link->ipv4ll_route = false;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering link->ipv4ll_address = false;
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (r < 0)
db73295accbec0c6513817f0a64a92018592bb26Lennart Poettering return 0;
d8500c53789eafefe28d4ace088bf4b912280bf9Tom Gundersen
266b538958932e6fc27dfce4917336e70e17e29eTom Gundersen log_link_debug(link, "IPv4 link-local release %u.%u.%u.%u", ADDRESS_FMT_VAL(addr));
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering r = address_new_dynamic(&address);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (r < 0) {
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering log_link_error(link, "Could not allocate address: %s", strerror(-r));
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering return r;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering }
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering address->family = AF_INET;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering address->in_addr.in = addr;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering address->prefixlen = 16;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering address->scope = RT_SCOPE_LINK;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering address_drop(address, link, &link_address_drop_handler);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering r = route_new_dynamic(&route, RTPROT_UNSPEC);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (r < 0) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering log_link_error(link, "Could not allocate route: %s",
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering strerror(-r));
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering return r;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering }
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering route->family = AF_INET;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering route->scope = RT_SCOPE_LINK;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering route->metrics = IPV4LL_ROUTE_METRIC;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering route_drop(route, link, &link_route_drop_handler);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering link_client_handler(link);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering return 0;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering}
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poetteringstatic int ipv4ll_route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_link_unref_ Link *link = userdata;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering int r;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering assert(link);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering assert(!link->ipv4ll_route);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering r = sd_rtnl_message_get_errno(m);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (r < 0 && r != -EEXIST) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering log_link_error(link, "could not set ipv4ll route: %s", strerror(-r));
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering link_enter_failed(link);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering }
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering link->ipv4ll_route = true;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (link->ipv4ll_address == true)
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering link_client_handler(link);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering return 1;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering}
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poetteringstatic int ipv4ll_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_link_unref_ Link *link = userdata;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering int r;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering assert(link);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering assert(!link->ipv4ll_address);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering r = sd_rtnl_message_get_errno(m);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering if (r < 0 && r != -EEXIST) {
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering log_link_error(link, "could not set ipv4ll address: %s", strerror(-r));
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering link_enter_failed(link);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering } else if (r >= 0)
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering link_rtnl_process_address(rtnl, m, link->manager);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering link->ipv4ll_address = true;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering if (link->ipv4ll_route == true)
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering link_client_handler(link);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering return 1;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering}
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poetteringstatic int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering _cleanup_address_free_ Address *ll_addr = NULL;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering _cleanup_route_free_ Route *route = NULL;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering struct in_addr address;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering int r;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering assert(ll);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering assert(link);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering r = sd_ipv4ll_get_address(ll, &address);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering if (r == -ENOENT)
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering return 0;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering else if (r < 0)
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering return r;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering log_link_debug(link, "IPv4 link-local claim %u.%u.%u.%u",
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering ADDRESS_FMT_VAL(address));
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering r = address_new_dynamic(&ll_addr);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering if (r < 0)
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering return r;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering ll_addr->family = AF_INET;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering ll_addr->in_addr.in = address;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering ll_addr->prefixlen = 16;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering ll_addr->scope = RT_SCOPE_LINK;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering r = address_configure(ll_addr, link, ipv4ll_address_handler);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering if (r < 0)
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering return r;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
a6a4f528899b1dab47408733b4a423c66ea40f7aThomas Hindoe Paaboel Andersen link->ipv4ll_address = false;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering r = route_new_dynamic(&route, RTPROT_STATIC);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering if (r < 0)
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering return r;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering route->family = AF_INET;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering route->scope = RT_SCOPE_LINK;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering route->metrics = IPV4LL_ROUTE_METRIC;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering r = route_configure(route, link, ipv4ll_route_handler);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering if (r < 0)
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering return r;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering link->ipv4ll_route = false;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering return 0;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering}
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poetteringstatic void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering Link *link = userdata;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering int r;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering assert(link);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering assert(link->network);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering assert(link->manager);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering return;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering switch(event) {
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering case IPV4LL_EVENT_STOP:
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering case IPV4LL_EVENT_CONFLICT:
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering r = ipv4ll_address_lost(link);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering if (r < 0) {
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering link_enter_failed(link);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering return;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering }
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering break;
266b538958932e6fc27dfce4917336e70e17e29eTom Gundersen case IPV4LL_EVENT_BIND:
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering r = ipv4ll_address_claimed(ll, link);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (r < 0) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering link_enter_failed(link);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering return;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering }
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering break;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering default:
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (event < 0)
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering log_link_warning(link, "IPv4 link-local error: %s", strerror(-event));
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt else
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt log_link_warning(link, "IPv4 link-local unknown event: %d", event);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering break;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering }
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt}
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poetteringint ipv4ll_configure(Link *link) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering uint8_t seed[8];
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering int r;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering assert(link);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering assert(link->network);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering assert(IN_SET(link->network->link_local, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES));
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering r = sd_ipv4ll_new(&link->ipv4ll);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (r < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return r;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (link->udev_device) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering r = net_get_unique_predictable_data(link->udev_device, seed);
3e3db0ee860025ad663b13b0ace4e6d627611332Lennart Poettering if (r >= 0) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering if (r < 0)
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering return r;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering }
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering }
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
ab1525bc2d92780b4dc64bc5b9cdb52594e2df7dLennart Poettering r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (r < 0)
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering return r;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering
df3fb561b2df486a495a5f0bcc83168bd1860533Lennart Poettering r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (r < 0)
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering return r;
d6731e4c7964ee2860d4f5abdb0b52acd7a66960Tom Gundersen
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering if (r < 0)
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering return r;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering if (r < 0)
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering return r;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering return 0;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering}
3e3db0ee860025ad663b13b0ace4e6d627611332Lennart Poettering