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; }
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; }