summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-01-14 16:10:50 +0100
committerThomas Haller <thaller@redhat.com>2020-01-14 16:10:50 +0100
commitc6f9002b1307b4cc6fe778119797cec2508093da (patch)
treecf63d7d51855b05975fa287e40cc3223314d3e89
parente6a9d5b99c7b674c3a932a5e16921eb9e3a7073c (diff)
parent791033352750f2ca414a6a4557e1dbcab581b171 (diff)
downloadNetworkManager-c6f9002b1307b4cc6fe778119797cec2508093da.tar.gz
platform: merge branch 'th/ifa-broadcast'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/391
-rw-r--r--src/platform/nm-fake-platform.c24
-rw-r--r--src/platform/nm-linux-platform.c24
-rw-r--r--src/platform/nm-platform.c63
-rw-r--r--src/platform/nm-platform.h35
-rw-r--r--src/platform/tests/test-cleanup.c3
-rw-r--r--src/platform/tests/test-common.c1
-rw-r--r--src/platform/tests/test-route.c1
7 files changed, 114 insertions, 37 deletions
diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c
index 124432a73c..a3c12becdd 100644
--- a/src/platform/nm-fake-platform.c
+++ b/src/platform/nm-fake-platform.c
@@ -938,6 +938,7 @@ ip4_address_add (NMPlatform *platform,
in_addr_t addr,
guint8 plen,
in_addr_t peer_addr,
+ in_addr_t broadcast_address,
guint32 lifetime,
guint32 preferred,
guint32 flags,
@@ -945,16 +946,19 @@ ip4_address_add (NMPlatform *platform,
{
NMPlatformIP4Address address;
- memset (&address, 0, sizeof (address));
- address.addr_source = NM_IP_CONFIG_SOURCE_KERNEL;
- address.ifindex = ifindex;
- address.address = addr;
- address.peer_address = peer_addr;
- address.plen = plen;
- address.timestamp = nm_utils_get_monotonic_timestamp_sec ();
- address.lifetime = lifetime;
- address.preferred = preferred;
- address.n_ifa_flags = flags;
+ address = (NMPlatformIP4Address) {
+ .addr_source = NM_IP_CONFIG_SOURCE_KERNEL,
+ .ifindex = ifindex,
+ .address = addr,
+ .plen = plen,
+ .peer_address = peer_addr,
+ .broadcast_address = broadcast_address,
+ .use_ip4_broadcast_address = TRUE,
+ .timestamp = nm_utils_get_monotonic_timestamp_sec (),
+ .lifetime = lifetime,
+ .preferred = preferred,
+ .n_ifa_flags = flags,
+ };
if (label)
g_strlcpy (address.label, label, sizeof (address.label));
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index 020db21ecd..c6e58284e0 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -3012,6 +3012,12 @@ _new_from_nl_addr (struct nlmsghdr *nlh, gboolean id_only)
memcpy (&obj->ip4_address.address, nla_data (tb[IFA_LOCAL]), addr_len);
if (tb[IFA_ADDRESS])
memcpy (&obj->ip4_address.peer_address, nla_data (tb[IFA_ADDRESS]), addr_len);
+
+ _check_addr_or_return_null (tb, IFA_BROADCAST, addr_len);
+ obj->ip4_address.broadcast_address = tb[IFA_BROADCAST]
+ ? nla_get_u32 (tb[IFA_BROADCAST])
+ : 0u;
+ obj->ip4_address.use_ip4_broadcast_address = TRUE;
} else {
/* For IPv6, IFA_ADDRESS is always present.
*
@@ -4177,6 +4183,7 @@ _nl_msg_new_address (int nlmsg_type,
int scope,
guint32 lifetime,
guint32 preferred,
+ in_addr_t ip4_broadcast_address,
const char *label)
{
nm_auto_nlmsg struct nl_msg *msg = NULL;
@@ -4220,16 +4227,8 @@ _nl_msg_new_address (int nlmsg_type,
if (label && label[0])
NLA_PUT_STRING (msg, IFA_LABEL, label);
- if ( family == AF_INET
- && nlmsg_type != RTM_DELADDR
- && plen < 31 /* RFC 3021 */
- && address
- && *((in_addr_t *) address) != 0) {
- in_addr_t broadcast;
-
- broadcast = *((in_addr_t *) address) | ~_nm_utils_ip4_prefix_to_netmask (plen);
- NLA_PUT (msg, IFA_BROADCAST, addr_len, &broadcast);
- }
+ if (ip4_broadcast_address != 0)
+ NLA_PUT (msg, IFA_BROADCAST, sizeof (in_addr_t), &ip4_broadcast_address);
if ( lifetime != NM_PLATFORM_LIFETIME_PERMANENT
|| preferred != NM_PLATFORM_LIFETIME_PERMANENT) {
@@ -8005,6 +8004,7 @@ ip4_address_add (NMPlatform *platform,
in_addr_t addr,
guint8 plen,
in_addr_t peer_addr,
+ in_addr_t broadcast_address,
guint32 lifetime,
guint32 preferred,
guint32 flags,
@@ -8024,6 +8024,7 @@ ip4_address_add (NMPlatform *platform,
nm_utils_ip4_address_is_link_local (addr) ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE,
lifetime,
preferred,
+ broadcast_address,
label);
nmp_object_stackinit_id_ip4_address (&obj_id, ifindex, addr, plen, peer_addr);
@@ -8054,6 +8055,7 @@ ip6_address_add (NMPlatform *platform,
RT_SCOPE_UNIVERSE,
lifetime,
preferred,
+ 0,
NULL);
nmp_object_stackinit_id_ip6_address (&obj_id, ifindex, &addr);
@@ -8077,6 +8079,7 @@ ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, guint8 pl
RT_SCOPE_NOWHERE,
NM_PLATFORM_LIFETIME_PERMANENT,
NM_PLATFORM_LIFETIME_PERMANENT,
+ 0,
NULL);
if (!nlmsg)
g_return_val_if_reached (FALSE);
@@ -8102,6 +8105,7 @@ ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, gui
RT_SCOPE_NOWHERE,
NM_PLATFORM_LIFETIME_PERMANENT,
NM_PLATFORM_LIFETIME_PERMANENT,
+ 0,
NULL);
if (!nlmsg)
g_return_val_if_reached (FALSE);
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index 2065b1818e..82d79d7a44 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -3314,6 +3314,7 @@ nm_platform_ip4_address_add (NMPlatform *self,
in_addr_t address,
guint8 plen,
in_addr_t peer_address,
+ in_addr_t broadcast_address,
guint32 lifetime,
guint32 preferred,
guint32 flags,
@@ -3328,22 +3329,26 @@ nm_platform_ip4_address_add (NMPlatform *self,
g_return_val_if_fail (!label || strlen (label) < sizeof (((NMPlatformIP4Address *) NULL)->label), FALSE);
if (_LOGD_ENABLED ()) {
- NMPlatformIP4Address addr = { 0 };
-
- addr.ifindex = ifindex;
- addr.address = address;
- addr.peer_address = peer_address;
- addr.plen = plen;
- addr.timestamp = 0; /* set it at zero, which to_string will treat as *now* */
- addr.lifetime = lifetime;
- addr.preferred = preferred;
- addr.n_ifa_flags = flags;
+ NMPlatformIP4Address addr;
+
+ addr = (NMPlatformIP4Address) {
+ .ifindex = ifindex,
+ .address = address,
+ .peer_address = peer_address,
+ .plen = plen,
+ .timestamp = 0, /* set it at zero, which to_string will treat as *now* */
+ .lifetime = lifetime,
+ .preferred = preferred,
+ .n_ifa_flags = flags,
+ .broadcast_address = broadcast_address,
+ .use_ip4_broadcast_address = TRUE,
+ };
if (label)
g_strlcpy (addr.label, label, sizeof (addr.label));
_LOG3D ("address: adding or updating IPv4 address: %s", nm_platform_ip4_address_to_string (&addr, NULL, 0));
}
- return klass->ip4_address_add (self, ifindex, address, plen, peer_address, lifetime, preferred, flags, label);
+ return klass->ip4_address_add (self, ifindex, address, plen, peer_address, broadcast_address, lifetime, preferred, flags, label);
}
gboolean
@@ -3802,8 +3807,14 @@ nm_platform_ip4_address_sync (NMPlatform *self,
if (!lifetime)
goto delete_and_next2;
- if (!nm_platform_ip4_address_add (self, ifindex, known_address->address, known_address->plen,
- known_address->peer_address, lifetime, preferred,
+ if (!nm_platform_ip4_address_add (self,
+ ifindex,
+ known_address->address,
+ known_address->plen,
+ known_address->peer_address,
+ nm_platform_ip4_broadcast_address_from_addr (known_address),
+ lifetime,
+ preferred,
ifa_flags,
known_address->label))
goto delete_and_next2;
@@ -5708,6 +5719,8 @@ nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address, char *bu
char *str_peer = NULL;
const char *str_lft_p, *str_pref_p, *str_time_p;
gint32 now = nm_utils_get_monotonic_timestamp_sec ();
+ in_addr_t broadcast_address;
+ char str_broadcast[INET_ADDRSTRLEN];
if (!nm_utils_to_string_buffer_init_null (address, &buf, &len))
return buf;
@@ -5736,9 +5749,27 @@ nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address, char *bu
now, str_pref, sizeof (str_pref)) );
str_time_p = _lifetime_summary_to_string (now, address->timestamp, address->preferred, address->lifetime, str_time, sizeof (str_time));
+ broadcast_address = nm_platform_ip4_broadcast_address_from_addr (address);
+
g_snprintf (buf, len,
- "%s/%d lft %s pref %s%s%s%s%s%s src %s%s",
- s_address, address->plen, str_lft_p, str_pref_p, str_time_p,
+ "%s/%d"
+ "%s%s" /* broadcast */
+ " lft %s"
+ " pref %s"
+ "%s" /* time */
+ "%s" /* peer */
+ "%s" /* dev */
+ "%s" /* flags */
+ "%s" /* label */
+ " src %s"
+ "%s" /* external */
+ "",
+ s_address, address->plen,
+ broadcast_address ? " brd " : "",
+ broadcast_address ? nm_utils_inet4_ntop (broadcast_address, str_broadcast) : "",
+ str_lft_p,
+ str_pref_p,
+ str_time_p,
str_peer ?: "",
str_dev,
_to_string_ifa_flags (address->n_ifa_flags, s_flags, sizeof (s_flags)),
@@ -6966,6 +6997,7 @@ nm_platform_ip4_address_hash_update (const NMPlatformIP4Address *obj, NMHashStat
nm_hash_update_vals (h,
obj->ifindex,
obj->addr_source,
+ nm_platform_ip4_broadcast_address_from_addr (obj),
obj->timestamp,
obj->lifetime,
obj->preferred,
@@ -6985,6 +7017,7 @@ nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4A
NM_CMP_FIELD (a, b, address);
NM_CMP_FIELD (a, b, plen);
NM_CMP_FIELD (a, b, peer_address);
+ NM_CMP_DIRECT (nm_platform_ip4_broadcast_address_from_addr (a), nm_platform_ip4_broadcast_address_from_addr (b));
NM_CMP_FIELD (a, b, addr_source);
NM_CMP_FIELD (a, b, timestamp);
NM_CMP_FIELD (a, b, lifetime);
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index d18208081a..56788c182e 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -308,6 +308,8 @@ typedef enum {
guint8 plen; \
\
bool external:1; \
+ \
+ bool use_ip4_broadcast_address:1; \
;
/**
@@ -344,6 +346,12 @@ struct _NMPlatformIP4Address {
* */
in_addr_t peer_address; /* PTP peer address */
+ /* IFA_BROADCAST.
+ *
+ * This parameter is ignored unless use_ip4_broadcast_address is TRUE.
+ * See nm_platform_ip4_broadcast_address_from_addr(). */
+ in_addr_t broadcast_address;
+
char label[NMP_IFNAMSIZ];
};
@@ -1080,6 +1088,7 @@ typedef struct {
in_addr_t address,
guint8 plen,
in_addr_t peer_address,
+ in_addr_t broadcast_address,
guint32 lifetime,
guint32 preferred_lft,
guint32 flags,
@@ -1151,6 +1160,31 @@ NMPlatform *nm_platform_get (void);
/*****************************************************************************/
+static inline in_addr_t
+nm_platform_ip4_broadcast_address_create (in_addr_t address,
+ guint8 plen)
+{
+ return address | ~_nm_utils_ip4_prefix_to_netmask (plen);
+}
+
+static inline in_addr_t
+nm_platform_ip4_broadcast_address_from_addr (const NMPlatformIP4Address *addr)
+{
+ nm_assert (addr);
+
+ if (addr->use_ip4_broadcast_address)
+ return addr->broadcast_address;
+
+ /* the set broadcast-address gets ignored, and we determine a default brd base
+ * on the peer IFA_ADDRESS. */
+ if ( addr->peer_address != 0u
+ && addr->plen < 31 /* RFC3021 */)
+ return nm_platform_ip4_broadcast_address_create (addr->peer_address, addr->plen);
+ return 0u;
+}
+
+/*****************************************************************************/
+
/**
* nm_platform_route_table_coerce:
* @table: the route table, in its original value as received
@@ -1727,6 +1761,7 @@ gboolean nm_platform_ip4_address_add (NMPlatform *self,
in_addr_t address,
guint8 plen,
in_addr_t peer_address,
+ in_addr_t broadcast_address,
guint32 lifetime,
guint32 preferred_lft,
guint32 flags,
diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c
index 34175c0160..d19ff1f0af 100644
--- a/src/platform/tests/test-cleanup.c
+++ b/src/platform/tests/test-cleanup.c
@@ -61,8 +61,7 @@ test_cleanup_internal (void)
break;
});
- /* Add routes and addresses */
- g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr4, plen4, addr4, lifetime, preferred, 0, NULL));
+ g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr4, plen4, addr4, nm_platform_ip4_broadcast_address_create (addr4, plen4), lifetime, preferred, 0, NULL));
g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, addr6, plen6, in6addr_any, lifetime, preferred, flags));
nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway4, 32, INADDR_ANY, 0, metric, mss);
nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network4, plen4, gateway4, 0, metric, mss);
diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c
index 2fbfb90d4c..f6a77daa08 100644
--- a/src/platform/tests/test-common.c
+++ b/src/platform/tests/test-common.c
@@ -867,6 +867,7 @@ _ip_address_add (NMPlatform *platform,
address->addr4,
plen,
peer_address->addr4,
+ 0u,
lifetime,
preferred,
flags,
diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c
index e2c1ed80e4..707313b4ca 100644
--- a/src/platform/tests/test-route.c
+++ b/src/platform/tests/test-route.c
@@ -544,6 +544,7 @@ test_ip4_route_options (gconstpointer test_data)
a->address,
a->plen,
a->peer_address,
+ nm_platform_ip4_broadcast_address_create (a->address, a->plen),
a->lifetime,
a->preferred,
a->n_ifa_flags,