networkd-ndisc.c revision 9d96e6c3efbe5ef52b2855612d51db52c469beb2
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>
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen#include <netinet/icmp6.h>
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen#include <linux/if.h>
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen#include "sd-ndisc.h"
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "networkd-link.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersenstatic void ndisc_router_handler(sd_ndisc *nd, uint8_t flags, const struct in6_addr *gateway, unsigned lifetime, int pref, void *userdata) {
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen Link *link = userdata;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen assert(link);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen assert(link->network);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen return;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen if (flags & ND_RA_FLAG_MANAGED)
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen dhcp6_configure(link, false);
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen else if (flags & ND_RA_FLAG_OTHER)
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen dhcp6_configure(link, true);
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen}
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersenstatic void ndisc_handler(sd_ndisc *nd, int event, void *userdata) {
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen Link *link = userdata;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen assert(link);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen return;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen switch (event) {
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen case SD_NDISC_EVENT_TIMEOUT:
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen dhcp6_configure(link, false);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen break;
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen case SD_NDISC_EVENT_STOP:
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen break;
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen default:
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen log_link_warning(link, "IPv6 Neighbor Discovery unknown event: %d", event);
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,
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen ndisc_router_handler,
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen NULL,
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen NULL,
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen ndisc_handler,
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen link);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen return r;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen}