1
0
Fork 0

[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: Harald Welte <laforge@gnumonks.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
wifi-calibration
Harald Welte 2005-05-29 20:23:46 -07:00 committed by David S. Miller
parent 79158229b0
commit 8f937c6099
3 changed files with 32 additions and 5 deletions

View File

@ -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) && \

View File

@ -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
};

View File

@ -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;
}
*ifap1 = ifa->ifa_next;
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);
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 = {
{