int address_update(Address *address, Link *link,
                   sd_rtnl_message_handler_t callback) {
        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
        int r;

        assert(address);
        assert(address->family == AF_INET || address->family == AF_INET6);
        assert(link->ifindex > 0);
        assert(link->manager);
        assert(link->manager->rtnl);

        r = sd_rtnl_message_new_addr_update(link->manager->rtnl, &req,
                                     link->ifindex, address->family);
        if (r < 0)
                return log_error_errno(r, "Could not allocate RTM_NEWADDR message: %m");

        r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen);
        if (r < 0)
                return log_error_errno(r, "Could not set prefixlen: %m");

        r = sd_rtnl_message_addr_set_flags(req, IFA_F_PERMANENT);
        if (r < 0)
                return log_error_errno(r, "Could not set flags: %m");

        r = sd_rtnl_message_addr_set_scope(req, address->scope);
        if (r < 0)
                return log_error_errno(r, "Could not set scope: %m");

        if (address->family == AF_INET)
                r = sd_rtnl_message_append_in_addr(req, IFA_LOCAL, &address->in_addr.in);
        else if (address->family == AF_INET6)
                r = sd_rtnl_message_append_in6_addr(req, IFA_LOCAL, &address->in_addr.in6);
        if (r < 0)
                return log_error_errno(r, "Could not append IFA_LOCAL attribute: %m");

        if (address->family == AF_INET) {
                r = sd_rtnl_message_append_in_addr(req, IFA_BROADCAST, &address->broadcast);
                if (r < 0)
                        return log_error_errno(r, "Could not append IFA_BROADCAST attribute: %m");
        }

        if (address->label) {
                r = sd_rtnl_message_append_string(req, IFA_LABEL, address->label);
                if (r < 0)
                        return log_error_errno(r, "Could not append IFA_LABEL attribute: %m");
        }

        r = sd_rtnl_message_append_cache_info(req, IFA_CACHEINFO, &address->cinfo);
        if (r < 0)
                return log_error_errno(r, "Could not append IFA_CACHEINFO attribute: %m");

        r = sd_rtnl_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
        if (r < 0)
                return log_error_errno(r, "Could not send rtnetlink message: %m");

        link_ref(link);

        return 0;
}
Exemplo n.º 2
0
int route_configure(Route *route, Link *link,
                    sd_rtnl_message_handler_t callback) {
        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
        int r;

        assert(link);
        assert(link->manager);
        assert(link->manager->rtnl);
        assert(link->ifindex > 0);
        assert(route->family == AF_INET || route->family == AF_INET6);

        r = sd_rtnl_message_new_route(link->manager->rtnl, RTM_NEWROUTE,
                                      route->family, &req);
        if (r < 0) {
                log_error("Could not create RTM_NEWROUTE message: %s", strerror(-r));
                return r;
        }

        if (route->family == AF_INET)
                r = sd_rtnl_message_append_in_addr(req, RTA_GATEWAY, &route->in_addr.in);
        else if (route->family == AF_INET6)
                r = sd_rtnl_message_append_in6_addr(req, RTA_GATEWAY, &route->in_addr.in6);
        if (r < 0) {
                log_error("Could not append RTA_GATEWAY attribute: %s", strerror(-r));
                return r;
        }

        if (route->dst_prefixlen) {
                if (route->family == AF_INET)
                        r = sd_rtnl_message_append_in_addr(req, RTA_DST, &route->dst_addr.in);
                else if (route->family == AF_INET6)
                        r = sd_rtnl_message_append_in6_addr(req, RTA_DST, &route->dst_addr.in6);
                if (r < 0) {
                        log_error("Could not append RTA_DST attribute: %s", strerror(-r));
                        return r;
                }

                r = sd_rtnl_message_route_set_dst_prefixlen(req, route->dst_prefixlen);
                if (r < 0) {
                        log_error("Could not set destination prefix length: %s", strerror(-r));
                        return r;
                }
        }

        r = sd_rtnl_message_append_u32(req, RTA_OIF, link->ifindex);
        if (r < 0) {
                log_error("Could not append RTA_OIF attribute: %s", strerror(-r));
                return r;
        }

        r = sd_rtnl_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
        if (r < 0) {
                log_error("Could not send rtnetlink message: %s", strerror(-r));
                return r;
        }

        return 0;
}
Exemplo n.º 3
0
static void test_pipe(int ifindex) {
        _cleanup_sd_rtnl_unref_ sd_rtnl *rtnl = NULL;
        _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *m1 = NULL, *m2 = NULL;
        int counter = 0;

        assert(sd_rtnl_open(0, &rtnl) >= 0);

        assert(sd_rtnl_message_link_new(RTM_GETLINK, ifindex, 0, 0, &m1) >= 0);
        assert(sd_rtnl_message_link_new(RTM_GETLINK, ifindex, 0, 0, &m2) >= 0);

        counter ++;
        assert(sd_rtnl_call_async(rtnl, m1, &pipe_handler, &counter, 0, NULL) >= 0);

        counter ++;
        assert(sd_rtnl_call_async(rtnl, m2, &pipe_handler, &counter, 0, NULL) >= 0);

        while (counter > 0) {
                assert(sd_rtnl_wait(rtnl, 0) >= 0);
                assert(sd_rtnl_process(rtnl, NULL) >= 0);
        }
}
Exemplo n.º 4
0
static void test_async(int ifindex) {
        _cleanup_sd_rtnl_unref_ sd_rtnl *rtnl = NULL;
        _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *m = NULL, *r = NULL;
        uint32_t serial;
        char *ifname;

        ifname = strdup("lo");
        assert(ifname);

        assert(sd_rtnl_open(0, &rtnl) >= 0);

        assert(sd_rtnl_message_link_new(RTM_GETLINK, ifindex, 0, 0, &m) >= 0);

        assert(sd_rtnl_call_async(rtnl, m, &link_handler, ifname, 0, &serial) >= 0);

        assert(sd_rtnl_wait(rtnl, 0) >= 0);
        assert(sd_rtnl_process(rtnl, &r) >= 0);
}
Exemplo n.º 5
0
int address_drop(Address *address, Link *link,
                 sd_rtnl_message_handler_t callback) {
        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
        int r;

        assert(address);
        assert(address->family == AF_INET || address->family == AF_INET6);
        assert(link);
        assert(link->ifindex > 0);
        assert(link->manager);
        assert(link->manager->rtnl);

        r = sd_rtnl_message_new_addr(link->manager->rtnl, &req, RTM_DELADDR,
                                     link->ifindex, address->family);
        if (r < 0) {
                log_error("Could not allocate RTM_DELADDR message: %s",
                          strerror(-r));
                return r;
        }

        r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen);
        if (r < 0) {
                log_error("Could not set prefixlen: %s", strerror(-r));
                return r;
        }

        if (address->family == AF_INET)
                r = sd_rtnl_message_append_in_addr(req, IFA_LOCAL, &address->in_addr.in);
        else if (address->family == AF_INET6)
                r = sd_rtnl_message_append_in6_addr(req, IFA_LOCAL, &address->in_addr.in6);
        if (r < 0) {
                log_error("Could not append IFA_LOCAL attribute: %s",
                          strerror(-r));
                return r;
        }

        r = sd_rtnl_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
        if (r < 0) {
                log_error("Could not send rtnetlink message: %s", strerror(-r));
                return r;
        }

        return 0;
}
Exemplo n.º 6
0
int netdev_create_veth(NetDev *netdev, sd_rtnl_message_handler_t callback) {
        _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
        int r;

        assert(netdev);
        assert(netdev->ifname);
        assert(netdev->manager);
        assert(netdev->manager->rtnl);

        r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
        if (r < 0) {
                log_error_netdev(netdev,
                                 "Could not allocate RTM_NEWLINK message: %s",
                                 strerror(-r));
                return r;
        }

        if(netdev->kind != NETDEV_KIND_VETH)
                return -ENOTSUP;

        r = netdev_fill_veth_rtnl_message(netdev, m);
        if(r < 0)
                return r;

        r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, netdev, 0, NULL);
        if (r < 0) {
                log_error_netdev(netdev,
                                 "Could not send rtnetlink message: %s", strerror(-r));
                return r;
        }

        netdev_ref(netdev);

        log_debug_netdev(netdev, "Creating veth netdev: %s",
                         netdev_kind_to_string(netdev->kind));

        netdev->state = NETDEV_STATE_CREATING;

        return 0;
}
Exemplo n.º 7
0
static void test_event_loop(int ifindex) {
        _cleanup_event_unref_ sd_event *event = NULL;
        _cleanup_sd_rtnl_unref_ sd_rtnl *rtnl = NULL;
        _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *m = NULL;
        char *ifname;

        ifname = strdup("lo2");
        assert(ifname);

        assert(sd_rtnl_open(0, &rtnl) >= 0);
        assert(sd_rtnl_message_link_new(RTM_GETLINK, ifindex, 0, 0, &m) >= 0);

        assert(sd_rtnl_call_async(rtnl, m, &link_handler, ifname, 0, NULL) >= 0);

        assert(sd_event_default(&event) >= 0);

        assert(sd_rtnl_attach_event(rtnl, event, 0) >= 0);

        assert(sd_event_run(event, 0) >= 0);

        assert(sd_rtnl_detach_event(rtnl) >= 0);
}
Exemplo n.º 8
0
int netdev_create_vxlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
        _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
        int r;

        assert(netdev);
        assert(!(netdev->kind == NETDEV_KIND_VXLAN) || (link && callback));
        assert(netdev->ifname);
        assert(netdev->manager);
        assert(netdev->manager->rtnl);

        r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
        if (r < 0) {
                log_error_netdev(netdev,
                                 "Could not allocate RTM_NEWLINK message: %s",
                                 strerror(-r));
                return r;
        }

        r = netdev_fill_vxlan_rtnl_message(netdev, link, m);
        if(r < 0)
                return r;

        r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, link, 0, NULL);
        if (r < 0) {
                log_error_netdev(netdev,
                                 "Could not send rtnetlink message: %s", strerror(-r));
                return r;
        }

        link_ref(link);

        log_debug_netdev(netdev, "Creating vxlan netdev: %s",
                         netdev_kind_to_string(netdev->kind));

        netdev->state = NETDEV_STATE_CREATING;

        return 0;
}
Exemplo n.º 9
0
int address_configure(Address *address, Link *link,
                      sd_rtnl_message_handler_t callback) {
    _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
    int r;

    assert(address);
    assert(address->family == AF_INET || address->family == AF_INET6);
    assert(link);
    assert(link->ifindex > 0);
    assert(link->manager);
    assert(link->manager->rtnl);

    r = sd_rtnl_message_new_addr(RTM_NEWADDR, link->ifindex,
                                 address->family, &req);
    if (r < 0) {
        log_error("Could not allocate RTM_NEWADDR message: %s",
                  strerror(-r));
        return r;
    }

    r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen);
    if (r < 0) {
        log_error("Could not set prefixlen: %s", strerror(-r));
        return r;
    }

    r = sd_rtnl_message_addr_set_flags(req, IFA_F_PERMANENT);
    if (r < 0) {
        log_error("Could not set flags: %s", strerror(-r));
        return r;
    }

    r = sd_rtnl_message_addr_set_scope(req, RT_SCOPE_UNIVERSE);
    if (r < 0) {
        log_error("Could not set scope: %s", strerror(-r));
        return r;
    }

    if (address->family == AF_INET)
        r = sd_rtnl_message_append_in_addr(req, IFA_LOCAL, &address->in_addr.in);
    else if (address->family == AF_INET6)
        r = sd_rtnl_message_append_in6_addr(req, IFA_LOCAL, &address->in_addr.in6);
    if (r < 0) {
        log_error("Could not append IFA_LOCAL attribute: %s",
                  strerror(-r));
        return r;
    }

    if (address->family == AF_INET) {
        r = sd_rtnl_message_append_in_addr(req, IFA_BROADCAST, &address->broadcast);
        if (r < 0) {
            log_error("Could not append IFA_BROADCAST attribute: %s",
                      strerror(-r));
            return r;
        }
    }

    if (address->label) {
        r = sd_rtnl_message_append_string(req, IFA_LABEL, address->label);
        if (r < 0) {
            log_error("Could not append IFA_LABEL attribute: %s",
                      strerror(-r));
            return r;
        }
    }

    r = sd_rtnl_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
    if (r < 0) {
        log_error("Could not send rtnetlink message: %s", strerror(-r));
        return r;
    }

    return 0;
}
Exemplo n.º 10
0
int netdev_create_vlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
        const char *kind;
        int r;

        assert(netdev);
        assert(netdev->kind == NETDEV_KIND_VLAN);
        assert(link);
        assert(callback);
        assert(netdev->ifname);
        assert(netdev->manager);
        assert(netdev->manager->rtnl);

        r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_NEWLINK, 0);
        if (r < 0) {
                log_error_netdev(netdev,
                                 "Could not allocate RTM_NEWLINK message: %s",
                                 strerror(-r));
                return r;
        }

        if (link) {
                r = sd_rtnl_message_append_u32(req, IFLA_LINK, link->ifindex);
                if (r < 0) {
                        log_error_netdev(netdev,
                                         "Could not append IFLA_LINK attribute: %s",
                                         strerror(-r));
                        return r;
                }
        }

        r = sd_rtnl_message_append_string(req, IFLA_IFNAME, netdev->ifname);
        if (r < 0) {
                log_error_netdev(netdev,
                                 "Could not append IFLA_IFNAME attribute: %s",
                                 strerror(-r));
                return r;
        }

        if (netdev->mtu) {
                r = sd_rtnl_message_append_u32(req, IFLA_MTU, netdev->mtu);
                if (r < 0) {
                        log_error_netdev(netdev,
                                         "Could not append IFLA_MTU attribute: %s",
                                         strerror(-r));
                        return r;
                }
        }

        if (netdev->mac) {
                r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, netdev->mac);
                if (r < 0) {
                        log_error_netdev(netdev,
                                         "Colud not append IFLA_ADDRESS attribute: %s",
                                         strerror(-r));
                    return r;
                }
        }

        r = sd_rtnl_message_open_container(req, IFLA_LINKINFO);
        if (r < 0) {
                log_error_netdev(netdev,
                                 "Could not open IFLA_LINKINFO container: %s",
                                 strerror(-r));
                return r;
        }

        kind = netdev_kind_to_string(netdev->kind);
        if (!kind) {
                log_error_netdev(netdev, "Invalid kind");
                return -EINVAL;
        }

        r = sd_rtnl_message_open_container_union(req, IFLA_INFO_DATA, kind);
        if (r < 0) {
                log_error_netdev(netdev,
                                 "Could not open IFLA_INFO_DATA container: %s",
                                  strerror(-r));
                return r;
        }

        if (netdev->vlanid <= VLANID_MAX) {
                r = sd_rtnl_message_append_u16(req, IFLA_VLAN_ID, netdev->vlanid);
                if (r < 0) {
                        log_error_netdev(netdev,
                                         "Could not append IFLA_VLAN_ID attribute: %s",
                                         strerror(-r));
                        return r;
                }
        }

        r = sd_rtnl_message_close_container(req);
        if (r < 0) {
                log_error_netdev(netdev,
                                 "Could not close IFLA_INFO_DATA container %s",
                                 strerror(-r));
                return r;
        }

        r = sd_rtnl_message_close_container(req);
        if (r < 0) {
                log_error_netdev(netdev,
                                 "Could not close IFLA_LINKINFO container %s",
                                 strerror(-r));
                return r;
        }

        r = sd_rtnl_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL);
        if (r < 0) {
                log_error_netdev(netdev,
                                 "Could not send rtnetlink message: %s", strerror(-r));
                return r;
        }

        link_ref(link);

        log_debug_netdev(netdev, "creating netdev");

        netdev->state = NETDEV_STATE_CREATING;

        return 0;
}
Exemplo n.º 11
0
int netdev_create_tunnel(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
        _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
        int r;

        assert(netdev);
        assert(netdev->ifname);
        assert(netdev->manager);
        assert(netdev->manager->rtnl);
        assert(link);
        assert(link->network);
        assert(link->network->tunnel == netdev);

        r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
        if (r < 0) {
                log_error_netdev(netdev,
                                 "Could not allocate RTM_NEWLINK message: %s",
                                 strerror(-r));
                return r;
        }

        switch(netdev->kind) {
        case NETDEV_KIND_IPIP:
                r = netdev_fill_ipip_rtnl_message(link, m);
                if(r < 0)
                        return r;
                break;
        case NETDEV_KIND_SIT:
                r = netdev_fill_sit_rtnl_message(link, m);
                if(r < 0)
                        return r;
                break;
        case NETDEV_KIND_VTI:
                netdev_fill_vti_rtnl_message(link, m);
                if(r < 0)
                        return r;
                break;
        case NETDEV_KIND_GRE:
                r = netdev_fill_ipgre_rtnl_message(link, m);
                if(r < 0)
                        return r;
                break;
        default:
                return -ENOTSUP;
        }

        r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, link, 0, NULL);
        if (r < 0) {
                log_error_netdev(netdev,
                                 "Could not send rtnetlink message: %s", strerror(-r));
                return r;
        }

        link_ref(link);

        log_debug_netdev(netdev, "Creating tunnel netdev: %s",
                         netdev_kind_to_string(netdev->kind));

        netdev->state = NETDEV_STATE_CREATING;

        return 0;
}