@ -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 = {
{