Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
aports
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
815
Issues
815
List
Boards
Labels
Milestones
Merge Requests
58
Merge Requests
58
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
alpine
aports
Commits
87760fec
Commit
87760fec
authored
May 27, 2013
by
Natanael Copa
2
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
main/linux-grsec: upgrade to 3.9.4 and use reworked arp and frag patches
fixes
#1782
(cherry picked from commit
a43c9a40
)
parent
4d918a90
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
1257 additions
and
774 deletions
+1257
-774
main/linux-grsec/0001-net-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch
...et-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch
+68
-0
main/linux-grsec/0002-arp-flush-arp-cache-on-IFF_NOARP-change.patch
...-grsec/0002-arp-flush-arp-cache-on-IFF_NOARP-change.patch
+35
-0
main/linux-grsec/0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch
...pv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch
+201
-0
main/linux-grsec/0004-ipv4-rate-limit-updating-of-next-hop-exceptions-with.patch
...pv4-rate-limit-updating-of-next-hop-exceptions-with.patch
+37
-0
main/linux-grsec/0005-ipv4-use-separate-genid-for-next-hop-exceptions.patch
...005-ipv4-use-separate-genid-for-next-hop-exceptions.patch
+116
-0
main/linux-grsec/0006-ipv4-use-next-hop-exceptions-also-for-input-routes.patch
...-ipv4-use-next-hop-exceptions-also-for-input-routes.patch
+87
-52
main/linux-grsec/APKBUILD
main/linux-grsec/APKBUILD
+34
-17
main/linux-grsec/grsecurity-2.9.1-3.9.4-201305251009.patch
main/linux-grsec/grsecurity-2.9.1-3.9.4-201305251009.patch
+679
-616
main/linux-grsec/v2-net-next-arp-flush-arp-cache-on-IFF_NOARP-change.patch
...v2-net-next-arp-flush-arp-cache-on-IFF_NOARP-change.patch
+0
-89
No files found.
main/linux-grsec/0001-net-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch
0 → 100644
View file @
87760fec
From 1225b1090991bdcab819bdab96be329397563f1c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
Date: Thu, 23 May 2013 11:30:23 +0300
Subject: [PATCH 1/6] net: inform NETDEV_CHANGE callbacks which flags were
changed
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In certain cases (like the follow up commit to arp.c) will need to
check which flags actually changed to avoid excessive work.
Ben Hutchings nicely worded why to put these transient flags to
struct net_device for the time being:
> It's inelegant to put transient data associated with an event in a
> persistent data structure. On the other hand, having every user cache
> the old state is pretty awful as well.
>
> Really, netdev notifiers should be changed to accept a structure that
> encapsulates the changes rather than just a pointer to the net_device.
> But making such a change would be an enormous pain and error-prone
> because notifier functions aren't type-safe.
>
> As an interim solution, I think either the general flags_changed or
> old_flags would be preferable to defining extra transient flags.
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
Acked-by: Ben Hutchings <bhutchings@solarflare.com>
---
include/linux/netdevice.h | 4 +++-
net/core/dev.c | 5 ++++-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 6151e90..8b3c649 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1112,7 +1112,9 @@
struct net_device {
/* Hardware header description */
const struct header_ops *header_ops;
- unsigned int flags; /* interface flags (a la BSD) */
+ unsigned int flags; /* interface flags (a la BSD) */
+ unsigned int flags_changed; /* flags that are being changed
+ * valid during NETDEV_CHANGE notifier */
unsigned int priv_flags; /* Like 'flags' but invisible to userspace.
* See if.h for definitions. */
unsigned short gflags;
diff --git a/net/core/dev.c b/net/core/dev.c
index 9a278e9..2f3feae 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4683,8 +4683,11 @@
void __dev_notify_flags(struct net_device *dev, unsigned int old_flags)
}
if (dev->flags & IFF_UP &&
- (changes & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI | IFF_VOLATILE)))
+ (changes & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI | IFF_VOLATILE))) {
+ dev->flags_changed = changes;
call_netdevice_notifiers(NETDEV_CHANGE, dev);
+ dev->flags_changed = 0;
+ }
}
/**
--
1.8.2.3
main/linux-grsec/0002-arp-flush-arp-cache-on-IFF_NOARP-change.patch
0 → 100644
View file @
87760fec
From 36fbd62c47d800705d9989c69994359711514165 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
Date: Thu, 23 May 2013 11:43:55 +0300
Subject: [PATCH 2/6] arp: flush arp cache on IFF_NOARP change
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
IFF_NOARP affects what kind of neighbor entries are created
(nud
NOARP or nud INCOMPLETE). If the flag changes, flush the arp
cache to refresh all entries.
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
---
net/ipv4/arp.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index fea4929..2a06ecf 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1226,6 +1226,10 @@
static int arp_netdev_event(struct notifier_block *this, unsigned long event,
neigh_changeaddr(&arp_tbl, dev);
rt_cache_flush(dev_net(dev));
break;
+ case NETDEV_CHANGE:
+ if (dev->flags_changed & IFF_NOARP)
+ neigh_changeaddr(&arp_tbl, dev);
+ break;
default:
break;
}
--
1.8.2.3
main/linux-grsec/0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch
0 → 100644
View file @
87760fec
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
main/linux-grsec/0004-ipv4-rate-limit-updating-of-next-hop-exceptions-with.patch
0 → 100644
View file @
87760fec
From 90f586dba1465a73295d752abe2451e924ba1888 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
Date: Mon, 27 May 2013 08:33:10 +0300
Subject: [PATCH 4/6] ipv4: rate limit updating of next hop exceptions with
same pmtu
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The tunnel devices call update_pmtu for each packet sent, this causes
contention on the fnhe_lock. Ignore the pmtu update if pmtu is not
actually changed, and there is still plenty of time before the entry
expires.
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
---
net/ipv4/route.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 8dedfeb..85b9c07 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -947,6 +947,10 @@
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 == mtu &&
+ time_before(jiffies, dst->expires - ip_rt_mtu_expires / 2))
+ return;
+
rcu_read_lock();
if (fib_lookup(dev_net(dst->dev), fl4, &res) == 0) {
struct fib_nh *nh = &FIB_RES_NH(res);
--
1.8.2.3
main/linux-grsec/0005-ipv4-use-separate-genid-for-next-hop-exceptions.patch
0 → 100644
View file @
87760fec
From 4a7dbb238480fac2b1ad02a74240efcf225c1f45 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
Date: Mon, 27 May 2013 10:55:52 +0300
Subject: [PATCH 5/6] ipv4: use separate genid for next hop exceptions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
commit 13d82bf5 (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 quote 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>
---
include/net/ip_fib.h | 1 +
include/net/net_namespace.h | 11 +++++++++++
net/ipv4/route.c | 12 ++++++++++--
3 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index e49db91..44424e9 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -51,6 +51,7 @@
struct rtable;
struct fib_nh_exception {
struct fib_nh_exception __rcu *fnhe_next;
+ int fnhe_genid;
__be32 fnhe_daddr;
u32 fnhe_pmtu;
__be32 fnhe_gw;
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index de644bc..b5a5baf 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -116,6 +116,7 @@
struct net {
struct netns_ipvs *ipvs;
struct sock *diag_nlsk;
atomic_unchecked_t rt_genid;
+ atomic_unchecked_t fnhe_genid;
};
/*
@@ -338,4 +339,14 @@
static inline void rt_genid_bump(struct net *net)
atomic_inc_unchecked(&net->rt_genid);
}
+static inline int fnhe_genid(struct net *net)
+{
+ return atomic_read_unchecked(&net->fnhe_genid);
+}
+
+static inline void fnhe_genid_bump(struct net *net)
+{
+ atomic_inc_unchecked(&net->fnhe_genid);
+}
+
#endif /* __NET_NET_NAMESPACE_H */
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 85b9c07..f44a4bb 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -658,6 +658,7 @@
static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw,
fnhe->fnhe_next = hash->chain;
rcu_assign_pointer(hash->chain, fnhe);
}
+ fnhe->fnhe_genid = fnhe_genid(dev_net(nh->nh_dev));
fnhe->fnhe_daddr = daddr;
fnhe->fnhe_gw = gw;
fnhe->fnhe_pmtu = pmtu;
@@ -1236,8 +1237,11 @@
static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
spin_lock_bh(&fnhe_lock);
if (daddr == fnhe->fnhe_daddr) {
+ int genid = fnhe_genid(dev_net(rt->dst.dev));
struct rtable *orig = rcu_dereference(fnhe->fnhe_rth);
- if (orig && rt_is_expired(orig)) {
+
+ if (fnhe->fnhe_genid != genid) {
+ fnhe->fnhe_genid = genid;
fnhe->fnhe_gw = 0;
fnhe->fnhe_pmtu = 0;
fnhe->fnhe_expires = 0;
@@ -2443,8 +2447,11 @@
static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
void __user *buffer,
size_t *lenp, loff_t *ppos)
{
+ struct net *net = (struct net *)__ctl->extra1;
+
if (write) {
- rt_cache_flush((struct net *)__ctl->extra1);
+ rt_cache_flush(net);
+ fnhe_genid_bump(net);
return 0;
}
@@ -2619,6 +2626,7 @@
static __net_initdata struct pernet_operations sysctl_route_ops = {
static __net_init int rt_genid_init(struct net *net)
{
atomic_set_unchecked(&net->rt_genid, 0);
+ atomic_set_unchecked(&net->fnhe_genid, 0);
get_random_bytes(&net->ipv4.dev_addr_genid,
sizeof(net->ipv4.dev_addr_genid));
return 0;
--
1.8.2.3
main/linux-grsec/
RFC-net-ipv4-U
se-next-hop-exceptions-also-for-input-routes.patch
→
main/linux-grsec/
0006-ipv4-u
se-next-hop-exceptions-also-for-input-routes.patch
View file @
87760fec
From patchwork Thu May 23 13:15:46 2013
Content-Type: text/plain; charset="utf-8"
From 87151ab93a08bcc4abe23aa2e87fbc2b956ae2cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
Date: Mon, 27 May 2013 08:40:22 +0300
Subject: [PATCH 6/6] ipv4: use next hop exceptions also for input routes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Subject: [RFC] net/ipv4: Use next hop exceptions also for input routes
Date: Thu, 23 May 2013 03:15:46 -0000
From: =?utf-8?q?Timo_Ter=C3=A4s?= <timo.teras@iki.fi>
X-Patchwork-Id: 245949
Message-Id: <1369314946-12692-1-git-send-email-timo.teras@iki.fi>
To: netdev@vger.kernel.org
Cc: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
Commit d2d68ba9 (ipv4: Cache input routes in fib_info nexthops)
assmued that "locally destined, and routed packets, never trigger
...
...
@@ -22,39 +18,23 @@ next hop exceptions are not consulted for pmtu, IP fragmentation will
not be done properly for these routes.
It also seems that we really need to have the PMTU information always
for netfilter TCPMSS
'
clamp-to-pmtu feature to work properly.
for netfilter TCPMSS clamp-to-pmtu feature to work properly.
So for the time being, cache separate copies of input routes for
each next hop exception.
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
---
I had ideas to make optimizations where pmtu information would not
be needed. This includes:
- Target devices with IFF_XMIT_DST_RELEASE set (practically all devices
except tunnels). If skb_dst() is early freed the target device cannot
generate PMTU events
- Add flag for input route generation if pmtu info is needed for
fragmentation. Basically a flag saying if DF bit was set in ip_hdr.
However, TCPMSS clamp-to-pmtu prevents both optimizations.
I'm not yet all familiar with the recent changes in routing caching,
so there might be caveats that I missed. Basic testing shows this fixes
the fragmentation issues I'm seeing, and I have not yet found any ill
side effects either.
include/net/ip_fib.h | 3 ++-
net/ipv4/fib_semantics.c | 3 ++-
net/ipv4/route.c |
41 +++++++++++++++++++++++++++++++
----------
3 files changed,
35 insertions(+), 12
deletions(-)
net/ipv4/route.c |
65 +++++++++++++++++++++++++++++++++++++-
----------
3 files changed,
54 insertions(+), 17
deletions(-)
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index
e49db91..20529a6
100644
index
44424e9..aac8553
100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -5
5,7 +55
,8 @@
struct fib_nh_exception {
@@ -5
6,7 +56
,8 @@
struct fib_nh_exception {
u32 fnhe_pmtu;
__be32 fnhe_gw;
unsigned long fnhe_expires;
...
...
@@ -79,45 +59,97 @@ index 8f6cb7a..d5dbca5 100644
kfree(fnhe);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index
550781a..073df96
100644
index
f44a4bb..a7a36f7
100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -576,9 +576,14 @@
static struct fib_nh_exception *fnhe_oldest(struct fnhe_hash_bucket *hash)
@@ -565,10 +565,25 @@
static inline void rt_free(struct rtable *rt)
static DEFINE_SPINLOCK(fnhe_lock);
+static void fnhe_flush_routes(struct fib_nh_exception *fnhe)
+{
+ struct rtable *rt;
+
+ rt = rcu_dereference(fnhe->fnhe_rth_input);
+ if (rt) {
+ RCU_INIT_POINTER(fnhe->fnhe_rth_input, NULL);
+ rt_free(rt);
+ }
+ rt = rcu_dereference(fnhe->fnhe_rth_output);
+ if (rt) {
+ RCU_INIT_POINTER(fnhe->fnhe_rth_output, NULL);
+ rt_free(rt);
+ }
+}
+
static struct fib_nh_exception *fnhe_oldest(struct fnhe_hash_bucket *hash)
{
struct fib_nh_exception *fnhe, *oldest;
- struct rtable *orig;
oldest = rcu_dereference(hash->chain);
for (fnhe = rcu_dereference(oldest->fnhe_next); fnhe;
@@ -576,11 +591,7 @@
static struct fib_nh_exception *fnhe_oldest(struct fnhe_hash_bucket *hash)
if (time_before(fnhe->fnhe_stamp, oldest->fnhe_stamp))
oldest = fnhe;
}
- orig = rcu_dereference(oldest->fnhe_rth);
+ orig = rcu_dereference(oldest->fnhe_rth_input);
if (orig) {
- if (orig) {
- RCU_INIT_POINTER(oldest->fnhe_rth, NULL);
+ RCU_INIT_POINTER(oldest->fnhe_rth_input, NULL);
+ rt_free(orig);
+ }
+ orig = rcu_dereference(oldest->fnhe_rth_output);
+ if (orig) {
+ RCU_INIT_POINTER(oldest->fnhe_rth_output, NULL);
rt_free(orig);
}
- rt_free(orig);
- }
+ fnhe_flush_routes(oldest);
return oldest;
@@ -1209,7 +1214,15 @@
static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
}
@@ -644,7 +655,10 @@
static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw,
fnhe->fnhe_expires = max(1UL, expires);
}
/* Update all cached dsts too */
- rt = rcu_dereference(fnhe->fnhe_rth);
+ rt = rcu_dereference(fnhe->fnhe_rth_input);
+ if (rt)
+ fill_route_from_fnhe(rt, fnhe);
+ rt = rcu_dereference(fnhe->fnhe_rth_output);
if (rt)
fill_route_from_fnhe(rt, fnhe);
} else {
@@ -668,6 +682,10 @@
static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw,
* stale, so anyone caching it rechecks if this exception
* applies to them.
*/
+ rt = rcu_dereference(nh->nh_rth_input);
+ if (rt)
+ rt->dst.obsolete = DST_OBSOLETE_KILL;
+
for_each_possible_cpu(i) {
struct rtable __rcu **prt;
prt = per_cpu_ptr(nh->nh_pcpu_rth_output, i);
@@ -1237,25 +1255,36 @@
static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
spin_lock_bh(&fnhe_lock);
if (daddr == fnhe->fnhe_daddr) {
- struct rtable *orig = rcu_dereference(fnhe->fnhe_rth);
+ struct rtable __rcu **porig;
+ struct rtable *orig;
int genid = fnhe_genid(dev_net(rt->dst.dev));
- struct rtable *orig = rcu_dereference(fnhe->fnhe_rth);
+
+ if (rt_is_input_route(rt))
+ porig = &fnhe->fnhe_rth_input;
+ else
+ porig = &fnhe->fnhe_rth_output;
+
+ orig = rcu_dereference(*porig);
if (orig && rt_is_expired(orig)) {
if (fnhe->fnhe_genid != genid) {
fnhe->fnhe_genid = genid;
fnhe->fnhe_gw = 0;
fnhe->fnhe_pmtu = 0;
@@ -1231,12 +1244,14 @@
static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
} else if (!rt->rt_gateway)
fnhe->fnhe_expires = 0;
+ fnhe_flush_routes(fnhe);
+ orig = NULL;
}
fill_route_from_fnhe(rt, fnhe);
if (!rt->rt_gateway)
rt->rt_gateway = daddr;
- rcu_assign_pointer(fnhe->fnhe_rth, rt);
...
...
@@ -135,7 +167,7 @@ index 550781a..073df96 100644
}
spin_unlock_bh(&fnhe_lock);
@@ -14
68,6 +1483
,7 @@
static int __mkroute_input(struct sk_buff *skb,
@@ -14
87,6 +1516
,7 @@
static int __mkroute_input(struct sk_buff *skb,
struct in_device *in_dev,
__be32 daddr, __be32 saddr, u32 tos)
{
...
...
@@ -143,7 +175,7 @@ index 550781a..073df96 100644
struct rtable *rth;
int err;
struct in_device *out_dev;
@@ -15
14,8 +1530
,13 @@
static int __mkroute_input(struct sk_buff *skb,
@@ -15
33,8 +1563
,13 @@
static int __mkroute_input(struct sk_buff *skb,
}
}
...
...
@@ -158,7 +190,7 @@ index 550781a..073df96 100644
if (rt_cache_valid(rth)) {
skb_dst_set_noref(skb, &rth->dst);
goto out;
@@ -15
43,7 +1564
,7 @@
static int __mkroute_input(struct sk_buff *skb,
@@ -15
62,7 +1597
,7 @@
static int __mkroute_input(struct sk_buff *skb,
rth->dst.input = ip_forward;
rth->dst.output = ip_output;
...
...
@@ -167,7 +199,7 @@ index 550781a..073df96 100644
skb_dst_set(skb, &rth->dst);
out:
err = 0;
@@ -18
58,7 +1879
,7 @@
static struct rtable *__mkroute_output(const struct fib_result *res,
@@ -18
77,7 +1912
,7 @@
static struct rtable *__mkroute_output(const struct fib_result *res,
fnhe = find_exception(nh, fl4->daddr);
if (fnhe)
...
...
@@ -176,3 +208,6 @@ index 550781a..073df96 100644
else {
if (unlikely(fl4->flowi4_flags &
FLOWI_FLAG_KNOWN_NH &&
--
1.8.2.3
main/linux-grsec/APKBUILD
View file @
87760fec
...
...
@@ -2,12 +2,12 @@
_flavor
=
grsec
pkgname
=
linux-
${
_flavor
}
pkgver
=
3.9.
3
pkgver
=
3.9.
4
case
$pkgver
in
*
.
*
.
*
)
_kernver
=
${
pkgver
%.*
}
;;
*
.
*
)
_kernver
=
${
pkgver
}
;;
esac
pkgrel
=
2
pkgrel
=
0
pkgdesc
=
"Linux kernel with grsecurity"
url
=
http://grsecurity.net
depends
=
"mkinitfs linux-firmware"
...
...
@@ -17,12 +17,17 @@ _config=${config:-kernelconfig.${CARCH}}
install
=
source
=
"http://ftp.kernel.org/pub/linux/kernel/v3.x/linux-
$_kernver
.tar.xz
http://ftp.kernel.org/pub/linux/kernel/v3.x/patch-
$pkgver
.xz
grsecurity-2.9.1-3.9.
3-201305201732
.patch
grsecurity-2.9.1-3.9.
4-201305251009
.patch
v2-net-next-arp-flush-arp-cache-on-IFF_NOARP-change.patch
leds-leds-gpio-reserve-gpio-before-using-it.patch
ipsec-xfrm-properly-handle-invalid-states-as-an-error.patch
RFC-net-ipv4-Use-next-hop-exceptions-also-for-input-routes.patch
0001-net-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch
0002-arp-flush-arp-cache-on-IFF_NOARP-change.patch
0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch
0004-ipv4-rate-limit-updating-of-next-hop-exceptions-with.patch
0005-ipv4-use-separate-genid-for-next-hop-exceptions.patch
0006-ipv4-use-next-hop-exceptions-also-for-input-routes.patch
kernelconfig.x86
kernelconfig.x86_64
...
...
@@ -147,29 +152,41 @@ dev() {
}
md5sums
=
"4348c9b6b2eb3144d601e87c19d5d909 linux-3.9.tar.xz
71b31e29e0cb437a27017c781293b6f4 patch-3.9.3.xz