diff options
Diffstat (limited to 'main/linux-grsec/0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch')
-rw-r--r-- | main/linux-grsec/0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch | 201 |
1 files changed, 0 insertions, 201 deletions
diff --git a/main/linux-grsec/0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch b/main/linux-grsec/0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch deleted file mode 100644 index 807dba0b3..000000000 --- a/main/linux-grsec/0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch +++ /dev/null @@ -1,201 +0,0 @@ -From 777eadba40c19bcfdb48807e7b0547ef30555671 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi> -Date: Sat, 25 May 2013 15:42:30 +0300 -Subject: [PATCH 3/6] ipv4: properly refresh rtable entries on pmtu/redirect - events -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This reverts commit 05ab86c5 (xfrm4: Invalidate all ipv4 routes on -IPsec pmtu events). Flushing all cached entries is not needed. - -Instead, invalidate only the related next hop dsts to recheck for -the added next hop exception where needed. This also fixes a subtle -race due to bumping generation id's before updating the pmtu. - -Cc: Steffen Klassert <steffen.klassert@secunet.com> -Signed-off-by: Timo Teräs <timo.teras@iki.fi> ---- - net/ipv4/ah4.c | 7 ++----- - net/ipv4/esp4.c | 7 ++----- - net/ipv4/ipcomp.c | 7 ++----- - net/ipv4/route.c | 63 ++++++++++++++++++++++++++++++++----------------------- - 4 files changed, 43 insertions(+), 41 deletions(-) - -diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c -index 2e7f194..7179026 100644 ---- a/net/ipv4/ah4.c -+++ b/net/ipv4/ah4.c -@@ -419,12 +419,9 @@ static void ah4_err(struct sk_buff *skb, u32 info) - if (!x) - return; - -- if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) { -- atomic_inc_unchecked(&flow_cache_genid); -- rt_genid_bump(net); -- -+ if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) - ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_AH, 0); -- } else -+ else - ipv4_redirect(skb, net, 0, 0, IPPROTO_AH, 0); - xfrm_state_put(x); - } -diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c -index 4cfe34d..ab3d814 100644 ---- a/net/ipv4/esp4.c -+++ b/net/ipv4/esp4.c -@@ -502,12 +502,9 @@ static void esp4_err(struct sk_buff *skb, u32 info) - if (!x) - return; - -- if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) { -- atomic_inc_unchecked(&flow_cache_genid); -- rt_genid_bump(net); -- -+ if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) - ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_ESP, 0); -- } else -+ else - ipv4_redirect(skb, net, 0, 0, IPPROTO_ESP, 0); - xfrm_state_put(x); - } -diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c -index f01d1b1..48b3f0b 100644 ---- a/net/ipv4/ipcomp.c -+++ b/net/ipv4/ipcomp.c -@@ -47,12 +47,9 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info) - if (!x) - return; - -- if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) { -- atomic_inc_unchecked(&flow_cache_genid); -- rt_genid_bump(net); -- -+ if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) - ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_COMP, 0); -- } else -+ else - ipv4_redirect(skb, net, 0, 0, IPPROTO_COMP, 0); - xfrm_state_put(x); - } -diff --git a/net/ipv4/route.c b/net/ipv4/route.c -index 6e28514..8dedfeb 100644 ---- a/net/ipv4/route.c -+++ b/net/ipv4/route.c -@@ -594,11 +594,25 @@ static inline u32 fnhe_hashfun(__be32 daddr) - return hval & (FNHE_HASH_SIZE - 1); - } - -+static void fill_route_from_fnhe(struct rtable *rt, struct fib_nh_exception *fnhe) -+{ -+ rt->rt_pmtu = fnhe->fnhe_pmtu; -+ rt->dst.expires = fnhe->fnhe_expires; -+ -+ if (fnhe->fnhe_gw) { -+ rt->rt_flags |= RTCF_REDIRECTED; -+ rt->rt_gateway = fnhe->fnhe_gw; -+ rt->rt_uses_gateway = 1; -+ } -+} -+ - static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw, - u32 pmtu, unsigned long expires) - { - struct fnhe_hash_bucket *hash; - struct fib_nh_exception *fnhe; -+ struct rtable *rt; -+ unsigned int i; - int depth; - u32 hval = fnhe_hashfun(daddr); - -@@ -627,8 +641,12 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw, - fnhe->fnhe_gw = gw; - if (pmtu) { - fnhe->fnhe_pmtu = pmtu; -- fnhe->fnhe_expires = expires; -+ fnhe->fnhe_expires = max(1UL, expires); - } -+ /* Update all cached dsts too */ -+ rt = rcu_dereference(fnhe->fnhe_rth); -+ if (rt) -+ fill_route_from_fnhe(rt, fnhe); - } else { - if (depth > FNHE_RECLAIM_DEPTH) - fnhe = fnhe_oldest(hash); -@@ -644,6 +662,18 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw, - fnhe->fnhe_gw = gw; - fnhe->fnhe_pmtu = pmtu; - fnhe->fnhe_expires = expires; -+ -+ /* Exception created; mark the cached routes for the nexthop -+ * stale, so anyone caching it rechecks if this exception -+ * applies to them. -+ */ -+ for_each_possible_cpu(i) { -+ struct rtable __rcu **prt; -+ prt = per_cpu_ptr(nh->nh_pcpu_rth_output, i); -+ rt = rcu_dereference(*prt); -+ if (rt) -+ rt->dst.obsolete = DST_OBSOLETE_KILL; -+ } - } - - fnhe->fnhe_stamp = jiffies; -@@ -917,13 +947,6 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) - if (mtu < ip_rt_min_pmtu) - mtu = ip_rt_min_pmtu; - -- if (!rt->rt_pmtu) { -- dst->obsolete = DST_OBSOLETE_KILL; -- } else { -- rt->rt_pmtu = mtu; -- dst->expires = max(1UL, jiffies + ip_rt_mtu_expires); -- } -- - rcu_read_lock(); - if (fib_lookup(dev_net(dst->dev), fl4, &res) == 0) { - struct fib_nh *nh = &FIB_RES_NH(res); -@@ -1063,11 +1086,11 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) - * DST_OBSOLETE_FORCE_CHK which forces validation calls down - * into this function always. - * -- * When a PMTU/redirect information update invalidates a -- * route, this is indicated by setting obsolete to -- * DST_OBSOLETE_KILL. -+ * When a PMTU/redirect information update invalidates a route, -+ * this is indicated by setting obsolete to DST_OBSOLETE_KILL or -+ * DST_OBSOLETE_DEAD by dst_free(). - */ -- if (dst->obsolete == DST_OBSOLETE_KILL || rt_is_expired(rt)) -+ if (dst->obsolete != DST_OBSOLETE_FORCE_CHK || rt_is_expired(rt)) - return NULL; - return dst; - } -@@ -1215,20 +1238,8 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe, - fnhe->fnhe_pmtu = 0; - fnhe->fnhe_expires = 0; - } -- if (fnhe->fnhe_pmtu) { -- unsigned long expires = fnhe->fnhe_expires; -- unsigned long diff = expires - jiffies; -- -- if (time_before(jiffies, expires)) { -- rt->rt_pmtu = fnhe->fnhe_pmtu; -- dst_set_expires(&rt->dst, diff); -- } -- } -- if (fnhe->fnhe_gw) { -- rt->rt_flags |= RTCF_REDIRECTED; -- rt->rt_gateway = fnhe->fnhe_gw; -- rt->rt_uses_gateway = 1; -- } else if (!rt->rt_gateway) -+ fill_route_from_fnhe(rt, fnhe); -+ if (!rt->rt_gateway) - rt->rt_gateway = daddr; - - rcu_assign_pointer(fnhe->fnhe_rth, rt); --- -1.8.2.3 - |