networkd-ndisc.c revision a13c50e7a33e2b8e0481f725c6272142e6f71751
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen/***
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen This file is part of systemd.
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen Copyright (C) 2014 Intel Corporation. All rights reserved.
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen systemd is free software; you can redistribute it and/or modify it
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen under the terms of the GNU Lesser General Public License as published by
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen the Free Software Foundation; either version 2.1 of the License, or
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen (at your option) any later version.
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen systemd is distributed in the hope that it will be useful, but
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen Lesser General Public License for more details.
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen You should have received a copy of the GNU Lesser General Public License
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen***/
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen#include <netinet/ether.h>
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen#include <linux/if.h>
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen#include "networkd-link.h"
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen#include "sd-ndisc.h"
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersenstatic void ndisc_router_handler(sd_ndisc *nd, int event, void *userdata) {
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen Link *link = userdata;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen assert(link);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen assert(link->network);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen assert(link->manager);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen return;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen switch(event) {
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_NONE:
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen return;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_OTHER:
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen dhcp6_configure(link, true);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen break;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_MANAGED:
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen dhcp6_configure(link, false);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen break;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen case SD_NDISC_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED:
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen if (!link->rtnl_extended_attrs)
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen dhcp6_prefix_expired(link);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen break;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen default:
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen if (event < 0)
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen log_link_warning_errno(link, event, "IPv6 Neighbor Discover error: %m");
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen else
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen log_link_warning(link, "IPv6 Neighbor Discovery unknown event: %d", event);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen break;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen }
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen}
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersenint ndisc_configure(Link *link) {
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen int r;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen assert_return(link, -EINVAL);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen r = sd_ndisc_new(&link->ndisc_router_discovery);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen if (r < 0)
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen return r;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen r = sd_ndisc_attach_event(link->ndisc_router_discovery, NULL, 0);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen if (r < 0)
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen return r;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen r = sd_ndisc_set_mac(link->ndisc_router_discovery, &link->mac);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen if (r < 0)
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen return r;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen r = sd_ndisc_set_index(link->ndisc_router_discovery, link->ifindex);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen if (r < 0)
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen return r;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen r = sd_ndisc_set_callback(link->ndisc_router_discovery,
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen ndisc_router_handler, link);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen return r;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen}