mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-08 12:40:36 +01:00
core/rdisc: limit the number of autoconf addresses to 'max_addresses'
NetworkManager uses the sysctl value 'max_addresses' as the kernel does. There is however a difference in what addresses are taken into account. The kernel counts all addresses on the interface (including temporary, private addresses and user configured ones). NM instead only limits the number of public autoconf addresses to 'max_addresses'. This is because it is difficult for NM to count all addresses (which can come from different sources) and it is not necessarily a more logical behavior. Only be aware, that NM uses the same config value as the kernel, but counts differently. Especially, the kernel might reach the limit earlier then NM in the presence of temporary addresses or addresses not from SLAAC. Note, that the kernel uses 'max_addresses' only to limit public, autoconf addresses. So this limit does not affect NM adding as many addresses as it wants. Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
parent
616fdb35ea
commit
84dc64c8af
7 changed files with 38 additions and 7 deletions
|
|
@ -477,6 +477,21 @@ restore_ip6_properties (NMDevice *self)
|
|||
}
|
||||
}
|
||||
|
||||
static gint32
|
||||
sysctl_get_ipv6_max_addresses (const char *dev)
|
||||
{
|
||||
gint32 max_addresses = 16;
|
||||
char *path;
|
||||
|
||||
g_return_val_if_fail (dev && *dev, max_addresses);
|
||||
|
||||
path = g_strdup_printf ("/proc/sys/net/ipv6/conf/%s/max_addresses", dev);
|
||||
max_addresses = nm_platform_sysctl_get_int32 (path, max_addresses);
|
||||
g_free (path);
|
||||
|
||||
return max_addresses;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get driver info from SIOCETHTOOL ioctl() for 'iface'
|
||||
* Returns driver and firmware versions to 'driver_version and' 'firmware_version'
|
||||
|
|
@ -3320,6 +3335,11 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device
|
|||
/* Rebuild address list from router discovery cache. */
|
||||
nm_ip6_config_reset_addresses (priv->ac_ip6_config);
|
||||
|
||||
/* rdisc->addresses contains at most max_addresses entries.
|
||||
* This is different from what the kernel does, which
|
||||
* also counts static and temporary addresses when checking
|
||||
* max_addresses.
|
||||
**/
|
||||
for (i = 0; i < rdisc->addresses->len; i++) {
|
||||
NMRDiscAddress *discovered_address = &g_array_index (rdisc->addresses, NMRDiscAddress, i);
|
||||
NMPlatformIP6Address address;
|
||||
|
|
@ -3428,7 +3448,8 @@ addrconf6_start (NMDevice *self)
|
|||
priv->ac_ip6_config = NULL;
|
||||
}
|
||||
|
||||
priv->rdisc = nm_lndp_rdisc_new (nm_device_get_ip_ifindex (self), ip_iface);
|
||||
priv->rdisc = nm_lndp_rdisc_new (nm_device_get_ip_ifindex (self), ip_iface,
|
||||
sysctl_get_ipv6_max_addresses (ip_iface));
|
||||
if (!priv->rdisc) {
|
||||
nm_log_err (LOGD_IP6, "(%s): failed to start router discovery.", ip_iface);
|
||||
return FALSE;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ G_DEFINE_TYPE (NMFakeRDisc, nm_fake_rdisc, NM_TYPE_RDISC)
|
|||
/******************************************************************/
|
||||
|
||||
NMRDisc *
|
||||
nm_fake_rdisc_new (int ifindex, const char *ifname)
|
||||
nm_fake_rdisc_new (int ifindex, const char *ifname, gint32 max_addresses)
|
||||
{
|
||||
NMRDisc *rdisc = g_object_new (NM_TYPE_FAKE_RDISC, NULL);
|
||||
|
||||
|
|
@ -44,6 +44,7 @@ nm_fake_rdisc_new (int ifindex, const char *ifname)
|
|||
|
||||
rdisc->ifindex = ifindex;
|
||||
rdisc->ifname = g_strdup (ifname);
|
||||
rdisc->max_addresses = max_addresses;
|
||||
|
||||
return rdisc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,6 @@ typedef struct {
|
|||
|
||||
GType nm_fake_rdisc_get_type (void);
|
||||
|
||||
NMRDisc *nm_fake_rdisc_new (int ifindex, const char *ifname);
|
||||
NMRDisc *nm_fake_rdisc_new (int ifindex, const char *ifname, gint32 max_addressses);
|
||||
|
||||
#endif /* NM_FAKE_RDISC_H */
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ G_DEFINE_TYPE (NMLNDPRDisc, nm_lndp_rdisc, NM_TYPE_RDISC)
|
|||
/******************************************************************/
|
||||
|
||||
NMRDisc *
|
||||
nm_lndp_rdisc_new (int ifindex, const char *ifname)
|
||||
nm_lndp_rdisc_new (int ifindex, const char *ifname, gint32 max_addresses)
|
||||
{
|
||||
NMRDisc *rdisc;
|
||||
NMLNDPRDiscPrivate *priv;
|
||||
|
|
@ -59,6 +59,7 @@ nm_lndp_rdisc_new (int ifindex, const char *ifname)
|
|||
|
||||
rdisc->ifindex = ifindex;
|
||||
rdisc->ifname = g_strdup (ifname);
|
||||
rdisc->max_addresses = max_addresses;
|
||||
|
||||
priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc);
|
||||
error = ndp_open (&priv->ndp);
|
||||
|
|
@ -113,6 +114,13 @@ add_address (NMRDisc *rdisc, const NMRDiscAddress *new)
|
|||
}
|
||||
}
|
||||
|
||||
/* we create at most max_addresses autoconf addresses. This is different from
|
||||
* what the kernel does, because it considers *all* addresses (including
|
||||
* static and other temporary addresses).
|
||||
**/
|
||||
if (rdisc->max_addresses && rdisc->addresses->len >= rdisc->max_addresses)
|
||||
return FALSE;
|
||||
|
||||
g_array_insert_val (rdisc->addresses, i, *new);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,6 @@ typedef struct {
|
|||
|
||||
GType nm_lndp_rdisc_get_type (void);
|
||||
|
||||
NMRDisc *nm_lndp_rdisc_new (int ifindex, const char *ifname);
|
||||
NMRDisc *nm_lndp_rdisc_new (int ifindex, const char *ifname, gint32 max_addresses);
|
||||
|
||||
#endif /* NM_LNDP_RDISC_H */
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ typedef struct {
|
|||
int ifindex;
|
||||
char *ifname;
|
||||
GBytes *lladdr;
|
||||
gint32 max_addresses;
|
||||
|
||||
NMRDiscDHCPLevel dhcp_level;
|
||||
GArray *gateways;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ main (int argc, char **argv)
|
|||
{
|
||||
GMainLoop *loop;
|
||||
NMRDisc *rdisc;
|
||||
NMRDisc *(*new) (int ifindex, const char *ifname) = nm_lndp_rdisc_new;
|
||||
NMRDisc *(*new) (int ifindex, const char *ifname, gint32 max_addresses) = nm_lndp_rdisc_new;
|
||||
int ifindex = 1;
|
||||
char ifname[IF_NAMESIZE];
|
||||
char mac[6] = { 0x02, 0xaa, 0xbb, 0xcc, 0xdd, 0xee };
|
||||
|
|
@ -34,7 +34,7 @@ main (int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
rdisc = new (ifindex, ifname);
|
||||
rdisc = new (ifindex, ifname, 0);
|
||||
if (!rdisc)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue