-static int link_set_bridge(Link *link) {
- _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
- int r;
-
- assert(link);
- assert(link->network);
-
- r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
-
- r = sd_rtnl_message_link_set_family(req, PF_BRIDGE);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not set message family: %m");
-
- r = sd_netlink_message_open_container(req, IFLA_PROTINFO);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m");
-
- if (link->network->use_bpdu >= 0) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_GUARD, link->network->use_bpdu);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_GUARD attribute: %m");
- }
-
- if (link->network->hairpin >= 0) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MODE, link->network->hairpin);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MODE attribute: %m");
- }
-
- if (link->network->fast_leave >= 0) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_FAST_LEAVE, link->network->fast_leave);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_FAST_LEAVE attribute: %m");
- }
-
- if (link->network->allow_port_to_be_root >= 0) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROTECT, link->network->allow_port_to_be_root);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROTECT attribute: %m");
-
- }
-
- if (link->network->unicast_flood >= 0) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_UNICAST_FLOOD, link->network->unicast_flood);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_UNICAST_FLOOD attribute: %m");
- }
-
- if (link->network->multicast_flood >= 0) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MCAST_FLOOD, link->network->multicast_flood);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MCAST_FLOOD attribute: %m");
- }
-
- if (link->network->multicast_to_unicast >= 0) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MCAST_TO_UCAST, link->network->multicast_to_unicast);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MCAST_TO_UCAST attribute: %m");
- }
-
- if (link->network->neighbor_suppression >= 0) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_NEIGH_SUPPRESS, link->network->neighbor_suppression);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_NEIGH_SUPPRESS attribute: %m");
- }
-
- if (link->network->learning >= 0) {
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_LEARNING, link->network->learning);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_LEARNING attribute: %m");
- }
-
- if (link->network->cost != 0) {
- r = sd_netlink_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_COST attribute: %m");
- }
-
- if (link->network->priority != LINK_BRIDGE_PORT_PRIORITY_INVALID) {
- r = sd_netlink_message_append_u16(req, IFLA_BRPORT_PRIORITY, link->network->priority);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PRIORITY attribute: %m");
- }
-
- r = sd_netlink_message_close_container(req);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
-
- r = netlink_call_async(link->manager->rtnl, NULL, req, link_set_handler,
- link_netlink_destroy_callback, link);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
-
- link_ref(link);
-
- return r;
-}
-
-static int link_set_bond_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
- int r;
-
- assert(m);
- assert(link);
- assert(link->ifname);
-
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0) {
- log_link_warning_errno(link, r, "Could not set bonding interface: %m");
- return 1;
- }
-
- return 1;
-}
-
-static int link_set_bond(Link *link) {
- _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
- int r;
-
- assert(link);
- assert(link->network);
-
- r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_NEWLINK, link->network->bond->ifindex);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
-
- r = sd_netlink_message_set_flags(req, NLM_F_REQUEST | NLM_F_ACK);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not set netlink flags: %m");
-
- r = sd_netlink_message_open_container(req, IFLA_LINKINFO);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m");
-
- r = sd_netlink_message_open_container_union(req, IFLA_INFO_DATA, "bond");
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
-
- if (link->network->active_slave) {
- r = sd_netlink_message_append_u32(req, IFLA_BOND_ACTIVE_SLAVE, link->ifindex);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BOND_ACTIVE_SLAVE attribute: %m");
- }
-
- if (link->network->primary_slave) {
- r = sd_netlink_message_append_u32(req, IFLA_BOND_PRIMARY, link->ifindex);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BOND_PRIMARY attribute: %m");
- }
-
- r = sd_netlink_message_close_container(req);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
-
- r = sd_netlink_message_close_container(req);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
-
- r = netlink_call_async(link->manager->rtnl, NULL, req, link_set_bond_handler,
- link_netlink_destroy_callback, link);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
-
- link_ref(link);
-
- return r;
-}
-
-static int link_lldp_save(Link *link) {
- _cleanup_free_ char *temp_path = NULL;
- _cleanup_fclose_ FILE *f = NULL;
- sd_lldp_neighbor **l = NULL;
- int n = 0, r, i;
-
- assert(link);
- assert(link->lldp_file);
-
- if (!link->lldp) {
- (void) unlink(link->lldp_file);
- return 0;
- }
-
- r = sd_lldp_get_neighbors(link->lldp, &l);
- if (r < 0)
- goto finish;
- if (r == 0) {
- (void) unlink(link->lldp_file);
- goto finish;
- }
-
- n = r;
-
- r = fopen_temporary(link->lldp_file, &f, &temp_path);
- if (r < 0)
- goto finish;
-
- fchmod(fileno(f), 0644);
-
- for (i = 0; i < n; i++) {
- const void *p;
- le64_t u;
- size_t sz;
-
- r = sd_lldp_neighbor_get_raw(l[i], &p, &sz);
- if (r < 0)
- goto finish;
-
- u = htole64(sz);
- (void) fwrite(&u, 1, sizeof(u), f);
- (void) fwrite(p, 1, sz, f);
- }
-
- r = fflush_and_check(f);
- if (r < 0)
- goto finish;
-
- if (rename(temp_path, link->lldp_file) < 0) {
- r = -errno;
- goto finish;
- }
-
-finish:
- if (r < 0) {
- (void) unlink(link->lldp_file);
- if (temp_path)
- (void) unlink(temp_path);
-
- log_link_error_errno(link, r, "Failed to save LLDP data to %s: %m", link->lldp_file);
- }
-
- if (l) {
- for (i = 0; i < n; i++)
- sd_lldp_neighbor_unref(l[i]);
- free(l);
- }
-
- return r;
-}
-
-static void lldp_handler(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n, void *userdata) {
- Link *link = userdata;
- int r;
-
- assert(link);
-
- (void) link_lldp_save(link);
-
- if (link_lldp_emit_enabled(link) && event == SD_LLDP_EVENT_ADDED) {
- /* If we received information about a new neighbor, restart the LLDP "fast" logic */
-
- log_link_debug(link, "Received LLDP datagram from previously unknown neighbor, restarting 'fast' LLDP transmission.");
-
- r = link_lldp_emit_start(link);
- if (r < 0)
- log_link_warning_errno(link, r, "Failed to restart LLDP transmission: %m");
- }
-}
-