mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-01 07:10:12 +01:00
core: add nm_netns_shared_ip_reserve() API
Add a better way of tracking the shared IP addresses that are in use. This will replace NMDevice's usage of a global hash table. For one, the API is more formalized with reserve() and release() functions. Also, it ties the used IP addresses to the netns, which would be more correct (in the future when we may support more netns).
This commit is contained in:
parent
991999489a
commit
3fcfb53c4b
2 changed files with 120 additions and 0 deletions
108
src/nm-netns.c
108
src/nm-netns.c
|
|
@ -28,6 +28,7 @@ typedef struct {
|
|||
NMPNetns *platform_netns;
|
||||
NMPRulesManager *rules_manager;
|
||||
GHashTable *l3cfgs;
|
||||
GHashTable *shared_ips;
|
||||
CList l3cfg_signal_pending_lst_head;
|
||||
guint signal_pending_idle_id;
|
||||
} NMNetnsPrivate;
|
||||
|
|
@ -218,6 +219,112 @@ _platform_signal_cb (NMPlatform *platform,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMNetnsSharedIPHandle *
|
||||
nm_netns_shared_ip_reserve (NMNetns *self)
|
||||
{
|
||||
NMNetnsPrivate *priv;
|
||||
NMNetnsSharedIPHandle *handle;
|
||||
const in_addr_t addr_start = ntohl (0x0a2a0001u); /* 10.42.0.1 */
|
||||
in_addr_t addr;
|
||||
char sbuf_addr[NM_UTILS_INET_ADDRSTRLEN];
|
||||
|
||||
/* Find an unused address in the 10.42.x.x range */
|
||||
|
||||
g_return_val_if_fail (NM_IS_NETNS (self), NULL);
|
||||
|
||||
priv = NM_NETNS_GET_PRIVATE (self);
|
||||
|
||||
if (!priv->shared_ips) {
|
||||
addr = addr_start;
|
||||
priv->shared_ips = g_hash_table_new (nm_puint32_hash, nm_puint32_equals);
|
||||
g_object_ref (self);
|
||||
} else {
|
||||
guint32 count;
|
||||
|
||||
nm_assert (g_hash_table_size (priv->shared_ips) > 0);
|
||||
|
||||
count = 0u;
|
||||
for (;;) {
|
||||
addr = addr_start + htonl (count << 8u);
|
||||
|
||||
handle = g_hash_table_lookup (priv->shared_ips, &addr);
|
||||
if (!handle)
|
||||
break;
|
||||
|
||||
count++;
|
||||
|
||||
if (count > 0xFFu) {
|
||||
if (handle->_ref_count == 1) {
|
||||
_LOGE ("shared-ip4: ran out of shared IP addresses. Reuse %s/24",
|
||||
_nm_utils_inet4_ntop (handle->addr, sbuf_addr));
|
||||
} else {
|
||||
_LOGD ("shared-ip4: reserved IP address range %s/24 (duplicate)",
|
||||
_nm_utils_inet4_ntop (handle->addr, sbuf_addr));
|
||||
}
|
||||
handle->_ref_count++;
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handle = g_slice_new (NMNetnsSharedIPHandle);
|
||||
*handle = (NMNetnsSharedIPHandle) {
|
||||
.addr = addr,
|
||||
._ref_count = 1,
|
||||
._self = self,
|
||||
};
|
||||
|
||||
g_hash_table_add (priv->shared_ips, handle);
|
||||
|
||||
_LOGD ("shared-ip4: reserved IP address range %s/24",
|
||||
_nm_utils_inet4_ntop (handle->addr, sbuf_addr));
|
||||
return handle;
|
||||
}
|
||||
|
||||
void
|
||||
nm_netns_shared_ip_release (NMNetnsSharedIPHandle *handle)
|
||||
{
|
||||
NMNetns *self;
|
||||
NMNetnsPrivate *priv;
|
||||
char sbuf_addr[NM_UTILS_INET_ADDRSTRLEN];
|
||||
|
||||
g_return_if_fail (handle);
|
||||
|
||||
self = handle->_self;
|
||||
|
||||
g_return_if_fail (NM_IS_NETNS (self));
|
||||
|
||||
priv = NM_NETNS_GET_PRIVATE (self);
|
||||
|
||||
nm_assert (handle->_ref_count > 0);
|
||||
nm_assert (handle == nm_g_hash_table_lookup (priv->shared_ips, handle));
|
||||
|
||||
if (handle->_ref_count > 1) {
|
||||
nm_assert (handle->addr == ntohl (0x0A2AFF01u)); /* 10.42.255.1 */
|
||||
handle->_ref_count--;
|
||||
_LOGD ("shared-ip4: release IP address range %s/24 (%d more references held)",
|
||||
_nm_utils_inet4_ntop (handle->addr, sbuf_addr),
|
||||
handle->_ref_count);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_hash_table_remove (priv->shared_ips, handle))
|
||||
nm_assert_not_reached ();
|
||||
|
||||
if (g_hash_table_size (priv->shared_ips) == 0) {
|
||||
nm_clear_pointer (&priv->shared_ips, g_hash_table_unref);
|
||||
g_object_unref (self);
|
||||
}
|
||||
|
||||
_LOGD ("shared-ip4: release IP address range %s/24",
|
||||
_nm_utils_inet4_ntop (handle->addr, sbuf_addr));
|
||||
|
||||
handle->_self = NULL;
|
||||
nm_g_slice_free (handle);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
|
|
@ -312,6 +419,7 @@ dispose (GObject *object)
|
|||
|
||||
nm_assert (nm_g_hash_table_size (priv->l3cfgs) == 0);
|
||||
nm_assert (c_list_is_empty (&priv->l3cfg_signal_pending_lst_head));
|
||||
nm_assert (!priv->shared_ips);
|
||||
|
||||
nm_clear_g_source (&priv->signal_pending_idle_id);
|
||||
|
||||
|
|
|
|||
|
|
@ -34,4 +34,16 @@ struct _NMDedupMultiIndex *nm_netns_get_multi_idx (NMNetns *self);
|
|||
NML3Cfg *nm_netns_access_l3cfg (NMNetns *netns,
|
||||
int ifindex);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
in_addr_t addr;
|
||||
int _ref_count;
|
||||
NMNetns *_self;
|
||||
} NMNetnsSharedIPHandle;
|
||||
|
||||
NMNetnsSharedIPHandle *nm_netns_shared_ip_reserve (NMNetns *self);
|
||||
|
||||
void nm_netns_shared_ip_release (NMNetnsSharedIPHandle *handle);
|
||||
|
||||
#endif /* __NM_NETNS_H__ */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue