networkd-ipv4ll.c revision f0213e3796b4dd66e546e2de4d677db319f9171b
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering This file is part of systemd.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Copyright 2013-2014 Tom Gundersen <teg@jklm.no>
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering systemd is free software; you can redistribute it and/or modify it
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering under the terms of the GNU Lesser General Public License as published by
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering (at your option) any later version.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering systemd is distributed in the hope that it will be useful, but
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Lesser General Public License for more details.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering You should have received a copy of the GNU Lesser General Public License
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int ipv4ll_address_lost(Link *link) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering _cleanup_address_free_ Address *address = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering _cleanup_route_free_ Route *route = NULL;
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_link_debug(link, "IPv4 link-local release %u.%u.%u.%u", ADDRESS_FMT_VAL(addr));
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_link_error_errno(link, r, "Could not allocate address: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering address_drop(address, link, &link_address_drop_handler);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_link_error_errno(link, r, "Could not allocate route: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering route_drop(route, link, &link_route_drop_handler);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int ipv4ll_route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering _cleanup_link_unref_ Link *link = userdata;
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0 && r != -EEXIST) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_link_error_errno(link, r, "could not set ipv4ll route: %m");
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering _cleanup_link_unref_ Link *link = userdata;
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0 && r != -EEXIST) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_link_error_errno(link, r, "could not set ipv4ll address: %m");
13790add4bf648fed816361794d8277a75253410Lennart Poettering } else if (r >= 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering link_rtnl_process_address(rtnl, m, link->manager);
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering _cleanup_address_free_ Address *ll_addr = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering _cleanup_route_free_ Route *route = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering else if (r < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_link_debug(link, "IPv4 link-local claim %u.%u.%u.%u",
13790add4bf648fed816361794d8277a75253410Lennart Poettering ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = address_configure(ll_addr, link, ipv4ll_address_handler);
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = route_configure(route, link, ipv4ll_route_handler);
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_link_warning(link, "IPv4 link-local unknown event: %d", event);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(link->network->link_local & ADDRESS_FAMILY_IPV4);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = net_get_unique_predictable_data(link->udev_device, seed);
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek assert_cc(sizeof(unsigned) <= 8);
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek r = sd_ipv4ll_set_address_seed(link->ipv4ll, *(unsigned *)seed);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);