r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -EEXIST)
- log_link_struct(LOG_WARNING, link,
- "MESSAGE=%-*s: could not set route: %s",
- IFNAMSIZ,
- link->ifname, strerror(-r),
- "ERRNO=%d", -r,
- NULL);
+ log_link_warning_errno(link, -r, "%-*s: could not set route: %m", IFNAMSIZ, link->ifname);
if (link->link_messages == 0) {
log_link_debug(link, "routes set");
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -ESRCH)
- log_link_struct(LOG_WARNING, link,
- "MESSAGE=%-*s: could not drop route: %s",
- IFNAMSIZ,
- link->ifname, strerror(-r),
- "ERRNO=%d", -r,
- NULL);
-
- return 1;
-}
-
-int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
- _cleanup_link_unref_ Link *link = userdata;
- int r;
-
- assert(rtnl);
- assert(m);
- assert(link);
- assert(link->manager);
-
- for (; m; m = sd_rtnl_message_next(m)) {
- r = sd_rtnl_message_get_errno(m);
- if (r < 0) {
- log_link_debug(link, "getting address failed: %s",
- strerror(-r));
- continue;
- }
-
- r = link_rtnl_process_address(rtnl, m, link->manager);
- if (r < 0)
- log_link_warning(link, "could not process address: %s",
- strerror(-r));
- }
+ log_link_warning_errno(link, -r, "%-*s: could not drop route: %m", IFNAMSIZ, link->ifname);
return 1;
}
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -EEXIST)
- log_link_struct(LOG_WARNING, link,
- "MESSAGE=%-*s: could not set address: %s",
- IFNAMSIZ,
- link->ifname, strerror(-r),
- "ERRNO=%d", -r,
- NULL);
- else if (r >= 0) {
- /* calling handler directly so take a ref */
- link_ref(link);
- link_get_address_handler(rtnl, m, link);
- }
+ log_link_warning_errno(link, -r, "%-*s: could not set address: %m", IFNAMSIZ, link->ifname);
+ else if (r >= 0)
+ link_rtnl_process_address(rtnl, m, link->manager);
if (link->link_messages == 0) {
log_link_debug(link, "addresses set");
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -EADDRNOTAVAIL)
- log_link_struct(LOG_WARNING, link,
- "MESSAGE=%-*s: could not drop address: %s",
+ log_link_warning_errno(link, -r, "%-*s: could not drop address: %m", IFNAMSIZ, link->ifname);
+
+ return 1;
+}
+
+static int link_set_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
+ _cleanup_link_unref_ Link *link = userdata;
+ int r;
+
+ log_link_debug(link, "set link");
+
+ r = sd_rtnl_message_get_errno(m);
+ if (r < 0 && r != -EEXIST) {
+ log_link_struct(link, LOG_ERR,
+ "MESSAGE=%-*s: could not join netdev: %s",
IFNAMSIZ,
link->ifname, strerror(-r),
"ERRNO=%d", -r,
NULL);
+ link_enter_failed(link);
+ return 1;
+ }
- return 1;
+ return 0;
}
static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata,
r = sd_rtnl_message_get_errno(m);
if (r < 0)
- log_link_struct(LOG_WARNING, link,
- "MESSAGE=%-*s: could not set MTU: %s",
- IFNAMSIZ, link->ifname, strerror(-r),
- "ERRNO=%d", -r,
- NULL);
+ log_link_warning_errno(link, -r, "%-*s: could not set MTU: %m", IFNAMSIZ, link->ifname);
return 1;
}
return 0;
}
-static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
- Link *link = userdata;
-
- assert(link);
- assert(link->network);
- assert(link->manager);
-
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return;
-
- switch(event) {
- case DHCP6_EVENT_STOP:
- case DHCP6_EVENT_RESEND_EXPIRE:
- case DHCP6_EVENT_RETRANS_MAX:
- case DHCP6_EVENT_IP_ACQUIRE:
- log_link_debug(link, "DHCPv6 event %d", event);
-
- break;
-
- default:
- if (event < 0)
- log_link_warning(link, "DHCPv6 error: %s",
- strerror(-event));
- else
- log_link_warning(link, "DHCPv6 unknown event: %d",
- event);
- return;
- }
-}
-
-static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
- Link *link = userdata;
+static int link_set_bridge(Link *link) {
+ _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
int r;
assert(link);
assert(link->network);
- assert(link->manager);
-
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return;
-
- switch(event) {
- case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE:
- case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER:
- return;
- case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
- case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED:
- break;
-
- default:
- if (event < 0)
- log_link_warning(link, "ICMPv6 error: %s",
- strerror(-event));
- else
- log_link_warning(link, "ICMPv6 unknown event: %d",
- event);
+ if(link->network->cost == 0)
+ return 0;
- return;
+ r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
+ RTM_SETLINK, link->ifindex);
+ if (r < 0) {
+ log_link_error(link, "Could not allocate RTM_SETLINK message");
+ return r;
}
- if (link->dhcp6_client)
- return;
-
- r = sd_dhcp6_client_new(&link->dhcp6_client);
- if (r < 0)
- return;
-
- r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
+ r = sd_rtnl_message_link_set_family(req, PF_BRIDGE);
if (r < 0) {
- link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
- return;
+ log_link_error(link,
+ "Could not set message family %s", strerror(-r));
+ return r;
}
- r = sd_dhcp6_client_set_mac(link->dhcp6_client,
- (const uint8_t *) &link->mac,
- sizeof (link->mac), ARPHRD_ETHER);
+ r = sd_rtnl_message_open_container(req, IFLA_PROTINFO);
if (r < 0) {
- link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
- return;
+ log_link_error(link,
+ "Could not append IFLA_PROTINFO attribute: %s",
+ strerror(-r));
+ return r;
}
- r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
+ if(link->network->cost != 0) {
+ r = sd_rtnl_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost);
+ if (r < 0) {
+ log_link_error(link,
+ "Could not append IFLA_BRPORT_COST attribute: %s",
+ strerror(-r));
+ return r;
+ }
+ }
+
+ r = sd_rtnl_message_close_container(req);
if (r < 0) {
- link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
- return;
+ log_link_error(link,
+ "Could not append IFLA_LINKINFO attribute: %s",
+ strerror(-r));
+ return r;
}
- r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
- link);
+ r = sd_rtnl_call_async(link->manager->rtnl, req, link_set_handler, link, 0, NULL);
if (r < 0) {
- link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
- return;
+ log_link_error(link,
+ "Could not send rtnetlink message: %s",
+ strerror(-r));
+ return r;
}
- r = sd_dhcp6_client_start(link->dhcp6_client);
- if (r < 0)
- link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
+ link_ref(link);
+
+ return r;
}
static int link_acquire_conf(Link *link) {
if (r < 0) {
/* we warn but don't fail the link, as it may
be brought up later */
- log_link_struct(LOG_WARNING, link,
- "MESSAGE=%-*s: could not bring up interface: %s",
- IFNAMSIZ,
- link->ifname, strerror(-r),
- "ERRNO=%d", -r,
- NULL);
+ log_link_warning_errno(link, -r, "%-*s: could not bring up interface: %m", IFNAMSIZ, link->ifname);
}
return 1;
int r;
assert(link);
+ assert(link->network);
assert(link->manager);
assert(link->manager->rtnl);
return r;
}
+ if (link->network->mac) {
+ r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac);
+ if (r < 0) {
+ log_link_error(link, "Could not set MAC address: %s", strerror(-r));
+ return r;
+ }
+ }
+
+ if (link->network->mtu) {
+ r = sd_rtnl_message_append_u32(req, IFLA_MTU, link->network->mtu);
+ if (r < 0) {
+ log_link_error(link, "Could not set MTU: %s", strerror(-r));
+ return r;
+ }
+ }
+
r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link,
0, NULL);
if (r < 0) {
}
}
+ if(link->network->bridge) {
+ r = link_set_bridge(link);
+ if (r < 0) {
+ log_link_error(link,
+ "Could not set bridge message: %s",
+ strerror(-r));
+ }
+ }
+
return link_enter_set_addresses(link);
}
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
- log_link_struct(LOG_ERR, link,
- "MESSAGE=%-*s: could not join netdev: %s",
- IFNAMSIZ,
- link->ifname, strerror(-r),
- "ERRNO=%d", -r,
- NULL);
+ log_link_error_errno(link, -r, "%-*s: could not join netdev: %m", IFNAMSIZ, link->ifname);
link_enter_failed(link);
return 1;
} else
return link_joined(link);
if (link->network->bond) {
- log_link_struct(LOG_DEBUG, link,
+ log_link_struct(link, LOG_DEBUG,
"MESSAGE=%-*s: enslaving by '%s'",
IFNAMSIZ,
link->ifname, link->network->bond->ifname,
r = netdev_join(link->network->bond, link, &netdev_join_handler);
if (r < 0) {
- log_link_struct(LOG_WARNING, link,
+ log_link_struct(link, LOG_WARNING,
"MESSAGE=%-*s: could not join netdev '%s': %s",
IFNAMSIZ,
link->ifname, link->network->bond->ifname,
}
if (link->network->bridge) {
- log_link_struct(LOG_DEBUG, link,
+ log_link_struct(link, LOG_DEBUG,
"MESSAGE=%-*s: enslaving by '%s'",
IFNAMSIZ,
link->ifname, link->network->bridge->ifname,
r = netdev_join(link->network->bridge, link,
&netdev_join_handler);
if (r < 0) {
- log_link_struct(LOG_WARNING, link,
+ log_link_struct(link, LOG_WARNING,
"MESSAGE=%-*s: could not join netdev '%s': %s",
IFNAMSIZ,
link->ifname, link->network->bridge->ifname,
}
HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
- log_link_struct(LOG_DEBUG, link,
+ log_link_struct(link, LOG_DEBUG,
"MESSAGE=%-*s: enslaving by '%s'",
IFNAMSIZ,
link->ifname, netdev->ifname, NETDEVIF(netdev),
r = netdev_join(netdev, link, &netdev_join_handler);
if (r < 0) {
- log_link_struct(LOG_WARNING, link,
+ log_link_struct(link, LOG_WARNING,
"MESSAGE=%-*s: could not join netdev '%s': %s",
IFNAMSIZ,
link->ifname, netdev->ifname,
}
if (link_dhcp6_enabled(link)) {
- r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
- if (r < 0)
- return r;
-
- r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery,
- NULL, 0);
- if (r < 0)
- return r;
-
- r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery,
- &link->mac);
- if (r < 0)
- return r;
-
- r = sd_icmp6_nd_set_index(link->icmp6_router_discovery,
- link->ifindex);
- if (r < 0)
- return r;
-
- r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery,
- icmp6_router_handler, link);
+ r = icmp6_configure(link);
if (r < 0)
return r;
}
return 0;
}
-int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message,
- void *userdata) {
+int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
Manager *m = userdata;
Link *link = NULL;
uint16_t type;
assert(message);
assert(m);
+ if (sd_rtnl_message_is_error(message)) {
+ r = sd_rtnl_message_get_errno(message);
+ if (r < 0)
+ log_warning_errno(r, "rtnl: failed to receive address: %m");
+
+ return 0;
+ }
+
r = sd_rtnl_message_get_type(message, &type);
if (r < 0) {
log_warning("rtnl: could not get message type");
}
r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
- if (r < 0 || ifindex <= 0) {
- log_warning("rtnl: received address message without valid ifindex, ignoring");
+ if (r < 0) {
+ log_warning_errno(r, "rtnl: could not get ifindex: %m");
+ return 0;
+ } else if (ifindex <= 0) {
+ log_warning("rtnl: received address message with invalid ifindex: %d", ifindex);
return 0;
} else {
r = link_get(m, ifindex, &link);
if (r < 0 || !link) {
- log_warning("rtnl: received address for a nonexistent link (%d), ignoring", ifindex);
+ log_warning("rtnl: received address for nonexistent link (%d), ignoring", ifindex);
return 0;
}
}
int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
Link *link;
- _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
_cleanup_udev_device_unref_ struct udev_device *device = NULL;
char ifindex_str[2 + DECIMAL_STR_MAX(int)];
int r;
log_link_debug(link, "link %d added", link->ifindex);
- r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex,
- 0);
- if (r < 0)
- return r;
-
- r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0,
- NULL);
- if (r < 0)
- return r;
-
- link_ref(link);
-
if (detect_container(NULL) <= 0) {
/* not in a container, udev will be around */
sprintf(ifindex_str, "n%d", link->ifindex);