aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-04-07 02:53:30 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-07 02:53:30 -0400
commit4a35ecf8bf1c4b039503fa554100fe85c761de76 (patch)
tree9b75f5d5636004d9a9aa496924377379be09aa1f /net/ipv4
parentb4d562e3c3553ac58c7120555c4e4aefbb090a2a (diff)
parentfb9e2d887243499b8d28efcf80821c4f6a092395 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: drivers/net/bonding/bond_main.c drivers/net/via-velocity.c drivers/net/wireless/iwlwifi/iwl-agn.c
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/af_inet.c5
-rw-r--r--net/ipv4/devinet.c2
-rw-r--r--net/ipv4/fib_trie.c4
-rw-r--r--net/ipv4/ip_gre.c4
-rw-r--r--net/ipv4/ipmr.c11
-rw-r--r--net/ipv4/route.c24
-rw-r--r--net/ipv4/tcp.c1
7 files changed, 35 insertions, 16 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 55e11906a73a..b5924f178812 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -530,6 +530,8 @@ int inet_dgram_connect(struct socket *sock, struct sockaddr * uaddr,
530{ 530{
531 struct sock *sk = sock->sk; 531 struct sock *sk = sock->sk;
532 532
533 if (addr_len < sizeof(uaddr->sa_family))
534 return -EINVAL;
533 if (uaddr->sa_family == AF_UNSPEC) 535 if (uaddr->sa_family == AF_UNSPEC)
534 return sk->sk_prot->disconnect(sk, flags); 536 return sk->sk_prot->disconnect(sk, flags);
535 537
@@ -573,6 +575,9 @@ int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
573 int err; 575 int err;
574 long timeo; 576 long timeo;
575 577
578 if (addr_len < sizeof(uaddr->sa_family))
579 return -EINVAL;
580
576 lock_sock(sk); 581 lock_sock(sk);
577 582
578 if (uaddr->sa_family == AF_UNSPEC) { 583 if (uaddr->sa_family == AF_UNSPEC) {
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index c75320ef95c2..d009c6a5d9ad 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/fib_trie.c b/net/ipv4/fib_trie.c
index af5d89792860..01ef8ba9025c 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -961,7 +961,9 @@ fib_find_node(struct trie *t, u32 key)
961 struct node *n; 961 struct node *n;
962 962
963 pos = 0; 963 pos = 0;
964 n = rcu_dereference(t->trie); 964 n = rcu_dereference_check(t->trie,
965 rcu_read_lock_held() ||
966 lockdep_rtnl_is_held());
965 967
966 while (n != NULL && NODE_TYPE(n) == T_TNODE) { 968 while (n != NULL && NODE_TYPE(n) == T_TNODE) {
967 tn = (struct tnode *) n; 969 tn = (struct tnode *) n;
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index f47c9f76754b..f78402d097b3 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -810,11 +810,13 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
810 tunnel->err_count = 0; 810 tunnel->err_count = 0;
811 } 811 }
812 812
813 max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen; 813 max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen + rt->u.dst.header_len;
814 814
815 if (skb_headroom(skb) < max_headroom || skb_shared(skb)|| 815 if (skb_headroom(skb) < max_headroom || skb_shared(skb)||
816 (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { 816 (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
817 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); 817 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
818 if (max_headroom > dev->needed_headroom)
819 dev->needed_headroom = max_headroom;
818 if (!new_skb) { 820 if (!new_skb) {
819 ip_rt_put(rt); 821 ip_rt_put(rt);
820 txq->tx_dropped++; 822 txq->tx_dropped++;
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 32d396196df8..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
1099static int rt_intern_hash(unsigned hash, struct rtable *rt, 1099static 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 }
@@ -1510,7 +1515,8 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
1510 ip_rt_put(rt); 1515 ip_rt_put(rt);
1511 ret = NULL; 1516 ret = NULL;
1512 } else if ((rt->rt_flags & RTCF_REDIRECTED) || 1517 } else if ((rt->rt_flags & RTCF_REDIRECTED) ||
1513 rt->u.dst.expires) { 1518 (rt->u.dst.expires &&
1519 time_after_eq(jiffies, rt->u.dst.expires))) {
1514 unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src, 1520 unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src,
1515 rt->fl.oif, 1521 rt->fl.oif,
1516 rt_genid(dev_net(dst->dev))); 1522 rt_genid(dev_net(dst->dev)));
@@ -1930,7 +1936,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1930 1936
1931 in_dev_put(in_dev); 1937 in_dev_put(in_dev);
1932 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)));
1933 return rt_intern_hash(hash, rth, NULL, skb); 1939 return rt_intern_hash(hash, rth, NULL, skb, dev->ifindex);
1934 1940
1935e_nobufs: 1941e_nobufs:
1936 in_dev_put(in_dev); 1942 in_dev_put(in_dev);
@@ -2097,7 +2103,7 @@ static int ip_mkroute_input(struct sk_buff *skb,
2097 /* put it into the cache */ 2103 /* put it into the cache */
2098 hash = rt_hash(daddr, saddr, fl->iif, 2104 hash = rt_hash(daddr, saddr, fl->iif,
2099 rt_genid(dev_net(rth->u.dst.dev))); 2105 rt_genid(dev_net(rth->u.dst.dev)));
2100 return rt_intern_hash(hash, rth, NULL, skb); 2106 return rt_intern_hash(hash, rth, NULL, skb, fl->iif);
2101} 2107}
2102 2108
2103/* 2109/*
@@ -2254,7 +2260,7 @@ local_input:
2254 } 2260 }
2255 rth->rt_type = res.type; 2261 rth->rt_type = res.type;
2256 hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); 2262 hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net));
2257 err = rt_intern_hash(hash, rth, NULL, skb); 2263 err = rt_intern_hash(hash, rth, NULL, skb, fl.iif);
2258 goto done; 2264 goto done;
2259 2265
2260no_route: 2266no_route:
@@ -2501,7 +2507,7 @@ static int ip_mkroute_output(struct rtable **rp,
2501 if (err == 0) { 2507 if (err == 0) {
2502 hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, 2508 hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif,
2503 rt_genid(dev_net(dev_out))); 2509 rt_genid(dev_net(dev_out)));
2504 err = rt_intern_hash(hash, rth, rp, NULL); 2510 err = rt_intern_hash(hash, rth, rp, NULL, oldflp->oif);
2505 } 2511 }
2506 2512
2507 return err; 2513 return err;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 6afb6d8662b2..2c75f891914e 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1368,6 +1368,7 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
1368 sk_eat_skb(sk, skb, 0); 1368 sk_eat_skb(sk, skb, 0);
1369 if (!desc->count) 1369 if (!desc->count)
1370 break; 1370 break;
1371 tp->copied_seq = seq;
1371 } 1372 }
1372 tp->copied_seq = seq; 1373 tp->copied_seq = seq;
1373 1374