From a6809b0253b2a86218df5afaf1d6b3b7354fc224 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 5 Mar 2012 09:39:12 -0600 Subject: [PATCH] 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. --- src/nm-ip6-config.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 2f231638f5..f06e4069c4 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -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);