static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
        Tunnel *t = SIT(netdev);
        int r;

        assert(netdev);
        assert(link);
        assert(m);
        assert(t);
        assert(t->family == AF_INET);

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

        r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
                                 strerror(-r));
                return r;
        }

        r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
                                 strerror(-r));
                return r;
        }

        r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_IPTUN_TTL attribute: %s",
                                 strerror(-r));
                return r;
        }

        r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PMTUDISC, t->pmtudisc);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_IPTUN_PMTUDISC attribute: %s",
                                 strerror(-r));
                return r;
        }

        return r;
}
static int netdev_ip6gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
        Tunnel *t;
        int r;

        assert(netdev);

        if (netdev->kind == NETDEV_KIND_IP6GRE)
                 t = IP6GRE(netdev);
        else
                 t = IP6GRETAP(netdev);

        assert(t);
        assert(t->family == AF_INET6);
        assert(link);
        assert(m);

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

        r = sd_rtnl_message_append_in6_addr(m, IFLA_GRE_LOCAL, &t->local.in6);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_GRE_LOCAL attribute: %s",
                                 strerror(-r));
                return r;
        }

        r = sd_rtnl_message_append_in6_addr(m, IFLA_GRE_REMOTE, &t->remote.in6);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_GRE_REMOTE attribute: %s",
                                 strerror(-r));
                return r;
        }

        r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, t->ttl);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_GRE_TTL attribute: %s",
                                 strerror(-r));
                return r;
        }

        return r;
}
Example #3
0
static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
        Tunnel *t = NULL;

        assert(netdev);
        assert(filename);

        switch (netdev->kind) {
        case NETDEV_KIND_IPIP:
                t = IPIP(netdev);
                break;
        case NETDEV_KIND_SIT:
                t = SIT(netdev);
                break;
        case NETDEV_KIND_GRE:
                t = GRE(netdev);
                break;
        case NETDEV_KIND_GRETAP:
                t = GRETAP(netdev);
                break;
        case NETDEV_KIND_IP6GRE:
                t = IP6GRE(netdev);
                break;
        case NETDEV_KIND_IP6GRETAP:
                t = IP6GRETAP(netdev);
                break;
        case NETDEV_KIND_VTI:
                t = VTI(netdev);
                break;
        case NETDEV_KIND_VTI6:
                t = VTI6(netdev);
                break;
        case NETDEV_KIND_IP6TNL:
                t = IP6TNL(netdev);
                break;
        default:
                assert_not_reached("Invalid tunnel kind");
        }

        assert(t);

        if (!IN_SET(t->family, AF_INET, AF_INET6, AF_UNSPEC)) {
                log_netdev_error(netdev,
                                 "Tunnel with invalid address family configured in %s. Ignoring", filename);
                return -EINVAL;
        }

        if (netdev->kind == NETDEV_KIND_VTI &&
            (t->family != AF_INET || in_addr_is_null(t->family, &t->local))) {
                log_netdev_error(netdev,
                                 "vti tunnel without a local IPv4 address configured in %s. Ignoring", filename);
                return -EINVAL;
        }

        if (IN_SET(netdev->kind, NETDEV_KIND_VTI6, NETDEV_KIND_IP6TNL, NETDEV_KIND_IP6GRE) &&
            (t->family != AF_INET6 || in_addr_is_null(t->family, &t->local))) {
                log_netdev_error(netdev,
                                 "vti6/ip6tnl/ip6gre tunnel without a local IPv6 address configured in %s. Ignoring", filename);
                return -EINVAL;
        }

        if (netdev->kind == NETDEV_KIND_IP6TNL &&
            t->ip6tnl_mode == _NETDEV_IP6_TNL_MODE_INVALID) {
                log_netdev_error(netdev,
                                 "ip6tnl without mode configured in %s. Ignoring", filename);
                return -EINVAL;
        }

        return 0;
}
static int netdev_ip6tnl_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
        Tunnel *t = IP6TNL(netdev);
        uint8_t proto;
        int r;

        assert(netdev);
        assert(link);
        assert(m);
        assert(t);
        assert(t->family == AF_INET6);

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

        r = sd_rtnl_message_append_in6_addr(m, IFLA_IPTUN_LOCAL, &t->local.in6);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
                                 strerror(-r));
                return r;
        }

        r = sd_rtnl_message_append_in6_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in6);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
                                 strerror(-r));
                return r;
        }

        r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_IPTUN_TTL attribute: %s",
                                 strerror(-r));
                return r;
        }

        switch (t->ip6tnl_mode) {
        case NETDEV_IP6_TNL_MODE_IP6IP6:
                proto = IPPROTO_IPV6;
                break;
        case NETDEV_IP6_TNL_MODE_IPIP6:
                proto = IPPROTO_IPIP;
                break;
        case NETDEV_IP6_TNL_MODE_ANYIP6:
        default:
                proto = 0;
                break;
        }

        r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PROTO, proto);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_IPTUN_MODE attribute: %s",
                                 strerror(-r));
                return r;
        }

        return r;
}
static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
        VxLan *v = VXLAN(netdev);
        int r;

        assert(netdev);
        assert(v);
        assert(link);
        assert(m);


        if (v->id <= VXLAN_VID_MAX) {
                r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_ID, v->id);
                if (r < 0) {
                        log_netdev_error(netdev,
                                         "Could not append IFLA_VXLAN_ID attribute: %s",
                                         strerror(-r));
                        return r;
                }
        }

        r = sd_rtnl_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->group.in);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_VXLAN_GROUP attribute: %s",
                                 strerror(-r));
                return r;
        }

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

        if(v->ttl) {
                r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TTL, v->ttl);
                if (r < 0) {
                        log_netdev_error(netdev,
                                         "Could not append IFLA_VXLAN_TTL attribute: %s",
                                         strerror(-r));
                        return r;
                }
        }

        if(v->tos) {
                r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TOS, v->tos);
                if (r < 0) {
                        log_netdev_error(netdev,
                                         "Could not append IFLA_VXLAN_TOS attribute: %s",
                                         strerror(-r));
                        return r;
                }
        }

        r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_LEARNING, v->learning);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_VXLAN_LEARNING attribute: %s",
                                 strerror(-r));
                return r;
        }

        r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_RSC, v->route_short_circuit);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_VXLAN_RSC attribute: %s",
                                 strerror(-r));
                return r;
        }

        r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_PROXY, v->arp_proxy);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_VXLAN_PROXY attribute: %s",
                                 strerror(-r));
                return r;
        }

        r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_L2MISS, v->l2miss);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_VXLAN_L2MISS attribute: %s",
                                 strerror(-r));
                return r;
        }

        r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_L3MISS, v->l3miss);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_VXLAN_L3MISS attribute: %s",
                                 strerror(-r));
                return r;
        }

        if(v->fdb_ageing) {
                r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_AGEING, v->fdb_ageing / USEC_PER_SEC);
                if (r < 0) {
                        log_netdev_error(netdev,
                                         "Could not append IFLA_VXLAN_AGEING attribute: %s",
                                         strerror(-r));
                        return r;
                }
        }

        r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_UDP_CSUM, v->udpcsum);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_VXLAN_UDP_CSUM attribute: %s",
                                 strerror(-r));
                return r;
        }

        r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, v->udp6zerocsumtx);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_VXLAN_UDP_ZERO_CSUM6_TX attribute: %s",
                                 strerror(-r));
                return r;
        }

        r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, v->udp6zerocsumrx);
        if (r < 0) {
                log_netdev_error(netdev,
                                 "Could not append IFLA_VXLAN_UDP_ZERO_CSUM6_RX attribute: %s",
                                 strerror(-r));
                return r;
        }

        return r;
}
static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
        Bond *b = BOND(netdev);
        int r;

        assert(netdev);
        assert(!link);
        assert(b);
        assert(m);

        if (b->mode != _NETDEV_BOND_MODE_INVALID) {
                r = sd_rtnl_message_append_u8(m, IFLA_BOND_MODE,
                                              bond_mode_to_kernel(b->mode));
                if (r < 0) {
                        log_netdev_error(netdev,
                                         "Could not append IFLA_BOND_MODE attribute: %s",
                                         strerror(-r));
                        return r;
                }
        }

        if (b->xmit_hash_policy != _NETDEV_BOND_XMIT_HASH_POLICY_INVALID) {
                r = sd_rtnl_message_append_u8(m, IFLA_BOND_XMIT_HASH_POLICY,
                                              bond_xmit_hash_policy_to_kernel(b->xmit_hash_policy));
                if (r < 0) {
                        log_netdev_error(netdev,
                                         "Could not append IFLA_BOND_XMIT_HASH_POLICY attribute: %s",
                                         strerror(-r));
                        return r;
                }
        }

        if (b->lacp_rate != _NETDEV_BOND_LACP_RATE_INVALID &&
            b->mode == NETDEV_BOND_MODE_802_3AD) {
                r = sd_rtnl_message_append_u8(m, IFLA_BOND_AD_LACP_RATE, b->lacp_rate );
                if (r < 0) {
                        log_netdev_error(netdev,
                                         "Could not append IFLA_BOND_AD_LACP_RATE attribute: %s",
                                         strerror(-r));
                        return r;
                }
        }

        if (b->miimon != 0) {
                r = sd_rtnl_message_append_u32(m, IFLA_BOND_MIIMON, b->miimon / USEC_PER_MSEC);
                if (r < 0) {
                        log_netdev_error(netdev,
                                         "Could not append IFLA_BOND_BOND_MIIMON attribute: %s",
                                         strerror(-r));
                        return r;
                }
        }

        if (b->downdelay != 0) {
                r = sd_rtnl_message_append_u32(m, IFLA_BOND_DOWNDELAY, b->downdelay / USEC_PER_MSEC);
                if (r < 0) {
                        log_netdev_error(netdev,
                                         "Could not append IFLA_BOND_DOWNDELAY attribute: %s",
                                         strerror(-r));
                        return r;
                }
        }

        if (b->updelay != 0) {
                r = sd_rtnl_message_append_u32(m, IFLA_BOND_UPDELAY, b->updelay / USEC_PER_MSEC);
                if (r < 0) {
                        log_netdev_error(netdev,
                                         "Could not append IFLA_BOND_UPDELAY attribute: %s",
                                         strerror(-r));
                        return r;
                }
        }

        return 0;
}
static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
    _cleanup_close_ int fd;
    TunTap *t = NULL;
    const char *user;
    const char *group;
    uid_t uid;
    gid_t gid;
    int r;

    assert(netdev);
    assert(ifr);

    fd = open(TUN_DEV, O_RDWR);
    if (fd < 0) {
        log_netdev_error(netdev, "Failed to open tun dev: %m");
        return -errno;
    }

    r = ioctl(fd, TUNSETIFF, ifr);
    if (r < 0) {
        log_netdev_error(netdev,
                         "TUNSETIFF failed on tun dev: %s",
                         strerror(-r));
        return r;
    }

    if (netdev->kind == NETDEV_KIND_TAP)
        t = TAP(netdev);
    else
        t = TUN(netdev);

    assert(t);

    if(t->user_name) {

        user = t->user_name;

        r = get_user_creds(&user, &uid, NULL, NULL, NULL);
        if (r < 0) {
            log_error_errno(r, "Cannot resolve user name %s: %m",
                            t->user_name);
            return 0;
        }

        r = ioctl(fd, TUNSETOWNER, uid);
        if ( r < 0) {
            log_netdev_error(netdev,
                             "TUNSETOWNER failed on tun dev: %s",
                             strerror(-r));
        }
    }

    if(t->group_name) {

        group = t->group_name;

        r = get_group_creds(&group, &gid);
        if (r < 0) {
            log_error_errno(r, "Cannot resolve group name %s: %m",
                            t->group_name);
            return 0;
        }

        r = ioctl(fd, TUNSETGROUP, gid);
        if( r < 0) {
            log_netdev_error(netdev,
                             "TUNSETGROUP failed on tun dev: %s",
                             strerror(-r));
            return r;
        }

    }

    r = ioctl(fd, TUNSETPERSIST, 1);
    if (r < 0) {
        log_netdev_error(netdev,
                         "TUNSETPERSIST failed on tun dev: %s",
                         strerror(-r));
        return r;
    }

    return 0;
}