Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 275746
b: refs/heads/master
c: 9cc20b2
h: refs/heads/master
v: v3
  • Loading branch information
Eric Dumazet authored and David S. Miller committed Nov 18, 2011
1 parent 4e2a910 commit f604a72
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 52 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fb120c0a2775b0d2d095a99ea8432bfb5d444ab2
refs/heads/master: 9cc20b268a5a14f5e57b8ad405a83513ab0d78dc
110 changes: 59 additions & 51 deletions trunk/net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -1304,16 +1304,42 @@ static void rt_del(unsigned hash, struct rtable *rt)
spin_unlock_bh(rt_hash_lock_addr(hash));
}

static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer)
{
struct rtable *rt = (struct rtable *) dst;
__be32 orig_gw = rt->rt_gateway;
struct neighbour *n, *old_n;

dst_confirm(&rt->dst);

rt->rt_gateway = peer->redirect_learned.a4;

n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway);
if (IS_ERR(n))
return PTR_ERR(n);
old_n = xchg(&rt->dst._neighbour, n);
if (old_n)
neigh_release(old_n);
if (!n || !(n->nud_state & NUD_VALID)) {
if (n)
neigh_event_send(n, NULL);
rt->rt_gateway = orig_gw;
return -EAGAIN;
} else {
rt->rt_flags |= RTCF_REDIRECTED;
call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
}
return 0;
}

/* called in rcu_read_lock() section */
void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
__be32 saddr, struct net_device *dev)
{
int s, i;
struct in_device *in_dev = __in_dev_get_rcu(dev);
struct rtable *rt;
__be32 skeys[2] = { saddr, 0 };
int ikeys[2] = { dev->ifindex, 0 };
struct flowi4 fl4;
struct inet_peer *peer;
struct net *net;

Expand All @@ -1336,33 +1362,42 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
goto reject_redirect;
}

memset(&fl4, 0, sizeof(fl4));
fl4.daddr = daddr;
for (s = 0; s < 2; s++) {
for (i = 0; i < 2; i++) {
fl4.flowi4_oif = ikeys[i];
fl4.saddr = skeys[s];
rt = __ip_route_output_key(net, &fl4);
if (IS_ERR(rt))
continue;

if (rt->dst.error || rt->dst.dev != dev ||
rt->rt_gateway != old_gw) {
ip_rt_put(rt);
continue;
}
unsigned int hash;
struct rtable __rcu **rthp;
struct rtable *rt;

hash = rt_hash(daddr, skeys[s], ikeys[i], rt_genid(net));

rthp = &rt_hash_table[hash].chain;

while ((rt = rcu_dereference(*rthp)) != NULL) {
rthp = &rt->dst.rt_next;

if (rt->rt_key_dst != daddr ||
rt->rt_key_src != skeys[s] ||
rt->rt_oif != ikeys[i] ||
rt_is_input_route(rt) ||
rt_is_expired(rt) ||
!net_eq(dev_net(rt->dst.dev), net) ||
rt->dst.error ||
rt->dst.dev != dev ||
rt->rt_gateway != old_gw)
continue;

if (!rt->peer)
rt_bind_peer(rt, rt->rt_dst, 1);
if (!rt->peer)
rt_bind_peer(rt, rt->rt_dst, 1);

peer = rt->peer;
if (peer) {
peer->redirect_learned.a4 = new_gw;
atomic_inc(&__rt_peer_genid);
peer = rt->peer;
if (peer) {
if (peer->redirect_learned.a4 != new_gw) {
peer->redirect_learned.a4 = new_gw;
atomic_inc(&__rt_peer_genid);
}
check_peer_redir(&rt->dst, peer);
}
}

ip_rt_put(rt);
return;
}
}
return;
Expand Down Expand Up @@ -1649,33 +1684,6 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
}
}

static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer)
{
struct rtable *rt = (struct rtable *) dst;
__be32 orig_gw = rt->rt_gateway;
struct neighbour *n, *old_n;

dst_confirm(&rt->dst);

rt->rt_gateway = peer->redirect_learned.a4;

n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway);
if (IS_ERR(n))
return PTR_ERR(n);
old_n = xchg(&rt->dst._neighbour, n);
if (old_n)
neigh_release(old_n);
if (!n || !(n->nud_state & NUD_VALID)) {
if (n)
neigh_event_send(n, NULL);
rt->rt_gateway = orig_gw;
return -EAGAIN;
} else {
rt->rt_flags |= RTCF_REDIRECTED;
call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
}
return 0;
}

static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
{
Expand Down

0 comments on commit f604a72

Please sign in to comment.