diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-08 10:55:01 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-08 10:55:01 -0500 |
commit | d7fc02c7bae7b1cf69269992cf880a43a350cdaa (patch) | |
tree | a43d56fa72913a1cc98a0bbebe054d08581b3a7c /net/ipv4/route.c | |
parent | ee1262dbc65ce0b6234a915d8432171e8d77f518 (diff) | |
parent | 28b4d5cc17c20786848cdc07b7ea237a309776bb (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1815 commits)
mac80211: fix reorder buffer release
iwmc3200wifi: Enable wimax core through module parameter
iwmc3200wifi: Add wifi-wimax coexistence mode as a module parameter
iwmc3200wifi: Coex table command does not expect a response
iwmc3200wifi: Update wiwi priority table
iwlwifi: driver version track kernel version
iwlwifi: indicate uCode type when fail dump error/event log
iwl3945: remove duplicated event logging code
b43: fix two warnings
ipw2100: fix rebooting hang with driver loaded
cfg80211: indent regulatory messages with spaces
iwmc3200wifi: fix NULL pointer dereference in pmkid update
mac80211: Fix TX status reporting for injected data frames
ath9k: enable 2GHz band only if the device supports it
airo: Fix integer overflow warning
rt2x00: Fix padding bug on L2PAD devices.
WE: Fix set events not propagated
b43legacy: avoid PPC fault during resume
b43: avoid PPC fault during resume
tcp: fix a timewait refcnt race
...
Fix up conflicts due to sysctl cleanups (dead sysctl_check code and
CTL_UNNUMBERED removed) in
kernel/sysctl_check.c
net/ipv4/sysctl_net_ipv4.c
net/ipv6/addrconf.c
net/sctp/sysctl.c
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r-- | net/ipv4/route.c | 102 |
1 files changed, 52 insertions, 50 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 0d9f584a3811..e446496f564f 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -513,43 +513,42 @@ static const struct file_operations rt_cpu_seq_fops = { | |||
513 | }; | 513 | }; |
514 | 514 | ||
515 | #ifdef CONFIG_NET_CLS_ROUTE | 515 | #ifdef CONFIG_NET_CLS_ROUTE |
516 | static int ip_rt_acct_read(char *buffer, char **start, off_t offset, | 516 | static int rt_acct_proc_show(struct seq_file *m, void *v) |
517 | int length, int *eof, void *data) | 517 | { |
518 | { | 518 | struct ip_rt_acct *dst, *src; |
519 | unsigned int i; | 519 | unsigned int i, j; |
520 | 520 | ||
521 | if ((offset & 3) || (length & 3)) | 521 | dst = kcalloc(256, sizeof(struct ip_rt_acct), GFP_KERNEL); |
522 | return -EIO; | 522 | if (!dst) |
523 | 523 | return -ENOMEM; | |
524 | if (offset >= sizeof(struct ip_rt_acct) * 256) { | 524 | |
525 | *eof = 1; | 525 | for_each_possible_cpu(i) { |
526 | return 0; | 526 | src = (struct ip_rt_acct *)per_cpu_ptr(ip_rt_acct, i); |
527 | } | 527 | for (j = 0; j < 256; j++) { |
528 | 528 | dst[j].o_bytes += src[j].o_bytes; | |
529 | if (offset + length >= sizeof(struct ip_rt_acct) * 256) { | 529 | dst[j].o_packets += src[j].o_packets; |
530 | length = sizeof(struct ip_rt_acct) * 256 - offset; | 530 | dst[j].i_bytes += src[j].i_bytes; |
531 | *eof = 1; | 531 | dst[j].i_packets += src[j].i_packets; |
532 | } | ||
532 | } | 533 | } |
533 | 534 | ||
534 | offset /= sizeof(u32); | 535 | seq_write(m, dst, 256 * sizeof(struct ip_rt_acct)); |
535 | 536 | kfree(dst); | |
536 | if (length > 0) { | 537 | return 0; |
537 | u32 *dst = (u32 *) buffer; | 538 | } |
538 | |||
539 | *start = buffer; | ||
540 | memset(dst, 0, length); | ||
541 | |||
542 | for_each_possible_cpu(i) { | ||
543 | unsigned int j; | ||
544 | u32 *src; | ||
545 | 539 | ||
546 | src = ((u32 *) per_cpu_ptr(ip_rt_acct, i)) + offset; | 540 | static int rt_acct_proc_open(struct inode *inode, struct file *file) |
547 | for (j = 0; j < length/4; j++) | 541 | { |
548 | dst[j] += src[j]; | 542 | return single_open(file, rt_acct_proc_show, NULL); |
549 | } | ||
550 | } | ||
551 | return length; | ||
552 | } | 543 | } |
544 | |||
545 | static const struct file_operations rt_acct_proc_fops = { | ||
546 | .owner = THIS_MODULE, | ||
547 | .open = rt_acct_proc_open, | ||
548 | .read = seq_read, | ||
549 | .llseek = seq_lseek, | ||
550 | .release = single_release, | ||
551 | }; | ||
553 | #endif | 552 | #endif |
554 | 553 | ||
555 | static int __net_init ip_rt_do_proc_init(struct net *net) | 554 | static int __net_init ip_rt_do_proc_init(struct net *net) |
@@ -567,8 +566,7 @@ static int __net_init ip_rt_do_proc_init(struct net *net) | |||
567 | goto err2; | 566 | goto err2; |
568 | 567 | ||
569 | #ifdef CONFIG_NET_CLS_ROUTE | 568 | #ifdef CONFIG_NET_CLS_ROUTE |
570 | pde = create_proc_read_entry("rt_acct", 0, net->proc_net, | 569 | pde = proc_create("rt_acct", 0, net->proc_net, &rt_acct_proc_fops); |
571 | ip_rt_acct_read, NULL); | ||
572 | if (!pde) | 570 | if (!pde) |
573 | goto err3; | 571 | goto err3; |
574 | #endif | 572 | #endif |
@@ -703,7 +701,7 @@ static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) | |||
703 | 701 | ||
704 | static inline int compare_netns(struct rtable *rt1, struct rtable *rt2) | 702 | static inline int compare_netns(struct rtable *rt1, struct rtable *rt2) |
705 | { | 703 | { |
706 | return dev_net(rt1->u.dst.dev) == dev_net(rt2->u.dst.dev); | 704 | return net_eq(dev_net(rt1->u.dst.dev), dev_net(rt2->u.dst.dev)); |
707 | } | 705 | } |
708 | 706 | ||
709 | static inline int rt_is_expired(struct rtable *rth) | 707 | static inline int rt_is_expired(struct rtable *rth) |
@@ -902,6 +900,12 @@ void rt_cache_flush(struct net *net, int delay) | |||
902 | rt_do_flush(!in_softirq()); | 900 | rt_do_flush(!in_softirq()); |
903 | } | 901 | } |
904 | 902 | ||
903 | /* Flush previous cache invalidated entries from the cache */ | ||
904 | void rt_cache_flush_batch(void) | ||
905 | { | ||
906 | rt_do_flush(!in_softirq()); | ||
907 | } | ||
908 | |||
905 | /* | 909 | /* |
906 | * We change rt_genid and let gc do the cleanup | 910 | * We change rt_genid and let gc do the cleanup |
907 | */ | 911 | */ |
@@ -1346,9 +1350,9 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | |||
1346 | return; | 1350 | return; |
1347 | 1351 | ||
1348 | net = dev_net(dev); | 1352 | net = dev_net(dev); |
1349 | if (new_gw == old_gw || !IN_DEV_RX_REDIRECTS(in_dev) | 1353 | if (new_gw == old_gw || !IN_DEV_RX_REDIRECTS(in_dev) || |
1350 | || ipv4_is_multicast(new_gw) || ipv4_is_lbcast(new_gw) | 1354 | ipv4_is_multicast(new_gw) || ipv4_is_lbcast(new_gw) || |
1351 | || ipv4_is_zeronet(new_gw)) | 1355 | ipv4_is_zeronet(new_gw)) |
1352 | goto reject_redirect; | 1356 | goto reject_redirect; |
1353 | 1357 | ||
1354 | if (!rt_caching(net)) | 1358 | if (!rt_caching(net)) |
@@ -1628,9 +1632,6 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, | |||
1628 | __be32 daddr = iph->daddr; | 1632 | __be32 daddr = iph->daddr; |
1629 | unsigned short est_mtu = 0; | 1633 | unsigned short est_mtu = 0; |
1630 | 1634 | ||
1631 | if (ipv4_config.no_pmtu_disc) | ||
1632 | return 0; | ||
1633 | |||
1634 | for (k = 0; k < 2; k++) { | 1635 | for (k = 0; k < 2; k++) { |
1635 | for (i = 0; i < 2; i++) { | 1636 | for (i = 0; i < 2; i++) { |
1636 | unsigned hash = rt_hash(daddr, skeys[i], ikeys[k], | 1637 | unsigned hash = rt_hash(daddr, skeys[i], ikeys[k], |
@@ -2314,10 +2315,11 @@ skip_cache: | |||
2314 | ip_hdr(skb)->protocol); | 2315 | ip_hdr(skb)->protocol); |
2315 | if (our | 2316 | if (our |
2316 | #ifdef CONFIG_IP_MROUTE | 2317 | #ifdef CONFIG_IP_MROUTE |
2317 | || (!ipv4_is_local_multicast(daddr) && | 2318 | || |
2318 | IN_DEV_MFORWARD(in_dev)) | 2319 | (!ipv4_is_local_multicast(daddr) && |
2320 | IN_DEV_MFORWARD(in_dev)) | ||
2319 | #endif | 2321 | #endif |
2320 | ) { | 2322 | ) { |
2321 | rcu_read_unlock(); | 2323 | rcu_read_unlock(); |
2322 | return ip_route_input_mc(skb, daddr, saddr, | 2324 | return ip_route_input_mc(skb, daddr, saddr, |
2323 | tos, dev, our); | 2325 | tos, dev, our); |
@@ -2514,9 +2516,9 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, | |||
2514 | of another iface. --ANK | 2516 | of another iface. --ANK |
2515 | */ | 2517 | */ |
2516 | 2518 | ||
2517 | if (oldflp->oif == 0 | 2519 | if (oldflp->oif == 0 && |
2518 | && (ipv4_is_multicast(oldflp->fl4_dst) || | 2520 | (ipv4_is_multicast(oldflp->fl4_dst) || |
2519 | oldflp->fl4_dst == htonl(0xFFFFFFFF))) { | 2521 | oldflp->fl4_dst == htonl(0xFFFFFFFF))) { |
2520 | /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */ | 2522 | /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */ |
2521 | dev_out = ip_dev_find(net, oldflp->fl4_src); | 2523 | dev_out = ip_dev_find(net, oldflp->fl4_src); |
2522 | if (dev_out == NULL) | 2524 | if (dev_out == NULL) |
@@ -2855,7 +2857,7 @@ static int rt_fill_info(struct net *net, | |||
2855 | error = rt->u.dst.error; | 2857 | error = rt->u.dst.error; |
2856 | expires = rt->u.dst.expires ? rt->u.dst.expires - jiffies : 0; | 2858 | expires = rt->u.dst.expires ? rt->u.dst.expires - jiffies : 0; |
2857 | if (rt->peer) { | 2859 | if (rt->peer) { |
2858 | id = rt->peer->ip_id_count; | 2860 | id = atomic_read(&rt->peer->ip_id_count) & 0xffff; |
2859 | if (rt->peer->tcp_ts_stamp) { | 2861 | if (rt->peer->tcp_ts_stamp) { |
2860 | ts = rt->peer->tcp_ts; | 2862 | ts = rt->peer->tcp_ts; |
2861 | tsage = get_seconds() - rt->peer->tcp_ts_stamp; | 2863 | tsage = get_seconds() - rt->peer->tcp_ts_stamp; |
@@ -3257,7 +3259,7 @@ static __net_init int sysctl_route_net_init(struct net *net) | |||
3257 | struct ctl_table *tbl; | 3259 | struct ctl_table *tbl; |
3258 | 3260 | ||
3259 | tbl = ipv4_route_flush_table; | 3261 | tbl = ipv4_route_flush_table; |
3260 | if (net != &init_net) { | 3262 | if (!net_eq(net, &init_net)) { |
3261 | tbl = kmemdup(tbl, sizeof(ipv4_route_flush_table), GFP_KERNEL); | 3263 | tbl = kmemdup(tbl, sizeof(ipv4_route_flush_table), GFP_KERNEL); |
3262 | if (tbl == NULL) | 3264 | if (tbl == NULL) |
3263 | goto err_dup; | 3265 | goto err_dup; |