static int netdev_veth_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { Veth *v = VETH(netdev); int r; assert(netdev); assert(!link); assert(v); assert(m); r = sd_netlink_message_open_container(m, VETH_INFO_PEER); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append VETH_INFO_PEER attribute: %m"); if (v->ifname_peer) { r = sd_netlink_message_append_string(m, IFLA_IFNAME, v->ifname_peer); if (r < 0) return log_error_errno(r, "Failed to add netlink interface name: %m"); } if (v->mac_peer) { r = sd_netlink_message_append_ether_addr(m, IFLA_ADDRESS, v->mac_peer); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_ADDRESS attribute: %m"); } r = sd_netlink_message_close_container(m); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m"); return r; }
int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned short type, const char *key) { const NLTypeSystemUnion *type_system_union; int r; assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, type); if (r < 0) return r; r = type_system_union_get_type_system(type_system_union, &m->containers[m->n_containers + 1].type_system, key); if (r < 0) return r; r = sd_netlink_message_append_string(m, type_system_union->match, key); if (r < 0) return r; /* do we evere need non-null size */ r = add_rtattr(m, type | NLA_F_NESTED, NULL, 0); if (r < 0) return r; m->containers[m->n_containers ++].offset = r; return 0; }
static int test_acd(const char *ifname, const char *address) { _cleanup_(sd_event_unrefp) sd_event *e = NULL; _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *reply = NULL; union in_addr_union pa; struct ether_addr ha; int ifindex; assert_se(in_addr_from_string(AF_INET, address, &pa) >= 0); assert_se(sd_event_new(&e) >= 0); assert_se(sd_netlink_open(&rtnl) >= 0); assert_se(sd_netlink_attach_event(rtnl, e, 0) >= 0); assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, 0) >= 0); assert_se(sd_netlink_message_append_string(m, IFLA_IFNAME, ifname) >= 0); assert_se(sd_netlink_call(rtnl, m, 0, &reply) >= 0); assert_se(sd_rtnl_message_link_get_ifindex(reply, &ifindex) >= 0); assert_se(sd_netlink_message_read_ether_addr(reply, IFLA_ADDRESS, &ha) >= 0); client_run(ifindex, &pa.in, &ha, e); return EXIT_SUCCESS; }
static void test_link_configure(sd_netlink *rtnl, int ifindex) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; const char *mac = "98:fe:94:3f:c6:18", *name = "test"; char buffer[ETHER_ADDR_TO_STRING_MAX]; uint32_t mtu = 1450, mtu_out; const char *name_out; struct ether_addr mac_out; /* we'd really like to test NEWLINK, but let's not mess with the running kernel */ assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_GETLINK, ifindex) >= 0); assert_se(sd_netlink_message_append_string(message, IFLA_IFNAME, name) >= 0); assert_se(sd_netlink_message_append_ether_addr(message, IFLA_ADDRESS, ether_aton(mac)) >= 0); assert_se(sd_netlink_message_append_u32(message, IFLA_MTU, mtu) >= 0); assert_se(sd_netlink_call(rtnl, message, 0, NULL) == 1); assert_se(sd_netlink_message_rewind(message) >= 0); assert_se(sd_netlink_message_read_string(message, IFLA_IFNAME, &name_out) >= 0); assert_se(streq(name, name_out)); assert_se(sd_netlink_message_read_ether_addr(message, IFLA_ADDRESS, &mac_out) >= 0); assert_se(streq(mac, ether_addr_to_string(&mac_out, buffer))); assert_se(sd_netlink_message_read_u32(message, IFLA_MTU, &mtu_out) >= 0); assert_se(mtu == mtu_out); }
static void test_container(sd_netlink *rtnl) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; uint16_t u16_data; uint32_t u32_data; const char *string_data; assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0) >= 0); assert_se(sd_netlink_message_open_container(m, IFLA_LINKINFO) >= 0); assert_se(sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, "vlan") >= 0); assert_se(sd_netlink_message_append_u16(m, IFLA_VLAN_ID, 100) >= 0); assert_se(sd_netlink_message_close_container(m) >= 0); assert_se(sd_netlink_message_append_string(m, IFLA_INFO_KIND, "vlan") >= 0); assert_se(sd_netlink_message_close_container(m) >= 0); assert_se(sd_netlink_message_close_container(m) == -EINVAL); assert_se(sd_netlink_message_rewind(m) >= 0); assert_se(sd_netlink_message_enter_container(m, IFLA_LINKINFO) >= 0); assert_se(sd_netlink_message_read_string(m, IFLA_INFO_KIND, &string_data) >= 0); assert_se(streq("vlan", string_data)); assert_se(sd_netlink_message_enter_container(m, IFLA_INFO_DATA) >= 0); assert_se(sd_netlink_message_read_u16(m, IFLA_VLAN_ID, &u16_data) >= 0); assert_se(sd_netlink_message_exit_container(m) >= 0); assert_se(sd_netlink_message_read_string(m, IFLA_INFO_KIND, &string_data) >= 0); assert_se(streq("vlan", string_data)); assert_se(sd_netlink_message_exit_container(m) >= 0); assert_se(sd_netlink_message_read_u32(m, IFLA_LINKINFO, &u32_data) < 0); assert_se(sd_netlink_message_exit_container(m) == -EINVAL); }
static int lookup_id(sd_netlink *nl, sd_genl_family family, uint16_t *id) { int r; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL; r = sd_genl_message_new(nl, SD_GENL_ID_CTRL, CTRL_CMD_GETFAMILY, &req); if (r < 0) return r; r = sd_netlink_message_append_string(req, CTRL_ATTR_FAMILY_NAME, genl_families[family].name); if (r < 0) return r; r = sd_netlink_call(nl, req, 0, &reply); if (r < 0) return r; return sd_netlink_message_read_u16(reply, CTRL_ATTR_FAMILY_ID, id); }
int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, sd_netlink_message_handler_t callback, bool update) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; int r; assert(rule); assert(link); assert(link->ifindex > 0); assert(link->manager); assert(link->manager->rtnl); r = sd_rtnl_message_new_routing_policy_rule(link->manager->rtnl, &m, RTM_NEWRULE, rule->family); if (r < 0) return log_error_errno(r, "Could not allocate RTM_NEWRULE message: %m"); if (!in_addr_is_null(rule->family, &rule->from)) { if (rule->family == AF_INET) r = sd_netlink_message_append_in_addr(m, FRA_SRC, &rule->from.in); else r = sd_netlink_message_append_in6_addr(m, FRA_SRC, &rule->from.in6); if (r < 0) return log_error_errno(r, "Could not append FRA_SRC attribute: %m"); r = sd_rtnl_message_routing_policy_rule_set_rtm_src_prefixlen(m, rule->from_prefixlen); if (r < 0) return log_error_errno(r, "Could not set source prefix length: %m"); } if (!in_addr_is_null(rule->family, &rule->to)) { if (rule->family == AF_INET) r = sd_netlink_message_append_in_addr(m, FRA_DST, &rule->to.in); else r = sd_netlink_message_append_in6_addr(m, FRA_DST, &rule->to.in6); if (r < 0) return log_error_errno(r, "Could not append FRA_DST attribute: %m"); r = sd_rtnl_message_routing_policy_rule_set_rtm_dst_prefixlen(m, rule->to_prefixlen); if (r < 0) return log_error_errno(r, "Could not set destination prefix length: %m"); } r = sd_netlink_message_append_u32(m, FRA_PRIORITY, rule->priority); if (r < 0) return log_error_errno(r, "Could not append FRA_PRIORITY attribute: %m"); if (rule->tos > 0) { r = sd_rtnl_message_routing_policy_rule_set_tos(m, rule->tos); if (r < 0) return log_error_errno(r, "Could not set ip rule tos: %m"); } if (rule->table < 256) { r = sd_rtnl_message_routing_policy_rule_set_table(m, rule->table); if (r < 0) return log_error_errno(r, "Could not set ip rule table: %m"); } else { r = sd_rtnl_message_routing_policy_rule_set_table(m, RT_TABLE_UNSPEC); if (r < 0) return log_error_errno(r, "Could not set ip rule table: %m"); r = sd_netlink_message_append_u32(m, FRA_TABLE, rule->table); if (r < 0) return log_error_errno(r, "Could not append FRA_TABLE attribute: %m"); } if (rule->fwmark > 0) { r = sd_netlink_message_append_u32(m, FRA_FWMARK, rule->fwmark); if (r < 0) return log_error_errno(r, "Could not append FRA_FWMARK attribute: %m"); } if (rule->fwmask > 0) { r = sd_netlink_message_append_u32(m, FRA_FWMASK, rule->fwmask); if (r < 0) return log_error_errno(r, "Could not append FRA_FWMASK attribute: %m"); } if (rule->iif) { r = sd_netlink_message_append_string(m, FRA_IFNAME, rule->iif); if (r < 0) return log_error_errno(r, "Could not append FRA_IFNAME attribute: %m"); } if (rule->oif) { r = sd_netlink_message_append_string(m, FRA_OIFNAME, rule->oif); if (r < 0) return log_error_errno(r, "Could not append FRA_OIFNAME attribute: %m"); } rule->link = link; r = sd_netlink_call_async(link->manager->rtnl, m, callback, link, 0, NULL); if (r < 0) return log_error_errno(r, "Could not send rtnetlink message: %m"); link_ref(link); r = routing_policy_rule_add(link->manager, rule->family, &rule->from, rule->from_prefixlen, &rule->to, rule->to_prefixlen, rule->tos, rule->fwmark, rule->table, rule->iif, rule->oif, NULL); if (r < 0) return log_error_errno(r, "Could not add rule : %m"); return 0; }
static int netdev_geneve_create(NetDev *netdev) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; Geneve *v; int r; assert(netdev); v = GENEVE(netdev); r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not allocate RTM_NEWLINK message: %m"); r = sd_netlink_message_append_string(m, IFLA_IFNAME, netdev->ifname); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_IFNAME, attribute: %m"); if (netdev->mac) { r = sd_netlink_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_ADDRESS attribute: %m"); } if (netdev->mtu != 0) { r = sd_netlink_message_append_u32(m, IFLA_MTU, netdev->mtu); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_MTU attribute: %m"); } r = sd_netlink_message_open_container(m, IFLA_LINKINFO); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m"); r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, netdev_kind_to_string(netdev->kind)); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m"); if (v->id <= GENEVE_VID_MAX) { r = sd_netlink_message_append_u32(m, IFLA_GENEVE_ID, v->id); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_ID attribute: %m"); } if (in_addr_is_null(v->remote_family, &v->remote) == 0) { if (v->remote_family == AF_INET) r = sd_netlink_message_append_in_addr(m, IFLA_GENEVE_REMOTE, &v->remote.in); else r = sd_netlink_message_append_in6_addr(m, IFLA_GENEVE_REMOTE6, &v->remote.in6); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_REMOTE/IFLA_GENEVE_REMOTE6 attribute: %m"); } if (v->ttl > 0) { r = sd_netlink_message_append_u8(m, IFLA_GENEVE_TTL, v->ttl); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_TTL attribute: %m"); } r = sd_netlink_message_append_u8(m, IFLA_GENEVE_TOS, v->tos); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_TOS attribute: %m"); r = sd_netlink_message_append_u8(m, IFLA_GENEVE_UDP_CSUM, v->udpcsum); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_UDP_CSUM attribute: %m"); r = sd_netlink_message_append_u8(m, IFLA_GENEVE_UDP_ZERO_CSUM6_TX, v->udp6zerocsumtx); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_UDP_ZERO_CSUM6_TX attribute: %m"); r = sd_netlink_message_append_u8(m, IFLA_GENEVE_UDP_ZERO_CSUM6_RX, v->udp6zerocsumrx); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_UDP_ZERO_CSUM6_RX attribute: %m"); if (v->dest_port != DEFAULT_GENEVE_DESTINATION_PORT) { r = sd_netlink_message_append_u16(m, IFLA_GENEVE_PORT, htobe16(v->dest_port)); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_PORT attribute: %m"); } if (v->flow_label > 0) { r = sd_netlink_message_append_u32(m, IFLA_GENEVE_LABEL, htobe32(v->flow_label)); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_LABEL attribute: %m"); } r = sd_netlink_message_close_container(m); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m"); r = sd_netlink_message_close_container(m); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m"); r = netlink_call_async(netdev->manager->rtnl, NULL, m, geneve_netdev_create_handler, netdev_destroy_callback, netdev); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m"); netdev_ref(netdev); netdev->state = NETDEV_STATE_CREATING; log_netdev_debug(netdev, "Creating"); return r; }
static int test_pppoe_server(sd_event *e) { sd_netlink *rtnl; sd_netlink_message *m; pid_t pid; int r, client_ifindex, server_ifindex; r = unshare(CLONE_NEWNET); if (r < 0 && errno == EPERM) return EXIT_TEST_SKIP; assert_se(r >= 0); assert_se(sd_netlink_open(&rtnl) >= 0); assert_se(sd_netlink_attach_event(rtnl, e, 0) >= 0); assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0) >= 0); assert_se(sd_netlink_message_append_string(m, IFLA_IFNAME, "pppoe-server") >= 0); assert_se(sd_netlink_message_open_container(m, IFLA_LINKINFO) >= 0); assert_se(sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, "veth") >= 0); assert_se(sd_netlink_message_open_container(m, VETH_INFO_PEER) >= 0); assert_se(sd_netlink_message_append_string(m, IFLA_IFNAME, "pppoe-client") >= 0); assert_se(sd_netlink_message_close_container(m) >= 0); assert_se(sd_netlink_message_close_container(m) >= 0); assert_se(sd_netlink_message_close_container(m) >= 0); assert_se(sd_netlink_call(rtnl, m, 0, NULL) >= 0); client_ifindex = (int) if_nametoindex("pppoe-client"); assert_se(client_ifindex > 0); server_ifindex = (int) if_nametoindex("pppoe-server"); assert_se(server_ifindex > 0); m = sd_netlink_message_unref(m); assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_SETLINK, client_ifindex) >= 0); assert_se(sd_rtnl_message_link_set_flags(m, IFF_UP, IFF_UP) >= 0); assert_se(sd_netlink_call(rtnl, m, 0, NULL) >= 0); m = sd_netlink_message_unref(m); assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_SETLINK, server_ifindex) >= 0); assert_se(sd_rtnl_message_link_set_flags(m, IFF_UP, IFF_UP) >= 0); assert_se(sd_netlink_call(rtnl, m, 0, NULL) >= 0); pid = fork(); assert_se(pid >= 0); if (pid == 0) { /* let the client send some discover messages before the server is started */ sleep(2); /* TODO: manage pppoe-server-options */ execlp("pppoe-server", "pppoe-server", "-F", "-I", "pppoe-server", "-C", "Test-AC", "-S", "Service-Default", "-S", "Service-First-Auxiliary", "-S", "Service-Second-Auxiliary", NULL); assert_not_reached("failed to execute pppoe-server. not installed?"); } client_run("pppoe-client", e); assert_se(kill(pid, SIGTERM) >= 0); assert_se(wait_for_terminate(pid, NULL) >= 0); assert_se(!sd_netlink_message_unref(m)); assert_se(!sd_netlink_unref(rtnl)); return EXIT_SUCCESS; }
static int test_tunnel_configure(sd_netlink *rtnl) { int r; sd_netlink_message *m, *n; struct in_addr local, remote; /* skip test if module cannot be loaded */ r = load_module("ipip"); if(r < 0) return EXIT_TEST_SKIP; if(getuid() != 0) return EXIT_TEST_SKIP; /* IPIP tunnel */ assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0) >= 0); assert_se(m); assert_se(sd_netlink_message_append_string(m, IFLA_IFNAME, "ipip-tunnel") >= 0); assert_se(sd_netlink_message_append_u32(m, IFLA_MTU, 1234)>= 0); assert_se(sd_netlink_message_open_container(m, IFLA_LINKINFO) >= 0); assert_se(sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, "ipip") >= 0); inet_pton(AF_INET, "192.168.21.1", &local.s_addr); assert_se(sd_netlink_message_append_u32(m, IFLA_IPTUN_LOCAL, local.s_addr) >= 0); inet_pton(AF_INET, "192.168.21.2", &remote.s_addr); assert_se(sd_netlink_message_append_u32(m, IFLA_IPTUN_REMOTE, remote.s_addr) >= 0); assert_se(sd_netlink_message_close_container(m) >= 0); assert_se(sd_netlink_message_close_container(m) >= 0); assert_se(sd_netlink_call(rtnl, m, -1, 0) == 1); assert_se((m = sd_netlink_message_unref(m)) == NULL); r = load_module("sit"); if(r < 0) return EXIT_TEST_SKIP; /* sit */ assert_se(sd_rtnl_message_new_link(rtnl, &n, RTM_NEWLINK, 0) >= 0); assert_se(n); assert_se(sd_netlink_message_append_string(n, IFLA_IFNAME, "sit-tunnel") >= 0); assert_se(sd_netlink_message_append_u32(n, IFLA_MTU, 1234)>= 0); assert_se(sd_netlink_message_open_container(n, IFLA_LINKINFO) >= 0); assert_se(sd_netlink_message_open_container_union(n, IFLA_INFO_DATA, "sit") >= 0); assert_se(sd_netlink_message_append_u8(n, IFLA_IPTUN_PROTO, IPPROTO_IPIP) >= 0); inet_pton(AF_INET, "192.168.21.3", &local.s_addr); assert_se(sd_netlink_message_append_u32(n, IFLA_IPTUN_LOCAL, local.s_addr) >= 0); inet_pton(AF_INET, "192.168.21.4", &remote.s_addr); assert_se(sd_netlink_message_append_u32(n, IFLA_IPTUN_REMOTE, remote.s_addr) >= 0); assert_se(sd_netlink_message_close_container(n) >= 0); assert_se(sd_netlink_message_close_container(n) >= 0); assert_se(sd_netlink_call(rtnl, n, -1, 0) == 1); assert_se((n = sd_netlink_message_unref(n)) == NULL); return EXIT_SUCCESS; }