ip6: set binary NL address prefix too

There's both nl_addr_set_prefixlen() to set the binary address's
prefix length and rtnl_addr_set_prefixlen() to set the container
RTNL address's prefix length.  When the addresses come in from
the kernel these are the same, but when sending addresses to
the kernel, NM wasn't setting them to the same thing.  Do that,
since apparently libnl wants that when matching addresses in
nm-system.c:sync_addresses() here:

	if (addrs[i] && nl_object_identical (match, (struct nl_object *) addrs[i]))
		break;

otherwise the kernel addres (match) doesn't match the NM-derived
address (addrs[i]) that we got from the IP6Manager when reading
back kernel IPv6 addresses in response to netlink events.
This commit is contained in:
Dan Williams 2012-03-05 09:39:12 -06:00
parent a9c3fe021a
commit a6809b0253

View file

@ -71,7 +71,7 @@ enum {
static struct nl_addr *
nm_utils_ip6_addr_to_nl_addr (const struct in6_addr *ip6_addr)
nm_utils_ip6_addr_to_nl_addr (const struct in6_addr *ip6_addr, guint prefix)
{
struct nl_addr * nla = NULL;
@ -79,6 +79,8 @@ nm_utils_ip6_addr_to_nl_addr (const struct in6_addr *ip6_addr)
return NULL;
nl_addr_set_family (nla, AF_INET6);
nl_addr_set_binary_addr (nla, (struct in6_addr *)ip6_addr, sizeof (struct in6_addr));
if (prefix)
nl_addr_set_prefixlen (nla, prefix);
return nla;
}
@ -428,14 +430,16 @@ nm_ip6_config_set_never_default (NMIP6Config *config, gboolean never_default)
/* libnl convenience/conversion functions */
static int ip6_addr_to_rtnl_local (const struct in6_addr *ip6_address, struct rtnl_addr *addr)
static int ip6_addr_to_rtnl_local (const struct in6_addr *ip6_address,
struct rtnl_addr *addr,
guint prefix)
{
struct nl_addr * local = NULL;
int err = 0;
g_return_val_if_fail (addr != NULL, -1);
local = nm_utils_ip6_addr_to_nl_addr (ip6_address);
local = nm_utils_ip6_addr_to_nl_addr (ip6_address, prefix);
err = rtnl_addr_set_local (addr, local);
nl_addr_put (local);
@ -449,7 +453,7 @@ static int ip6_addr_to_rtnl_peer (const struct in6_addr *ip6_address, struct rtn
g_return_val_if_fail (addr != NULL, -1);
peer = nm_utils_ip6_addr_to_nl_addr (ip6_address);
peer = nm_utils_ip6_addr_to_nl_addr (ip6_address, 0);
err = rtnl_addr_set_peer (addr, peer);
nl_addr_put (peer);
@ -472,8 +476,11 @@ nm_ip6_config_to_rtnl_addr (NMIP6Config *config, guint32 i, guint32 flags)
if (!(addr = rtnl_addr_alloc()))
return NULL;
if (flags & NM_RTNL_ADDR_ADDR)
success = (ip6_addr_to_rtnl_local (nm_ip6_address_get_address (config_addr), addr) >= 0);
if (flags & NM_RTNL_ADDR_ADDR) {
success = (ip6_addr_to_rtnl_local (nm_ip6_address_get_address (config_addr),
addr,
nm_ip6_address_get_prefix (config_addr)) >= 0);
}
if (flags & NM_RTNL_ADDR_PTP_ADDR)
success = (ip6_addr_to_rtnl_peer (&priv->ptp_address, addr) >= 0);