Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8f937c60 authored by Harald Welte's avatar Harald Welte Committed by David S. Miller
Browse files

[IPV4]: Primary and secondary addresses



Add an option to make secondary IP addresses get promoted
when primary IP addresses are removed from the device.
It defaults to off to preserve existing behavior.

Signed-off-by: default avatarHarald Welte <laforge@gnumonks.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 79158229
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ struct ipv4_devconf
	int	no_xfrm;
	int	no_policy;
	int	force_igmp_version;
	int	promote_secondaries;
	void	*sysctl;
};

@@ -71,6 +72,7 @@ struct in_device
#define IN_DEV_SEC_REDIRECTS(in_dev)	(ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects)
#define IN_DEV_IDTAG(in_dev)		((in_dev)->cnf.tag)
#define IN_DEV_MEDIUM_ID(in_dev)	((in_dev)->cnf.medium_id)
#define IN_DEV_PROMOTE_SECONDARIES(in_dev)	(ipv4_devconf.promote_secondaries || (in_dev)->cnf.promote_secondaries)

#define IN_DEV_RX_REDIRECTS(in_dev) \
	((IN_DEV_FORWARD(in_dev) && \
+1 −0
Original line number Diff line number Diff line
@@ -399,6 +399,7 @@ enum
	NET_IPV4_CONF_FORCE_IGMP_VERSION=17,
	NET_IPV4_CONF_ARP_ANNOUNCE=18,
	NET_IPV4_CONF_ARP_IGNORE=19,
	NET_IPV4_CONF_PROMOTE_SECONDARIES=20,
	__NET_IPV4_CONF_MAX
};

+29 −5
Original line number Diff line number Diff line
@@ -233,11 +233,14 @@ int inet_addr_onlink(struct in_device *in_dev, u32 a, u32 b)
static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
			 int destroy)
{
	struct in_ifaddr *promote = NULL;
	struct in_ifaddr *ifa1 = *ifap;

	ASSERT_RTNL();

	/* 1. Deleting primary ifaddr forces deletion all secondaries */
	/* 1. Deleting primary ifaddr forces deletion all secondaries 
	 * unless alias promotion is set
	 **/

	if (!(ifa1->ifa_flags & IFA_F_SECONDARY)) {
		struct in_ifaddr *ifa;
@@ -251,11 +254,16 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
				continue;
			}

			if (!IN_DEV_PROMOTE_SECONDARIES(in_dev)) {
				*ifap1 = ifa->ifa_next;

				rtmsg_ifa(RTM_DELADDR, ifa);
				notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa);
				inet_free_ifa(ifa);
			} else {
				promote = ifa;
				break;
			}
		}
	}

@@ -281,6 +289,13 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
		if (!in_dev->ifa_list)
			inetdev_destroy(in_dev);
	}

	if (promote && IN_DEV_PROMOTE_SECONDARIES(in_dev)) {
		/* not sure if we should send a delete notify first? */
		promote->ifa_flags &= ~IFA_F_SECONDARY;
		rtmsg_ifa(RTM_NEWADDR, promote);
		notifier_call_chain(&inetaddr_chain, NETDEV_UP, promote);
	}
}

static int inet_insert_ifa(struct in_ifaddr *ifa)
@@ -1384,6 +1399,15 @@ static struct devinet_sysctl_table {
			.proc_handler	= &ipv4_doint_and_flush,
			.strategy	= &ipv4_doint_and_flush_strategy,
		},
		{
			.ctl_name	= NET_IPV4_CONF_PROMOTE_SECONDARIES,
			.procname	= "promote_secondaries",
			.data		= &ipv4_devconf.promote_secondaries,
			.maxlen		= sizeof(int),
			.mode		= 0644,
			.proc_handler	= &ipv4_doint_and_flush,
			.strategy	= &ipv4_doint_and_flush_strategy,
		},
	},
	.devinet_dev = {
		{