diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/devinet.c | 2 | ||||
-rw-r--r-- | net/ipv4/ipmr.c | 11 | ||||
-rw-r--r-- | net/ipv4/route.c | 21 |
3 files changed, 21 insertions, 13 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 51ca946e3392..3feb2b390308 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1194,7 +1194,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) | |||
1194 | hlist_for_each_entry_rcu(dev, node, head, index_hlist) { | 1194 | hlist_for_each_entry_rcu(dev, node, head, index_hlist) { |
1195 | if (idx < s_idx) | 1195 | if (idx < s_idx) |
1196 | goto cont; | 1196 | goto cont; |
1197 | if (idx > s_idx) | 1197 | if (h > s_h || idx > s_idx) |
1198 | s_ip_idx = 0; | 1198 | s_ip_idx = 0; |
1199 | in_dev = __in_dev_get_rcu(dev); | 1199 | in_dev = __in_dev_get_rcu(dev); |
1200 | if (!in_dev) | 1200 | if (!in_dev) |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 0b9d03c54dc3..d0a6092a67be 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -1616,17 +1616,20 @@ ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm) | |||
1616 | int ct; | 1616 | int ct; |
1617 | struct rtnexthop *nhp; | 1617 | struct rtnexthop *nhp; |
1618 | struct net *net = mfc_net(c); | 1618 | struct net *net = mfc_net(c); |
1619 | struct net_device *dev = net->ipv4.vif_table[c->mfc_parent].dev; | ||
1620 | u8 *b = skb_tail_pointer(skb); | 1619 | u8 *b = skb_tail_pointer(skb); |
1621 | struct rtattr *mp_head; | 1620 | struct rtattr *mp_head; |
1622 | 1621 | ||
1623 | if (dev) | 1622 | /* If cache is unresolved, don't try to parse IIF and OIF */ |
1624 | RTA_PUT(skb, RTA_IIF, 4, &dev->ifindex); | 1623 | if (c->mfc_parent > MAXVIFS) |
1624 | return -ENOENT; | ||
1625 | |||
1626 | if (VIF_EXISTS(net, c->mfc_parent)) | ||
1627 | RTA_PUT(skb, RTA_IIF, 4, &net->ipv4.vif_table[c->mfc_parent].dev->ifindex); | ||
1625 | 1628 | ||
1626 | mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); | 1629 | mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); |
1627 | 1630 | ||
1628 | for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { | 1631 | for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { |
1629 | if (c->mfc_un.res.ttls[ct] < 255) { | 1632 | if (VIF_EXISTS(net, ct) && c->mfc_un.res.ttls[ct] < 255) { |
1630 | if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) | 1633 | if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) |
1631 | goto rtattr_failure; | 1634 | goto rtattr_failure; |
1632 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); | 1635 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 54fd68c14c87..d413b57be9b3 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1097,7 +1097,7 @@ static int slow_chain_length(const struct rtable *head) | |||
1097 | } | 1097 | } |
1098 | 1098 | ||
1099 | static int rt_intern_hash(unsigned hash, struct rtable *rt, | 1099 | static int rt_intern_hash(unsigned hash, struct rtable *rt, |
1100 | struct rtable **rp, struct sk_buff *skb) | 1100 | struct rtable **rp, struct sk_buff *skb, int ifindex) |
1101 | { | 1101 | { |
1102 | struct rtable *rth, **rthp; | 1102 | struct rtable *rth, **rthp; |
1103 | unsigned long now; | 1103 | unsigned long now; |
@@ -1212,11 +1212,16 @@ restart: | |||
1212 | slow_chain_length(rt_hash_table[hash].chain) > rt_chain_length_max) { | 1212 | slow_chain_length(rt_hash_table[hash].chain) > rt_chain_length_max) { |
1213 | struct net *net = dev_net(rt->u.dst.dev); | 1213 | struct net *net = dev_net(rt->u.dst.dev); |
1214 | int num = ++net->ipv4.current_rt_cache_rebuild_count; | 1214 | int num = ++net->ipv4.current_rt_cache_rebuild_count; |
1215 | if (!rt_caching(dev_net(rt->u.dst.dev))) { | 1215 | if (!rt_caching(net)) { |
1216 | printk(KERN_WARNING "%s: %d rebuilds is over limit, route caching disabled\n", | 1216 | printk(KERN_WARNING "%s: %d rebuilds is over limit, route caching disabled\n", |
1217 | rt->u.dst.dev->name, num); | 1217 | rt->u.dst.dev->name, num); |
1218 | } | 1218 | } |
1219 | rt_emergency_hash_rebuild(dev_net(rt->u.dst.dev)); | 1219 | rt_emergency_hash_rebuild(net); |
1220 | spin_unlock_bh(rt_hash_lock_addr(hash)); | ||
1221 | |||
1222 | hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src, | ||
1223 | ifindex, rt_genid(net)); | ||
1224 | goto restart; | ||
1220 | } | 1225 | } |
1221 | } | 1226 | } |
1222 | 1227 | ||
@@ -1477,7 +1482,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | |||
1477 | &netevent); | 1482 | &netevent); |
1478 | 1483 | ||
1479 | rt_del(hash, rth); | 1484 | rt_del(hash, rth); |
1480 | if (!rt_intern_hash(hash, rt, &rt, NULL)) | 1485 | if (!rt_intern_hash(hash, rt, &rt, NULL, rt->fl.oif)) |
1481 | ip_rt_put(rt); | 1486 | ip_rt_put(rt); |
1482 | goto do_next; | 1487 | goto do_next; |
1483 | } | 1488 | } |
@@ -1931,7 +1936,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1931 | 1936 | ||
1932 | in_dev_put(in_dev); | 1937 | in_dev_put(in_dev); |
1933 | hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); | 1938 | hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); |
1934 | return rt_intern_hash(hash, rth, NULL, skb); | 1939 | return rt_intern_hash(hash, rth, NULL, skb, dev->ifindex); |
1935 | 1940 | ||
1936 | e_nobufs: | 1941 | e_nobufs: |
1937 | in_dev_put(in_dev); | 1942 | in_dev_put(in_dev); |
@@ -2098,7 +2103,7 @@ static int ip_mkroute_input(struct sk_buff *skb, | |||
2098 | /* put it into the cache */ | 2103 | /* put it into the cache */ |
2099 | hash = rt_hash(daddr, saddr, fl->iif, | 2104 | hash = rt_hash(daddr, saddr, fl->iif, |
2100 | rt_genid(dev_net(rth->u.dst.dev))); | 2105 | rt_genid(dev_net(rth->u.dst.dev))); |
2101 | return rt_intern_hash(hash, rth, NULL, skb); | 2106 | return rt_intern_hash(hash, rth, NULL, skb, fl->iif); |
2102 | } | 2107 | } |
2103 | 2108 | ||
2104 | /* | 2109 | /* |
@@ -2255,7 +2260,7 @@ local_input: | |||
2255 | } | 2260 | } |
2256 | rth->rt_type = res.type; | 2261 | rth->rt_type = res.type; |
2257 | hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); | 2262 | hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); |
2258 | err = rt_intern_hash(hash, rth, NULL, skb); | 2263 | err = rt_intern_hash(hash, rth, NULL, skb, fl.iif); |
2259 | goto done; | 2264 | goto done; |
2260 | 2265 | ||
2261 | no_route: | 2266 | no_route: |
@@ -2502,7 +2507,7 @@ static int ip_mkroute_output(struct rtable **rp, | |||
2502 | if (err == 0) { | 2507 | if (err == 0) { |
2503 | hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, | 2508 | hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, |
2504 | rt_genid(dev_net(dev_out))); | 2509 | rt_genid(dev_net(dev_out))); |
2505 | err = rt_intern_hash(hash, rth, rp, NULL); | 2510 | err = rt_intern_hash(hash, rth, rp, NULL, oldflp->oif); |
2506 | } | 2511 | } |
2507 | 2512 | ||
2508 | return err; | 2513 | return err; |