Commit 36c82963 authored by David S. Miller's avatar David S. Miller

Merge branch 'rt6_pmtu'

Martin KaFai Lau says:

====================
ipv6: Stop /128 route from disappearing after pmtu update

The series is separated from another patch series,
'ipv6: Only create RTF_CACHE route after encountering pmtu exception',
which can be found here:
http://thread.gmane.org/gmane.linux.network/359140

This series focus on fixing the /128 route issues.  It is currently targeted
for net-next due to the number of code churn but it is also applicable
to net (should be without conflict).  The original reported problem can be
found here:
http://thread.gmane.org/gmane.linux.network/348138

Patch 01 and 02 are to prepare the fib6 search to expect both the
RTF_CACHE clone and its original route exist at the same fib6_node.

Patch 03 fixes the /128 route disappearing bug.

Patch 04 and 05 stop rt6_info from using the inet_peer's metrics to
avoid the /128 routes (like the /128 clone and its original route)
from stepping on each others' metrics.

The second patch is by 'Steffen Klassert <steffen.klassert@secunet.com>'
which I pulled off from netdev.  The third patch is also mostly by
Steffen with one minor optimization.

Many thanks to Hannes Frederic Sowa <hannes@stressinduktion.org> on
reviewing the patches and giving advice.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 355b590c afc4eef8
......@@ -109,7 +109,6 @@ u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old);
extern const u32 dst_default_metrics[];
#define DST_METRICS_READ_ONLY 0x1UL
#define DST_METRICS_FORCE_OVERWRITE 0x2UL
#define DST_METRICS_FLAGS 0x3UL
#define __DST_METRICS_PTR(Y) \
((u32 *)((Y) & ~DST_METRICS_FLAGS))
......@@ -120,11 +119,6 @@ static inline bool dst_metrics_read_only(const struct dst_entry *dst)
return dst->_metrics & DST_METRICS_READ_ONLY;
}
static inline void dst_metrics_set_force_overwrite(struct dst_entry *dst)
{
dst->_metrics |= DST_METRICS_FORCE_OVERWRITE;
}
void __dst_destroy_metrics_generic(struct dst_entry *dst, unsigned long old);
static inline void dst_destroy_metrics_generic(struct dst_entry *dst)
......
......@@ -121,44 +121,14 @@ struct rt6_info {
struct rt6key rt6i_prefsrc;
struct inet6_dev *rt6i_idev;
unsigned long _rt6i_peer;
u32 rt6i_metric;
u32 rt6i_pmtu;
/* more non-fragment space at head required */
unsigned short rt6i_nfheader_len;
u8 rt6i_protocol;
};
static inline struct inet_peer *rt6_peer_ptr(struct rt6_info *rt)
{
return inetpeer_ptr(rt->_rt6i_peer);
}
static inline bool rt6_has_peer(struct rt6_info *rt)
{
return inetpeer_ptr_is_peer(rt->_rt6i_peer);
}
static inline void __rt6_set_peer(struct rt6_info *rt, struct inet_peer *peer)
{
__inetpeer_ptr_set_peer(&rt->_rt6i_peer, peer);
}
static inline bool rt6_set_peer(struct rt6_info *rt, struct inet_peer *peer)
{
return inetpeer_ptr_set_peer(&rt->_rt6i_peer, peer);
}
static inline void rt6_init_peer(struct rt6_info *rt, struct inet_peer_base *base)
{
inetpeer_init_ptr(&rt->_rt6i_peer, base);
}
static inline void rt6_transfer_peer(struct rt6_info *rt, struct rt6_info *ort)
{
inetpeer_transfer_peer(&rt->_rt6i_peer, &ort->_rt6i_peer);
}
static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
{
return ((struct rt6_info *)dst)->rt6i_idev;
......@@ -189,15 +159,6 @@ static inline void rt6_update_expires(struct rt6_info *rt0, int timeout)
rt0->rt6i_flags |= RTF_EXPIRES;
}
static inline void rt6_set_from(struct rt6_info *rt, struct rt6_info *from)
{
struct dst_entry *new = (struct dst_entry *) from;
rt->rt6i_flags &= ~RTF_EXPIRES;
dst_hold(new);
rt->dst.from = new;
}
static inline void ip6_rt_put(struct rt6_info *rt)
{
/* dst_release() accepts a NULL parameter.
......
......@@ -2121,6 +2121,8 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
fn = fib6_locate(&table->tb6_root, pfx, plen, NULL, 0);
if (!fn)
goto out;
noflags |= RTF_CACHE;
for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) {
if (rt->dst.dev->ifindex != dev->ifindex)
continue;
......
This diff is collapsed.
......@@ -71,13 +71,6 @@ static int xfrm6_get_tos(const struct flowi *fl)
return 0;
}
static void xfrm6_init_dst(struct net *net, struct xfrm_dst *xdst)
{
struct rt6_info *rt = (struct rt6_info *)xdst;
rt6_init_peer(rt, net->ipv6.peers);
}
static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst,
int nfheader_len)
{
......@@ -106,8 +99,6 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
return -ENODEV;
}
rt6_transfer_peer(&xdst->u.rt6, rt);
/* Sheit... I remember I did this right. Apparently,
* it was magically lost, so this code needs audit */
xdst->u.rt6.rt6i_flags = rt->rt6i_flags & (RTF_ANYCAST |
......@@ -255,10 +246,6 @@ static void xfrm6_dst_destroy(struct dst_entry *dst)
if (likely(xdst->u.rt6.rt6i_idev))
in6_dev_put(xdst->u.rt6.rt6i_idev);
dst_destroy_metrics_generic(dst);
if (rt6_has_peer(&xdst->u.rt6)) {
struct inet_peer *peer = rt6_peer_ptr(&xdst->u.rt6);
inet_putpeer(peer);
}
xfrm_dst_destroy(xdst);
}
......@@ -308,7 +295,6 @@ static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
.get_saddr = xfrm6_get_saddr,
.decode_session = _decode_session6,
.get_tos = xfrm6_get_tos,
.init_dst = xfrm6_init_dst,
.init_path = xfrm6_init_path,
.fill_dst = xfrm6_fill_dst,
.blackhole_route = ip6_blackhole_route,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment