summaryrefslogtreecommitdiffstats
path: root/main/linux-virt-grsec/0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch
diff options
context:
space:
mode:
Diffstat (limited to 'main/linux-virt-grsec/0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch')
-rw-r--r--main/linux-virt-grsec/0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch201
1 files changed, 0 insertions, 201 deletions
diff --git a/main/linux-virt-grsec/0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch b/main/linux-virt-grsec/0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch
deleted file mode 100644
index 807dba0b3..000000000
--- a/main/linux-virt-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
-