Skip to content

Commit

Permalink
[IPV4]: Primary and secondary addresses
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Harald Welte authored and David S. Miller committed May 30, 2005
1 parent 7915822 commit 8f937c6
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 5 deletions.
2 changes: 2 additions & 0 deletions include/linux/inetdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct ipv4_devconf
int no_xfrm;
int no_policy;
int force_igmp_version;
int promote_secondaries;
void *sysctl;
};

Expand Down Expand Up @@ -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) && \
Expand Down
1 change: 1 addition & 0 deletions include/linux/sysctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

Expand Down
34 changes: 29 additions & 5 deletions net/ipv4/devinet.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
}
}

Expand All @@ -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)
Expand Down Expand Up @@ -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 = {
{
Expand Down

0 comments on commit 8f937c6

Please sign in to comment.