Skip to content

Commit 5aad1de

Browse files
fableddavem330
authored andcommitted
ipv4: use separate genid for next hop exceptions
commit 13d82bf (ipv4: Fix flushing of cached routing informations) added the support to flush learned pmtu information. However, using rt_genid is quite heavy as it is bumped on route add/change and multicast events amongst other places. These can happen quite often, especially if using dynamic routing protocols. While this is ok with routes (as they are just recreated locally), the pmtu information is learned from remote systems and the icmp notification can come with long delays. It is worthy to have separate genid to avoid excessive pmtu resets. Cc: Steffen Klassert <steffen.klassert@secunet.com> Signed-off-by: Timo Teräs <timo.teras@iki.fi> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent f016229 commit 5aad1de

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

include/net/ip_fib.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ struct rtable;
5151

5252
struct fib_nh_exception {
5353
struct fib_nh_exception __rcu *fnhe_next;
54+
int fnhe_genid;
5455
__be32 fnhe_daddr;
5556
u32 fnhe_pmtu;
5657
__be32 fnhe_gw;

include/net/net_namespace.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ struct net {
118118
struct netns_ipvs *ipvs;
119119
struct sock *diag_nlsk;
120120
atomic_t rt_genid;
121+
atomic_t fnhe_genid;
121122
};
122123

123124
/*
@@ -340,4 +341,14 @@ static inline void rt_genid_bump(struct net *net)
340341
atomic_inc(&net->rt_genid);
341342
}
342343

344+
static inline int fnhe_genid(struct net *net)
345+
{
346+
return atomic_read(&net->fnhe_genid);
347+
}
348+
349+
static inline void fnhe_genid_bump(struct net *net)
350+
{
351+
atomic_inc(&net->fnhe_genid);
352+
}
353+
343354
#endif /* __NET_NET_NAMESPACE_H */

net/ipv4/route.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,7 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw,
658658
fnhe->fnhe_next = hash->chain;
659659
rcu_assign_pointer(hash->chain, fnhe);
660660
}
661+
fnhe->fnhe_genid = fnhe_genid(dev_net(nh->nh_dev));
661662
fnhe->fnhe_daddr = daddr;
662663
fnhe->fnhe_gw = gw;
663664
fnhe->fnhe_pmtu = pmtu;
@@ -1236,8 +1237,11 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
12361237
spin_lock_bh(&fnhe_lock);
12371238

12381239
if (daddr == fnhe->fnhe_daddr) {
1240+
int genid = fnhe_genid(dev_net(rt->dst.dev));
12391241
struct rtable *orig = rcu_dereference(fnhe->fnhe_rth);
1240-
if (orig && rt_is_expired(orig)) {
1242+
1243+
if (fnhe->fnhe_genid != genid) {
1244+
fnhe->fnhe_genid = genid;
12411245
fnhe->fnhe_gw = 0;
12421246
fnhe->fnhe_pmtu = 0;
12431247
fnhe->fnhe_expires = 0;
@@ -2443,8 +2447,11 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
24432447
void __user *buffer,
24442448
size_t *lenp, loff_t *ppos)
24452449
{
2450+
struct net *net = (struct net *)__ctl->extra1;
2451+
24462452
if (write) {
2447-
rt_cache_flush((struct net *)__ctl->extra1);
2453+
rt_cache_flush(net);
2454+
fnhe_genid_bump(net);
24482455
return 0;
24492456
}
24502457

@@ -2619,6 +2626,7 @@ static __net_initdata struct pernet_operations sysctl_route_ops = {
26192626
static __net_init int rt_genid_init(struct net *net)
26202627
{
26212628
atomic_set(&net->rt_genid, 0);
2629+
atomic_set(&net->fnhe_genid, 0);
26222630
get_random_bytes(&net->ipv4.dev_addr_genid,
26232631
sizeof(net->ipv4.dev_addr_genid));
26242632
return 0;

0 commit comments

Comments
 (0)