Skip to content

Commit d0098e4

Browse files
liuhangbindavem330
authored andcommitted
net/ipv6: remove the old peer route if change it to a new one
When we modify the peer route and changed it to a new one, we should remove the old route first. Before the fix: + ip addr add dev dummy1 2001:db8::1 peer 2001:db8::2 + ip -6 route show dev dummy1 2001:db8::1 proto kernel metric 256 pref medium 2001:db8::2 proto kernel metric 256 pref medium + ip addr change dev dummy1 2001:db8::1 peer 2001:db8::3 + ip -6 route show dev dummy1 2001:db8::1 proto kernel metric 256 pref medium 2001:db8::2 proto kernel metric 256 pref medium After the fix: + ip addr change dev dummy1 2001:db8::1 peer 2001:db8::3 + ip -6 route show dev dummy1 2001:db8::1 proto kernel metric 256 pref medium 2001:db8::3 proto kernel metric 256 pref medium This patch depend on the previous patch "net/ipv6: need update peer route when modify metric" to update new peer route after delete old one. Signed-off-by: Hangbin Liu <[email protected]> Reviewed-by: David Ahern <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6179401 commit d0098e4

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

net/ipv6/addrconf.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,11 +1226,13 @@ check_cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long *expires)
12261226
}
12271227

12281228
static void
1229-
cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires, bool del_rt)
1229+
cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires,
1230+
bool del_rt, bool del_peer)
12301231
{
12311232
struct fib6_info *f6i;
12321233

1233-
f6i = addrconf_get_prefix_route(&ifp->addr, ifp->prefix_len,
1234+
f6i = addrconf_get_prefix_route(del_peer ? &ifp->peer_addr : &ifp->addr,
1235+
ifp->prefix_len,
12341236
ifp->idev->dev, 0, RTF_DEFAULT, true);
12351237
if (f6i) {
12361238
if (del_rt)
@@ -1293,7 +1295,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
12931295

12941296
if (action != CLEANUP_PREFIX_RT_NOP) {
12951297
cleanup_prefix_route(ifp, expires,
1296-
action == CLEANUP_PREFIX_RT_DEL);
1298+
action == CLEANUP_PREFIX_RT_DEL, false);
12971299
}
12981300

12991301
/* clean up prefsrc entries */
@@ -4627,6 +4629,7 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, struct ifa6_config *cfg)
46274629
unsigned long timeout;
46284630
bool was_managetempaddr;
46294631
bool had_prefixroute;
4632+
bool new_peer = false;
46304633

46314634
ASSERT_RTNL();
46324635

@@ -4658,6 +4661,13 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, struct ifa6_config *cfg)
46584661
cfg->preferred_lft = timeout;
46594662
}
46604663

4664+
if (cfg->peer_pfx &&
4665+
memcmp(&ifp->peer_addr, cfg->peer_pfx, sizeof(struct in6_addr))) {
4666+
if (!ipv6_addr_any(&ifp->peer_addr))
4667+
cleanup_prefix_route(ifp, expires, true, true);
4668+
new_peer = true;
4669+
}
4670+
46614671
spin_lock_bh(&ifp->lock);
46624672
was_managetempaddr = ifp->flags & IFA_F_MANAGETEMPADDR;
46634673
had_prefixroute = ifp->flags & IFA_F_PERMANENT &&
@@ -4673,6 +4683,9 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, struct ifa6_config *cfg)
46734683
if (cfg->rt_priority && cfg->rt_priority != ifp->rt_priority)
46744684
ifp->rt_priority = cfg->rt_priority;
46754685

4686+
if (new_peer)
4687+
ifp->peer_addr = *cfg->peer_pfx;
4688+
46764689
spin_unlock_bh(&ifp->lock);
46774690
if (!(ifp->flags&IFA_F_TENTATIVE))
46784691
ipv6_ifa_notify(0, ifp);
@@ -4708,7 +4721,7 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, struct ifa6_config *cfg)
47084721

47094722
if (action != CLEANUP_PREFIX_RT_NOP) {
47104723
cleanup_prefix_route(ifp, rt_expires,
4711-
action == CLEANUP_PREFIX_RT_DEL);
4724+
action == CLEANUP_PREFIX_RT_DEL, false);
47124725
}
47134726
}
47144727

0 commit comments

Comments
 (0)