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