diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-29 17:41:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-29 17:41:18 -0400 |
commit | 6631424fd2efd75e7394b318ad2a8597327857a9 (patch) | |
tree | 09cc31036c9c53c5faec578ad68d443fd53e1b3d /net | |
parent | c45140a996b511bccdcbbdbea7e36f001826bdf2 (diff) | |
parent | c0cd884af045338476b8e69a61fceb3f34ff22f1 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (33 commits)
r8169: offical fix for CVE-2009-4537 (overlength frame DMAs)
ipv6: Don't drop cache route entry unless timer actually expired.
tulip: Add missing parens.
r8169: fix broken register writes
pcnet_cs: add new id
bonding: fix broken multicast with round-robin mode
drivers/net: Fix continuation lines
e1000: do not modify tx_queue_len on link speed change
net: ipmr/ip6mr: prevent out-of-bounds vif_table access
ixgbe: Do not run all Diagnostic offline tests when VFs are active
igb: use correct bits to identify if managability is enabled
benet: Fix compile warnnings in drivers/net/benet/be_ethtool.c
net: Add MSG_WAITFORONE flag to recvmmsg
e1000e: do not modify tx_queue_len on link speed change
igbvf: do not modify tx_queue_len on link speed change
ipv4: Restart rt_intern_hash after emergency rebuild (v2)
ipv4: Cleanup struct net dereference in rt_intern_hash
net: fix netlink address dumping in IPv4/IPv6
tulip: Fix null dereference in uli526x_rx_packet()
gianfar: fix undo of reserve()
...
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/devinet.c | 2 | ||||
-rw-r--r-- | net/ipv4/ipmr.c | 11 | ||||
-rw-r--r-- | net/ipv4/route.c | 21 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 11 | ||||
-rw-r--r-- | net/ipv6/route.c | 13 | ||||
-rw-r--r-- | net/socket.c | 4 |
7 files changed, 42 insertions, 22 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; |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 3381b4317c27..7e567ae5eaab 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -3610,7 +3610,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, | |||
3610 | hlist_for_each_entry_rcu(dev, node, head, index_hlist) { | 3610 | hlist_for_each_entry_rcu(dev, node, head, index_hlist) { |
3611 | if (idx < s_idx) | 3611 | if (idx < s_idx) |
3612 | goto cont; | 3612 | goto cont; |
3613 | if (idx > s_idx) | 3613 | if (h > s_h || idx > s_idx) |
3614 | s_ip_idx = 0; | 3614 | s_ip_idx = 0; |
3615 | ip_idx = 0; | 3615 | ip_idx = 0; |
3616 | if ((idev = __in6_dev_get(dev)) == NULL) | 3616 | if ((idev = __in6_dev_get(dev)) == NULL) |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 23e4ac0cc30e..27acfb58650a 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -1695,17 +1695,20 @@ ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm) | |||
1695 | int ct; | 1695 | int ct; |
1696 | struct rtnexthop *nhp; | 1696 | struct rtnexthop *nhp; |
1697 | struct net *net = mfc6_net(c); | 1697 | struct net *net = mfc6_net(c); |
1698 | struct net_device *dev = net->ipv6.vif6_table[c->mf6c_parent].dev; | ||
1699 | u8 *b = skb_tail_pointer(skb); | 1698 | u8 *b = skb_tail_pointer(skb); |
1700 | struct rtattr *mp_head; | 1699 | struct rtattr *mp_head; |
1701 | 1700 | ||
1702 | if (dev) | 1701 | /* If cache is unresolved, don't try to parse IIF and OIF */ |
1703 | RTA_PUT(skb, RTA_IIF, 4, &dev->ifindex); | 1702 | if (c->mf6c_parent > MAXMIFS) |
1703 | return -ENOENT; | ||
1704 | |||
1705 | if (MIF_EXISTS(net, c->mf6c_parent)) | ||
1706 | RTA_PUT(skb, RTA_IIF, 4, &net->ipv6.vif6_table[c->mf6c_parent].dev->ifindex); | ||
1704 | 1707 | ||
1705 | mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); | 1708 | mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); |
1706 | 1709 | ||
1707 | for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { | 1710 | for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { |
1708 | if (c->mfc_un.res.ttls[ct] < 255) { | 1711 | if (MIF_EXISTS(net, ct) && c->mfc_un.res.ttls[ct] < 255) { |
1709 | if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) | 1712 | if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) |
1710 | goto rtattr_failure; | 1713 | goto rtattr_failure; |
1711 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); | 1714 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 7fcb0e5d1213..0d7713c5c206 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -890,12 +890,17 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst) | |||
890 | struct rt6_info *rt = (struct rt6_info *) dst; | 890 | struct rt6_info *rt = (struct rt6_info *) dst; |
891 | 891 | ||
892 | if (rt) { | 892 | if (rt) { |
893 | if (rt->rt6i_flags & RTF_CACHE) | 893 | if (rt->rt6i_flags & RTF_CACHE) { |
894 | ip6_del_rt(rt); | 894 | if (rt6_check_expired(rt)) { |
895 | else | 895 | ip6_del_rt(rt); |
896 | dst = NULL; | ||
897 | } | ||
898 | } else { | ||
896 | dst_release(dst); | 899 | dst_release(dst); |
900 | dst = NULL; | ||
901 | } | ||
897 | } | 902 | } |
898 | return NULL; | 903 | return dst; |
899 | } | 904 | } |
900 | 905 | ||
901 | static void ip6_link_failure(struct sk_buff *skb) | 906 | static void ip6_link_failure(struct sk_buff *skb) |
diff --git a/net/socket.c b/net/socket.c index 769c386bd428..f55ffe9f8c87 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -2135,6 +2135,10 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
2135 | break; | 2135 | break; |
2136 | ++datagrams; | 2136 | ++datagrams; |
2137 | 2137 | ||
2138 | /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */ | ||
2139 | if (flags & MSG_WAITFORONE) | ||
2140 | flags |= MSG_DONTWAIT; | ||
2141 | |||
2138 | if (timeout) { | 2142 | if (timeout) { |
2139 | ktime_get_ts(timeout); | 2143 | ktime_get_ts(timeout); |
2140 | *timeout = timespec_sub(end_time, *timeout); | 2144 | *timeout = timespec_sub(end_time, *timeout); |