Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de68dca1 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

inet: add a redirect generation id in inetpeer



Now inetpeer is the place where we cache redirect information for ipv4
destinations, we must be able to invalidate informations when a route is
added/removed on host.

As inetpeer is not yet namespace aware, this patch adds a shared
redirect_genid, and a per inetpeer redirect_genid. This might be changed
later if inetpeer becomes ns aware.

Cache information for one inerpeer is valid as long as its
redirect_genid has the same value than global redirect_genid.

Reported-by: default avatarArkadiusz Miśkiewicz <a.miskiewicz@gmail.com>
Tested-by: default avatarArkadiusz Miśkiewicz <a.miskiewicz@gmail.com>
Signed-off-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0884d7aa
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ struct inet_peer {

	u32			metrics[RTAX_MAX];
	u32			rate_tokens;	/* rate limiting for ICMP */
	int			redirect_genid;
	unsigned long		rate_last;
	unsigned long		pmtu_expires;
	u32			pmtu_orig;
+9 −1
Original line number Diff line number Diff line
@@ -131,6 +131,7 @@ static int ip_rt_mtu_expires __read_mostly = 10 * 60 * HZ;
static int ip_rt_min_pmtu __read_mostly		= 512 + 20 + 20;
static int ip_rt_min_advmss __read_mostly	= 256;
static int rt_chain_length_max __read_mostly	= 20;
static int redirect_genid;

/*
 *	Interface to generic destination cache.
@@ -837,6 +838,7 @@ static void rt_cache_invalidate(struct net *net)

	get_random_bytes(&shuffle, sizeof(shuffle));
	atomic_add(shuffle + 1U, &net->ipv4.rt_genid);
	redirect_genid++;
}

/*
@@ -1391,8 +1393,10 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,

				peer = rt->peer;
				if (peer) {
					if (peer->redirect_learned.a4 != new_gw) {
					if (peer->redirect_learned.a4 != new_gw ||
					    peer->redirect_genid != redirect_genid) {
						peer->redirect_learned.a4 = new_gw;
						peer->redirect_genid = redirect_genid;
						atomic_inc(&__rt_peer_genid);
					}
					check_peer_redir(&rt->dst, peer);
@@ -1701,6 +1705,8 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
		if (peer) {
			check_peer_pmtu(dst, peer);

			if (peer->redirect_genid != redirect_genid)
				peer->redirect_learned.a4 = 0;
			if (peer->redirect_learned.a4 &&
			    peer->redirect_learned.a4 != rt->rt_gateway) {
				if (check_peer_redir(dst, peer))
@@ -1857,6 +1863,8 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4,
		dst_init_metrics(&rt->dst, peer->metrics, false);

		check_peer_pmtu(&rt->dst, peer);
		if (peer->redirect_genid != redirect_genid)
			peer->redirect_learned.a4 = 0;
		if (peer->redirect_learned.a4 &&
		    peer->redirect_learned.a4 != rt->rt_gateway) {
			rt->rt_gateway = peer->redirect_learned.a4;