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; }
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); }
/* send a request to the kernel to add a FDB entry in its static MAC table. */ int fdb_entry_configure(Link *link, FdbEntry *fdb_entry) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; sd_netlink *rtnl; int r; uint8_t flags; Bridge *bridge; assert(link); assert(link->network); assert(link->manager); assert(fdb_entry); rtnl = link->manager->rtnl; bridge = BRIDGE(link->network->bridge); /* create new RTM message */ r = sd_rtnl_message_new_neigh(rtnl, &req, RTM_NEWNEIGH, link->ifindex, PF_BRIDGE); if (r < 0) return rtnl_log_create_error(r); if (bridge) flags = NTF_MASTER; else flags = NTF_SELF; r = sd_rtnl_message_neigh_set_flags(req, flags); if (r < 0) return rtnl_log_create_error(r); /* only NUD_PERMANENT state supported. */ r = sd_rtnl_message_neigh_set_state(req, NUD_NOARP | NUD_PERMANENT); if (r < 0) return rtnl_log_create_error(r); r = sd_netlink_message_append_ether_addr(req, NDA_LLADDR, fdb_entry->mac_addr); if (r < 0) return rtnl_log_create_error(r); /* VLAN Id is optional. We'll add VLAN Id only if it's specified. */ if (0 != fdb_entry->vlan_id) { r = sd_netlink_message_append_u16(req, NDA_VLAN, fdb_entry->vlan_id); if (r < 0) return rtnl_log_create_error(r); } /* send message to the kernel to update its internal static MAC table. */ r = sd_netlink_call_async(rtnl, NULL, req, set_fdb_handler, link_netlink_destroy_callback, link, 0, __func__); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); link_ref(link); 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; }