Exemplo n.º 1
0
static int dhcp6_address_change(Link *link, struct in6_addr *ip6_addr,
                                uint8_t prefixlen, uint32_t lifetime_preferred,
                                uint32_t lifetime_valid) {
        int r;
        _cleanup_address_free_ Address *addr = NULL;

        r = address_new(&addr);
        if (r < 0)
                return r;

        addr->family = AF_INET6;
        memcpy(&addr->in_addr.in6, ip6_addr, sizeof(*ip6_addr));

        addr->flags = IFA_F_NOPREFIXROUTE;
        addr->prefixlen = prefixlen;

        addr->cinfo.ifa_prefered = lifetime_preferred;
        addr->cinfo.ifa_valid = lifetime_valid;

        log_link_info(link,
                      "DHCPv6 address "SD_ICMP6_ND_ADDRESS_FORMAT_STR"/%d timeout preferred %d valid %d",
                      SD_ICMP6_ND_ADDRESS_FORMAT_VAL(addr->in_addr.in6),
                      addr->prefixlen, lifetime_preferred, lifetime_valid);

        r = address_configure(addr, link, dhcp6_address_handler, true);
        if (r < 0)
                log_link_warning_errno(link, r, "Could not assign DHCPv6 address: %m");

        return r;
}
Exemplo n.º 2
0
static int dhcp4_update_address(Link *link,
                                struct in_addr *address,
                                struct in_addr *netmask,
                                uint32_t lifetime) {
        _cleanup_address_free_ Address *addr = NULL;
        unsigned prefixlen;
        int r;

        assert(address);
        assert(netmask);
        assert(lifetime);

        prefixlen = in_addr_netmask_to_prefixlen(netmask);

        r = address_new(&addr);
        if (r < 0)
                return r;

        addr->family = AF_INET;
        addr->in_addr.in.s_addr = address->s_addr;
        addr->cinfo.ifa_prefered = lifetime;
        addr->cinfo.ifa_valid = lifetime;
        addr->prefixlen = prefixlen;
        addr->broadcast.s_addr = address->s_addr | ~netmask->s_addr;

        /* allow reusing an existing address and simply update its lifetime
         * in case it already exists */
        r = address_configure(addr, link, dhcp4_address_handler, true);
        if (r < 0)
                return r;

        return 0;
}
Exemplo n.º 3
0
static int dhcp6_address_change(
                Link *link,
                struct in6_addr *ip6_addr,
                uint32_t lifetime_preferred,
                uint32_t lifetime_valid) {

        _cleanup_address_free_ Address *addr = NULL;
        char buffer[INET6_ADDRSTRLEN];
        int r;

        r = address_new(&addr);
        if (r < 0)
                return r;

        addr->family = AF_INET6;
        memcpy(&addr->in_addr.in6, ip6_addr, sizeof(*ip6_addr));

        addr->flags = IFA_F_NOPREFIXROUTE;
        addr->prefixlen = 128;

        addr->cinfo.ifa_prefered = lifetime_preferred;
        addr->cinfo.ifa_valid = lifetime_valid;

        log_link_info(link,
                      "DHCPv6 address %s/%d timeout preferred %d valid %d",
                      inet_ntop(AF_INET6, &addr->in_addr.in6, buffer, sizeof(buffer)),
                      addr->prefixlen, lifetime_preferred, lifetime_valid);

        r = address_configure(addr, link, dhcp6_address_handler, true);
        if (r < 0)
                log_link_warning_errno(link, r, "Could not assign DHCPv6 address: %m");

        return r;
}
Exemplo n.º 4
0
static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
        _cleanup_address_free_ Address *ll_addr = NULL;
        _cleanup_route_free_ Route *route = NULL;
        struct in_addr address;
        int r;

        assert(ll);
        assert(link);

        r = sd_ipv4ll_get_address(ll, &address);
        if (r == -ENOENT)
                return 0;
        else if (r < 0)
                return r;

        log_link_debug(link, "IPv4 link-local claim %u.%u.%u.%u",
                       ADDRESS_FMT_VAL(address));

        r = address_new(&ll_addr);
        if (r < 0)
                return r;

        ll_addr->family = AF_INET;
        ll_addr->in_addr.in = address;
        ll_addr->prefixlen = 16;
        ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
        ll_addr->scope = RT_SCOPE_LINK;

        r = address_configure(ll_addr, link, ipv4ll_address_handler, false);
        if (r < 0)
                return r;

        link->ipv4ll_address = false;

        r = route_new(&route);
        if (r < 0)
                return r;

        route->family = AF_INET;
        route->scope = RT_SCOPE_LINK;
        route->protocol = RTPROT_STATIC;
        route->priority = IPV4LL_ROUTE_METRIC;

        r = route_configure(route, link, ipv4ll_route_handler);
        if (r < 0)
                return r;

        link->ipv4ll_route = false;

        return 0;
}
Exemplo n.º 5
0
static void ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *rt) {
        _cleanup_address_free_ Address *address = NULL;
        uint32_t lifetime_valid, lifetime_preferred;
        unsigned prefixlen;
        int r;

        assert(link);
        assert(rt);

        r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen);
        if (r < 0) {
                log_link_error_errno(link, r, "Failed to get prefix length: %m");
                return;
        }

        r = sd_ndisc_router_prefix_get_valid_lifetime(rt, &lifetime_valid);
        if (r < 0) {
                log_link_error_errno(link, r, "Failed to get prefix valid lifetime: %m");
                return;
        }

        r = sd_ndisc_router_prefix_get_preferred_lifetime(rt, &lifetime_preferred);
        if (r < 0) {
                log_link_error_errno(link, r, "Failed to get prefix preferred lifetime: %m");
                return;
        }

        r = address_new(&address);
        if (r < 0) {
                log_link_error_errno(link, r, "Could not allocate address: %m");
                return;
        }

        address->family = AF_INET6;
        r = sd_ndisc_router_prefix_get_address(rt, &address->in_addr.in6);
        if (r < 0) {
                log_link_error_errno(link, r, "Failed to get prefix address: %m");
                return;
        }

        if (in_addr_is_null(AF_INET6, (const union in_addr_union *) &link->network->ipv6_token) == 0)
                memcpy(((char *)&address->in_addr.in6) + 8, ((char *)&link->network->ipv6_token) + 8, 8);
        else {
                /* see RFC4291 section 2.5.1 */
                address->in_addr.in6.s6_addr[8]  = link->mac.ether_addr_octet[0];
                address->in_addr.in6.s6_addr[8] ^= 1 << 1;
                address->in_addr.in6.s6_addr[9]  = link->mac.ether_addr_octet[1];
                address->in_addr.in6.s6_addr[10] = link->mac.ether_addr_octet[2];
                address->in_addr.in6.s6_addr[11] = 0xff;
                address->in_addr.in6.s6_addr[12] = 0xfe;
                address->in_addr.in6.s6_addr[13] = link->mac.ether_addr_octet[3];
                address->in_addr.in6.s6_addr[14] = link->mac.ether_addr_octet[4];
                address->in_addr.in6.s6_addr[15] = link->mac.ether_addr_octet[5];
        }
        address->prefixlen = prefixlen;
        address->flags = IFA_F_NOPREFIXROUTE|IFA_F_MANAGETEMPADDR;
        address->cinfo.ifa_prefered = lifetime_preferred;
        address->cinfo.ifa_valid = lifetime_valid;

        r = address_configure(address, link, ndisc_netlink_handler, true);
        if (r < 0) {
                log_link_warning_errno(link, r, "Could not set SLAAC address: %m");
                link_enter_failed(link);
                return;
        }

        link->ndisc_messages++;
}