Skip to content

Commit a627945

Browse files
yoshfujiDavid S. Miller
authored andcommitted
[IPV6] NDISC: Search over all possible rules on receipt of redirect.
Split up function for finding routes for redirects. Signed-off-by: YOSHIFUJI Hideaki <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 5e032e3 commit a627945

File tree

1 file changed

+61
-24
lines changed

1 file changed

+61
-24
lines changed

net/ipv6/route.c

Lines changed: 61 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,19 +1279,18 @@ static int ip6_route_del(struct fib6_config *cfg)
12791279
/*
12801280
* Handle redirects
12811281
*/
1282-
void rt6_redirect(struct in6_addr *dest, struct in6_addr *src,
1283-
struct in6_addr *saddr,
1284-
struct neighbour *neigh, u8 *lladdr, int on_link)
1282+
struct ip6rd_flowi {
1283+
struct flowi fl;
1284+
struct in6_addr gateway;
1285+
};
1286+
1287+
static struct rt6_info *__ip6_route_redirect(struct fib6_table *table,
1288+
struct flowi *fl,
1289+
int flags)
12851290
{
1286-
struct rt6_info *rt, *nrt = NULL;
1291+
struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl;
1292+
struct rt6_info *rt;
12871293
struct fib6_node *fn;
1288-
struct fib6_table *table;
1289-
struct netevent_redirect netevent;
1290-
1291-
/* TODO: Very lazy, might need to check all tables */
1292-
table = fib6_get_table(RT6_TABLE_MAIN);
1293-
if (table == NULL)
1294-
return;
12951294

12961295
/*
12971296
* Get the "current" route for this destination and
@@ -1305,7 +1304,7 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *src,
13051304
*/
13061305

13071306
read_lock_bh(&table->tb6_lock);
1308-
fn = fib6_lookup(&table->tb6_root, dest, src);
1307+
fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
13091308
restart:
13101309
for (rt = fn->leaf; rt; rt = rt->u.next) {
13111310
/*
@@ -1320,29 +1319,67 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *src,
13201319
continue;
13211320
if (!(rt->rt6i_flags & RTF_GATEWAY))
13221321
continue;
1323-
if (neigh->dev != rt->rt6i_dev)
1322+
if (fl->oif != rt->rt6i_dev->ifindex)
13241323
continue;
1325-
if (!ipv6_addr_equal(saddr, &rt->rt6i_gateway))
1324+
if (!ipv6_addr_equal(&rdfl->gateway, &rt->rt6i_gateway))
13261325
continue;
13271326
break;
13281327
}
1329-
if (rt)
1330-
dst_hold(&rt->u.dst);
1331-
else if (rt6_need_strict(dest)) {
1332-
while ((fn = fn->parent) != NULL) {
1333-
if (fn->fn_flags & RTN_ROOT)
1334-
break;
1335-
if (fn->fn_flags & RTN_RTINFO)
1336-
goto restart;
1328+
1329+
if (!rt) {
1330+
if (rt6_need_strict(&fl->fl6_dst)) {
1331+
while ((fn = fn->parent) != NULL) {
1332+
if (fn->fn_flags & RTN_ROOT)
1333+
break;
1334+
if (fn->fn_flags & RTN_RTINFO)
1335+
goto restart;
1336+
}
13371337
}
1338+
rt = &ip6_null_entry;
13381339
}
1340+
dst_hold(&rt->u.dst);
1341+
13391342
read_unlock_bh(&table->tb6_lock);
13401343

1341-
if (!rt) {
1344+
return rt;
1345+
};
1346+
1347+
static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
1348+
struct in6_addr *src,
1349+
struct in6_addr *gateway,
1350+
struct net_device *dev)
1351+
{
1352+
struct ip6rd_flowi rdfl = {
1353+
.fl = {
1354+
.oif = dev->ifindex,
1355+
.nl_u = {
1356+
.ip6_u = {
1357+
.daddr = *dest,
1358+
.saddr = *src,
1359+
},
1360+
},
1361+
},
1362+
.gateway = *gateway,
1363+
};
1364+
int flags = rt6_need_strict(dest) ? RT6_F_STRICT : 0;
1365+
1366+
return (struct rt6_info *)fib6_rule_lookup((struct flowi *)&rdfl, flags, __ip6_route_redirect);
1367+
}
1368+
1369+
void rt6_redirect(struct in6_addr *dest, struct in6_addr *src,
1370+
struct in6_addr *saddr,
1371+
struct neighbour *neigh, u8 *lladdr, int on_link)
1372+
{
1373+
struct rt6_info *rt, *nrt = NULL;
1374+
struct netevent_redirect netevent;
1375+
1376+
rt = ip6_route_redirect(dest, src, saddr, neigh->dev);
1377+
1378+
if (rt == &ip6_null_entry) {
13421379
if (net_ratelimit())
13431380
printk(KERN_DEBUG "rt6_redirect: source isn't a valid nexthop "
13441381
"for redirect target\n");
1345-
return;
1382+
goto out;
13461383
}
13471384

13481385
/*

0 commit comments

Comments
 (0)