aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r--net/ipv4/route.c175
1 files changed, 61 insertions, 114 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 5b1050a5d874..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
516static int ip_rt_acct_read(char *buffer, char **start, off_t offset, 516static 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; 540static 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
545static 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
555static int __net_init ip_rt_do_proc_init(struct net *net) 554static 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
704static inline int compare_netns(struct rtable *rt1, struct rtable *rt2) 702static 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
709static inline int rt_is_expired(struct rtable *rth) 707static 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 */
904void 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;
@@ -3056,23 +3058,6 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
3056 return -EINVAL; 3058 return -EINVAL;
3057} 3059}
3058 3060
3059static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table,
3060 void __user *oldval,
3061 size_t __user *oldlenp,
3062 void __user *newval,
3063 size_t newlen)
3064{
3065 int delay;
3066 struct net *net;
3067 if (newlen != sizeof(int))
3068 return -EINVAL;
3069 if (get_user(delay, (int __user *)newval))
3070 return -EFAULT;
3071 net = (struct net *)table->extra1;
3072 rt_cache_flush(net, delay);
3073 return 0;
3074}
3075
3076static void rt_secret_reschedule(int old) 3061static void rt_secret_reschedule(int old)
3077{ 3062{
3078 struct net *net; 3063 struct net *net;
@@ -3117,23 +3102,8 @@ static int ipv4_sysctl_rt_secret_interval(ctl_table *ctl, int write,
3117 return ret; 3102 return ret;
3118} 3103}
3119 3104
3120static int ipv4_sysctl_rt_secret_interval_strategy(ctl_table *table,
3121 void __user *oldval,
3122 size_t __user *oldlenp,
3123 void __user *newval,
3124 size_t newlen)
3125{
3126 int old = ip_rt_secret_interval;
3127 int ret = sysctl_jiffies(table, oldval, oldlenp, newval, newlen);
3128
3129 rt_secret_reschedule(old);
3130
3131 return ret;
3132}
3133
3134static ctl_table ipv4_route_table[] = { 3105static ctl_table ipv4_route_table[] = {
3135 { 3106 {
3136 .ctl_name = NET_IPV4_ROUTE_GC_THRESH,
3137 .procname = "gc_thresh", 3107 .procname = "gc_thresh",
3138 .data = &ipv4_dst_ops.gc_thresh, 3108 .data = &ipv4_dst_ops.gc_thresh,
3139 .maxlen = sizeof(int), 3109 .maxlen = sizeof(int),
@@ -3141,7 +3111,6 @@ static ctl_table ipv4_route_table[] = {
3141 .proc_handler = proc_dointvec, 3111 .proc_handler = proc_dointvec,
3142 }, 3112 },
3143 { 3113 {
3144 .ctl_name = NET_IPV4_ROUTE_MAX_SIZE,
3145 .procname = "max_size", 3114 .procname = "max_size",
3146 .data = &ip_rt_max_size, 3115 .data = &ip_rt_max_size,
3147 .maxlen = sizeof(int), 3116 .maxlen = sizeof(int),
@@ -3151,43 +3120,34 @@ static ctl_table ipv4_route_table[] = {
3151 { 3120 {
3152 /* Deprecated. Use gc_min_interval_ms */ 3121 /* Deprecated. Use gc_min_interval_ms */
3153 3122
3154 .ctl_name = NET_IPV4_ROUTE_GC_MIN_INTERVAL,
3155 .procname = "gc_min_interval", 3123 .procname = "gc_min_interval",
3156 .data = &ip_rt_gc_min_interval, 3124 .data = &ip_rt_gc_min_interval,
3157 .maxlen = sizeof(int), 3125 .maxlen = sizeof(int),
3158 .mode = 0644, 3126 .mode = 0644,
3159 .proc_handler = proc_dointvec_jiffies, 3127 .proc_handler = proc_dointvec_jiffies,
3160 .strategy = sysctl_jiffies,
3161 }, 3128 },
3162 { 3129 {
3163 .ctl_name = NET_IPV4_ROUTE_GC_MIN_INTERVAL_MS,
3164 .procname = "gc_min_interval_ms", 3130 .procname = "gc_min_interval_ms",
3165 .data = &ip_rt_gc_min_interval, 3131 .data = &ip_rt_gc_min_interval,
3166 .maxlen = sizeof(int), 3132 .maxlen = sizeof(int),
3167 .mode = 0644, 3133 .mode = 0644,
3168 .proc_handler = proc_dointvec_ms_jiffies, 3134 .proc_handler = proc_dointvec_ms_jiffies,
3169 .strategy = sysctl_ms_jiffies,
3170 }, 3135 },
3171 { 3136 {
3172 .ctl_name = NET_IPV4_ROUTE_GC_TIMEOUT,
3173 .procname = "gc_timeout", 3137 .procname = "gc_timeout",
3174 .data = &ip_rt_gc_timeout, 3138 .data = &ip_rt_gc_timeout,
3175 .maxlen = sizeof(int), 3139 .maxlen = sizeof(int),
3176 .mode = 0644, 3140 .mode = 0644,
3177 .proc_handler = proc_dointvec_jiffies, 3141 .proc_handler = proc_dointvec_jiffies,
3178 .strategy = sysctl_jiffies,
3179 }, 3142 },
3180 { 3143 {
3181 .ctl_name = NET_IPV4_ROUTE_GC_INTERVAL,
3182 .procname = "gc_interval", 3144 .procname = "gc_interval",
3183 .data = &ip_rt_gc_interval, 3145 .data = &ip_rt_gc_interval,
3184 .maxlen = sizeof(int), 3146 .maxlen = sizeof(int),
3185 .mode = 0644, 3147 .mode = 0644,
3186 .proc_handler = proc_dointvec_jiffies, 3148 .proc_handler = proc_dointvec_jiffies,
3187 .strategy = sysctl_jiffies,
3188 }, 3149 },
3189 { 3150 {
3190 .ctl_name = NET_IPV4_ROUTE_REDIRECT_LOAD,
3191 .procname = "redirect_load", 3151 .procname = "redirect_load",
3192 .data = &ip_rt_redirect_load, 3152 .data = &ip_rt_redirect_load,
3193 .maxlen = sizeof(int), 3153 .maxlen = sizeof(int),
@@ -3195,7 +3155,6 @@ static ctl_table ipv4_route_table[] = {
3195 .proc_handler = proc_dointvec, 3155 .proc_handler = proc_dointvec,
3196 }, 3156 },
3197 { 3157 {
3198 .ctl_name = NET_IPV4_ROUTE_REDIRECT_NUMBER,
3199 .procname = "redirect_number", 3158 .procname = "redirect_number",
3200 .data = &ip_rt_redirect_number, 3159 .data = &ip_rt_redirect_number,
3201 .maxlen = sizeof(int), 3160 .maxlen = sizeof(int),
@@ -3203,7 +3162,6 @@ static ctl_table ipv4_route_table[] = {
3203 .proc_handler = proc_dointvec, 3162 .proc_handler = proc_dointvec,
3204 }, 3163 },
3205 { 3164 {
3206 .ctl_name = NET_IPV4_ROUTE_REDIRECT_SILENCE,
3207 .procname = "redirect_silence", 3165 .procname = "redirect_silence",
3208 .data = &ip_rt_redirect_silence, 3166 .data = &ip_rt_redirect_silence,
3209 .maxlen = sizeof(int), 3167 .maxlen = sizeof(int),
@@ -3211,7 +3169,6 @@ static ctl_table ipv4_route_table[] = {
3211 .proc_handler = proc_dointvec, 3169 .proc_handler = proc_dointvec,
3212 }, 3170 },
3213 { 3171 {
3214 .ctl_name = NET_IPV4_ROUTE_ERROR_COST,
3215 .procname = "error_cost", 3172 .procname = "error_cost",
3216 .data = &ip_rt_error_cost, 3173 .data = &ip_rt_error_cost,
3217 .maxlen = sizeof(int), 3174 .maxlen = sizeof(int),
@@ -3219,7 +3176,6 @@ static ctl_table ipv4_route_table[] = {
3219 .proc_handler = proc_dointvec, 3176 .proc_handler = proc_dointvec,
3220 }, 3177 },
3221 { 3178 {
3222 .ctl_name = NET_IPV4_ROUTE_ERROR_BURST,
3223 .procname = "error_burst", 3179 .procname = "error_burst",
3224 .data = &ip_rt_error_burst, 3180 .data = &ip_rt_error_burst,
3225 .maxlen = sizeof(int), 3181 .maxlen = sizeof(int),
@@ -3227,7 +3183,6 @@ static ctl_table ipv4_route_table[] = {
3227 .proc_handler = proc_dointvec, 3183 .proc_handler = proc_dointvec,
3228 }, 3184 },
3229 { 3185 {
3230 .ctl_name = NET_IPV4_ROUTE_GC_ELASTICITY,
3231 .procname = "gc_elasticity", 3186 .procname = "gc_elasticity",
3232 .data = &ip_rt_gc_elasticity, 3187 .data = &ip_rt_gc_elasticity,
3233 .maxlen = sizeof(int), 3188 .maxlen = sizeof(int),
@@ -3235,16 +3190,13 @@ static ctl_table ipv4_route_table[] = {
3235 .proc_handler = proc_dointvec, 3190 .proc_handler = proc_dointvec,
3236 }, 3191 },
3237 { 3192 {
3238 .ctl_name = NET_IPV4_ROUTE_MTU_EXPIRES,
3239 .procname = "mtu_expires", 3193 .procname = "mtu_expires",
3240 .data = &ip_rt_mtu_expires, 3194 .data = &ip_rt_mtu_expires,
3241 .maxlen = sizeof(int), 3195 .maxlen = sizeof(int),
3242 .mode = 0644, 3196 .mode = 0644,
3243 .proc_handler = proc_dointvec_jiffies, 3197 .proc_handler = proc_dointvec_jiffies,
3244 .strategy = sysctl_jiffies,
3245 }, 3198 },
3246 { 3199 {
3247 .ctl_name = NET_IPV4_ROUTE_MIN_PMTU,
3248 .procname = "min_pmtu", 3200 .procname = "min_pmtu",
3249 .data = &ip_rt_min_pmtu, 3201 .data = &ip_rt_min_pmtu,
3250 .maxlen = sizeof(int), 3202 .maxlen = sizeof(int),
@@ -3252,7 +3204,6 @@ static ctl_table ipv4_route_table[] = {
3252 .proc_handler = proc_dointvec, 3204 .proc_handler = proc_dointvec,
3253 }, 3205 },
3254 { 3206 {
3255 .ctl_name = NET_IPV4_ROUTE_MIN_ADVMSS,
3256 .procname = "min_adv_mss", 3207 .procname = "min_adv_mss",
3257 .data = &ip_rt_min_advmss, 3208 .data = &ip_rt_min_advmss,
3258 .maxlen = sizeof(int), 3209 .maxlen = sizeof(int),
@@ -3260,50 +3211,46 @@ static ctl_table ipv4_route_table[] = {
3260 .proc_handler = proc_dointvec, 3211 .proc_handler = proc_dointvec,
3261 }, 3212 },
3262 { 3213 {
3263 .ctl_name = NET_IPV4_ROUTE_SECRET_INTERVAL,
3264 .procname = "secret_interval", 3214 .procname = "secret_interval",
3265 .data = &ip_rt_secret_interval, 3215 .data = &ip_rt_secret_interval,
3266 .maxlen = sizeof(int), 3216 .maxlen = sizeof(int),
3267 .mode = 0644, 3217 .mode = 0644,
3268 .proc_handler = ipv4_sysctl_rt_secret_interval, 3218 .proc_handler = ipv4_sysctl_rt_secret_interval,
3269 .strategy = ipv4_sysctl_rt_secret_interval_strategy,
3270 }, 3219 },
3271 { .ctl_name = 0 } 3220 { }
3272}; 3221};
3273 3222
3274static struct ctl_table empty[1]; 3223static struct ctl_table empty[1];
3275 3224
3276static struct ctl_table ipv4_skeleton[] = 3225static struct ctl_table ipv4_skeleton[] =
3277{ 3226{
3278 { .procname = "route", .ctl_name = NET_IPV4_ROUTE, 3227 { .procname = "route",
3279 .mode = 0555, .child = ipv4_route_table}, 3228 .mode = 0555, .child = ipv4_route_table},
3280 { .procname = "neigh", .ctl_name = NET_IPV4_NEIGH, 3229 { .procname = "neigh",
3281 .mode = 0555, .child = empty}, 3230 .mode = 0555, .child = empty},
3282 { } 3231 { }
3283}; 3232};
3284 3233
3285static __net_initdata struct ctl_path ipv4_path[] = { 3234static __net_initdata struct ctl_path ipv4_path[] = {
3286 { .procname = "net", .ctl_name = CTL_NET, }, 3235 { .procname = "net", },
3287 { .procname = "ipv4", .ctl_name = NET_IPV4, }, 3236 { .procname = "ipv4", },
3288 { }, 3237 { },
3289}; 3238};
3290 3239
3291static struct ctl_table ipv4_route_flush_table[] = { 3240static struct ctl_table ipv4_route_flush_table[] = {
3292 { 3241 {
3293 .ctl_name = NET_IPV4_ROUTE_FLUSH,
3294 .procname = "flush", 3242 .procname = "flush",
3295 .maxlen = sizeof(int), 3243 .maxlen = sizeof(int),
3296 .mode = 0200, 3244 .mode = 0200,
3297 .proc_handler = ipv4_sysctl_rtcache_flush, 3245 .proc_handler = ipv4_sysctl_rtcache_flush,
3298 .strategy = ipv4_sysctl_rtcache_flush_strategy,
3299 }, 3246 },
3300 { .ctl_name = 0 }, 3247 { },
3301}; 3248};
3302 3249
3303static __net_initdata struct ctl_path ipv4_route_path[] = { 3250static __net_initdata struct ctl_path ipv4_route_path[] = {
3304 { .procname = "net", .ctl_name = CTL_NET, }, 3251 { .procname = "net", },
3305 { .procname = "ipv4", .ctl_name = NET_IPV4, }, 3252 { .procname = "ipv4", },
3306 { .procname = "route", .ctl_name = NET_IPV4_ROUTE, }, 3253 { .procname = "route", },
3307 { }, 3254 { },
3308}; 3255};
3309 3256
@@ -3312,7 +3259,7 @@ static __net_init int sysctl_route_net_init(struct net *net)
3312 struct ctl_table *tbl; 3259 struct ctl_table *tbl;
3313 3260
3314 tbl = ipv4_route_flush_table; 3261 tbl = ipv4_route_flush_table;
3315 if (net != &init_net) { 3262 if (!net_eq(net, &init_net)) {
3316 tbl = kmemdup(tbl, sizeof(ipv4_route_flush_table), GFP_KERNEL); 3263 tbl = kmemdup(tbl, sizeof(ipv4_route_flush_table), GFP_KERNEL);
3317 if (tbl == NULL) 3264 if (tbl == NULL)
3318 goto err_dup; 3265 goto err_dup;