netlink: Propagate errors for "dump" operations
Currently if we receive any netlink errors while discovering network configuration from the host, we'll just ignore it and carry on. This might lead to cryptic error messages later on, or even silent misconfiguration. We now have the mechanisms to detect errors from get/dump netlink operations. Propgate these errors up to the callers and report them usefully. Link: https://bugs.passt.top/show_bug.cgi?id=60 Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
4d6e9d0816
commit
5103811e2d
3 changed files with 70 additions and 22 deletions
59
conf.c
59
conf.c
|
@ -648,12 +648,24 @@ static unsigned int conf_ip4(unsigned int ifi,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IN4_IS_ADDR_UNSPECIFIED(&ip4->gw))
|
if (IN4_IS_ADDR_UNSPECIFIED(&ip4->gw)) {
|
||||||
nl_route_get_def(nl_sock, ifi, AF_INET, &ip4->gw);
|
int rc = nl_route_get_def(nl_sock, ifi, AF_INET, &ip4->gw);
|
||||||
|
if (rc < 0) {
|
||||||
|
err("Couldn't discover IPv4 gateway address: %s",
|
||||||
|
strerror(-rc));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (IN4_IS_ADDR_UNSPECIFIED(&ip4->addr))
|
if (IN4_IS_ADDR_UNSPECIFIED(&ip4->addr)) {
|
||||||
nl_addr_get(nl_sock, ifi, AF_INET,
|
int rc = nl_addr_get(nl_sock, ifi, AF_INET,
|
||||||
&ip4->addr, &ip4->prefix_len, NULL);
|
&ip4->addr, &ip4->prefix_len, NULL);
|
||||||
|
if (rc < 0) {
|
||||||
|
err("Couldn't discover IPv4 address: %s",
|
||||||
|
strerror(-rc));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!ip4->prefix_len) {
|
if (!ip4->prefix_len) {
|
||||||
in_addr_t addr = ntohl(ip4->addr.s_addr);
|
in_addr_t addr = ntohl(ip4->addr.s_addr);
|
||||||
|
@ -669,8 +681,15 @@ static unsigned int conf_ip4(unsigned int ifi,
|
||||||
|
|
||||||
memcpy(&ip4->addr_seen, &ip4->addr, sizeof(ip4->addr_seen));
|
memcpy(&ip4->addr_seen, &ip4->addr, sizeof(ip4->addr_seen));
|
||||||
|
|
||||||
if (MAC_IS_ZERO(mac))
|
if (MAC_IS_ZERO(mac)) {
|
||||||
nl_link_get_mac(nl_sock, ifi, mac);
|
int rc = nl_link_get_mac(nl_sock, ifi, mac);
|
||||||
|
if (rc < 0) {
|
||||||
|
char ifname[IFNAMSIZ];
|
||||||
|
err("Couldn't discover MAC for %s: %s",
|
||||||
|
if_indextoname(ifi, ifname), strerror(-rc));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (IN4_IS_ADDR_UNSPECIFIED(&ip4->addr) ||
|
if (IN4_IS_ADDR_UNSPECIFIED(&ip4->addr) ||
|
||||||
MAC_IS_ZERO(mac))
|
MAC_IS_ZERO(mac))
|
||||||
|
@ -691,6 +710,7 @@ static unsigned int conf_ip6(unsigned int ifi,
|
||||||
struct ip6_ctx *ip6, unsigned char *mac)
|
struct ip6_ctx *ip6, unsigned char *mac)
|
||||||
{
|
{
|
||||||
int prefix_len = 0;
|
int prefix_len = 0;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (!ifi)
|
if (!ifi)
|
||||||
ifi = nl_get_ext_if(nl_sock, AF_INET6);
|
ifi = nl_get_ext_if(nl_sock, AF_INET6);
|
||||||
|
@ -700,18 +720,35 @@ static unsigned int conf_ip6(unsigned int ifi,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IN6_IS_ADDR_UNSPECIFIED(&ip6->gw))
|
if (IN6_IS_ADDR_UNSPECIFIED(&ip6->gw)) {
|
||||||
nl_route_get_def(nl_sock, ifi, AF_INET6, &ip6->gw);
|
rc = nl_route_get_def(nl_sock, ifi, AF_INET6, &ip6->gw);
|
||||||
|
if (rc < 0) {
|
||||||
|
err("Couldn't discover IPv6 gateway address: %s",
|
||||||
|
strerror(-rc));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nl_addr_get(nl_sock, ifi, AF_INET6,
|
rc = nl_addr_get(nl_sock, ifi, AF_INET6,
|
||||||
IN6_IS_ADDR_UNSPECIFIED(&ip6->addr) ? &ip6->addr : NULL,
|
IN6_IS_ADDR_UNSPECIFIED(&ip6->addr) ? &ip6->addr : NULL,
|
||||||
&prefix_len, &ip6->addr_ll);
|
&prefix_len, &ip6->addr_ll);
|
||||||
|
if (rc < 0) {
|
||||||
|
err("Couldn't discover IPv6 address: %s", strerror(-rc));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(&ip6->addr_seen, &ip6->addr, sizeof(ip6->addr));
|
memcpy(&ip6->addr_seen, &ip6->addr, sizeof(ip6->addr));
|
||||||
memcpy(&ip6->addr_ll_seen, &ip6->addr_ll, sizeof(ip6->addr_ll));
|
memcpy(&ip6->addr_ll_seen, &ip6->addr_ll, sizeof(ip6->addr_ll));
|
||||||
|
|
||||||
if (MAC_IS_ZERO(mac))
|
if (MAC_IS_ZERO(mac)) {
|
||||||
nl_link_get_mac(0, ifi, mac);
|
rc = nl_link_get_mac(nl_sock, ifi, mac);
|
||||||
|
if (rc < 0) {
|
||||||
|
char ifname[IFNAMSIZ];
|
||||||
|
err("Couldn't discover MAC for %s: %s",
|
||||||
|
if_indextoname(ifi, ifname), strerror(-rc));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (IN6_IS_ADDR_UNSPECIFIED(&ip6->addr) ||
|
if (IN6_IS_ADDR_UNSPECIFIED(&ip6->addr) ||
|
||||||
IN6_IS_ADDR_UNSPECIFIED(&ip6->addr_ll) ||
|
IN6_IS_ADDR_UNSPECIFIED(&ip6->addr_ll) ||
|
||||||
|
|
17
netlink.c
17
netlink.c
|
@ -277,6 +277,8 @@ unsigned int nl_get_ext_if(int s, sa_family_t af)
|
||||||
ifi = *(unsigned int *)RTA_DATA(rta);
|
ifi = *(unsigned int *)RTA_DATA(rta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (status < 0)
|
||||||
|
warn("netlink: RTM_GETROUTE failed: %s", strerror(-status));
|
||||||
|
|
||||||
return ifi;
|
return ifi;
|
||||||
}
|
}
|
||||||
|
@ -287,8 +289,10 @@ unsigned int nl_get_ext_if(int s, sa_family_t af)
|
||||||
* @ifi: Interface index
|
* @ifi: Interface index
|
||||||
* @af: Address family
|
* @af: Address family
|
||||||
* @gw: Default gateway to fill on NL_GET
|
* @gw: Default gateway to fill on NL_GET
|
||||||
|
*
|
||||||
|
* Return: 0 on success, negative error code on failure
|
||||||
*/
|
*/
|
||||||
void nl_route_get_def(int s, unsigned int ifi, sa_family_t af, void *gw)
|
int nl_route_get_def(int s, unsigned int ifi, sa_family_t af, void *gw)
|
||||||
{
|
{
|
||||||
struct req_t {
|
struct req_t {
|
||||||
struct nlmsghdr nlh;
|
struct nlmsghdr nlh;
|
||||||
|
@ -329,6 +333,7 @@ void nl_route_get_def(int s, unsigned int ifi, sa_family_t af, void *gw)
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -507,8 +512,10 @@ void nl_route_dup(int s_src, unsigned int ifi_src,
|
||||||
* @addr: Global address to fill
|
* @addr: Global address to fill
|
||||||
* @prefix_len: Mask or prefix length, to fill (for IPv4)
|
* @prefix_len: Mask or prefix length, to fill (for IPv4)
|
||||||
* @addr_l: Link-scoped address to fill (for IPv6)
|
* @addr_l: Link-scoped address to fill (for IPv6)
|
||||||
|
*
|
||||||
|
* Return: 9 on success, negative error code on failure
|
||||||
*/
|
*/
|
||||||
void nl_addr_get(int s, unsigned int ifi, sa_family_t af,
|
int nl_addr_get(int s, unsigned int ifi, sa_family_t af,
|
||||||
void *addr, int *prefix_len, void *addr_l)
|
void *addr, int *prefix_len, void *addr_l)
|
||||||
{
|
{
|
||||||
struct req_t {
|
struct req_t {
|
||||||
|
@ -550,6 +557,7 @@ void nl_addr_get(int s, unsigned int ifi, sa_family_t af,
|
||||||
memcpy(addr_l, RTA_DATA(rta), RTA_PAYLOAD(rta));
|
memcpy(addr_l, RTA_DATA(rta), RTA_PAYLOAD(rta));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -677,8 +685,10 @@ void nl_addr_dup(int s_src, unsigned int ifi_src,
|
||||||
* @s: Netlink socket
|
* @s: Netlink socket
|
||||||
* @ifi: Interface index
|
* @ifi: Interface index
|
||||||
* @mac: Fill with current MAC address
|
* @mac: Fill with current MAC address
|
||||||
|
*
|
||||||
|
* Return: 0 on success, negative error code on failure
|
||||||
*/
|
*/
|
||||||
void nl_link_get_mac(int s, unsigned int ifi, void *mac)
|
int nl_link_get_mac(int s, unsigned int ifi, void *mac)
|
||||||
{
|
{
|
||||||
struct req_t {
|
struct req_t {
|
||||||
struct nlmsghdr nlh;
|
struct nlmsghdr nlh;
|
||||||
|
@ -707,6 +717,7 @@ void nl_link_get_mac(int s, unsigned int ifi, void *mac)
|
||||||
memcpy(mac, RTA_DATA(rta), ETH_ALEN);
|
memcpy(mac, RTA_DATA(rta), ETH_ALEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -11,17 +11,17 @@ extern int nl_sock_ns;
|
||||||
|
|
||||||
void nl_sock_init(const struct ctx *c, bool ns);
|
void nl_sock_init(const struct ctx *c, bool ns);
|
||||||
unsigned int nl_get_ext_if(int s, sa_family_t af);
|
unsigned int nl_get_ext_if(int s, sa_family_t af);
|
||||||
void nl_route_get_def(int s, unsigned int ifi, sa_family_t af, void *gw);
|
int nl_route_get_def(int s, unsigned int ifi, sa_family_t af, void *gw);
|
||||||
int nl_route_set_def(int s, unsigned int ifi, sa_family_t af, void *gw);
|
int nl_route_set_def(int s, unsigned int ifi, sa_family_t af, void *gw);
|
||||||
void nl_route_dup(int s_src, unsigned int ifi_src,
|
void nl_route_dup(int s_src, unsigned int ifi_src,
|
||||||
int s_dst, unsigned int ifi_dst, sa_family_t af);
|
int s_dst, unsigned int ifi_dst, sa_family_t af);
|
||||||
void nl_addr_get(int s, unsigned int ifi, sa_family_t af,
|
int nl_addr_get(int s, unsigned int ifi, sa_family_t af,
|
||||||
void *addr, int *prefix_len, void *addr_l);
|
void *addr, int *prefix_len, void *addr_l);
|
||||||
int nl_addr_set(int s, unsigned int ifi, sa_family_t af,
|
int nl_addr_set(int s, unsigned int ifi, sa_family_t af,
|
||||||
void *addr, int prefix_len);
|
void *addr, int prefix_len);
|
||||||
void nl_addr_dup(int s_src, unsigned int ifi_src,
|
void nl_addr_dup(int s_src, unsigned int ifi_src,
|
||||||
int s_dst, unsigned int ifi_dst, sa_family_t af);
|
int s_dst, unsigned int ifi_dst, sa_family_t af);
|
||||||
void nl_link_get_mac(int s, unsigned int ifi, void *mac);
|
int nl_link_get_mac(int s, unsigned int ifi, void *mac);
|
||||||
int nl_link_set_mac(int s, unsigned int ifi, void *mac);
|
int nl_link_set_mac(int s, unsigned int ifi, void *mac);
|
||||||
int nl_link_up(int s, unsigned int ifi, int mtu);
|
int nl_link_up(int s, unsigned int ifi, int mtu);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue