diff options
| author | Ingo Molnar <mingo@elte.hu> | 2008-09-04 07:02:35 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-09-04 07:02:35 -0400 |
| commit | 42390cdec5f6e6e2ee54f308474a6ef7dd16aa5c (patch) | |
| tree | e9684c84f53272319a5acd4b9c86503f30274a51 /net/ipv4 | |
| parent | 11c231a962c740b3216eb6565149ae5a7944cba7 (diff) | |
| parent | d210baf53b699fc61aa891c177b71d7082d3b957 (diff) | |
Merge branch 'linus' into x86/x2apic
Conflicts:
arch/x86/kernel/cpu/cyrix.c
include/asm-x86/cpufeature.h
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'net/ipv4')
| -rw-r--r-- | net/ipv4/devinet.c | 15 | ||||
| -rw-r--r-- | net/ipv4/icmp.c | 22 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ipt_addrtype.c | 2 | ||||
| -rw-r--r-- | net/ipv4/netfilter/nf_nat_proto_common.c | 8 | ||||
| -rw-r--r-- | net/ipv4/route.c | 100 | ||||
| -rw-r--r-- | net/ipv4/tcp_output.c | 6 |
6 files changed, 127 insertions, 26 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 91d3d96805d0..b12dae2b0b2d 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
| @@ -1029,6 +1029,11 @@ skip: | |||
| 1029 | } | 1029 | } |
| 1030 | } | 1030 | } |
| 1031 | 1031 | ||
| 1032 | static inline bool inetdev_valid_mtu(unsigned mtu) | ||
| 1033 | { | ||
| 1034 | return mtu >= 68; | ||
| 1035 | } | ||
| 1036 | |||
| 1032 | /* Called only under RTNL semaphore */ | 1037 | /* Called only under RTNL semaphore */ |
| 1033 | 1038 | ||
| 1034 | static int inetdev_event(struct notifier_block *this, unsigned long event, | 1039 | static int inetdev_event(struct notifier_block *this, unsigned long event, |
| @@ -1048,6 +1053,10 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, | |||
| 1048 | IN_DEV_CONF_SET(in_dev, NOXFRM, 1); | 1053 | IN_DEV_CONF_SET(in_dev, NOXFRM, 1); |
| 1049 | IN_DEV_CONF_SET(in_dev, NOPOLICY, 1); | 1054 | IN_DEV_CONF_SET(in_dev, NOPOLICY, 1); |
| 1050 | } | 1055 | } |
| 1056 | } else if (event == NETDEV_CHANGEMTU) { | ||
| 1057 | /* Re-enabling IP */ | ||
| 1058 | if (inetdev_valid_mtu(dev->mtu)) | ||
| 1059 | in_dev = inetdev_init(dev); | ||
| 1051 | } | 1060 | } |
| 1052 | goto out; | 1061 | goto out; |
| 1053 | } | 1062 | } |
| @@ -1058,7 +1067,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, | |||
| 1058 | dev->ip_ptr = NULL; | 1067 | dev->ip_ptr = NULL; |
| 1059 | break; | 1068 | break; |
| 1060 | case NETDEV_UP: | 1069 | case NETDEV_UP: |
| 1061 | if (dev->mtu < 68) | 1070 | if (!inetdev_valid_mtu(dev->mtu)) |
| 1062 | break; | 1071 | break; |
| 1063 | if (dev->flags & IFF_LOOPBACK) { | 1072 | if (dev->flags & IFF_LOOPBACK) { |
| 1064 | struct in_ifaddr *ifa; | 1073 | struct in_ifaddr *ifa; |
| @@ -1080,9 +1089,9 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, | |||
| 1080 | ip_mc_down(in_dev); | 1089 | ip_mc_down(in_dev); |
| 1081 | break; | 1090 | break; |
| 1082 | case NETDEV_CHANGEMTU: | 1091 | case NETDEV_CHANGEMTU: |
| 1083 | if (dev->mtu >= 68) | 1092 | if (inetdev_valid_mtu(dev->mtu)) |
| 1084 | break; | 1093 | break; |
| 1085 | /* MTU falled under 68, disable IP */ | 1094 | /* disable IP when MTU is not enough */ |
| 1086 | case NETDEV_UNREGISTER: | 1095 | case NETDEV_UNREGISTER: |
| 1087 | inetdev_destroy(in_dev); | 1096 | inetdev_destroy(in_dev); |
| 1088 | break; | 1097 | break; |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 860558633b2c..55c355e63234 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
| @@ -204,18 +204,22 @@ static struct sock *icmp_sk(struct net *net) | |||
| 204 | return net->ipv4.icmp_sk[smp_processor_id()]; | 204 | return net->ipv4.icmp_sk[smp_processor_id()]; |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | static inline int icmp_xmit_lock(struct sock *sk) | 207 | static inline struct sock *icmp_xmit_lock(struct net *net) |
| 208 | { | 208 | { |
| 209 | struct sock *sk; | ||
| 210 | |||
| 209 | local_bh_disable(); | 211 | local_bh_disable(); |
| 210 | 212 | ||
| 213 | sk = icmp_sk(net); | ||
| 214 | |||
| 211 | if (unlikely(!spin_trylock(&sk->sk_lock.slock))) { | 215 | if (unlikely(!spin_trylock(&sk->sk_lock.slock))) { |
| 212 | /* This can happen if the output path signals a | 216 | /* This can happen if the output path signals a |
| 213 | * dst_link_failure() for an outgoing ICMP packet. | 217 | * dst_link_failure() for an outgoing ICMP packet. |
| 214 | */ | 218 | */ |
| 215 | local_bh_enable(); | 219 | local_bh_enable(); |
| 216 | return 1; | 220 | return NULL; |
| 217 | } | 221 | } |
| 218 | return 0; | 222 | return sk; |
| 219 | } | 223 | } |
| 220 | 224 | ||
| 221 | static inline void icmp_xmit_unlock(struct sock *sk) | 225 | static inline void icmp_xmit_unlock(struct sock *sk) |
| @@ -354,15 +358,17 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) | |||
| 354 | struct ipcm_cookie ipc; | 358 | struct ipcm_cookie ipc; |
| 355 | struct rtable *rt = skb->rtable; | 359 | struct rtable *rt = skb->rtable; |
| 356 | struct net *net = dev_net(rt->u.dst.dev); | 360 | struct net *net = dev_net(rt->u.dst.dev); |
| 357 | struct sock *sk = icmp_sk(net); | 361 | struct sock *sk; |
| 358 | struct inet_sock *inet = inet_sk(sk); | 362 | struct inet_sock *inet; |
| 359 | __be32 daddr; | 363 | __be32 daddr; |
| 360 | 364 | ||
| 361 | if (ip_options_echo(&icmp_param->replyopts, skb)) | 365 | if (ip_options_echo(&icmp_param->replyopts, skb)) |
| 362 | return; | 366 | return; |
| 363 | 367 | ||
| 364 | if (icmp_xmit_lock(sk)) | 368 | sk = icmp_xmit_lock(net); |
| 369 | if (sk == NULL) | ||
| 365 | return; | 370 | return; |
| 371 | inet = inet_sk(sk); | ||
| 366 | 372 | ||
| 367 | icmp_param->data.icmph.checksum = 0; | 373 | icmp_param->data.icmph.checksum = 0; |
| 368 | 374 | ||
| @@ -419,7 +425,6 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
| 419 | if (!rt) | 425 | if (!rt) |
| 420 | goto out; | 426 | goto out; |
| 421 | net = dev_net(rt->u.dst.dev); | 427 | net = dev_net(rt->u.dst.dev); |
| 422 | sk = icmp_sk(net); | ||
| 423 | 428 | ||
| 424 | /* | 429 | /* |
| 425 | * Find the original header. It is expected to be valid, of course. | 430 | * Find the original header. It is expected to be valid, of course. |
| @@ -483,7 +488,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
| 483 | } | 488 | } |
| 484 | } | 489 | } |
| 485 | 490 | ||
| 486 | if (icmp_xmit_lock(sk)) | 491 | sk = icmp_xmit_lock(net); |
| 492 | if (sk == NULL) | ||
| 487 | return; | 493 | return; |
| 488 | 494 | ||
| 489 | /* | 495 | /* |
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c index 49587a497229..462a22c97877 100644 --- a/net/ipv4/netfilter/ipt_addrtype.c +++ b/net/ipv4/netfilter/ipt_addrtype.c | |||
| @@ -70,7 +70,7 @@ addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in, | |||
| 70 | (info->flags & IPT_ADDRTYPE_INVERT_SOURCE); | 70 | (info->flags & IPT_ADDRTYPE_INVERT_SOURCE); |
| 71 | if (ret && info->dest) | 71 | if (ret && info->dest) |
| 72 | ret &= match_type(dev, iph->daddr, info->dest) ^ | 72 | ret &= match_type(dev, iph->daddr, info->dest) ^ |
| 73 | (info->flags & IPT_ADDRTYPE_INVERT_DEST); | 73 | !!(info->flags & IPT_ADDRTYPE_INVERT_DEST); |
| 74 | return ret; | 74 | return ret; |
| 75 | } | 75 | } |
| 76 | 76 | ||
diff --git a/net/ipv4/netfilter/nf_nat_proto_common.c b/net/ipv4/netfilter/nf_nat_proto_common.c index 91537f11273f..6c4f11f51446 100644 --- a/net/ipv4/netfilter/nf_nat_proto_common.c +++ b/net/ipv4/netfilter/nf_nat_proto_common.c | |||
| @@ -73,9 +73,13 @@ bool nf_nat_proto_unique_tuple(struct nf_conntrack_tuple *tuple, | |||
| 73 | range_size = ntohs(range->max.all) - min + 1; | 73 | range_size = ntohs(range->max.all) - min + 1; |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | off = *rover; | ||
| 77 | if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) | 76 | if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) |
| 78 | off = net_random(); | 77 | off = secure_ipv4_port_ephemeral(tuple->src.u3.ip, tuple->dst.u3.ip, |
| 78 | maniptype == IP_NAT_MANIP_SRC | ||
| 79 | ? tuple->dst.u.all | ||
| 80 | : tuple->src.u.all); | ||
| 81 | else | ||
| 82 | off = *rover; | ||
| 79 | 83 | ||
| 80 | for (i = 0; i < range_size; i++, off++) { | 84 | for (i = 0; i < range_size; i++, off++) { |
| 81 | *portptr = htons(min + off % range_size); | 85 | *portptr = htons(min + off % range_size); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 16fc6f454a31..6ee5354c9aa1 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -2914,6 +2914,68 @@ static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table, | |||
| 2914 | return 0; | 2914 | return 0; |
| 2915 | } | 2915 | } |
| 2916 | 2916 | ||
| 2917 | static void rt_secret_reschedule(int old) | ||
| 2918 | { | ||
| 2919 | struct net *net; | ||
| 2920 | int new = ip_rt_secret_interval; | ||
| 2921 | int diff = new - old; | ||
| 2922 | |||
| 2923 | if (!diff) | ||
| 2924 | return; | ||
| 2925 | |||
| 2926 | rtnl_lock(); | ||
| 2927 | for_each_net(net) { | ||
| 2928 | int deleted = del_timer_sync(&net->ipv4.rt_secret_timer); | ||
| 2929 | |||
| 2930 | if (!new) | ||
| 2931 | continue; | ||
| 2932 | |||
| 2933 | if (deleted) { | ||
| 2934 | long time = net->ipv4.rt_secret_timer.expires - jiffies; | ||
| 2935 | |||
| 2936 | if (time <= 0 || (time += diff) <= 0) | ||
| 2937 | time = 0; | ||
| 2938 | |||
| 2939 | net->ipv4.rt_secret_timer.expires = time; | ||
| 2940 | } else | ||
| 2941 | net->ipv4.rt_secret_timer.expires = new; | ||
| 2942 | |||
| 2943 | net->ipv4.rt_secret_timer.expires += jiffies; | ||
| 2944 | add_timer(&net->ipv4.rt_secret_timer); | ||
| 2945 | } | ||
| 2946 | rtnl_unlock(); | ||
| 2947 | } | ||
| 2948 | |||
| 2949 | static int ipv4_sysctl_rt_secret_interval(ctl_table *ctl, int write, | ||
| 2950 | struct file *filp, | ||
| 2951 | void __user *buffer, size_t *lenp, | ||
| 2952 | loff_t *ppos) | ||
| 2953 | { | ||
| 2954 | int old = ip_rt_secret_interval; | ||
| 2955 | int ret = proc_dointvec_jiffies(ctl, write, filp, buffer, lenp, ppos); | ||
| 2956 | |||
| 2957 | rt_secret_reschedule(old); | ||
| 2958 | |||
| 2959 | return ret; | ||
| 2960 | } | ||
| 2961 | |||
| 2962 | static int ipv4_sysctl_rt_secret_interval_strategy(ctl_table *table, | ||
| 2963 | int __user *name, | ||
| 2964 | int nlen, | ||
| 2965 | void __user *oldval, | ||
| 2966 | size_t __user *oldlenp, | ||
| 2967 | void __user *newval, | ||
| 2968 | size_t newlen) | ||
| 2969 | { | ||
| 2970 | int old = ip_rt_secret_interval; | ||
| 2971 | int ret = sysctl_jiffies(table, name, nlen, oldval, oldlenp, newval, | ||
| 2972 | newlen); | ||
| 2973 | |||
| 2974 | rt_secret_reschedule(old); | ||
| 2975 | |||
| 2976 | return ret; | ||
| 2977 | } | ||
| 2978 | |||
| 2917 | static ctl_table ipv4_route_table[] = { | 2979 | static ctl_table ipv4_route_table[] = { |
| 2918 | { | 2980 | { |
| 2919 | .ctl_name = NET_IPV4_ROUTE_GC_THRESH, | 2981 | .ctl_name = NET_IPV4_ROUTE_GC_THRESH, |
| @@ -3048,20 +3110,29 @@ static ctl_table ipv4_route_table[] = { | |||
| 3048 | .data = &ip_rt_secret_interval, | 3110 | .data = &ip_rt_secret_interval, |
| 3049 | .maxlen = sizeof(int), | 3111 | .maxlen = sizeof(int), |
| 3050 | .mode = 0644, | 3112 | .mode = 0644, |
| 3051 | .proc_handler = &proc_dointvec_jiffies, | 3113 | .proc_handler = &ipv4_sysctl_rt_secret_interval, |
| 3052 | .strategy = &sysctl_jiffies, | 3114 | .strategy = &ipv4_sysctl_rt_secret_interval_strategy, |
| 3053 | }, | 3115 | }, |
| 3054 | { .ctl_name = 0 } | 3116 | { .ctl_name = 0 } |
| 3055 | }; | 3117 | }; |
| 3056 | 3118 | ||
| 3057 | static __net_initdata struct ctl_path ipv4_route_path[] = { | 3119 | static struct ctl_table empty[1]; |
| 3120 | |||
| 3121 | static struct ctl_table ipv4_skeleton[] = | ||
| 3122 | { | ||
| 3123 | { .procname = "route", .ctl_name = NET_IPV4_ROUTE, | ||
| 3124 | .mode = 0555, .child = ipv4_route_table}, | ||
| 3125 | { .procname = "neigh", .ctl_name = NET_IPV4_NEIGH, | ||
| 3126 | .mode = 0555, .child = empty}, | ||
| 3127 | { } | ||
| 3128 | }; | ||
| 3129 | |||
| 3130 | static __net_initdata struct ctl_path ipv4_path[] = { | ||
| 3058 | { .procname = "net", .ctl_name = CTL_NET, }, | 3131 | { .procname = "net", .ctl_name = CTL_NET, }, |
| 3059 | { .procname = "ipv4", .ctl_name = NET_IPV4, }, | 3132 | { .procname = "ipv4", .ctl_name = NET_IPV4, }, |
| 3060 | { .procname = "route", .ctl_name = NET_IPV4_ROUTE, }, | ||
| 3061 | { }, | 3133 | { }, |
| 3062 | }; | 3134 | }; |
| 3063 | 3135 | ||
| 3064 | |||
| 3065 | static struct ctl_table ipv4_route_flush_table[] = { | 3136 | static struct ctl_table ipv4_route_flush_table[] = { |
| 3066 | { | 3137 | { |
| 3067 | .ctl_name = NET_IPV4_ROUTE_FLUSH, | 3138 | .ctl_name = NET_IPV4_ROUTE_FLUSH, |
| @@ -3074,6 +3145,13 @@ static struct ctl_table ipv4_route_flush_table[] = { | |||
| 3074 | { .ctl_name = 0 }, | 3145 | { .ctl_name = 0 }, |
| 3075 | }; | 3146 | }; |
| 3076 | 3147 | ||
| 3148 | static __net_initdata struct ctl_path ipv4_route_path[] = { | ||
| 3149 | { .procname = "net", .ctl_name = CTL_NET, }, | ||
| 3150 | { .procname = "ipv4", .ctl_name = NET_IPV4, }, | ||
| 3151 | { .procname = "route", .ctl_name = NET_IPV4_ROUTE, }, | ||
| 3152 | { }, | ||
| 3153 | }; | ||
| 3154 | |||
| 3077 | static __net_init int sysctl_route_net_init(struct net *net) | 3155 | static __net_init int sysctl_route_net_init(struct net *net) |
| 3078 | { | 3156 | { |
| 3079 | struct ctl_table *tbl; | 3157 | struct ctl_table *tbl; |
| @@ -3126,10 +3204,12 @@ static __net_init int rt_secret_timer_init(struct net *net) | |||
| 3126 | net->ipv4.rt_secret_timer.data = (unsigned long)net; | 3204 | net->ipv4.rt_secret_timer.data = (unsigned long)net; |
| 3127 | init_timer_deferrable(&net->ipv4.rt_secret_timer); | 3205 | init_timer_deferrable(&net->ipv4.rt_secret_timer); |
| 3128 | 3206 | ||
| 3129 | net->ipv4.rt_secret_timer.expires = | 3207 | if (ip_rt_secret_interval) { |
| 3130 | jiffies + net_random() % ip_rt_secret_interval + | 3208 | net->ipv4.rt_secret_timer.expires = |
| 3131 | ip_rt_secret_interval; | 3209 | jiffies + net_random() % ip_rt_secret_interval + |
| 3132 | add_timer(&net->ipv4.rt_secret_timer); | 3210 | ip_rt_secret_interval; |
| 3211 | add_timer(&net->ipv4.rt_secret_timer); | ||
| 3212 | } | ||
| 3133 | return 0; | 3213 | return 0; |
| 3134 | } | 3214 | } |
| 3135 | 3215 | ||
| @@ -3223,7 +3303,7 @@ int __init ip_rt_init(void) | |||
| 3223 | */ | 3303 | */ |
| 3224 | void __init ip_static_sysctl_init(void) | 3304 | void __init ip_static_sysctl_init(void) |
| 3225 | { | 3305 | { |
| 3226 | register_sysctl_paths(ipv4_route_path, ipv4_route_table); | 3306 | register_sysctl_paths(ipv4_path, ipv4_skeleton); |
| 3227 | } | 3307 | } |
| 3228 | #endif | 3308 | #endif |
| 3229 | 3309 | ||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index a00532de2a8c..8165f5aa8c71 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -468,7 +468,8 @@ static unsigned tcp_syn_options(struct sock *sk, struct sk_buff *skb, | |||
| 468 | } | 468 | } |
| 469 | if (likely(sysctl_tcp_window_scaling)) { | 469 | if (likely(sysctl_tcp_window_scaling)) { |
| 470 | opts->ws = tp->rx_opt.rcv_wscale; | 470 | opts->ws = tp->rx_opt.rcv_wscale; |
| 471 | size += TCPOLEN_WSCALE_ALIGNED; | 471 | if(likely(opts->ws)) |
| 472 | size += TCPOLEN_WSCALE_ALIGNED; | ||
| 472 | } | 473 | } |
| 473 | if (likely(sysctl_tcp_sack)) { | 474 | if (likely(sysctl_tcp_sack)) { |
| 474 | opts->options |= OPTION_SACK_ADVERTISE; | 475 | opts->options |= OPTION_SACK_ADVERTISE; |
| @@ -509,7 +510,8 @@ static unsigned tcp_synack_options(struct sock *sk, | |||
| 509 | 510 | ||
| 510 | if (likely(ireq->wscale_ok)) { | 511 | if (likely(ireq->wscale_ok)) { |
| 511 | opts->ws = ireq->rcv_wscale; | 512 | opts->ws = ireq->rcv_wscale; |
| 512 | size += TCPOLEN_WSCALE_ALIGNED; | 513 | if(likely(opts->ws)) |
| 514 | size += TCPOLEN_WSCALE_ALIGNED; | ||
| 513 | } | 515 | } |
| 514 | if (likely(doing_ts)) { | 516 | if (likely(doing_ts)) { |
| 515 | opts->options |= OPTION_TS; | 517 | opts->options |= OPTION_TS; |
