ipv6: Regenerate host route according to node pointer upon interface up
When an interface is brought back up, the kernel tries to restore the
host routes tied to its permanent addresses.
However, if the host route was removed from the FIB, then we need to
reinsert it. This is done by releasing the current dst and allocating a
new, so as to not reuse a dst with obsolete values.
Since this function is called under RTNL and using the same explanation
from the previous patch, we can test if the route is in the FIB by
checking its node pointer instead of its reference count.
Tested using the following script and Andrey's reproducer mentioned
in commit 8048ced9be
("net: ipv6: regenerate host route if moved to gc
list") and linked below:
$ ip link set dev lo up
$ ip link add dummy1 type dummy
$ ip -6 address add cafe::1/64 dev dummy1
$ ip link set dev lo down # cafe::1/128 is removed
$ ip link set dev dummy1 up
$ ip link set dev lo up
The host route is correctly regenerated.
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Link: http://lkml.kernel.org/r/CAAeHK+zSe82vc5gCRgr_EoUwiALPnWVdWJBPwJZBpbxYz=kGJw@mail.gmail.com
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
9217d8c2fe
commit
fc882fcff1
|
@ -3321,11 +3321,11 @@ static void addrconf_gre_config(struct net_device *dev)
|
|||
static int fixup_permanent_addr(struct inet6_dev *idev,
|
||||
struct inet6_ifaddr *ifp)
|
||||
{
|
||||
/* rt6i_ref == 0 means the host route was removed from the
|
||||
/* !rt6i_node means the host route was removed from the
|
||||
* FIB, for example, if 'lo' device is taken down. In that
|
||||
* case regenerate the host route.
|
||||
*/
|
||||
if (!ifp->rt || !atomic_read(&ifp->rt->rt6i_ref)) {
|
||||
if (!ifp->rt || !ifp->rt->rt6i_node) {
|
||||
struct rt6_info *rt, *prev;
|
||||
|
||||
rt = addrconf_dst_alloc(idev, &ifp->addr, false);
|
||||
|
|
Loading…
Reference in New Issue