Blob Blame History Raw
From 7eb12a5b21f87d7592ec2c5235d1ed90c4fac132 Mon Sep 17 00:00:00 2001
From: Dan Williams <dcbw@redhat.com>
Date: Tue, 3 Dec 2013 11:42:28 -0600
Subject: [PATCH] platform: set IPv4 broadcast address too (rh #1032819)

When moving over the platform, setting of the IPv4 broadcast address
got lost.  Bring it back.

https://bugzilla.redhat.com/show_bug.cgi?id=1032819
---
 src/platform/nm-linux-platform.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index 8f0e077..3f57925 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -2213,14 +2213,33 @@ ip6_address_get_all (NMPlatform *platform, int ifindex)
 			nl_object_unmark (object);
 		}
 	}
 
 	return addresses;
 }
 
+static void
+addr4_to_broadcast (struct in_addr *dst, const struct in_addr *src, guint8 plen)
+{
+	guint nbytes = plen / 8;
+	guint nbits = plen % 8;
+
+	g_return_if_fail (plen <= 32);
+	g_assert (src);
+	g_assert (dst);
+
+	if (plen >= 32)
+		*dst = *src;
+	else {
+		dst->s_addr = 0xFFFFFFFF;
+		memcpy (dst, src, nbytes);
+		((guint8 *) dst)[nbytes] = (((const guint8 *) src)[nbytes] | (0xFF >> nbits));
+	}
+}
+
 static struct nl_object *
 build_rtnl_addr (int family,
                  int ifindex,
                  gconstpointer addr,
                  gconstpointer peer_addr,
                  int plen,
                  guint32 lifetime,
@@ -2230,18 +2249,31 @@ build_rtnl_addr (int family,
 	struct rtnl_addr *rtnladdr = rtnl_addr_alloc ();
 	int addrlen = family == AF_INET ? sizeof (in_addr_t) : sizeof (struct in6_addr);
 	auto_nl_addr struct nl_addr *nladdr = nl_addr_build (family, addr, addrlen);
 	int nle;
 
 	g_assert (rtnladdr && nladdr);
 
+	/* IP address */
 	rtnl_addr_set_ifindex (rtnladdr, ifindex);
 	nle = rtnl_addr_set_local (rtnladdr, nladdr);
 	g_assert (!nle);
 
+	/* IPv4 Broadcast address */
+	if (family == AF_INET) {
+		struct in_addr bcast;
+		auto_nl_addr struct nl_addr *bcaddr = NULL;
+
+		addr4_to_broadcast (&bcast, addr, plen);
+		bcaddr = nl_addr_build (family, &bcast, addrlen);
+		g_assert (bcaddr);
+		rtnl_addr_set_broadcast (rtnladdr, bcaddr);
+	}
+
+	/* Peer/point-to-point address */
 	if (peer_addr) {
 		auto_nl_addr struct nl_addr *nlpeer = nl_addr_build (family, peer_addr, addrlen);
 
 		nle = rtnl_addr_set_peer (rtnladdr, nlpeer);
 		g_assert (!nle);
 	}
 
-- 
1.8.3.1