diff options
Diffstat (limited to 'net/ipv6')
41 files changed, 857 insertions, 629 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d9da5eb9dcb2..e92ad8455c63 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -2031,8 +2031,8 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg) | |||
2031 | 2031 | ||
2032 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | 2032 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) |
2033 | if (dev->type == ARPHRD_SIT) { | 2033 | if (dev->type == ARPHRD_SIT) { |
2034 | const struct net_device_ops *ops = dev->netdev_ops; | ||
2034 | struct ifreq ifr; | 2035 | struct ifreq ifr; |
2035 | mm_segment_t oldfs; | ||
2036 | struct ip_tunnel_parm p; | 2036 | struct ip_tunnel_parm p; |
2037 | 2037 | ||
2038 | err = -EADDRNOTAVAIL; | 2038 | err = -EADDRNOTAVAIL; |
@@ -2048,9 +2048,14 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg) | |||
2048 | p.iph.ttl = 64; | 2048 | p.iph.ttl = 64; |
2049 | ifr.ifr_ifru.ifru_data = (__force void __user *)&p; | 2049 | ifr.ifr_ifru.ifru_data = (__force void __user *)&p; |
2050 | 2050 | ||
2051 | oldfs = get_fs(); set_fs(KERNEL_DS); | 2051 | if (ops->ndo_do_ioctl) { |
2052 | err = dev->do_ioctl(dev, &ifr, SIOCADDTUNNEL); | 2052 | mm_segment_t oldfs = get_fs(); |
2053 | set_fs(oldfs); | 2053 | |
2054 | set_fs(KERNEL_DS); | ||
2055 | err = ops->ndo_do_ioctl(dev, &ifr, SIOCADDTUNNEL); | ||
2056 | set_fs(oldfs); | ||
2057 | } else | ||
2058 | err = -EOPNOTSUPP; | ||
2054 | 2059 | ||
2055 | if (err == 0) { | 2060 | if (err == 0) { |
2056 | err = -ENOBUFS; | 2061 | err = -ENOBUFS; |
@@ -2988,9 +2993,8 @@ static void if6_seq_stop(struct seq_file *seq, void *v) | |||
2988 | static int if6_seq_show(struct seq_file *seq, void *v) | 2993 | static int if6_seq_show(struct seq_file *seq, void *v) |
2989 | { | 2994 | { |
2990 | struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v; | 2995 | struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v; |
2991 | seq_printf(seq, | 2996 | seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n", |
2992 | NIP6_SEQFMT " %02x %02x %02x %02x %8s\n", | 2997 | &ifp->addr, |
2993 | NIP6(ifp->addr), | ||
2994 | ifp->idev->dev->ifindex, | 2998 | ifp->idev->dev->ifindex, |
2995 | ifp->prefix_len, | 2999 | ifp->prefix_len, |
2996 | ifp->scope, | 3000 | ifp->scope, |
@@ -4033,8 +4037,8 @@ static struct addrconf_sysctl_table | |||
4033 | .data = &ipv6_devconf.forwarding, | 4037 | .data = &ipv6_devconf.forwarding, |
4034 | .maxlen = sizeof(int), | 4038 | .maxlen = sizeof(int), |
4035 | .mode = 0644, | 4039 | .mode = 0644, |
4036 | .proc_handler = &addrconf_sysctl_forward, | 4040 | .proc_handler = addrconf_sysctl_forward, |
4037 | .strategy = &addrconf_sysctl_forward_strategy, | 4041 | .strategy = addrconf_sysctl_forward_strategy, |
4038 | }, | 4042 | }, |
4039 | { | 4043 | { |
4040 | .ctl_name = NET_IPV6_HOP_LIMIT, | 4044 | .ctl_name = NET_IPV6_HOP_LIMIT, |
@@ -4050,7 +4054,7 @@ static struct addrconf_sysctl_table | |||
4050 | .data = &ipv6_devconf.mtu6, | 4054 | .data = &ipv6_devconf.mtu6, |
4051 | .maxlen = sizeof(int), | 4055 | .maxlen = sizeof(int), |
4052 | .mode = 0644, | 4056 | .mode = 0644, |
4053 | .proc_handler = &proc_dointvec, | 4057 | .proc_handler = proc_dointvec, |
4054 | }, | 4058 | }, |
4055 | { | 4059 | { |
4056 | .ctl_name = NET_IPV6_ACCEPT_RA, | 4060 | .ctl_name = NET_IPV6_ACCEPT_RA, |
@@ -4058,7 +4062,7 @@ static struct addrconf_sysctl_table | |||
4058 | .data = &ipv6_devconf.accept_ra, | 4062 | .data = &ipv6_devconf.accept_ra, |
4059 | .maxlen = sizeof(int), | 4063 | .maxlen = sizeof(int), |
4060 | .mode = 0644, | 4064 | .mode = 0644, |
4061 | .proc_handler = &proc_dointvec, | 4065 | .proc_handler = proc_dointvec, |
4062 | }, | 4066 | }, |
4063 | { | 4067 | { |
4064 | .ctl_name = NET_IPV6_ACCEPT_REDIRECTS, | 4068 | .ctl_name = NET_IPV6_ACCEPT_REDIRECTS, |
@@ -4066,7 +4070,7 @@ static struct addrconf_sysctl_table | |||
4066 | .data = &ipv6_devconf.accept_redirects, | 4070 | .data = &ipv6_devconf.accept_redirects, |
4067 | .maxlen = sizeof(int), | 4071 | .maxlen = sizeof(int), |
4068 | .mode = 0644, | 4072 | .mode = 0644, |
4069 | .proc_handler = &proc_dointvec, | 4073 | .proc_handler = proc_dointvec, |
4070 | }, | 4074 | }, |
4071 | { | 4075 | { |
4072 | .ctl_name = NET_IPV6_AUTOCONF, | 4076 | .ctl_name = NET_IPV6_AUTOCONF, |
@@ -4074,7 +4078,7 @@ static struct addrconf_sysctl_table | |||
4074 | .data = &ipv6_devconf.autoconf, | 4078 | .data = &ipv6_devconf.autoconf, |
4075 | .maxlen = sizeof(int), | 4079 | .maxlen = sizeof(int), |
4076 | .mode = 0644, | 4080 | .mode = 0644, |
4077 | .proc_handler = &proc_dointvec, | 4081 | .proc_handler = proc_dointvec, |
4078 | }, | 4082 | }, |
4079 | { | 4083 | { |
4080 | .ctl_name = NET_IPV6_DAD_TRANSMITS, | 4084 | .ctl_name = NET_IPV6_DAD_TRANSMITS, |
@@ -4082,7 +4086,7 @@ static struct addrconf_sysctl_table | |||
4082 | .data = &ipv6_devconf.dad_transmits, | 4086 | .data = &ipv6_devconf.dad_transmits, |
4083 | .maxlen = sizeof(int), | 4087 | .maxlen = sizeof(int), |
4084 | .mode = 0644, | 4088 | .mode = 0644, |
4085 | .proc_handler = &proc_dointvec, | 4089 | .proc_handler = proc_dointvec, |
4086 | }, | 4090 | }, |
4087 | { | 4091 | { |
4088 | .ctl_name = NET_IPV6_RTR_SOLICITS, | 4092 | .ctl_name = NET_IPV6_RTR_SOLICITS, |
@@ -4090,7 +4094,7 @@ static struct addrconf_sysctl_table | |||
4090 | .data = &ipv6_devconf.rtr_solicits, | 4094 | .data = &ipv6_devconf.rtr_solicits, |
4091 | .maxlen = sizeof(int), | 4095 | .maxlen = sizeof(int), |
4092 | .mode = 0644, | 4096 | .mode = 0644, |
4093 | .proc_handler = &proc_dointvec, | 4097 | .proc_handler = proc_dointvec, |
4094 | }, | 4098 | }, |
4095 | { | 4099 | { |
4096 | .ctl_name = NET_IPV6_RTR_SOLICIT_INTERVAL, | 4100 | .ctl_name = NET_IPV6_RTR_SOLICIT_INTERVAL, |
@@ -4098,8 +4102,8 @@ static struct addrconf_sysctl_table | |||
4098 | .data = &ipv6_devconf.rtr_solicit_interval, | 4102 | .data = &ipv6_devconf.rtr_solicit_interval, |
4099 | .maxlen = sizeof(int), | 4103 | .maxlen = sizeof(int), |
4100 | .mode = 0644, | 4104 | .mode = 0644, |
4101 | .proc_handler = &proc_dointvec_jiffies, | 4105 | .proc_handler = proc_dointvec_jiffies, |
4102 | .strategy = &sysctl_jiffies, | 4106 | .strategy = sysctl_jiffies, |
4103 | }, | 4107 | }, |
4104 | { | 4108 | { |
4105 | .ctl_name = NET_IPV6_RTR_SOLICIT_DELAY, | 4109 | .ctl_name = NET_IPV6_RTR_SOLICIT_DELAY, |
@@ -4107,8 +4111,8 @@ static struct addrconf_sysctl_table | |||
4107 | .data = &ipv6_devconf.rtr_solicit_delay, | 4111 | .data = &ipv6_devconf.rtr_solicit_delay, |
4108 | .maxlen = sizeof(int), | 4112 | .maxlen = sizeof(int), |
4109 | .mode = 0644, | 4113 | .mode = 0644, |
4110 | .proc_handler = &proc_dointvec_jiffies, | 4114 | .proc_handler = proc_dointvec_jiffies, |
4111 | .strategy = &sysctl_jiffies, | 4115 | .strategy = sysctl_jiffies, |
4112 | }, | 4116 | }, |
4113 | { | 4117 | { |
4114 | .ctl_name = NET_IPV6_FORCE_MLD_VERSION, | 4118 | .ctl_name = NET_IPV6_FORCE_MLD_VERSION, |
@@ -4116,7 +4120,7 @@ static struct addrconf_sysctl_table | |||
4116 | .data = &ipv6_devconf.force_mld_version, | 4120 | .data = &ipv6_devconf.force_mld_version, |
4117 | .maxlen = sizeof(int), | 4121 | .maxlen = sizeof(int), |
4118 | .mode = 0644, | 4122 | .mode = 0644, |
4119 | .proc_handler = &proc_dointvec, | 4123 | .proc_handler = proc_dointvec, |
4120 | }, | 4124 | }, |
4121 | #ifdef CONFIG_IPV6_PRIVACY | 4125 | #ifdef CONFIG_IPV6_PRIVACY |
4122 | { | 4126 | { |
@@ -4125,7 +4129,7 @@ static struct addrconf_sysctl_table | |||
4125 | .data = &ipv6_devconf.use_tempaddr, | 4129 | .data = &ipv6_devconf.use_tempaddr, |
4126 | .maxlen = sizeof(int), | 4130 | .maxlen = sizeof(int), |
4127 | .mode = 0644, | 4131 | .mode = 0644, |
4128 | .proc_handler = &proc_dointvec, | 4132 | .proc_handler = proc_dointvec, |
4129 | }, | 4133 | }, |
4130 | { | 4134 | { |
4131 | .ctl_name = NET_IPV6_TEMP_VALID_LFT, | 4135 | .ctl_name = NET_IPV6_TEMP_VALID_LFT, |
@@ -4133,7 +4137,7 @@ static struct addrconf_sysctl_table | |||
4133 | .data = &ipv6_devconf.temp_valid_lft, | 4137 | .data = &ipv6_devconf.temp_valid_lft, |
4134 | .maxlen = sizeof(int), | 4138 | .maxlen = sizeof(int), |
4135 | .mode = 0644, | 4139 | .mode = 0644, |
4136 | .proc_handler = &proc_dointvec, | 4140 | .proc_handler = proc_dointvec, |
4137 | }, | 4141 | }, |
4138 | { | 4142 | { |
4139 | .ctl_name = NET_IPV6_TEMP_PREFERED_LFT, | 4143 | .ctl_name = NET_IPV6_TEMP_PREFERED_LFT, |
@@ -4141,7 +4145,7 @@ static struct addrconf_sysctl_table | |||
4141 | .data = &ipv6_devconf.temp_prefered_lft, | 4145 | .data = &ipv6_devconf.temp_prefered_lft, |
4142 | .maxlen = sizeof(int), | 4146 | .maxlen = sizeof(int), |
4143 | .mode = 0644, | 4147 | .mode = 0644, |
4144 | .proc_handler = &proc_dointvec, | 4148 | .proc_handler = proc_dointvec, |
4145 | }, | 4149 | }, |
4146 | { | 4150 | { |
4147 | .ctl_name = NET_IPV6_REGEN_MAX_RETRY, | 4151 | .ctl_name = NET_IPV6_REGEN_MAX_RETRY, |
@@ -4149,7 +4153,7 @@ static struct addrconf_sysctl_table | |||
4149 | .data = &ipv6_devconf.regen_max_retry, | 4153 | .data = &ipv6_devconf.regen_max_retry, |
4150 | .maxlen = sizeof(int), | 4154 | .maxlen = sizeof(int), |
4151 | .mode = 0644, | 4155 | .mode = 0644, |
4152 | .proc_handler = &proc_dointvec, | 4156 | .proc_handler = proc_dointvec, |
4153 | }, | 4157 | }, |
4154 | { | 4158 | { |
4155 | .ctl_name = NET_IPV6_MAX_DESYNC_FACTOR, | 4159 | .ctl_name = NET_IPV6_MAX_DESYNC_FACTOR, |
@@ -4157,7 +4161,7 @@ static struct addrconf_sysctl_table | |||
4157 | .data = &ipv6_devconf.max_desync_factor, | 4161 | .data = &ipv6_devconf.max_desync_factor, |
4158 | .maxlen = sizeof(int), | 4162 | .maxlen = sizeof(int), |
4159 | .mode = 0644, | 4163 | .mode = 0644, |
4160 | .proc_handler = &proc_dointvec, | 4164 | .proc_handler = proc_dointvec, |
4161 | }, | 4165 | }, |
4162 | #endif | 4166 | #endif |
4163 | { | 4167 | { |
@@ -4166,7 +4170,7 @@ static struct addrconf_sysctl_table | |||
4166 | .data = &ipv6_devconf.max_addresses, | 4170 | .data = &ipv6_devconf.max_addresses, |
4167 | .maxlen = sizeof(int), | 4171 | .maxlen = sizeof(int), |
4168 | .mode = 0644, | 4172 | .mode = 0644, |
4169 | .proc_handler = &proc_dointvec, | 4173 | .proc_handler = proc_dointvec, |
4170 | }, | 4174 | }, |
4171 | { | 4175 | { |
4172 | .ctl_name = NET_IPV6_ACCEPT_RA_DEFRTR, | 4176 | .ctl_name = NET_IPV6_ACCEPT_RA_DEFRTR, |
@@ -4174,7 +4178,7 @@ static struct addrconf_sysctl_table | |||
4174 | .data = &ipv6_devconf.accept_ra_defrtr, | 4178 | .data = &ipv6_devconf.accept_ra_defrtr, |
4175 | .maxlen = sizeof(int), | 4179 | .maxlen = sizeof(int), |
4176 | .mode = 0644, | 4180 | .mode = 0644, |
4177 | .proc_handler = &proc_dointvec, | 4181 | .proc_handler = proc_dointvec, |
4178 | }, | 4182 | }, |
4179 | { | 4183 | { |
4180 | .ctl_name = NET_IPV6_ACCEPT_RA_PINFO, | 4184 | .ctl_name = NET_IPV6_ACCEPT_RA_PINFO, |
@@ -4182,7 +4186,7 @@ static struct addrconf_sysctl_table | |||
4182 | .data = &ipv6_devconf.accept_ra_pinfo, | 4186 | .data = &ipv6_devconf.accept_ra_pinfo, |
4183 | .maxlen = sizeof(int), | 4187 | .maxlen = sizeof(int), |
4184 | .mode = 0644, | 4188 | .mode = 0644, |
4185 | .proc_handler = &proc_dointvec, | 4189 | .proc_handler = proc_dointvec, |
4186 | }, | 4190 | }, |
4187 | #ifdef CONFIG_IPV6_ROUTER_PREF | 4191 | #ifdef CONFIG_IPV6_ROUTER_PREF |
4188 | { | 4192 | { |
@@ -4191,7 +4195,7 @@ static struct addrconf_sysctl_table | |||
4191 | .data = &ipv6_devconf.accept_ra_rtr_pref, | 4195 | .data = &ipv6_devconf.accept_ra_rtr_pref, |
4192 | .maxlen = sizeof(int), | 4196 | .maxlen = sizeof(int), |
4193 | .mode = 0644, | 4197 | .mode = 0644, |
4194 | .proc_handler = &proc_dointvec, | 4198 | .proc_handler = proc_dointvec, |
4195 | }, | 4199 | }, |
4196 | { | 4200 | { |
4197 | .ctl_name = NET_IPV6_RTR_PROBE_INTERVAL, | 4201 | .ctl_name = NET_IPV6_RTR_PROBE_INTERVAL, |
@@ -4199,8 +4203,8 @@ static struct addrconf_sysctl_table | |||
4199 | .data = &ipv6_devconf.rtr_probe_interval, | 4203 | .data = &ipv6_devconf.rtr_probe_interval, |
4200 | .maxlen = sizeof(int), | 4204 | .maxlen = sizeof(int), |
4201 | .mode = 0644, | 4205 | .mode = 0644, |
4202 | .proc_handler = &proc_dointvec_jiffies, | 4206 | .proc_handler = proc_dointvec_jiffies, |
4203 | .strategy = &sysctl_jiffies, | 4207 | .strategy = sysctl_jiffies, |
4204 | }, | 4208 | }, |
4205 | #ifdef CONFIG_IPV6_ROUTE_INFO | 4209 | #ifdef CONFIG_IPV6_ROUTE_INFO |
4206 | { | 4210 | { |
@@ -4209,7 +4213,7 @@ static struct addrconf_sysctl_table | |||
4209 | .data = &ipv6_devconf.accept_ra_rt_info_max_plen, | 4213 | .data = &ipv6_devconf.accept_ra_rt_info_max_plen, |
4210 | .maxlen = sizeof(int), | 4214 | .maxlen = sizeof(int), |
4211 | .mode = 0644, | 4215 | .mode = 0644, |
4212 | .proc_handler = &proc_dointvec, | 4216 | .proc_handler = proc_dointvec, |
4213 | }, | 4217 | }, |
4214 | #endif | 4218 | #endif |
4215 | #endif | 4219 | #endif |
@@ -4219,7 +4223,7 @@ static struct addrconf_sysctl_table | |||
4219 | .data = &ipv6_devconf.proxy_ndp, | 4223 | .data = &ipv6_devconf.proxy_ndp, |
4220 | .maxlen = sizeof(int), | 4224 | .maxlen = sizeof(int), |
4221 | .mode = 0644, | 4225 | .mode = 0644, |
4222 | .proc_handler = &proc_dointvec, | 4226 | .proc_handler = proc_dointvec, |
4223 | }, | 4227 | }, |
4224 | { | 4228 | { |
4225 | .ctl_name = NET_IPV6_ACCEPT_SOURCE_ROUTE, | 4229 | .ctl_name = NET_IPV6_ACCEPT_SOURCE_ROUTE, |
@@ -4227,7 +4231,7 @@ static struct addrconf_sysctl_table | |||
4227 | .data = &ipv6_devconf.accept_source_route, | 4231 | .data = &ipv6_devconf.accept_source_route, |
4228 | .maxlen = sizeof(int), | 4232 | .maxlen = sizeof(int), |
4229 | .mode = 0644, | 4233 | .mode = 0644, |
4230 | .proc_handler = &proc_dointvec, | 4234 | .proc_handler = proc_dointvec, |
4231 | }, | 4235 | }, |
4232 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD | 4236 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD |
4233 | { | 4237 | { |
@@ -4236,7 +4240,7 @@ static struct addrconf_sysctl_table | |||
4236 | .data = &ipv6_devconf.optimistic_dad, | 4240 | .data = &ipv6_devconf.optimistic_dad, |
4237 | .maxlen = sizeof(int), | 4241 | .maxlen = sizeof(int), |
4238 | .mode = 0644, | 4242 | .mode = 0644, |
4239 | .proc_handler = &proc_dointvec, | 4243 | .proc_handler = proc_dointvec, |
4240 | 4244 | ||
4241 | }, | 4245 | }, |
4242 | #endif | 4246 | #endif |
@@ -4247,7 +4251,7 @@ static struct addrconf_sysctl_table | |||
4247 | .data = &ipv6_devconf.mc_forwarding, | 4251 | .data = &ipv6_devconf.mc_forwarding, |
4248 | .maxlen = sizeof(int), | 4252 | .maxlen = sizeof(int), |
4249 | .mode = 0644, | 4253 | .mode = 0644, |
4250 | .proc_handler = &proc_dointvec, | 4254 | .proc_handler = proc_dointvec, |
4251 | }, | 4255 | }, |
4252 | #endif | 4256 | #endif |
4253 | { | 4257 | { |
@@ -4256,7 +4260,7 @@ static struct addrconf_sysctl_table | |||
4256 | .data = &ipv6_devconf.disable_ipv6, | 4260 | .data = &ipv6_devconf.disable_ipv6, |
4257 | .maxlen = sizeof(int), | 4261 | .maxlen = sizeof(int), |
4258 | .mode = 0644, | 4262 | .mode = 0644, |
4259 | .proc_handler = &proc_dointvec, | 4263 | .proc_handler = proc_dointvec, |
4260 | }, | 4264 | }, |
4261 | { | 4265 | { |
4262 | .ctl_name = CTL_UNNUMBERED, | 4266 | .ctl_name = CTL_UNNUMBERED, |
@@ -4264,7 +4268,7 @@ static struct addrconf_sysctl_table | |||
4264 | .data = &ipv6_devconf.accept_dad, | 4268 | .data = &ipv6_devconf.accept_dad, |
4265 | .maxlen = sizeof(int), | 4269 | .maxlen = sizeof(int), |
4266 | .mode = 0644, | 4270 | .mode = 0644, |
4267 | .proc_handler = &proc_dointvec, | 4271 | .proc_handler = proc_dointvec, |
4268 | }, | 4272 | }, |
4269 | { | 4273 | { |
4270 | .ctl_name = 0, /* sentinel */ | 4274 | .ctl_name = 0, /* sentinel */ |
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c index 08909039d87b..6ff73c4c126a 100644 --- a/net/ipv6/addrlabel.c +++ b/net/ipv6/addrlabel.c | |||
@@ -186,10 +186,8 @@ u32 ipv6_addr_label(struct net *net, | |||
186 | label = p ? p->label : IPV6_ADDR_LABEL_DEFAULT; | 186 | label = p ? p->label : IPV6_ADDR_LABEL_DEFAULT; |
187 | rcu_read_unlock(); | 187 | rcu_read_unlock(); |
188 | 188 | ||
189 | ADDRLABEL(KERN_DEBUG "%s(addr=" NIP6_FMT ", type=%d, ifindex=%d) => %08x\n", | 189 | ADDRLABEL(KERN_DEBUG "%s(addr=%pI6, type=%d, ifindex=%d) => %08x\n", |
190 | __func__, | 190 | __func__, addr, type, ifindex, label); |
191 | NIP6(*addr), type, ifindex, | ||
192 | label); | ||
193 | 191 | ||
194 | return label; | 192 | return label; |
195 | } | 193 | } |
@@ -203,11 +201,8 @@ static struct ip6addrlbl_entry *ip6addrlbl_alloc(struct net *net, | |||
203 | struct ip6addrlbl_entry *newp; | 201 | struct ip6addrlbl_entry *newp; |
204 | int addrtype; | 202 | int addrtype; |
205 | 203 | ||
206 | ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d, label=%u)\n", | 204 | ADDRLABEL(KERN_DEBUG "%s(prefix=%pI6, prefixlen=%d, ifindex=%d, label=%u)\n", |
207 | __func__, | 205 | __func__, prefix, prefixlen, ifindex, (unsigned int)label); |
208 | NIP6(*prefix), prefixlen, | ||
209 | ifindex, | ||
210 | (unsigned int)label); | ||
211 | 206 | ||
212 | addrtype = ipv6_addr_type(prefix) & (IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK); | 207 | addrtype = ipv6_addr_type(prefix) & (IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK); |
213 | 208 | ||
@@ -294,12 +289,9 @@ static int ip6addrlbl_add(struct net *net, | |||
294 | struct ip6addrlbl_entry *newp; | 289 | struct ip6addrlbl_entry *newp; |
295 | int ret = 0; | 290 | int ret = 0; |
296 | 291 | ||
297 | ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d, label=%u, replace=%d)\n", | 292 | ADDRLABEL(KERN_DEBUG "%s(prefix=%pI6, prefixlen=%d, ifindex=%d, label=%u, replace=%d)\n", |
298 | __func__, | 293 | __func__, prefix, prefixlen, ifindex, (unsigned int)label, |
299 | NIP6(*prefix), prefixlen, | 294 | replace); |
300 | ifindex, | ||
301 | (unsigned int)label, | ||
302 | replace); | ||
303 | 295 | ||
304 | newp = ip6addrlbl_alloc(net, prefix, prefixlen, ifindex, label); | 296 | newp = ip6addrlbl_alloc(net, prefix, prefixlen, ifindex, label); |
305 | if (IS_ERR(newp)) | 297 | if (IS_ERR(newp)) |
@@ -321,10 +313,8 @@ static int __ip6addrlbl_del(struct net *net, | |||
321 | struct hlist_node *pos, *n; | 313 | struct hlist_node *pos, *n; |
322 | int ret = -ESRCH; | 314 | int ret = -ESRCH; |
323 | 315 | ||
324 | ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d)\n", | 316 | ADDRLABEL(KERN_DEBUG "%s(prefix=%pI6, prefixlen=%d, ifindex=%d)\n", |
325 | __func__, | 317 | __func__, prefix, prefixlen, ifindex); |
326 | NIP6(*prefix), prefixlen, | ||
327 | ifindex); | ||
328 | 318 | ||
329 | hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) { | 319 | hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) { |
330 | if (p->prefixlen == prefixlen && | 320 | if (p->prefixlen == prefixlen && |
@@ -347,10 +337,8 @@ static int ip6addrlbl_del(struct net *net, | |||
347 | struct in6_addr prefix_buf; | 337 | struct in6_addr prefix_buf; |
348 | int ret; | 338 | int ret; |
349 | 339 | ||
350 | ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d)\n", | 340 | ADDRLABEL(KERN_DEBUG "%s(prefix=%pI6, prefixlen=%d, ifindex=%d)\n", |
351 | __func__, | 341 | __func__, prefix, prefixlen, ifindex); |
352 | NIP6(*prefix), prefixlen, | ||
353 | ifindex); | ||
354 | 342 | ||
355 | ipv6_addr_prefix(&prefix_buf, prefix, prefixlen); | 343 | ipv6_addr_prefix(&prefix_buf, prefix, prefixlen); |
356 | spin_lock(&ip6addrlbl_table.lock); | 344 | spin_lock(&ip6addrlbl_table.lock); |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 01edac888510..437b750b98fd 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -637,7 +637,7 @@ int inet6_sk_rebuild_header(struct sock *sk) | |||
637 | if (final_p) | 637 | if (final_p) |
638 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 638 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
639 | 639 | ||
640 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | 640 | if ((err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0) { |
641 | sk->sk_err_soft = -err; | 641 | sk->sk_err_soft = -err; |
642 | return err; | 642 | return err; |
643 | } | 643 | } |
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index 2ff0c8233e47..52449f7a1b71 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c | |||
@@ -407,6 +407,7 @@ out: | |||
407 | static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | 407 | static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
408 | int type, int code, int offset, __be32 info) | 408 | int type, int code, int offset, __be32 info) |
409 | { | 409 | { |
410 | struct net *net = dev_net(skb->dev); | ||
410 | struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; | 411 | struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; |
411 | struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+offset); | 412 | struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+offset); |
412 | struct xfrm_state *x; | 413 | struct xfrm_state *x; |
@@ -415,12 +416,12 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
415 | type != ICMPV6_PKT_TOOBIG) | 416 | type != ICMPV6_PKT_TOOBIG) |
416 | return; | 417 | return; |
417 | 418 | ||
418 | x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6); | 419 | x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6); |
419 | if (!x) | 420 | if (!x) |
420 | return; | 421 | return; |
421 | 422 | ||
422 | NETDEBUG(KERN_DEBUG "pmtu discovery on SA AH/%08x/" NIP6_FMT "\n", | 423 | NETDEBUG(KERN_DEBUG "pmtu discovery on SA AH/%08x/%pI6\n", |
423 | ntohl(ah->spi), NIP6(iph->daddr)); | 424 | ntohl(ah->spi), &iph->daddr); |
424 | 425 | ||
425 | xfrm_state_put(x); | 426 | xfrm_state_put(x); |
426 | } | 427 | } |
@@ -509,9 +510,7 @@ static void ah6_destroy(struct xfrm_state *x) | |||
509 | return; | 510 | return; |
510 | 511 | ||
511 | kfree(ahp->work_icv); | 512 | kfree(ahp->work_icv); |
512 | ahp->work_icv = NULL; | ||
513 | crypto_free_hash(ahp->tfm); | 513 | crypto_free_hash(ahp->tfm); |
514 | ahp->tfm = NULL; | ||
515 | kfree(ahp); | 514 | kfree(ahp); |
516 | } | 515 | } |
517 | 516 | ||
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index 8336cd81cb4f..1ae58bec1de0 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c | |||
@@ -512,11 +512,9 @@ static int ac6_seq_show(struct seq_file *seq, void *v) | |||
512 | struct ifacaddr6 *im = (struct ifacaddr6 *)v; | 512 | struct ifacaddr6 *im = (struct ifacaddr6 *)v; |
513 | struct ac6_iter_state *state = ac6_seq_private(seq); | 513 | struct ac6_iter_state *state = ac6_seq_private(seq); |
514 | 514 | ||
515 | seq_printf(seq, | 515 | seq_printf(seq, "%-4d %-15s %pi6 %5d\n", |
516 | "%-4d %-15s " NIP6_SEQFMT " %5d\n", | ||
517 | state->dev->ifindex, state->dev->name, | 516 | state->dev->ifindex, state->dev->name, |
518 | NIP6(im->aca_addr), | 517 | &im->aca_addr, im->aca_users); |
519 | im->aca_users); | ||
520 | return 0; | 518 | return 0; |
521 | } | 519 | } |
522 | 520 | ||
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index e44deb8d4df2..e2bdc6d83a43 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -175,7 +175,8 @@ ipv4_connected: | |||
175 | if (final_p) | 175 | if (final_p) |
176 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 176 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
177 | 177 | ||
178 | if ((err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT)) < 0) { | 178 | err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT); |
179 | if (err < 0) { | ||
179 | if (err == -EREMOTE) | 180 | if (err == -EREMOTE) |
180 | err = ip6_dst_blackhole(sk, &dst, &fl); | 181 | err = ip6_dst_blackhole(sk, &dst, &fl); |
181 | if (err < 0) | 182 | if (err < 0) |
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index b181b08fb761..c2f250150db1 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -356,6 +356,7 @@ static u32 esp6_get_mtu(struct xfrm_state *x, int mtu) | |||
356 | static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | 356 | static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
357 | int type, int code, int offset, __be32 info) | 357 | int type, int code, int offset, __be32 info) |
358 | { | 358 | { |
359 | struct net *net = dev_net(skb->dev); | ||
359 | struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; | 360 | struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; |
360 | struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data + offset); | 361 | struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data + offset); |
361 | struct xfrm_state *x; | 362 | struct xfrm_state *x; |
@@ -364,11 +365,11 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
364 | type != ICMPV6_PKT_TOOBIG) | 365 | type != ICMPV6_PKT_TOOBIG) |
365 | return; | 366 | return; |
366 | 367 | ||
367 | x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6); | 368 | x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6); |
368 | if (!x) | 369 | if (!x) |
369 | return; | 370 | return; |
370 | printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/" NIP6_FMT "\n", | 371 | printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%pI6\n", |
371 | ntohl(esph->spi), NIP6(iph->daddr)); | 372 | ntohl(esph->spi), &iph->daddr); |
372 | xfrm_state_put(x); | 373 | xfrm_state_put(x); |
373 | } | 374 | } |
374 | 375 | ||
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 6bfffec2371c..1c7f400a3cfe 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -219,7 +219,7 @@ static int ipv6_dest_hao(struct sk_buff *skb, int optoff) | |||
219 | 219 | ||
220 | if (!(ipv6_addr_type(&hao->addr) & IPV6_ADDR_UNICAST)) { | 220 | if (!(ipv6_addr_type(&hao->addr) & IPV6_ADDR_UNICAST)) { |
221 | LIMIT_NETDEBUG( | 221 | LIMIT_NETDEBUG( |
222 | KERN_DEBUG "hao is not an unicast addr: " NIP6_FMT "\n", NIP6(hao->addr)); | 222 | KERN_DEBUG "hao is not an unicast addr: %pI6\n", &hao->addr); |
223 | goto discard; | 223 | goto discard; |
224 | } | 224 | } |
225 | 225 | ||
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 9b7d19ae5ced..4f433847d95f 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -233,7 +233,7 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct | |||
233 | icmp6h->icmp6_cksum = 0; | 233 | icmp6h->icmp6_cksum = 0; |
234 | 234 | ||
235 | if (skb_queue_len(&sk->sk_write_queue) == 1) { | 235 | if (skb_queue_len(&sk->sk_write_queue) == 1) { |
236 | skb->csum = csum_partial((char *)icmp6h, | 236 | skb->csum = csum_partial(icmp6h, |
237 | sizeof(struct icmp6hdr), skb->csum); | 237 | sizeof(struct icmp6hdr), skb->csum); |
238 | icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src, | 238 | icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src, |
239 | &fl->fl6_dst, | 239 | &fl->fl6_dst, |
@@ -246,7 +246,7 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct | |||
246 | tmp_csum = csum_add(tmp_csum, skb->csum); | 246 | tmp_csum = csum_add(tmp_csum, skb->csum); |
247 | } | 247 | } |
248 | 248 | ||
249 | tmp_csum = csum_partial((char *)icmp6h, | 249 | tmp_csum = csum_partial(icmp6h, |
250 | sizeof(struct icmp6hdr), tmp_csum); | 250 | sizeof(struct icmp6hdr), tmp_csum); |
251 | icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src, | 251 | icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src, |
252 | &fl->fl6_dst, | 252 | &fl->fl6_dst, |
@@ -427,7 +427,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, | |||
427 | /* No need to clone since we're just using its address. */ | 427 | /* No need to clone since we're just using its address. */ |
428 | dst2 = dst; | 428 | dst2 = dst; |
429 | 429 | ||
430 | err = xfrm_lookup(&dst, &fl, sk, 0); | 430 | err = xfrm_lookup(net, &dst, &fl, sk, 0); |
431 | switch (err) { | 431 | switch (err) { |
432 | case 0: | 432 | case 0: |
433 | if (dst != dst2) | 433 | if (dst != dst2) |
@@ -446,7 +446,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, | |||
446 | if (ip6_dst_lookup(sk, &dst2, &fl)) | 446 | if (ip6_dst_lookup(sk, &dst2, &fl)) |
447 | goto relookup_failed; | 447 | goto relookup_failed; |
448 | 448 | ||
449 | err = xfrm_lookup(&dst2, &fl, sk, XFRM_LOOKUP_ICMP); | 449 | err = xfrm_lookup(net, &dst2, &fl, sk, XFRM_LOOKUP_ICMP); |
450 | switch (err) { | 450 | switch (err) { |
451 | case 0: | 451 | case 0: |
452 | dst_release(dst); | 452 | dst_release(dst); |
@@ -552,7 +552,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
552 | err = ip6_dst_lookup(sk, &dst, &fl); | 552 | err = ip6_dst_lookup(sk, &dst, &fl); |
553 | if (err) | 553 | if (err) |
554 | goto out; | 554 | goto out; |
555 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) | 555 | if ((err = xfrm_lookup(net, &dst, &fl, sk, 0)) < 0) |
556 | goto out; | 556 | goto out; |
557 | 557 | ||
558 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) | 558 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) |
@@ -646,9 +646,10 @@ static int icmpv6_rcv(struct sk_buff *skb) | |||
646 | int type; | 646 | int type; |
647 | 647 | ||
648 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { | 648 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { |
649 | struct sec_path *sp = skb_sec_path(skb); | ||
649 | int nh; | 650 | int nh; |
650 | 651 | ||
651 | if (!(skb->sp && skb->sp->xvec[skb->sp->len - 1]->props.flags & | 652 | if (!(sp && sp->xvec[sp->len - 1]->props.flags & |
652 | XFRM_STATE_ICMP)) | 653 | XFRM_STATE_ICMP)) |
653 | goto drop_no_count; | 654 | goto drop_no_count; |
654 | 655 | ||
@@ -680,8 +681,8 @@ static int icmpv6_rcv(struct sk_buff *skb) | |||
680 | skb->csum = ~csum_unfold(csum_ipv6_magic(saddr, daddr, skb->len, | 681 | skb->csum = ~csum_unfold(csum_ipv6_magic(saddr, daddr, skb->len, |
681 | IPPROTO_ICMPV6, 0)); | 682 | IPPROTO_ICMPV6, 0)); |
682 | if (__skb_checksum_complete(skb)) { | 683 | if (__skb_checksum_complete(skb)) { |
683 | LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [" NIP6_FMT " > " NIP6_FMT "]\n", | 684 | LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [%pI6 > %pI6]\n", |
684 | NIP6(*saddr), NIP6(*daddr)); | 685 | saddr, daddr); |
685 | goto discard_it; | 686 | goto discard_it; |
686 | } | 687 | } |
687 | } | 688 | } |
@@ -955,8 +956,8 @@ ctl_table ipv6_icmp_table_template[] = { | |||
955 | .data = &init_net.ipv6.sysctl.icmpv6_time, | 956 | .data = &init_net.ipv6.sysctl.icmpv6_time, |
956 | .maxlen = sizeof(int), | 957 | .maxlen = sizeof(int), |
957 | .mode = 0644, | 958 | .mode = 0644, |
958 | .proc_handler = &proc_dointvec_ms_jiffies, | 959 | .proc_handler = proc_dointvec_ms_jiffies, |
959 | .strategy = &sysctl_ms_jiffies | 960 | .strategy = sysctl_ms_jiffies |
960 | }, | 961 | }, |
961 | { .ctl_name = 0 }, | 962 | { .ctl_name = 0 }, |
962 | }; | 963 | }; |
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 16d43f20b32f..3c3732d50c1a 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
@@ -219,7 +219,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) | |||
219 | if (final_p) | 219 | if (final_p) |
220 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 220 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
221 | 221 | ||
222 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | 222 | if ((err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0) { |
223 | sk->sk_route_caps = 0; | 223 | sk->sk_route_caps = 0; |
224 | kfree_skb(skb); | 224 | kfree_skb(skb); |
225 | return err; | 225 | return err; |
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index 1646a5658255..8fe267feb81e 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c | |||
@@ -25,26 +25,30 @@ | |||
25 | void __inet6_hash(struct sock *sk) | 25 | void __inet6_hash(struct sock *sk) |
26 | { | 26 | { |
27 | struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; | 27 | struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; |
28 | struct hlist_head *list; | ||
29 | rwlock_t *lock; | ||
30 | 28 | ||
31 | WARN_ON(!sk_unhashed(sk)); | 29 | WARN_ON(!sk_unhashed(sk)); |
32 | 30 | ||
33 | if (sk->sk_state == TCP_LISTEN) { | 31 | if (sk->sk_state == TCP_LISTEN) { |
34 | list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; | 32 | struct inet_listen_hashbucket *ilb; |
35 | lock = &hashinfo->lhash_lock; | 33 | |
36 | inet_listen_wlock(hashinfo); | 34 | ilb = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; |
35 | spin_lock(&ilb->lock); | ||
36 | __sk_nulls_add_node_rcu(sk, &ilb->head); | ||
37 | spin_unlock(&ilb->lock); | ||
37 | } else { | 38 | } else { |
38 | unsigned int hash; | 39 | unsigned int hash; |
40 | struct hlist_nulls_head *list; | ||
41 | spinlock_t *lock; | ||
42 | |||
39 | sk->sk_hash = hash = inet6_sk_ehashfn(sk); | 43 | sk->sk_hash = hash = inet6_sk_ehashfn(sk); |
40 | list = &inet_ehash_bucket(hashinfo, hash)->chain; | 44 | list = &inet_ehash_bucket(hashinfo, hash)->chain; |
41 | lock = inet_ehash_lockp(hashinfo, hash); | 45 | lock = inet_ehash_lockp(hashinfo, hash); |
42 | write_lock(lock); | 46 | spin_lock(lock); |
47 | __sk_nulls_add_node_rcu(sk, list); | ||
48 | spin_unlock(lock); | ||
43 | } | 49 | } |
44 | 50 | ||
45 | __sk_add_node(sk, list); | ||
46 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); | 51 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); |
47 | write_unlock(lock); | ||
48 | } | 52 | } |
49 | EXPORT_SYMBOL(__inet6_hash); | 53 | EXPORT_SYMBOL(__inet6_hash); |
50 | 54 | ||
@@ -63,77 +67,122 @@ struct sock *__inet6_lookup_established(struct net *net, | |||
63 | const int dif) | 67 | const int dif) |
64 | { | 68 | { |
65 | struct sock *sk; | 69 | struct sock *sk; |
66 | const struct hlist_node *node; | 70 | const struct hlist_nulls_node *node; |
67 | const __portpair ports = INET_COMBINED_PORTS(sport, hnum); | 71 | const __portpair ports = INET_COMBINED_PORTS(sport, hnum); |
68 | /* Optimize here for direct hit, only listening connections can | 72 | /* Optimize here for direct hit, only listening connections can |
69 | * have wildcards anyways. | 73 | * have wildcards anyways. |
70 | */ | 74 | */ |
71 | unsigned int hash = inet6_ehashfn(net, daddr, hnum, saddr, sport); | 75 | unsigned int hash = inet6_ehashfn(net, daddr, hnum, saddr, sport); |
72 | struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash); | 76 | unsigned int slot = hash & (hashinfo->ehash_size - 1); |
73 | rwlock_t *lock = inet_ehash_lockp(hashinfo, hash); | 77 | struct inet_ehash_bucket *head = &hashinfo->ehash[slot]; |
74 | 78 | ||
75 | prefetch(head->chain.first); | 79 | |
76 | read_lock(lock); | 80 | rcu_read_lock(); |
77 | sk_for_each(sk, node, &head->chain) { | 81 | begin: |
82 | sk_nulls_for_each_rcu(sk, node, &head->chain) { | ||
78 | /* For IPV6 do the cheaper port and family tests first. */ | 83 | /* For IPV6 do the cheaper port and family tests first. */ |
79 | if (INET6_MATCH(sk, net, hash, saddr, daddr, ports, dif)) | 84 | if (INET6_MATCH(sk, net, hash, saddr, daddr, ports, dif)) { |
80 | goto hit; /* You sunk my battleship! */ | 85 | if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt))) |
86 | goto begintw; | ||
87 | if (!INET6_MATCH(sk, net, hash, saddr, daddr, ports, dif)) { | ||
88 | sock_put(sk); | ||
89 | goto begin; | ||
90 | } | ||
91 | goto out; | ||
92 | } | ||
81 | } | 93 | } |
94 | if (get_nulls_value(node) != slot) | ||
95 | goto begin; | ||
96 | |||
97 | begintw: | ||
82 | /* Must check for a TIME_WAIT'er before going to listener hash. */ | 98 | /* Must check for a TIME_WAIT'er before going to listener hash. */ |
83 | sk_for_each(sk, node, &head->twchain) { | 99 | sk_nulls_for_each_rcu(sk, node, &head->twchain) { |
84 | if (INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif)) | 100 | if (INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif)) { |
85 | goto hit; | 101 | if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt))) { |
102 | sk = NULL; | ||
103 | goto out; | ||
104 | } | ||
105 | if (!INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif)) { | ||
106 | sock_put(sk); | ||
107 | goto begintw; | ||
108 | } | ||
109 | goto out; | ||
110 | } | ||
86 | } | 111 | } |
87 | read_unlock(lock); | 112 | if (get_nulls_value(node) != slot) |
88 | return NULL; | 113 | goto begintw; |
89 | 114 | sk = NULL; | |
90 | hit: | 115 | out: |
91 | sock_hold(sk); | 116 | rcu_read_unlock(); |
92 | read_unlock(lock); | ||
93 | return sk; | 117 | return sk; |
94 | } | 118 | } |
95 | EXPORT_SYMBOL(__inet6_lookup_established); | 119 | EXPORT_SYMBOL(__inet6_lookup_established); |
96 | 120 | ||
121 | static int inline compute_score(struct sock *sk, struct net *net, | ||
122 | const unsigned short hnum, | ||
123 | const struct in6_addr *daddr, | ||
124 | const int dif) | ||
125 | { | ||
126 | int score = -1; | ||
127 | |||
128 | if (net_eq(sock_net(sk), net) && inet_sk(sk)->num == hnum && | ||
129 | sk->sk_family == PF_INET6) { | ||
130 | const struct ipv6_pinfo *np = inet6_sk(sk); | ||
131 | |||
132 | score = 1; | ||
133 | if (!ipv6_addr_any(&np->rcv_saddr)) { | ||
134 | if (!ipv6_addr_equal(&np->rcv_saddr, daddr)) | ||
135 | return -1; | ||
136 | score++; | ||
137 | } | ||
138 | if (sk->sk_bound_dev_if) { | ||
139 | if (sk->sk_bound_dev_if != dif) | ||
140 | return -1; | ||
141 | score++; | ||
142 | } | ||
143 | } | ||
144 | return score; | ||
145 | } | ||
146 | |||
97 | struct sock *inet6_lookup_listener(struct net *net, | 147 | struct sock *inet6_lookup_listener(struct net *net, |
98 | struct inet_hashinfo *hashinfo, const struct in6_addr *daddr, | 148 | struct inet_hashinfo *hashinfo, const struct in6_addr *daddr, |
99 | const unsigned short hnum, const int dif) | 149 | const unsigned short hnum, const int dif) |
100 | { | 150 | { |
101 | struct sock *sk; | 151 | struct sock *sk; |
102 | const struct hlist_node *node; | 152 | const struct hlist_nulls_node *node; |
103 | struct sock *result = NULL; | 153 | struct sock *result; |
104 | int score, hiscore = 0; | 154 | int score, hiscore; |
105 | 155 | unsigned int hash = inet_lhashfn(net, hnum); | |
106 | read_lock(&hashinfo->lhash_lock); | 156 | struct inet_listen_hashbucket *ilb = &hashinfo->listening_hash[hash]; |
107 | sk_for_each(sk, node, | 157 | |
108 | &hashinfo->listening_hash[inet_lhashfn(net, hnum)]) { | 158 | rcu_read_lock(); |
109 | if (net_eq(sock_net(sk), net) && inet_sk(sk)->num == hnum && | 159 | begin: |
110 | sk->sk_family == PF_INET6) { | 160 | result = NULL; |
111 | const struct ipv6_pinfo *np = inet6_sk(sk); | 161 | hiscore = -1; |
112 | 162 | sk_nulls_for_each(sk, node, &ilb->head) { | |
113 | score = 1; | 163 | score = compute_score(sk, net, hnum, daddr, dif); |
114 | if (!ipv6_addr_any(&np->rcv_saddr)) { | 164 | if (score > hiscore) { |
115 | if (!ipv6_addr_equal(&np->rcv_saddr, daddr)) | 165 | hiscore = score; |
116 | continue; | 166 | result = sk; |
117 | score++; | 167 | } |
118 | } | 168 | } |
119 | if (sk->sk_bound_dev_if) { | 169 | /* |
120 | if (sk->sk_bound_dev_if != dif) | 170 | * if the nulls value we got at the end of this lookup is |
121 | continue; | 171 | * not the expected one, we must restart lookup. |
122 | score++; | 172 | * We probably met an item that was moved to another chain. |
123 | } | 173 | */ |
124 | if (score == 3) { | 174 | if (get_nulls_value(node) != hash + LISTENING_NULLS_BASE) |
125 | result = sk; | 175 | goto begin; |
126 | break; | 176 | if (result) { |
127 | } | 177 | if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt))) |
128 | if (score > hiscore) { | 178 | result = NULL; |
129 | hiscore = score; | 179 | else if (unlikely(compute_score(result, net, hnum, daddr, |
130 | result = sk; | 180 | dif) < hiscore)) { |
131 | } | 181 | sock_put(result); |
182 | goto begin; | ||
132 | } | 183 | } |
133 | } | 184 | } |
134 | if (result) | 185 | rcu_read_unlock(); |
135 | sock_hold(result); | ||
136 | read_unlock(&hashinfo->lhash_lock); | ||
137 | return result; | 186 | return result; |
138 | } | 187 | } |
139 | 188 | ||
@@ -170,16 +219,15 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row, | |||
170 | const unsigned int hash = inet6_ehashfn(net, daddr, lport, saddr, | 219 | const unsigned int hash = inet6_ehashfn(net, daddr, lport, saddr, |
171 | inet->dport); | 220 | inet->dport); |
172 | struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash); | 221 | struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash); |
173 | rwlock_t *lock = inet_ehash_lockp(hinfo, hash); | 222 | spinlock_t *lock = inet_ehash_lockp(hinfo, hash); |
174 | struct sock *sk2; | 223 | struct sock *sk2; |
175 | const struct hlist_node *node; | 224 | const struct hlist_nulls_node *node; |
176 | struct inet_timewait_sock *tw; | 225 | struct inet_timewait_sock *tw; |
177 | 226 | ||
178 | prefetch(head->chain.first); | 227 | spin_lock(lock); |
179 | write_lock(lock); | ||
180 | 228 | ||
181 | /* Check TIME-WAIT sockets first. */ | 229 | /* Check TIME-WAIT sockets first. */ |
182 | sk_for_each(sk2, node, &head->twchain) { | 230 | sk_nulls_for_each(sk2, node, &head->twchain) { |
183 | tw = inet_twsk(sk2); | 231 | tw = inet_twsk(sk2); |
184 | 232 | ||
185 | if (INET6_TW_MATCH(sk2, net, hash, saddr, daddr, ports, dif)) { | 233 | if (INET6_TW_MATCH(sk2, net, hash, saddr, daddr, ports, dif)) { |
@@ -192,7 +240,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row, | |||
192 | tw = NULL; | 240 | tw = NULL; |
193 | 241 | ||
194 | /* And established part... */ | 242 | /* And established part... */ |
195 | sk_for_each(sk2, node, &head->chain) { | 243 | sk_nulls_for_each(sk2, node, &head->chain) { |
196 | if (INET6_MATCH(sk2, net, hash, saddr, daddr, ports, dif)) | 244 | if (INET6_MATCH(sk2, net, hash, saddr, daddr, ports, dif)) |
197 | goto not_unique; | 245 | goto not_unique; |
198 | } | 246 | } |
@@ -203,10 +251,10 @@ unique: | |||
203 | inet->num = lport; | 251 | inet->num = lport; |
204 | inet->sport = htons(lport); | 252 | inet->sport = htons(lport); |
205 | WARN_ON(!sk_unhashed(sk)); | 253 | WARN_ON(!sk_unhashed(sk)); |
206 | __sk_add_node(sk, &head->chain); | 254 | __sk_nulls_add_node_rcu(sk, &head->chain); |
207 | sk->sk_hash = hash; | 255 | sk->sk_hash = hash; |
256 | spin_unlock(lock); | ||
208 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); | 257 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); |
209 | write_unlock(lock); | ||
210 | 258 | ||
211 | if (twp != NULL) { | 259 | if (twp != NULL) { |
212 | *twp = tw; | 260 | *twp = tw; |
@@ -221,7 +269,7 @@ unique: | |||
221 | return 0; | 269 | return 0; |
222 | 270 | ||
223 | not_unique: | 271 | not_unique: |
224 | write_unlock(lock); | 272 | spin_unlock(lock); |
225 | return -EADDRNOTAVAIL; | 273 | return -EADDRNOTAVAIL; |
226 | } | 274 | } |
227 | 275 | ||
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index bd3c7b96bbaa..c62dd247774f 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
@@ -464,7 +464,7 @@ static inline void fl_link(struct ipv6_pinfo *np, struct ipv6_fl_socklist *sfl, | |||
464 | 464 | ||
465 | int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) | 465 | int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) |
466 | { | 466 | { |
467 | int err; | 467 | int uninitialized_var(err); |
468 | struct net *net = sock_net(sk); | 468 | struct net *net = sock_net(sk); |
469 | struct ipv6_pinfo *np = inet6_sk(sk); | 469 | struct ipv6_pinfo *np = inet6_sk(sk); |
470 | struct in6_flowlabel_req freq; | 470 | struct in6_flowlabel_req freq; |
@@ -696,14 +696,14 @@ static int ip6fl_seq_show(struct seq_file *seq, void *v) | |||
696 | else { | 696 | else { |
697 | struct ip6_flowlabel *fl = v; | 697 | struct ip6_flowlabel *fl = v; |
698 | seq_printf(seq, | 698 | seq_printf(seq, |
699 | "%05X %-1d %-6d %-6d %-6ld %-8ld " NIP6_SEQFMT " %-4d\n", | 699 | "%05X %-1d %-6d %-6d %-6ld %-8ld %pi6 %-4d\n", |
700 | (unsigned)ntohl(fl->label), | 700 | (unsigned)ntohl(fl->label), |
701 | fl->share, | 701 | fl->share, |
702 | (unsigned)fl->owner, | 702 | (unsigned)fl->owner, |
703 | atomic_read(&fl->users), | 703 | atomic_read(&fl->users), |
704 | fl->linger/HZ, | 704 | fl->linger/HZ, |
705 | (long)(fl->expires - jiffies)/HZ, | 705 | (long)(fl->expires - jiffies)/HZ, |
706 | NIP6(fl->dst), | 706 | &fl->dst, |
707 | fl->opt ? fl->opt->opt_nflen : 0); | 707 | fl->opt ? fl->opt->opt_nflen : 0); |
708 | } | 708 | } |
709 | return 0; | 709 | return 0; |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index c77db0b95e26..4b15938bef4d 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -137,7 +137,8 @@ static int ip6_output2(struct sk_buff *skb) | |||
137 | struct inet6_dev *idev = ip6_dst_idev(skb->dst); | 137 | struct inet6_dev *idev = ip6_dst_idev(skb->dst); |
138 | 138 | ||
139 | if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) && | 139 | if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) && |
140 | ((mroute6_socket && !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) || | 140 | ((mroute6_socket(dev_net(dev)) && |
141 | !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) || | ||
141 | ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr, | 142 | ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr, |
142 | &ipv6_hdr(skb)->saddr))) { | 143 | &ipv6_hdr(skb)->saddr))) { |
143 | struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); | 144 | struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); |
@@ -490,7 +491,7 @@ int ip6_forward(struct sk_buff *skb) | |||
490 | We don't send redirects to frames decapsulated from IPsec. | 491 | We don't send redirects to frames decapsulated from IPsec. |
491 | */ | 492 | */ |
492 | if (skb->dev == dst->dev && dst->neighbour && opt->srcrt == 0 && | 493 | if (skb->dev == dst->dev && dst->neighbour && opt->srcrt == 0 && |
493 | !skb->sp) { | 494 | !skb_sec_path(skb)) { |
494 | struct in6_addr *target = NULL; | 495 | struct in6_addr *target = NULL; |
495 | struct rt6_info *rt; | 496 | struct rt6_info *rt; |
496 | struct neighbour *n = dst->neighbour; | 497 | struct neighbour *n = dst->neighbour; |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 64ce3d33d9c6..58e2b0d93758 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -74,8 +74,8 @@ MODULE_LICENSE("GPL"); | |||
74 | (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \ | 74 | (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \ |
75 | (HASH_SIZE - 1)) | 75 | (HASH_SIZE - 1)) |
76 | 76 | ||
77 | static int ip6_fb_tnl_dev_init(struct net_device *dev); | 77 | static void ip6_fb_tnl_dev_init(struct net_device *dev); |
78 | static int ip6_tnl_dev_init(struct net_device *dev); | 78 | static void ip6_tnl_dev_init(struct net_device *dev); |
79 | static void ip6_tnl_dev_setup(struct net_device *dev); | 79 | static void ip6_tnl_dev_setup(struct net_device *dev); |
80 | 80 | ||
81 | static int ip6_tnl_net_id; | 81 | static int ip6_tnl_net_id; |
@@ -249,7 +249,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p) | |||
249 | } | 249 | } |
250 | 250 | ||
251 | t = netdev_priv(dev); | 251 | t = netdev_priv(dev); |
252 | dev->init = ip6_tnl_dev_init; | 252 | ip6_tnl_dev_init(dev); |
253 | t->parms = *p; | 253 | t->parms = *p; |
254 | 254 | ||
255 | if ((err = register_netdevice(dev)) < 0) | 255 | if ((err = register_netdevice(dev)) < 0) |
@@ -846,6 +846,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, | |||
846 | int encap_limit, | 846 | int encap_limit, |
847 | __u32 *pmtu) | 847 | __u32 *pmtu) |
848 | { | 848 | { |
849 | struct net *net = dev_net(dev); | ||
849 | struct ip6_tnl *t = netdev_priv(dev); | 850 | struct ip6_tnl *t = netdev_priv(dev); |
850 | struct net_device_stats *stats = &t->dev->stats; | 851 | struct net_device_stats *stats = &t->dev->stats; |
851 | struct ipv6hdr *ipv6h = ipv6_hdr(skb); | 852 | struct ipv6hdr *ipv6h = ipv6_hdr(skb); |
@@ -861,9 +862,9 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, | |||
861 | if ((dst = ip6_tnl_dst_check(t)) != NULL) | 862 | if ((dst = ip6_tnl_dst_check(t)) != NULL) |
862 | dst_hold(dst); | 863 | dst_hold(dst); |
863 | else { | 864 | else { |
864 | dst = ip6_route_output(dev_net(dev), NULL, fl); | 865 | dst = ip6_route_output(net, NULL, fl); |
865 | 866 | ||
866 | if (dst->error || xfrm_lookup(&dst, fl, NULL, 0) < 0) | 867 | if (dst->error || xfrm_lookup(net, &dst, fl, NULL, 0) < 0) |
867 | goto tx_err_link_failure; | 868 | goto tx_err_link_failure; |
868 | } | 869 | } |
869 | 870 | ||
@@ -1150,7 +1151,6 @@ static void ip6_tnl_link_config(struct ip6_tnl *t) | |||
1150 | * ip6_tnl_change - update the tunnel parameters | 1151 | * ip6_tnl_change - update the tunnel parameters |
1151 | * @t: tunnel to be changed | 1152 | * @t: tunnel to be changed |
1152 | * @p: tunnel configuration parameters | 1153 | * @p: tunnel configuration parameters |
1153 | * @active: != 0 if tunnel is ready for use | ||
1154 | * | 1154 | * |
1155 | * Description: | 1155 | * Description: |
1156 | * ip6_tnl_change() updates the tunnel parameters | 1156 | * ip6_tnl_change() updates the tunnel parameters |
@@ -1306,6 +1306,14 @@ ip6_tnl_change_mtu(struct net_device *dev, int new_mtu) | |||
1306 | return 0; | 1306 | return 0; |
1307 | } | 1307 | } |
1308 | 1308 | ||
1309 | |||
1310 | static const struct net_device_ops ip6_tnl_netdev_ops = { | ||
1311 | .ndo_uninit = ip6_tnl_dev_uninit, | ||
1312 | .ndo_start_xmit = ip6_tnl_xmit, | ||
1313 | .ndo_do_ioctl = ip6_tnl_ioctl, | ||
1314 | .ndo_change_mtu = ip6_tnl_change_mtu, | ||
1315 | }; | ||
1316 | |||
1309 | /** | 1317 | /** |
1310 | * ip6_tnl_dev_setup - setup virtual tunnel device | 1318 | * ip6_tnl_dev_setup - setup virtual tunnel device |
1311 | * @dev: virtual device associated with tunnel | 1319 | * @dev: virtual device associated with tunnel |
@@ -1316,11 +1324,8 @@ ip6_tnl_change_mtu(struct net_device *dev, int new_mtu) | |||
1316 | 1324 | ||
1317 | static void ip6_tnl_dev_setup(struct net_device *dev) | 1325 | static void ip6_tnl_dev_setup(struct net_device *dev) |
1318 | { | 1326 | { |
1319 | dev->uninit = ip6_tnl_dev_uninit; | 1327 | dev->netdev_ops = &ip6_tnl_netdev_ops; |
1320 | dev->destructor = free_netdev; | 1328 | dev->destructor = free_netdev; |
1321 | dev->hard_start_xmit = ip6_tnl_xmit; | ||
1322 | dev->do_ioctl = ip6_tnl_ioctl; | ||
1323 | dev->change_mtu = ip6_tnl_change_mtu; | ||
1324 | 1329 | ||
1325 | dev->type = ARPHRD_TUNNEL6; | 1330 | dev->type = ARPHRD_TUNNEL6; |
1326 | dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr); | 1331 | dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr); |
@@ -1349,13 +1354,11 @@ ip6_tnl_dev_init_gen(struct net_device *dev) | |||
1349 | * @dev: virtual device associated with tunnel | 1354 | * @dev: virtual device associated with tunnel |
1350 | **/ | 1355 | **/ |
1351 | 1356 | ||
1352 | static int | 1357 | static void ip6_tnl_dev_init(struct net_device *dev) |
1353 | ip6_tnl_dev_init(struct net_device *dev) | ||
1354 | { | 1358 | { |
1355 | struct ip6_tnl *t = netdev_priv(dev); | 1359 | struct ip6_tnl *t = netdev_priv(dev); |
1356 | ip6_tnl_dev_init_gen(dev); | 1360 | ip6_tnl_dev_init_gen(dev); |
1357 | ip6_tnl_link_config(t); | 1361 | ip6_tnl_link_config(t); |
1358 | return 0; | ||
1359 | } | 1362 | } |
1360 | 1363 | ||
1361 | /** | 1364 | /** |
@@ -1365,8 +1368,7 @@ ip6_tnl_dev_init(struct net_device *dev) | |||
1365 | * Return: 0 | 1368 | * Return: 0 |
1366 | **/ | 1369 | **/ |
1367 | 1370 | ||
1368 | static int | 1371 | static void ip6_fb_tnl_dev_init(struct net_device *dev) |
1369 | ip6_fb_tnl_dev_init(struct net_device *dev) | ||
1370 | { | 1372 | { |
1371 | struct ip6_tnl *t = netdev_priv(dev); | 1373 | struct ip6_tnl *t = netdev_priv(dev); |
1372 | struct net *net = dev_net(dev); | 1374 | struct net *net = dev_net(dev); |
@@ -1376,7 +1378,6 @@ ip6_fb_tnl_dev_init(struct net_device *dev) | |||
1376 | t->parms.proto = IPPROTO_IPV6; | 1378 | t->parms.proto = IPPROTO_IPV6; |
1377 | dev_hold(dev); | 1379 | dev_hold(dev); |
1378 | ip6n->tnls_wc[0] = t; | 1380 | ip6n->tnls_wc[0] = t; |
1379 | return 0; | ||
1380 | } | 1381 | } |
1381 | 1382 | ||
1382 | static struct xfrm6_tunnel ip4ip6_handler = { | 1383 | static struct xfrm6_tunnel ip4ip6_handler = { |
@@ -1428,10 +1429,10 @@ static int ip6_tnl_init_net(struct net *net) | |||
1428 | 1429 | ||
1429 | if (!ip6n->fb_tnl_dev) | 1430 | if (!ip6n->fb_tnl_dev) |
1430 | goto err_alloc_dev; | 1431 | goto err_alloc_dev; |
1431 | |||
1432 | ip6n->fb_tnl_dev->init = ip6_fb_tnl_dev_init; | ||
1433 | dev_net_set(ip6n->fb_tnl_dev, net); | 1432 | dev_net_set(ip6n->fb_tnl_dev, net); |
1434 | 1433 | ||
1434 | ip6_fb_tnl_dev_init(ip6n->fb_tnl_dev); | ||
1435 | |||
1435 | err = register_netdev(ip6n->fb_tnl_dev); | 1436 | err = register_netdev(ip6n->fb_tnl_dev); |
1436 | if (err < 0) | 1437 | if (err < 0) |
1437 | goto err_register; | 1438 | goto err_register; |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 0524769632e7..3c51b2d827f4 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -49,9 +49,6 @@ | |||
49 | #include <net/addrconf.h> | 49 | #include <net/addrconf.h> |
50 | #include <linux/netfilter_ipv6.h> | 50 | #include <linux/netfilter_ipv6.h> |
51 | 51 | ||
52 | struct sock *mroute6_socket; | ||
53 | |||
54 | |||
55 | /* Big lock, protecting vif table, mrt cache and mroute socket state. | 52 | /* Big lock, protecting vif table, mrt cache and mroute socket state. |
56 | Note that the changes are semaphored via rtnl_lock. | 53 | Note that the changes are semaphored via rtnl_lock. |
57 | */ | 54 | */ |
@@ -62,22 +59,9 @@ static DEFINE_RWLOCK(mrt_lock); | |||
62 | * Multicast router control variables | 59 | * Multicast router control variables |
63 | */ | 60 | */ |
64 | 61 | ||
65 | static struct mif_device vif6_table[MAXMIFS]; /* Devices */ | 62 | #define MIF_EXISTS(_net, _idx) ((_net)->ipv6.vif6_table[_idx].dev != NULL) |
66 | static int maxvif; | ||
67 | |||
68 | #define MIF_EXISTS(idx) (vif6_table[idx].dev != NULL) | ||
69 | |||
70 | static int mroute_do_assert; /* Set in PIM assert */ | ||
71 | #ifdef CONFIG_IPV6_PIMSM_V2 | ||
72 | static int mroute_do_pim; | ||
73 | #else | ||
74 | #define mroute_do_pim 0 | ||
75 | #endif | ||
76 | |||
77 | static struct mfc6_cache *mfc6_cache_array[MFC6_LINES]; /* Forwarding cache */ | ||
78 | 63 | ||
79 | static struct mfc6_cache *mfc_unres_queue; /* Queue of unresolved entries */ | 64 | static struct mfc6_cache *mfc_unres_queue; /* Queue of unresolved entries */ |
80 | static atomic_t cache_resolve_queue_len; /* Size of unresolved */ | ||
81 | 65 | ||
82 | /* Special spinlock for queue of unresolved entries */ | 66 | /* Special spinlock for queue of unresolved entries */ |
83 | static DEFINE_SPINLOCK(mfc_unres_lock); | 67 | static DEFINE_SPINLOCK(mfc_unres_lock); |
@@ -93,8 +77,10 @@ static DEFINE_SPINLOCK(mfc_unres_lock); | |||
93 | static struct kmem_cache *mrt_cachep __read_mostly; | 77 | static struct kmem_cache *mrt_cachep __read_mostly; |
94 | 78 | ||
95 | static int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache); | 79 | static int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache); |
96 | static int ip6mr_cache_report(struct sk_buff *pkt, mifi_t mifi, int assert); | 80 | static int ip6mr_cache_report(struct net *net, struct sk_buff *pkt, |
81 | mifi_t mifi, int assert); | ||
97 | static int ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm); | 82 | static int ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm); |
83 | static void mroute_clean_tables(struct net *net); | ||
98 | 84 | ||
99 | #ifdef CONFIG_IPV6_PIMSM_V2 | 85 | #ifdef CONFIG_IPV6_PIMSM_V2 |
100 | static struct inet6_protocol pim6_protocol; | 86 | static struct inet6_protocol pim6_protocol; |
@@ -106,19 +92,22 @@ static struct timer_list ipmr_expire_timer; | |||
106 | #ifdef CONFIG_PROC_FS | 92 | #ifdef CONFIG_PROC_FS |
107 | 93 | ||
108 | struct ipmr_mfc_iter { | 94 | struct ipmr_mfc_iter { |
95 | struct seq_net_private p; | ||
109 | struct mfc6_cache **cache; | 96 | struct mfc6_cache **cache; |
110 | int ct; | 97 | int ct; |
111 | }; | 98 | }; |
112 | 99 | ||
113 | 100 | ||
114 | static struct mfc6_cache *ipmr_mfc_seq_idx(struct ipmr_mfc_iter *it, loff_t pos) | 101 | static struct mfc6_cache *ipmr_mfc_seq_idx(struct net *net, |
102 | struct ipmr_mfc_iter *it, loff_t pos) | ||
115 | { | 103 | { |
116 | struct mfc6_cache *mfc; | 104 | struct mfc6_cache *mfc; |
117 | 105 | ||
118 | it->cache = mfc6_cache_array; | 106 | it->cache = net->ipv6.mfc6_cache_array; |
119 | read_lock(&mrt_lock); | 107 | read_lock(&mrt_lock); |
120 | for (it->ct = 0; it->ct < ARRAY_SIZE(mfc6_cache_array); it->ct++) | 108 | for (it->ct = 0; it->ct < MFC6_LINES; it->ct++) |
121 | for (mfc = mfc6_cache_array[it->ct]; mfc; mfc = mfc->next) | 109 | for (mfc = net->ipv6.mfc6_cache_array[it->ct]; |
110 | mfc; mfc = mfc->next) | ||
122 | if (pos-- == 0) | 111 | if (pos-- == 0) |
123 | return mfc; | 112 | return mfc; |
124 | read_unlock(&mrt_lock); | 113 | read_unlock(&mrt_lock); |
@@ -126,7 +115,8 @@ static struct mfc6_cache *ipmr_mfc_seq_idx(struct ipmr_mfc_iter *it, loff_t pos) | |||
126 | it->cache = &mfc_unres_queue; | 115 | it->cache = &mfc_unres_queue; |
127 | spin_lock_bh(&mfc_unres_lock); | 116 | spin_lock_bh(&mfc_unres_lock); |
128 | for (mfc = mfc_unres_queue; mfc; mfc = mfc->next) | 117 | for (mfc = mfc_unres_queue; mfc; mfc = mfc->next) |
129 | if (pos-- == 0) | 118 | if (net_eq(mfc6_net(mfc), net) && |
119 | pos-- == 0) | ||
130 | return mfc; | 120 | return mfc; |
131 | spin_unlock_bh(&mfc_unres_lock); | 121 | spin_unlock_bh(&mfc_unres_lock); |
132 | 122 | ||
@@ -142,17 +132,19 @@ static struct mfc6_cache *ipmr_mfc_seq_idx(struct ipmr_mfc_iter *it, loff_t pos) | |||
142 | */ | 132 | */ |
143 | 133 | ||
144 | struct ipmr_vif_iter { | 134 | struct ipmr_vif_iter { |
135 | struct seq_net_private p; | ||
145 | int ct; | 136 | int ct; |
146 | }; | 137 | }; |
147 | 138 | ||
148 | static struct mif_device *ip6mr_vif_seq_idx(struct ipmr_vif_iter *iter, | 139 | static struct mif_device *ip6mr_vif_seq_idx(struct net *net, |
140 | struct ipmr_vif_iter *iter, | ||
149 | loff_t pos) | 141 | loff_t pos) |
150 | { | 142 | { |
151 | for (iter->ct = 0; iter->ct < maxvif; ++iter->ct) { | 143 | for (iter->ct = 0; iter->ct < net->ipv6.maxvif; ++iter->ct) { |
152 | if (!MIF_EXISTS(iter->ct)) | 144 | if (!MIF_EXISTS(net, iter->ct)) |
153 | continue; | 145 | continue; |
154 | if (pos-- == 0) | 146 | if (pos-- == 0) |
155 | return &vif6_table[iter->ct]; | 147 | return &net->ipv6.vif6_table[iter->ct]; |
156 | } | 148 | } |
157 | return NULL; | 149 | return NULL; |
158 | } | 150 | } |
@@ -160,23 +152,26 @@ static struct mif_device *ip6mr_vif_seq_idx(struct ipmr_vif_iter *iter, | |||
160 | static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos) | 152 | static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos) |
161 | __acquires(mrt_lock) | 153 | __acquires(mrt_lock) |
162 | { | 154 | { |
155 | struct net *net = seq_file_net(seq); | ||
156 | |||
163 | read_lock(&mrt_lock); | 157 | read_lock(&mrt_lock); |
164 | return (*pos ? ip6mr_vif_seq_idx(seq->private, *pos - 1) | 158 | return *pos ? ip6mr_vif_seq_idx(net, seq->private, *pos - 1) |
165 | : SEQ_START_TOKEN); | 159 | : SEQ_START_TOKEN; |
166 | } | 160 | } |
167 | 161 | ||
168 | static void *ip6mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 162 | static void *ip6mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
169 | { | 163 | { |
170 | struct ipmr_vif_iter *iter = seq->private; | 164 | struct ipmr_vif_iter *iter = seq->private; |
165 | struct net *net = seq_file_net(seq); | ||
171 | 166 | ||
172 | ++*pos; | 167 | ++*pos; |
173 | if (v == SEQ_START_TOKEN) | 168 | if (v == SEQ_START_TOKEN) |
174 | return ip6mr_vif_seq_idx(iter, 0); | 169 | return ip6mr_vif_seq_idx(net, iter, 0); |
175 | 170 | ||
176 | while (++iter->ct < maxvif) { | 171 | while (++iter->ct < net->ipv6.maxvif) { |
177 | if (!MIF_EXISTS(iter->ct)) | 172 | if (!MIF_EXISTS(net, iter->ct)) |
178 | continue; | 173 | continue; |
179 | return &vif6_table[iter->ct]; | 174 | return &net->ipv6.vif6_table[iter->ct]; |
180 | } | 175 | } |
181 | return NULL; | 176 | return NULL; |
182 | } | 177 | } |
@@ -189,6 +184,8 @@ static void ip6mr_vif_seq_stop(struct seq_file *seq, void *v) | |||
189 | 184 | ||
190 | static int ip6mr_vif_seq_show(struct seq_file *seq, void *v) | 185 | static int ip6mr_vif_seq_show(struct seq_file *seq, void *v) |
191 | { | 186 | { |
187 | struct net *net = seq_file_net(seq); | ||
188 | |||
192 | if (v == SEQ_START_TOKEN) { | 189 | if (v == SEQ_START_TOKEN) { |
193 | seq_puts(seq, | 190 | seq_puts(seq, |
194 | "Interface BytesIn PktsIn BytesOut PktsOut Flags\n"); | 191 | "Interface BytesIn PktsIn BytesOut PktsOut Flags\n"); |
@@ -198,7 +195,7 @@ static int ip6mr_vif_seq_show(struct seq_file *seq, void *v) | |||
198 | 195 | ||
199 | seq_printf(seq, | 196 | seq_printf(seq, |
200 | "%2td %-10s %8ld %7ld %8ld %7ld %05X\n", | 197 | "%2td %-10s %8ld %7ld %8ld %7ld %05X\n", |
201 | vif - vif6_table, | 198 | vif - net->ipv6.vif6_table, |
202 | name, vif->bytes_in, vif->pkt_in, | 199 | name, vif->bytes_in, vif->pkt_in, |
203 | vif->bytes_out, vif->pkt_out, | 200 | vif->bytes_out, vif->pkt_out, |
204 | vif->flags); | 201 | vif->flags); |
@@ -215,8 +212,8 @@ static struct seq_operations ip6mr_vif_seq_ops = { | |||
215 | 212 | ||
216 | static int ip6mr_vif_open(struct inode *inode, struct file *file) | 213 | static int ip6mr_vif_open(struct inode *inode, struct file *file) |
217 | { | 214 | { |
218 | return seq_open_private(file, &ip6mr_vif_seq_ops, | 215 | return seq_open_net(inode, file, &ip6mr_vif_seq_ops, |
219 | sizeof(struct ipmr_vif_iter)); | 216 | sizeof(struct ipmr_vif_iter)); |
220 | } | 217 | } |
221 | 218 | ||
222 | static struct file_operations ip6mr_vif_fops = { | 219 | static struct file_operations ip6mr_vif_fops = { |
@@ -224,24 +221,27 @@ static struct file_operations ip6mr_vif_fops = { | |||
224 | .open = ip6mr_vif_open, | 221 | .open = ip6mr_vif_open, |
225 | .read = seq_read, | 222 | .read = seq_read, |
226 | .llseek = seq_lseek, | 223 | .llseek = seq_lseek, |
227 | .release = seq_release_private, | 224 | .release = seq_release_net, |
228 | }; | 225 | }; |
229 | 226 | ||
230 | static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos) | 227 | static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos) |
231 | { | 228 | { |
232 | return (*pos ? ipmr_mfc_seq_idx(seq->private, *pos - 1) | 229 | struct net *net = seq_file_net(seq); |
233 | : SEQ_START_TOKEN); | 230 | |
231 | return *pos ? ipmr_mfc_seq_idx(net, seq->private, *pos - 1) | ||
232 | : SEQ_START_TOKEN; | ||
234 | } | 233 | } |
235 | 234 | ||
236 | static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 235 | static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
237 | { | 236 | { |
238 | struct mfc6_cache *mfc = v; | 237 | struct mfc6_cache *mfc = v; |
239 | struct ipmr_mfc_iter *it = seq->private; | 238 | struct ipmr_mfc_iter *it = seq->private; |
239 | struct net *net = seq_file_net(seq); | ||
240 | 240 | ||
241 | ++*pos; | 241 | ++*pos; |
242 | 242 | ||
243 | if (v == SEQ_START_TOKEN) | 243 | if (v == SEQ_START_TOKEN) |
244 | return ipmr_mfc_seq_idx(seq->private, 0); | 244 | return ipmr_mfc_seq_idx(net, seq->private, 0); |
245 | 245 | ||
246 | if (mfc->next) | 246 | if (mfc->next) |
247 | return mfc->next; | 247 | return mfc->next; |
@@ -249,10 +249,10 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
249 | if (it->cache == &mfc_unres_queue) | 249 | if (it->cache == &mfc_unres_queue) |
250 | goto end_of_list; | 250 | goto end_of_list; |
251 | 251 | ||
252 | BUG_ON(it->cache != mfc6_cache_array); | 252 | BUG_ON(it->cache != net->ipv6.mfc6_cache_array); |
253 | 253 | ||
254 | while (++it->ct < ARRAY_SIZE(mfc6_cache_array)) { | 254 | while (++it->ct < MFC6_LINES) { |
255 | mfc = mfc6_cache_array[it->ct]; | 255 | mfc = net->ipv6.mfc6_cache_array[it->ct]; |
256 | if (mfc) | 256 | if (mfc) |
257 | return mfc; | 257 | return mfc; |
258 | } | 258 | } |
@@ -277,16 +277,18 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
277 | static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v) | 277 | static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v) |
278 | { | 278 | { |
279 | struct ipmr_mfc_iter *it = seq->private; | 279 | struct ipmr_mfc_iter *it = seq->private; |
280 | struct net *net = seq_file_net(seq); | ||
280 | 281 | ||
281 | if (it->cache == &mfc_unres_queue) | 282 | if (it->cache == &mfc_unres_queue) |
282 | spin_unlock_bh(&mfc_unres_lock); | 283 | spin_unlock_bh(&mfc_unres_lock); |
283 | else if (it->cache == mfc6_cache_array) | 284 | else if (it->cache == net->ipv6.mfc6_cache_array) |
284 | read_unlock(&mrt_lock); | 285 | read_unlock(&mrt_lock); |
285 | } | 286 | } |
286 | 287 | ||
287 | static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) | 288 | static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) |
288 | { | 289 | { |
289 | int n; | 290 | int n; |
291 | struct net *net = seq_file_net(seq); | ||
290 | 292 | ||
291 | if (v == SEQ_START_TOKEN) { | 293 | if (v == SEQ_START_TOKEN) { |
292 | seq_puts(seq, | 294 | seq_puts(seq, |
@@ -297,23 +299,28 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) | |||
297 | const struct mfc6_cache *mfc = v; | 299 | const struct mfc6_cache *mfc = v; |
298 | const struct ipmr_mfc_iter *it = seq->private; | 300 | const struct ipmr_mfc_iter *it = seq->private; |
299 | 301 | ||
300 | seq_printf(seq, | 302 | seq_printf(seq, "%pI6 %pI6 %-3hd", |
301 | NIP6_FMT " " NIP6_FMT " %-3d %8ld %8ld %8ld", | 303 | &mfc->mf6c_mcastgrp, &mfc->mf6c_origin, |
302 | NIP6(mfc->mf6c_mcastgrp), NIP6(mfc->mf6c_origin), | 304 | mfc->mf6c_parent); |
303 | mfc->mf6c_parent, | ||
304 | mfc->mfc_un.res.pkt, | ||
305 | mfc->mfc_un.res.bytes, | ||
306 | mfc->mfc_un.res.wrong_if); | ||
307 | 305 | ||
308 | if (it->cache != &mfc_unres_queue) { | 306 | if (it->cache != &mfc_unres_queue) { |
307 | seq_printf(seq, " %8lu %8lu %8lu", | ||
308 | mfc->mfc_un.res.pkt, | ||
309 | mfc->mfc_un.res.bytes, | ||
310 | mfc->mfc_un.res.wrong_if); | ||
309 | for (n = mfc->mfc_un.res.minvif; | 311 | for (n = mfc->mfc_un.res.minvif; |
310 | n < mfc->mfc_un.res.maxvif; n++) { | 312 | n < mfc->mfc_un.res.maxvif; n++) { |
311 | if (MIF_EXISTS(n) && | 313 | if (MIF_EXISTS(net, n) && |
312 | mfc->mfc_un.res.ttls[n] < 255) | 314 | mfc->mfc_un.res.ttls[n] < 255) |
313 | seq_printf(seq, | 315 | seq_printf(seq, |
314 | " %2d:%-3d", | 316 | " %2d:%-3d", |
315 | n, mfc->mfc_un.res.ttls[n]); | 317 | n, mfc->mfc_un.res.ttls[n]); |
316 | } | 318 | } |
319 | } else { | ||
320 | /* unresolved mfc_caches don't contain | ||
321 | * pkt, bytes and wrong_if values | ||
322 | */ | ||
323 | seq_printf(seq, " %8lu %8lu %8lu", 0ul, 0ul, 0ul); | ||
317 | } | 324 | } |
318 | seq_putc(seq, '\n'); | 325 | seq_putc(seq, '\n'); |
319 | } | 326 | } |
@@ -329,8 +336,8 @@ static struct seq_operations ipmr_mfc_seq_ops = { | |||
329 | 336 | ||
330 | static int ipmr_mfc_open(struct inode *inode, struct file *file) | 337 | static int ipmr_mfc_open(struct inode *inode, struct file *file) |
331 | { | 338 | { |
332 | return seq_open_private(file, &ipmr_mfc_seq_ops, | 339 | return seq_open_net(inode, file, &ipmr_mfc_seq_ops, |
333 | sizeof(struct ipmr_mfc_iter)); | 340 | sizeof(struct ipmr_mfc_iter)); |
334 | } | 341 | } |
335 | 342 | ||
336 | static struct file_operations ip6mr_mfc_fops = { | 343 | static struct file_operations ip6mr_mfc_fops = { |
@@ -338,18 +345,19 @@ static struct file_operations ip6mr_mfc_fops = { | |||
338 | .open = ipmr_mfc_open, | 345 | .open = ipmr_mfc_open, |
339 | .read = seq_read, | 346 | .read = seq_read, |
340 | .llseek = seq_lseek, | 347 | .llseek = seq_lseek, |
341 | .release = seq_release_private, | 348 | .release = seq_release_net, |
342 | }; | 349 | }; |
343 | #endif | 350 | #endif |
344 | 351 | ||
345 | #ifdef CONFIG_IPV6_PIMSM_V2 | 352 | #ifdef CONFIG_IPV6_PIMSM_V2 |
346 | static int reg_vif_num = -1; | ||
347 | 353 | ||
348 | static int pim6_rcv(struct sk_buff *skb) | 354 | static int pim6_rcv(struct sk_buff *skb) |
349 | { | 355 | { |
350 | struct pimreghdr *pim; | 356 | struct pimreghdr *pim; |
351 | struct ipv6hdr *encap; | 357 | struct ipv6hdr *encap; |
352 | struct net_device *reg_dev = NULL; | 358 | struct net_device *reg_dev = NULL; |
359 | struct net *net = dev_net(skb->dev); | ||
360 | int reg_vif_num = net->ipv6.mroute_reg_vif_num; | ||
353 | 361 | ||
354 | if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap))) | 362 | if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap))) |
355 | goto drop; | 363 | goto drop; |
@@ -372,7 +380,7 @@ static int pim6_rcv(struct sk_buff *skb) | |||
372 | 380 | ||
373 | read_lock(&mrt_lock); | 381 | read_lock(&mrt_lock); |
374 | if (reg_vif_num >= 0) | 382 | if (reg_vif_num >= 0) |
375 | reg_dev = vif6_table[reg_vif_num].dev; | 383 | reg_dev = net->ipv6.vif6_table[reg_vif_num].dev; |
376 | if (reg_dev) | 384 | if (reg_dev) |
377 | dev_hold(reg_dev); | 385 | dev_hold(reg_dev); |
378 | read_unlock(&mrt_lock); | 386 | read_unlock(&mrt_lock); |
@@ -408,25 +416,32 @@ static struct inet6_protocol pim6_protocol = { | |||
408 | 416 | ||
409 | static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) | 417 | static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) |
410 | { | 418 | { |
419 | struct net *net = dev_net(dev); | ||
420 | |||
411 | read_lock(&mrt_lock); | 421 | read_lock(&mrt_lock); |
412 | dev->stats.tx_bytes += skb->len; | 422 | dev->stats.tx_bytes += skb->len; |
413 | dev->stats.tx_packets++; | 423 | dev->stats.tx_packets++; |
414 | ip6mr_cache_report(skb, reg_vif_num, MRT6MSG_WHOLEPKT); | 424 | ip6mr_cache_report(net, skb, net->ipv6.mroute_reg_vif_num, |
425 | MRT6MSG_WHOLEPKT); | ||
415 | read_unlock(&mrt_lock); | 426 | read_unlock(&mrt_lock); |
416 | kfree_skb(skb); | 427 | kfree_skb(skb); |
417 | return 0; | 428 | return 0; |
418 | } | 429 | } |
419 | 430 | ||
431 | static const struct net_device_ops reg_vif_netdev_ops = { | ||
432 | .ndo_start_xmit = reg_vif_xmit, | ||
433 | }; | ||
434 | |||
420 | static void reg_vif_setup(struct net_device *dev) | 435 | static void reg_vif_setup(struct net_device *dev) |
421 | { | 436 | { |
422 | dev->type = ARPHRD_PIMREG; | 437 | dev->type = ARPHRD_PIMREG; |
423 | dev->mtu = 1500 - sizeof(struct ipv6hdr) - 8; | 438 | dev->mtu = 1500 - sizeof(struct ipv6hdr) - 8; |
424 | dev->flags = IFF_NOARP; | 439 | dev->flags = IFF_NOARP; |
425 | dev->hard_start_xmit = reg_vif_xmit; | 440 | dev->netdev_ops = ®_vif_netdev_ops; |
426 | dev->destructor = free_netdev; | 441 | dev->destructor = free_netdev; |
427 | } | 442 | } |
428 | 443 | ||
429 | static struct net_device *ip6mr_reg_vif(void) | 444 | static struct net_device *ip6mr_reg_vif(struct net *net) |
430 | { | 445 | { |
431 | struct net_device *dev; | 446 | struct net_device *dev; |
432 | 447 | ||
@@ -434,6 +449,8 @@ static struct net_device *ip6mr_reg_vif(void) | |||
434 | if (dev == NULL) | 449 | if (dev == NULL) |
435 | return NULL; | 450 | return NULL; |
436 | 451 | ||
452 | dev_net_set(dev, net); | ||
453 | |||
437 | if (register_netdevice(dev)) { | 454 | if (register_netdevice(dev)) { |
438 | free_netdev(dev); | 455 | free_netdev(dev); |
439 | return NULL; | 456 | return NULL; |
@@ -460,14 +477,14 @@ failure: | |||
460 | * Delete a VIF entry | 477 | * Delete a VIF entry |
461 | */ | 478 | */ |
462 | 479 | ||
463 | static int mif6_delete(int vifi) | 480 | static int mif6_delete(struct net *net, int vifi) |
464 | { | 481 | { |
465 | struct mif_device *v; | 482 | struct mif_device *v; |
466 | struct net_device *dev; | 483 | struct net_device *dev; |
467 | if (vifi < 0 || vifi >= maxvif) | 484 | if (vifi < 0 || vifi >= net->ipv6.maxvif) |
468 | return -EADDRNOTAVAIL; | 485 | return -EADDRNOTAVAIL; |
469 | 486 | ||
470 | v = &vif6_table[vifi]; | 487 | v = &net->ipv6.vif6_table[vifi]; |
471 | 488 | ||
472 | write_lock_bh(&mrt_lock); | 489 | write_lock_bh(&mrt_lock); |
473 | dev = v->dev; | 490 | dev = v->dev; |
@@ -479,17 +496,17 @@ static int mif6_delete(int vifi) | |||
479 | } | 496 | } |
480 | 497 | ||
481 | #ifdef CONFIG_IPV6_PIMSM_V2 | 498 | #ifdef CONFIG_IPV6_PIMSM_V2 |
482 | if (vifi == reg_vif_num) | 499 | if (vifi == net->ipv6.mroute_reg_vif_num) |
483 | reg_vif_num = -1; | 500 | net->ipv6.mroute_reg_vif_num = -1; |
484 | #endif | 501 | #endif |
485 | 502 | ||
486 | if (vifi + 1 == maxvif) { | 503 | if (vifi + 1 == net->ipv6.maxvif) { |
487 | int tmp; | 504 | int tmp; |
488 | for (tmp = vifi - 1; tmp >= 0; tmp--) { | 505 | for (tmp = vifi - 1; tmp >= 0; tmp--) { |
489 | if (MIF_EXISTS(tmp)) | 506 | if (MIF_EXISTS(net, tmp)) |
490 | break; | 507 | break; |
491 | } | 508 | } |
492 | maxvif = tmp + 1; | 509 | net->ipv6.maxvif = tmp + 1; |
493 | } | 510 | } |
494 | 511 | ||
495 | write_unlock_bh(&mrt_lock); | 512 | write_unlock_bh(&mrt_lock); |
@@ -503,6 +520,12 @@ static int mif6_delete(int vifi) | |||
503 | return 0; | 520 | return 0; |
504 | } | 521 | } |
505 | 522 | ||
523 | static inline void ip6mr_cache_free(struct mfc6_cache *c) | ||
524 | { | ||
525 | release_net(mfc6_net(c)); | ||
526 | kmem_cache_free(mrt_cachep, c); | ||
527 | } | ||
528 | |||
506 | /* Destroy an unresolved cache entry, killing queued skbs | 529 | /* Destroy an unresolved cache entry, killing queued skbs |
507 | and reporting error to netlink readers. | 530 | and reporting error to netlink readers. |
508 | */ | 531 | */ |
@@ -510,8 +533,9 @@ static int mif6_delete(int vifi) | |||
510 | static void ip6mr_destroy_unres(struct mfc6_cache *c) | 533 | static void ip6mr_destroy_unres(struct mfc6_cache *c) |
511 | { | 534 | { |
512 | struct sk_buff *skb; | 535 | struct sk_buff *skb; |
536 | struct net *net = mfc6_net(c); | ||
513 | 537 | ||
514 | atomic_dec(&cache_resolve_queue_len); | 538 | atomic_dec(&net->ipv6.cache_resolve_queue_len); |
515 | 539 | ||
516 | while((skb = skb_dequeue(&c->mfc_un.unres.unresolved)) != NULL) { | 540 | while((skb = skb_dequeue(&c->mfc_un.unres.unresolved)) != NULL) { |
517 | if (ipv6_hdr(skb)->version == 0) { | 541 | if (ipv6_hdr(skb)->version == 0) { |
@@ -520,12 +544,12 @@ static void ip6mr_destroy_unres(struct mfc6_cache *c) | |||
520 | nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); | 544 | nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); |
521 | skb_trim(skb, nlh->nlmsg_len); | 545 | skb_trim(skb, nlh->nlmsg_len); |
522 | ((struct nlmsgerr *)NLMSG_DATA(nlh))->error = -ETIMEDOUT; | 546 | ((struct nlmsgerr *)NLMSG_DATA(nlh))->error = -ETIMEDOUT; |
523 | rtnl_unicast(skb, &init_net, NETLINK_CB(skb).pid); | 547 | rtnl_unicast(skb, net, NETLINK_CB(skb).pid); |
524 | } else | 548 | } else |
525 | kfree_skb(skb); | 549 | kfree_skb(skb); |
526 | } | 550 | } |
527 | 551 | ||
528 | kmem_cache_free(mrt_cachep, c); | 552 | ip6mr_cache_free(c); |
529 | } | 553 | } |
530 | 554 | ||
531 | 555 | ||
@@ -553,7 +577,7 @@ static void ipmr_do_expire_process(unsigned long dummy) | |||
553 | ip6mr_destroy_unres(c); | 577 | ip6mr_destroy_unres(c); |
554 | } | 578 | } |
555 | 579 | ||
556 | if (atomic_read(&cache_resolve_queue_len)) | 580 | if (mfc_unres_queue != NULL) |
557 | mod_timer(&ipmr_expire_timer, jiffies + expires); | 581 | mod_timer(&ipmr_expire_timer, jiffies + expires); |
558 | } | 582 | } |
559 | 583 | ||
@@ -564,7 +588,7 @@ static void ipmr_expire_process(unsigned long dummy) | |||
564 | return; | 588 | return; |
565 | } | 589 | } |
566 | 590 | ||
567 | if (atomic_read(&cache_resolve_queue_len)) | 591 | if (mfc_unres_queue != NULL) |
568 | ipmr_do_expire_process(dummy); | 592 | ipmr_do_expire_process(dummy); |
569 | 593 | ||
570 | spin_unlock(&mfc_unres_lock); | 594 | spin_unlock(&mfc_unres_lock); |
@@ -575,13 +599,15 @@ static void ipmr_expire_process(unsigned long dummy) | |||
575 | static void ip6mr_update_thresholds(struct mfc6_cache *cache, unsigned char *ttls) | 599 | static void ip6mr_update_thresholds(struct mfc6_cache *cache, unsigned char *ttls) |
576 | { | 600 | { |
577 | int vifi; | 601 | int vifi; |
602 | struct net *net = mfc6_net(cache); | ||
578 | 603 | ||
579 | cache->mfc_un.res.minvif = MAXMIFS; | 604 | cache->mfc_un.res.minvif = MAXMIFS; |
580 | cache->mfc_un.res.maxvif = 0; | 605 | cache->mfc_un.res.maxvif = 0; |
581 | memset(cache->mfc_un.res.ttls, 255, MAXMIFS); | 606 | memset(cache->mfc_un.res.ttls, 255, MAXMIFS); |
582 | 607 | ||
583 | for (vifi = 0; vifi < maxvif; vifi++) { | 608 | for (vifi = 0; vifi < net->ipv6.maxvif; vifi++) { |
584 | if (MIF_EXISTS(vifi) && ttls[vifi] && ttls[vifi] < 255) { | 609 | if (MIF_EXISTS(net, vifi) && |
610 | ttls[vifi] && ttls[vifi] < 255) { | ||
585 | cache->mfc_un.res.ttls[vifi] = ttls[vifi]; | 611 | cache->mfc_un.res.ttls[vifi] = ttls[vifi]; |
586 | if (cache->mfc_un.res.minvif > vifi) | 612 | if (cache->mfc_un.res.minvif > vifi) |
587 | cache->mfc_un.res.minvif = vifi; | 613 | cache->mfc_un.res.minvif = vifi; |
@@ -591,15 +617,15 @@ static void ip6mr_update_thresholds(struct mfc6_cache *cache, unsigned char *ttl | |||
591 | } | 617 | } |
592 | } | 618 | } |
593 | 619 | ||
594 | static int mif6_add(struct mif6ctl *vifc, int mrtsock) | 620 | static int mif6_add(struct net *net, struct mif6ctl *vifc, int mrtsock) |
595 | { | 621 | { |
596 | int vifi = vifc->mif6c_mifi; | 622 | int vifi = vifc->mif6c_mifi; |
597 | struct mif_device *v = &vif6_table[vifi]; | 623 | struct mif_device *v = &net->ipv6.vif6_table[vifi]; |
598 | struct net_device *dev; | 624 | struct net_device *dev; |
599 | int err; | 625 | int err; |
600 | 626 | ||
601 | /* Is vif busy ? */ | 627 | /* Is vif busy ? */ |
602 | if (MIF_EXISTS(vifi)) | 628 | if (MIF_EXISTS(net, vifi)) |
603 | return -EADDRINUSE; | 629 | return -EADDRINUSE; |
604 | 630 | ||
605 | switch (vifc->mif6c_flags) { | 631 | switch (vifc->mif6c_flags) { |
@@ -609,9 +635,9 @@ static int mif6_add(struct mif6ctl *vifc, int mrtsock) | |||
609 | * Special Purpose VIF in PIM | 635 | * Special Purpose VIF in PIM |
610 | * All the packets will be sent to the daemon | 636 | * All the packets will be sent to the daemon |
611 | */ | 637 | */ |
612 | if (reg_vif_num >= 0) | 638 | if (net->ipv6.mroute_reg_vif_num >= 0) |
613 | return -EADDRINUSE; | 639 | return -EADDRINUSE; |
614 | dev = ip6mr_reg_vif(); | 640 | dev = ip6mr_reg_vif(net); |
615 | if (!dev) | 641 | if (!dev) |
616 | return -ENOBUFS; | 642 | return -ENOBUFS; |
617 | err = dev_set_allmulti(dev, 1); | 643 | err = dev_set_allmulti(dev, 1); |
@@ -623,7 +649,7 @@ static int mif6_add(struct mif6ctl *vifc, int mrtsock) | |||
623 | break; | 649 | break; |
624 | #endif | 650 | #endif |
625 | case 0: | 651 | case 0: |
626 | dev = dev_get_by_index(&init_net, vifc->mif6c_pifi); | 652 | dev = dev_get_by_index(net, vifc->mif6c_pifi); |
627 | if (!dev) | 653 | if (!dev) |
628 | return -EADDRNOTAVAIL; | 654 | return -EADDRNOTAVAIL; |
629 | err = dev_set_allmulti(dev, 1); | 655 | err = dev_set_allmulti(dev, 1); |
@@ -657,20 +683,22 @@ static int mif6_add(struct mif6ctl *vifc, int mrtsock) | |||
657 | v->dev = dev; | 683 | v->dev = dev; |
658 | #ifdef CONFIG_IPV6_PIMSM_V2 | 684 | #ifdef CONFIG_IPV6_PIMSM_V2 |
659 | if (v->flags & MIFF_REGISTER) | 685 | if (v->flags & MIFF_REGISTER) |
660 | reg_vif_num = vifi; | 686 | net->ipv6.mroute_reg_vif_num = vifi; |
661 | #endif | 687 | #endif |
662 | if (vifi + 1 > maxvif) | 688 | if (vifi + 1 > net->ipv6.maxvif) |
663 | maxvif = vifi + 1; | 689 | net->ipv6.maxvif = vifi + 1; |
664 | write_unlock_bh(&mrt_lock); | 690 | write_unlock_bh(&mrt_lock); |
665 | return 0; | 691 | return 0; |
666 | } | 692 | } |
667 | 693 | ||
668 | static struct mfc6_cache *ip6mr_cache_find(struct in6_addr *origin, struct in6_addr *mcastgrp) | 694 | static struct mfc6_cache *ip6mr_cache_find(struct net *net, |
695 | struct in6_addr *origin, | ||
696 | struct in6_addr *mcastgrp) | ||
669 | { | 697 | { |
670 | int line = MFC6_HASH(mcastgrp, origin); | 698 | int line = MFC6_HASH(mcastgrp, origin); |
671 | struct mfc6_cache *c; | 699 | struct mfc6_cache *c; |
672 | 700 | ||
673 | for (c = mfc6_cache_array[line]; c; c = c->next) { | 701 | for (c = net->ipv6.mfc6_cache_array[line]; c; c = c->next) { |
674 | if (ipv6_addr_equal(&c->mf6c_origin, origin) && | 702 | if (ipv6_addr_equal(&c->mf6c_origin, origin) && |
675 | ipv6_addr_equal(&c->mf6c_mcastgrp, mcastgrp)) | 703 | ipv6_addr_equal(&c->mf6c_mcastgrp, mcastgrp)) |
676 | break; | 704 | break; |
@@ -681,24 +709,24 @@ static struct mfc6_cache *ip6mr_cache_find(struct in6_addr *origin, struct in6_a | |||
681 | /* | 709 | /* |
682 | * Allocate a multicast cache entry | 710 | * Allocate a multicast cache entry |
683 | */ | 711 | */ |
684 | static struct mfc6_cache *ip6mr_cache_alloc(void) | 712 | static struct mfc6_cache *ip6mr_cache_alloc(struct net *net) |
685 | { | 713 | { |
686 | struct mfc6_cache *c = kmem_cache_alloc(mrt_cachep, GFP_KERNEL); | 714 | struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL); |
687 | if (c == NULL) | 715 | if (c == NULL) |
688 | return NULL; | 716 | return NULL; |
689 | memset(c, 0, sizeof(*c)); | ||
690 | c->mfc_un.res.minvif = MAXMIFS; | 717 | c->mfc_un.res.minvif = MAXMIFS; |
718 | mfc6_net_set(c, net); | ||
691 | return c; | 719 | return c; |
692 | } | 720 | } |
693 | 721 | ||
694 | static struct mfc6_cache *ip6mr_cache_alloc_unres(void) | 722 | static struct mfc6_cache *ip6mr_cache_alloc_unres(struct net *net) |
695 | { | 723 | { |
696 | struct mfc6_cache *c = kmem_cache_alloc(mrt_cachep, GFP_ATOMIC); | 724 | struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC); |
697 | if (c == NULL) | 725 | if (c == NULL) |
698 | return NULL; | 726 | return NULL; |
699 | memset(c, 0, sizeof(*c)); | ||
700 | skb_queue_head_init(&c->mfc_un.unres.unresolved); | 727 | skb_queue_head_init(&c->mfc_un.unres.unresolved); |
701 | c->mfc_un.unres.expires = jiffies + 10 * HZ; | 728 | c->mfc_un.unres.expires = jiffies + 10 * HZ; |
729 | mfc6_net_set(c, net); | ||
702 | return c; | 730 | return c; |
703 | } | 731 | } |
704 | 732 | ||
@@ -727,7 +755,7 @@ static void ip6mr_cache_resolve(struct mfc6_cache *uc, struct mfc6_cache *c) | |||
727 | skb_trim(skb, nlh->nlmsg_len); | 755 | skb_trim(skb, nlh->nlmsg_len); |
728 | ((struct nlmsgerr *)NLMSG_DATA(nlh))->error = -EMSGSIZE; | 756 | ((struct nlmsgerr *)NLMSG_DATA(nlh))->error = -EMSGSIZE; |
729 | } | 757 | } |
730 | err = rtnl_unicast(skb, &init_net, NETLINK_CB(skb).pid); | 758 | err = rtnl_unicast(skb, mfc6_net(uc), NETLINK_CB(skb).pid); |
731 | } else | 759 | } else |
732 | ip6_mr_forward(skb, c); | 760 | ip6_mr_forward(skb, c); |
733 | } | 761 | } |
@@ -740,7 +768,8 @@ static void ip6mr_cache_resolve(struct mfc6_cache *uc, struct mfc6_cache *c) | |||
740 | * Called under mrt_lock. | 768 | * Called under mrt_lock. |
741 | */ | 769 | */ |
742 | 770 | ||
743 | static int ip6mr_cache_report(struct sk_buff *pkt, mifi_t mifi, int assert) | 771 | static int ip6mr_cache_report(struct net *net, struct sk_buff *pkt, mifi_t mifi, |
772 | int assert) | ||
744 | { | 773 | { |
745 | struct sk_buff *skb; | 774 | struct sk_buff *skb; |
746 | struct mrt6msg *msg; | 775 | struct mrt6msg *msg; |
@@ -776,7 +805,7 @@ static int ip6mr_cache_report(struct sk_buff *pkt, mifi_t mifi, int assert) | |||
776 | msg = (struct mrt6msg *)skb_transport_header(skb); | 805 | msg = (struct mrt6msg *)skb_transport_header(skb); |
777 | msg->im6_mbz = 0; | 806 | msg->im6_mbz = 0; |
778 | msg->im6_msgtype = MRT6MSG_WHOLEPKT; | 807 | msg->im6_msgtype = MRT6MSG_WHOLEPKT; |
779 | msg->im6_mif = reg_vif_num; | 808 | msg->im6_mif = net->ipv6.mroute_reg_vif_num; |
780 | msg->im6_pad = 0; | 809 | msg->im6_pad = 0; |
781 | ipv6_addr_copy(&msg->im6_src, &ipv6_hdr(pkt)->saddr); | 810 | ipv6_addr_copy(&msg->im6_src, &ipv6_hdr(pkt)->saddr); |
782 | ipv6_addr_copy(&msg->im6_dst, &ipv6_hdr(pkt)->daddr); | 811 | ipv6_addr_copy(&msg->im6_dst, &ipv6_hdr(pkt)->daddr); |
@@ -813,7 +842,7 @@ static int ip6mr_cache_report(struct sk_buff *pkt, mifi_t mifi, int assert) | |||
813 | skb_pull(skb, sizeof(struct ipv6hdr)); | 842 | skb_pull(skb, sizeof(struct ipv6hdr)); |
814 | } | 843 | } |
815 | 844 | ||
816 | if (mroute6_socket == NULL) { | 845 | if (net->ipv6.mroute6_sk == NULL) { |
817 | kfree_skb(skb); | 846 | kfree_skb(skb); |
818 | return -EINVAL; | 847 | return -EINVAL; |
819 | } | 848 | } |
@@ -821,7 +850,8 @@ static int ip6mr_cache_report(struct sk_buff *pkt, mifi_t mifi, int assert) | |||
821 | /* | 850 | /* |
822 | * Deliver to user space multicast routing algorithms | 851 | * Deliver to user space multicast routing algorithms |
823 | */ | 852 | */ |
824 | if ((ret = sock_queue_rcv_skb(mroute6_socket, skb)) < 0) { | 853 | ret = sock_queue_rcv_skb(net->ipv6.mroute6_sk, skb); |
854 | if (ret < 0) { | ||
825 | if (net_ratelimit()) | 855 | if (net_ratelimit()) |
826 | printk(KERN_WARNING "mroute6: pending queue full, dropping entries.\n"); | 856 | printk(KERN_WARNING "mroute6: pending queue full, dropping entries.\n"); |
827 | kfree_skb(skb); | 857 | kfree_skb(skb); |
@@ -835,14 +865,15 @@ static int ip6mr_cache_report(struct sk_buff *pkt, mifi_t mifi, int assert) | |||
835 | */ | 865 | */ |
836 | 866 | ||
837 | static int | 867 | static int |
838 | ip6mr_cache_unresolved(mifi_t mifi, struct sk_buff *skb) | 868 | ip6mr_cache_unresolved(struct net *net, mifi_t mifi, struct sk_buff *skb) |
839 | { | 869 | { |
840 | int err; | 870 | int err; |
841 | struct mfc6_cache *c; | 871 | struct mfc6_cache *c; |
842 | 872 | ||
843 | spin_lock_bh(&mfc_unres_lock); | 873 | spin_lock_bh(&mfc_unres_lock); |
844 | for (c = mfc_unres_queue; c; c = c->next) { | 874 | for (c = mfc_unres_queue; c; c = c->next) { |
845 | if (ipv6_addr_equal(&c->mf6c_mcastgrp, &ipv6_hdr(skb)->daddr) && | 875 | if (net_eq(mfc6_net(c), net) && |
876 | ipv6_addr_equal(&c->mf6c_mcastgrp, &ipv6_hdr(skb)->daddr) && | ||
846 | ipv6_addr_equal(&c->mf6c_origin, &ipv6_hdr(skb)->saddr)) | 877 | ipv6_addr_equal(&c->mf6c_origin, &ipv6_hdr(skb)->saddr)) |
847 | break; | 878 | break; |
848 | } | 879 | } |
@@ -852,8 +883,8 @@ ip6mr_cache_unresolved(mifi_t mifi, struct sk_buff *skb) | |||
852 | * Create a new entry if allowable | 883 | * Create a new entry if allowable |
853 | */ | 884 | */ |
854 | 885 | ||
855 | if (atomic_read(&cache_resolve_queue_len) >= 10 || | 886 | if (atomic_read(&net->ipv6.cache_resolve_queue_len) >= 10 || |
856 | (c = ip6mr_cache_alloc_unres()) == NULL) { | 887 | (c = ip6mr_cache_alloc_unres(net)) == NULL) { |
857 | spin_unlock_bh(&mfc_unres_lock); | 888 | spin_unlock_bh(&mfc_unres_lock); |
858 | 889 | ||
859 | kfree_skb(skb); | 890 | kfree_skb(skb); |
@@ -870,18 +901,19 @@ ip6mr_cache_unresolved(mifi_t mifi, struct sk_buff *skb) | |||
870 | /* | 901 | /* |
871 | * Reflect first query at pim6sd | 902 | * Reflect first query at pim6sd |
872 | */ | 903 | */ |
873 | if ((err = ip6mr_cache_report(skb, mifi, MRT6MSG_NOCACHE)) < 0) { | 904 | err = ip6mr_cache_report(net, skb, mifi, MRT6MSG_NOCACHE); |
905 | if (err < 0) { | ||
874 | /* If the report failed throw the cache entry | 906 | /* If the report failed throw the cache entry |
875 | out - Brad Parker | 907 | out - Brad Parker |
876 | */ | 908 | */ |
877 | spin_unlock_bh(&mfc_unres_lock); | 909 | spin_unlock_bh(&mfc_unres_lock); |
878 | 910 | ||
879 | kmem_cache_free(mrt_cachep, c); | 911 | ip6mr_cache_free(c); |
880 | kfree_skb(skb); | 912 | kfree_skb(skb); |
881 | return err; | 913 | return err; |
882 | } | 914 | } |
883 | 915 | ||
884 | atomic_inc(&cache_resolve_queue_len); | 916 | atomic_inc(&net->ipv6.cache_resolve_queue_len); |
885 | c->next = mfc_unres_queue; | 917 | c->next = mfc_unres_queue; |
886 | mfc_unres_queue = c; | 918 | mfc_unres_queue = c; |
887 | 919 | ||
@@ -907,21 +939,22 @@ ip6mr_cache_unresolved(mifi_t mifi, struct sk_buff *skb) | |||
907 | * MFC6 cache manipulation by user space | 939 | * MFC6 cache manipulation by user space |
908 | */ | 940 | */ |
909 | 941 | ||
910 | static int ip6mr_mfc_delete(struct mf6cctl *mfc) | 942 | static int ip6mr_mfc_delete(struct net *net, struct mf6cctl *mfc) |
911 | { | 943 | { |
912 | int line; | 944 | int line; |
913 | struct mfc6_cache *c, **cp; | 945 | struct mfc6_cache *c, **cp; |
914 | 946 | ||
915 | line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr); | 947 | line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr); |
916 | 948 | ||
917 | for (cp = &mfc6_cache_array[line]; (c = *cp) != NULL; cp = &c->next) { | 949 | for (cp = &net->ipv6.mfc6_cache_array[line]; |
950 | (c = *cp) != NULL; cp = &c->next) { | ||
918 | if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) && | 951 | if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) && |
919 | ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr)) { | 952 | ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr)) { |
920 | write_lock_bh(&mrt_lock); | 953 | write_lock_bh(&mrt_lock); |
921 | *cp = c->next; | 954 | *cp = c->next; |
922 | write_unlock_bh(&mrt_lock); | 955 | write_unlock_bh(&mrt_lock); |
923 | 956 | ||
924 | kmem_cache_free(mrt_cachep, c); | 957 | ip6mr_cache_free(c); |
925 | return 0; | 958 | return 0; |
926 | } | 959 | } |
927 | } | 960 | } |
@@ -932,19 +965,17 @@ static int ip6mr_device_event(struct notifier_block *this, | |||
932 | unsigned long event, void *ptr) | 965 | unsigned long event, void *ptr) |
933 | { | 966 | { |
934 | struct net_device *dev = ptr; | 967 | struct net_device *dev = ptr; |
968 | struct net *net = dev_net(dev); | ||
935 | struct mif_device *v; | 969 | struct mif_device *v; |
936 | int ct; | 970 | int ct; |
937 | 971 | ||
938 | if (!net_eq(dev_net(dev), &init_net)) | ||
939 | return NOTIFY_DONE; | ||
940 | |||
941 | if (event != NETDEV_UNREGISTER) | 972 | if (event != NETDEV_UNREGISTER) |
942 | return NOTIFY_DONE; | 973 | return NOTIFY_DONE; |
943 | 974 | ||
944 | v = &vif6_table[0]; | 975 | v = &net->ipv6.vif6_table[0]; |
945 | for (ct = 0; ct < maxvif; ct++, v++) { | 976 | for (ct = 0; ct < net->ipv6.maxvif; ct++, v++) { |
946 | if (v->dev == dev) | 977 | if (v->dev == dev) |
947 | mif6_delete(ct); | 978 | mif6_delete(net, ct); |
948 | } | 979 | } |
949 | return NOTIFY_DONE; | 980 | return NOTIFY_DONE; |
950 | } | 981 | } |
@@ -957,6 +988,66 @@ static struct notifier_block ip6_mr_notifier = { | |||
957 | * Setup for IP multicast routing | 988 | * Setup for IP multicast routing |
958 | */ | 989 | */ |
959 | 990 | ||
991 | static int __net_init ip6mr_net_init(struct net *net) | ||
992 | { | ||
993 | int err = 0; | ||
994 | net->ipv6.vif6_table = kcalloc(MAXMIFS, sizeof(struct mif_device), | ||
995 | GFP_KERNEL); | ||
996 | if (!net->ipv6.vif6_table) { | ||
997 | err = -ENOMEM; | ||
998 | goto fail; | ||
999 | } | ||
1000 | |||
1001 | /* Forwarding cache */ | ||
1002 | net->ipv6.mfc6_cache_array = kcalloc(MFC6_LINES, | ||
1003 | sizeof(struct mfc6_cache *), | ||
1004 | GFP_KERNEL); | ||
1005 | if (!net->ipv6.mfc6_cache_array) { | ||
1006 | err = -ENOMEM; | ||
1007 | goto fail_mfc6_cache; | ||
1008 | } | ||
1009 | |||
1010 | #ifdef CONFIG_IPV6_PIMSM_V2 | ||
1011 | net->ipv6.mroute_reg_vif_num = -1; | ||
1012 | #endif | ||
1013 | |||
1014 | #ifdef CONFIG_PROC_FS | ||
1015 | err = -ENOMEM; | ||
1016 | if (!proc_net_fops_create(net, "ip6_mr_vif", 0, &ip6mr_vif_fops)) | ||
1017 | goto proc_vif_fail; | ||
1018 | if (!proc_net_fops_create(net, "ip6_mr_cache", 0, &ip6mr_mfc_fops)) | ||
1019 | goto proc_cache_fail; | ||
1020 | #endif | ||
1021 | return 0; | ||
1022 | |||
1023 | #ifdef CONFIG_PROC_FS | ||
1024 | proc_cache_fail: | ||
1025 | proc_net_remove(net, "ip6_mr_vif"); | ||
1026 | proc_vif_fail: | ||
1027 | kfree(net->ipv6.mfc6_cache_array); | ||
1028 | #endif | ||
1029 | fail_mfc6_cache: | ||
1030 | kfree(net->ipv6.vif6_table); | ||
1031 | fail: | ||
1032 | return err; | ||
1033 | } | ||
1034 | |||
1035 | static void __net_exit ip6mr_net_exit(struct net *net) | ||
1036 | { | ||
1037 | #ifdef CONFIG_PROC_FS | ||
1038 | proc_net_remove(net, "ip6_mr_cache"); | ||
1039 | proc_net_remove(net, "ip6_mr_vif"); | ||
1040 | #endif | ||
1041 | mroute_clean_tables(net); | ||
1042 | kfree(net->ipv6.mfc6_cache_array); | ||
1043 | kfree(net->ipv6.vif6_table); | ||
1044 | } | ||
1045 | |||
1046 | static struct pernet_operations ip6mr_net_ops = { | ||
1047 | .init = ip6mr_net_init, | ||
1048 | .exit = ip6mr_net_exit, | ||
1049 | }; | ||
1050 | |||
960 | int __init ip6_mr_init(void) | 1051 | int __init ip6_mr_init(void) |
961 | { | 1052 | { |
962 | int err; | 1053 | int err; |
@@ -968,43 +1059,32 @@ int __init ip6_mr_init(void) | |||
968 | if (!mrt_cachep) | 1059 | if (!mrt_cachep) |
969 | return -ENOMEM; | 1060 | return -ENOMEM; |
970 | 1061 | ||
1062 | err = register_pernet_subsys(&ip6mr_net_ops); | ||
1063 | if (err) | ||
1064 | goto reg_pernet_fail; | ||
1065 | |||
971 | setup_timer(&ipmr_expire_timer, ipmr_expire_process, 0); | 1066 | setup_timer(&ipmr_expire_timer, ipmr_expire_process, 0); |
972 | err = register_netdevice_notifier(&ip6_mr_notifier); | 1067 | err = register_netdevice_notifier(&ip6_mr_notifier); |
973 | if (err) | 1068 | if (err) |
974 | goto reg_notif_fail; | 1069 | goto reg_notif_fail; |
975 | #ifdef CONFIG_PROC_FS | ||
976 | err = -ENOMEM; | ||
977 | if (!proc_net_fops_create(&init_net, "ip6_mr_vif", 0, &ip6mr_vif_fops)) | ||
978 | goto proc_vif_fail; | ||
979 | if (!proc_net_fops_create(&init_net, "ip6_mr_cache", | ||
980 | 0, &ip6mr_mfc_fops)) | ||
981 | goto proc_cache_fail; | ||
982 | #endif | ||
983 | return 0; | 1070 | return 0; |
984 | #ifdef CONFIG_PROC_FS | ||
985 | proc_cache_fail: | ||
986 | proc_net_remove(&init_net, "ip6_mr_vif"); | ||
987 | proc_vif_fail: | ||
988 | unregister_netdevice_notifier(&ip6_mr_notifier); | ||
989 | #endif | ||
990 | reg_notif_fail: | 1071 | reg_notif_fail: |
991 | del_timer(&ipmr_expire_timer); | 1072 | del_timer(&ipmr_expire_timer); |
1073 | unregister_pernet_subsys(&ip6mr_net_ops); | ||
1074 | reg_pernet_fail: | ||
992 | kmem_cache_destroy(mrt_cachep); | 1075 | kmem_cache_destroy(mrt_cachep); |
993 | return err; | 1076 | return err; |
994 | } | 1077 | } |
995 | 1078 | ||
996 | void ip6_mr_cleanup(void) | 1079 | void ip6_mr_cleanup(void) |
997 | { | 1080 | { |
998 | #ifdef CONFIG_PROC_FS | ||
999 | proc_net_remove(&init_net, "ip6_mr_cache"); | ||
1000 | proc_net_remove(&init_net, "ip6_mr_vif"); | ||
1001 | #endif | ||
1002 | unregister_netdevice_notifier(&ip6_mr_notifier); | 1081 | unregister_netdevice_notifier(&ip6_mr_notifier); |
1003 | del_timer(&ipmr_expire_timer); | 1082 | del_timer(&ipmr_expire_timer); |
1083 | unregister_pernet_subsys(&ip6mr_net_ops); | ||
1004 | kmem_cache_destroy(mrt_cachep); | 1084 | kmem_cache_destroy(mrt_cachep); |
1005 | } | 1085 | } |
1006 | 1086 | ||
1007 | static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock) | 1087 | static int ip6mr_mfc_add(struct net *net, struct mf6cctl *mfc, int mrtsock) |
1008 | { | 1088 | { |
1009 | int line; | 1089 | int line; |
1010 | struct mfc6_cache *uc, *c, **cp; | 1090 | struct mfc6_cache *uc, *c, **cp; |
@@ -1020,7 +1100,8 @@ static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock) | |||
1020 | 1100 | ||
1021 | line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr); | 1101 | line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr); |
1022 | 1102 | ||
1023 | for (cp = &mfc6_cache_array[line]; (c = *cp) != NULL; cp = &c->next) { | 1103 | for (cp = &net->ipv6.mfc6_cache_array[line]; |
1104 | (c = *cp) != NULL; cp = &c->next) { | ||
1024 | if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) && | 1105 | if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) && |
1025 | ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr)) | 1106 | ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr)) |
1026 | break; | 1107 | break; |
@@ -1039,7 +1120,7 @@ static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock) | |||
1039 | if (!ipv6_addr_is_multicast(&mfc->mf6cc_mcastgrp.sin6_addr)) | 1120 | if (!ipv6_addr_is_multicast(&mfc->mf6cc_mcastgrp.sin6_addr)) |
1040 | return -EINVAL; | 1121 | return -EINVAL; |
1041 | 1122 | ||
1042 | c = ip6mr_cache_alloc(); | 1123 | c = ip6mr_cache_alloc(net); |
1043 | if (c == NULL) | 1124 | if (c == NULL) |
1044 | return -ENOMEM; | 1125 | return -ENOMEM; |
1045 | 1126 | ||
@@ -1051,8 +1132,8 @@ static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock) | |||
1051 | c->mfc_flags |= MFC_STATIC; | 1132 | c->mfc_flags |= MFC_STATIC; |
1052 | 1133 | ||
1053 | write_lock_bh(&mrt_lock); | 1134 | write_lock_bh(&mrt_lock); |
1054 | c->next = mfc6_cache_array[line]; | 1135 | c->next = net->ipv6.mfc6_cache_array[line]; |
1055 | mfc6_cache_array[line] = c; | 1136 | net->ipv6.mfc6_cache_array[line] = c; |
1056 | write_unlock_bh(&mrt_lock); | 1137 | write_unlock_bh(&mrt_lock); |
1057 | 1138 | ||
1058 | /* | 1139 | /* |
@@ -1062,19 +1143,21 @@ static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock) | |||
1062 | spin_lock_bh(&mfc_unres_lock); | 1143 | spin_lock_bh(&mfc_unres_lock); |
1063 | for (cp = &mfc_unres_queue; (uc = *cp) != NULL; | 1144 | for (cp = &mfc_unres_queue; (uc = *cp) != NULL; |
1064 | cp = &uc->next) { | 1145 | cp = &uc->next) { |
1065 | if (ipv6_addr_equal(&uc->mf6c_origin, &c->mf6c_origin) && | 1146 | if (net_eq(mfc6_net(uc), net) && |
1147 | ipv6_addr_equal(&uc->mf6c_origin, &c->mf6c_origin) && | ||
1066 | ipv6_addr_equal(&uc->mf6c_mcastgrp, &c->mf6c_mcastgrp)) { | 1148 | ipv6_addr_equal(&uc->mf6c_mcastgrp, &c->mf6c_mcastgrp)) { |
1067 | *cp = uc->next; | 1149 | *cp = uc->next; |
1068 | if (atomic_dec_and_test(&cache_resolve_queue_len)) | 1150 | atomic_dec(&net->ipv6.cache_resolve_queue_len); |
1069 | del_timer(&ipmr_expire_timer); | ||
1070 | break; | 1151 | break; |
1071 | } | 1152 | } |
1072 | } | 1153 | } |
1154 | if (mfc_unres_queue == NULL) | ||
1155 | del_timer(&ipmr_expire_timer); | ||
1073 | spin_unlock_bh(&mfc_unres_lock); | 1156 | spin_unlock_bh(&mfc_unres_lock); |
1074 | 1157 | ||
1075 | if (uc) { | 1158 | if (uc) { |
1076 | ip6mr_cache_resolve(uc, c); | 1159 | ip6mr_cache_resolve(uc, c); |
1077 | kmem_cache_free(mrt_cachep, uc); | 1160 | ip6mr_cache_free(uc); |
1078 | } | 1161 | } |
1079 | return 0; | 1162 | return 0; |
1080 | } | 1163 | } |
@@ -1083,25 +1166,25 @@ static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock) | |||
1083 | * Close the multicast socket, and clear the vif tables etc | 1166 | * Close the multicast socket, and clear the vif tables etc |
1084 | */ | 1167 | */ |
1085 | 1168 | ||
1086 | static void mroute_clean_tables(struct sock *sk) | 1169 | static void mroute_clean_tables(struct net *net) |
1087 | { | 1170 | { |
1088 | int i; | 1171 | int i; |
1089 | 1172 | ||
1090 | /* | 1173 | /* |
1091 | * Shut down all active vif entries | 1174 | * Shut down all active vif entries |
1092 | */ | 1175 | */ |
1093 | for (i = 0; i < maxvif; i++) { | 1176 | for (i = 0; i < net->ipv6.maxvif; i++) { |
1094 | if (!(vif6_table[i].flags & VIFF_STATIC)) | 1177 | if (!(net->ipv6.vif6_table[i].flags & VIFF_STATIC)) |
1095 | mif6_delete(i); | 1178 | mif6_delete(net, i); |
1096 | } | 1179 | } |
1097 | 1180 | ||
1098 | /* | 1181 | /* |
1099 | * Wipe the cache | 1182 | * Wipe the cache |
1100 | */ | 1183 | */ |
1101 | for (i = 0; i < ARRAY_SIZE(mfc6_cache_array); i++) { | 1184 | for (i = 0; i < MFC6_LINES; i++) { |
1102 | struct mfc6_cache *c, **cp; | 1185 | struct mfc6_cache *c, **cp; |
1103 | 1186 | ||
1104 | cp = &mfc6_cache_array[i]; | 1187 | cp = &net->ipv6.mfc6_cache_array[i]; |
1105 | while ((c = *cp) != NULL) { | 1188 | while ((c = *cp) != NULL) { |
1106 | if (c->mfc_flags & MFC_STATIC) { | 1189 | if (c->mfc_flags & MFC_STATIC) { |
1107 | cp = &c->next; | 1190 | cp = &c->next; |
@@ -1111,22 +1194,22 @@ static void mroute_clean_tables(struct sock *sk) | |||
1111 | *cp = c->next; | 1194 | *cp = c->next; |
1112 | write_unlock_bh(&mrt_lock); | 1195 | write_unlock_bh(&mrt_lock); |
1113 | 1196 | ||
1114 | kmem_cache_free(mrt_cachep, c); | 1197 | ip6mr_cache_free(c); |
1115 | } | 1198 | } |
1116 | } | 1199 | } |
1117 | 1200 | ||
1118 | if (atomic_read(&cache_resolve_queue_len) != 0) { | 1201 | if (atomic_read(&net->ipv6.cache_resolve_queue_len) != 0) { |
1119 | struct mfc6_cache *c; | 1202 | struct mfc6_cache *c, **cp; |
1120 | 1203 | ||
1121 | spin_lock_bh(&mfc_unres_lock); | 1204 | spin_lock_bh(&mfc_unres_lock); |
1122 | while (mfc_unres_queue != NULL) { | 1205 | cp = &mfc_unres_queue; |
1123 | c = mfc_unres_queue; | 1206 | while ((c = *cp) != NULL) { |
1124 | mfc_unres_queue = c->next; | 1207 | if (!net_eq(mfc6_net(c), net)) { |
1125 | spin_unlock_bh(&mfc_unres_lock); | 1208 | cp = &c->next; |
1126 | 1209 | continue; | |
1210 | } | ||
1211 | *cp = c->next; | ||
1127 | ip6mr_destroy_unres(c); | 1212 | ip6mr_destroy_unres(c); |
1128 | |||
1129 | spin_lock_bh(&mfc_unres_lock); | ||
1130 | } | 1213 | } |
1131 | spin_unlock_bh(&mfc_unres_lock); | 1214 | spin_unlock_bh(&mfc_unres_lock); |
1132 | } | 1215 | } |
@@ -1135,11 +1218,12 @@ static void mroute_clean_tables(struct sock *sk) | |||
1135 | static int ip6mr_sk_init(struct sock *sk) | 1218 | static int ip6mr_sk_init(struct sock *sk) |
1136 | { | 1219 | { |
1137 | int err = 0; | 1220 | int err = 0; |
1221 | struct net *net = sock_net(sk); | ||
1138 | 1222 | ||
1139 | rtnl_lock(); | 1223 | rtnl_lock(); |
1140 | write_lock_bh(&mrt_lock); | 1224 | write_lock_bh(&mrt_lock); |
1141 | if (likely(mroute6_socket == NULL)) | 1225 | if (likely(net->ipv6.mroute6_sk == NULL)) |
1142 | mroute6_socket = sk; | 1226 | net->ipv6.mroute6_sk = sk; |
1143 | else | 1227 | else |
1144 | err = -EADDRINUSE; | 1228 | err = -EADDRINUSE; |
1145 | write_unlock_bh(&mrt_lock); | 1229 | write_unlock_bh(&mrt_lock); |
@@ -1152,14 +1236,15 @@ static int ip6mr_sk_init(struct sock *sk) | |||
1152 | int ip6mr_sk_done(struct sock *sk) | 1236 | int ip6mr_sk_done(struct sock *sk) |
1153 | { | 1237 | { |
1154 | int err = 0; | 1238 | int err = 0; |
1239 | struct net *net = sock_net(sk); | ||
1155 | 1240 | ||
1156 | rtnl_lock(); | 1241 | rtnl_lock(); |
1157 | if (sk == mroute6_socket) { | 1242 | if (sk == net->ipv6.mroute6_sk) { |
1158 | write_lock_bh(&mrt_lock); | 1243 | write_lock_bh(&mrt_lock); |
1159 | mroute6_socket = NULL; | 1244 | net->ipv6.mroute6_sk = NULL; |
1160 | write_unlock_bh(&mrt_lock); | 1245 | write_unlock_bh(&mrt_lock); |
1161 | 1246 | ||
1162 | mroute_clean_tables(sk); | 1247 | mroute_clean_tables(net); |
1163 | } else | 1248 | } else |
1164 | err = -EACCES; | 1249 | err = -EACCES; |
1165 | rtnl_unlock(); | 1250 | rtnl_unlock(); |
@@ -1180,9 +1265,10 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1180 | struct mif6ctl vif; | 1265 | struct mif6ctl vif; |
1181 | struct mf6cctl mfc; | 1266 | struct mf6cctl mfc; |
1182 | mifi_t mifi; | 1267 | mifi_t mifi; |
1268 | struct net *net = sock_net(sk); | ||
1183 | 1269 | ||
1184 | if (optname != MRT6_INIT) { | 1270 | if (optname != MRT6_INIT) { |
1185 | if (sk != mroute6_socket && !capable(CAP_NET_ADMIN)) | 1271 | if (sk != net->ipv6.mroute6_sk && !capable(CAP_NET_ADMIN)) |
1186 | return -EACCES; | 1272 | return -EACCES; |
1187 | } | 1273 | } |
1188 | 1274 | ||
@@ -1207,7 +1293,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1207 | if (vif.mif6c_mifi >= MAXMIFS) | 1293 | if (vif.mif6c_mifi >= MAXMIFS) |
1208 | return -ENFILE; | 1294 | return -ENFILE; |
1209 | rtnl_lock(); | 1295 | rtnl_lock(); |
1210 | ret = mif6_add(&vif, sk == mroute6_socket); | 1296 | ret = mif6_add(net, &vif, sk == net->ipv6.mroute6_sk); |
1211 | rtnl_unlock(); | 1297 | rtnl_unlock(); |
1212 | return ret; | 1298 | return ret; |
1213 | 1299 | ||
@@ -1217,7 +1303,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1217 | if (copy_from_user(&mifi, optval, sizeof(mifi_t))) | 1303 | if (copy_from_user(&mifi, optval, sizeof(mifi_t))) |
1218 | return -EFAULT; | 1304 | return -EFAULT; |
1219 | rtnl_lock(); | 1305 | rtnl_lock(); |
1220 | ret = mif6_delete(mifi); | 1306 | ret = mif6_delete(net, mifi); |
1221 | rtnl_unlock(); | 1307 | rtnl_unlock(); |
1222 | return ret; | 1308 | return ret; |
1223 | 1309 | ||
@@ -1233,9 +1319,10 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1233 | return -EFAULT; | 1319 | return -EFAULT; |
1234 | rtnl_lock(); | 1320 | rtnl_lock(); |
1235 | if (optname == MRT6_DEL_MFC) | 1321 | if (optname == MRT6_DEL_MFC) |
1236 | ret = ip6mr_mfc_delete(&mfc); | 1322 | ret = ip6mr_mfc_delete(net, &mfc); |
1237 | else | 1323 | else |
1238 | ret = ip6mr_mfc_add(&mfc, sk == mroute6_socket); | 1324 | ret = ip6mr_mfc_add(net, &mfc, |
1325 | sk == net->ipv6.mroute6_sk); | ||
1239 | rtnl_unlock(); | 1326 | rtnl_unlock(); |
1240 | return ret; | 1327 | return ret; |
1241 | 1328 | ||
@@ -1247,7 +1334,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1247 | int v; | 1334 | int v; |
1248 | if (get_user(v, (int __user *)optval)) | 1335 | if (get_user(v, (int __user *)optval)) |
1249 | return -EFAULT; | 1336 | return -EFAULT; |
1250 | mroute_do_assert = !!v; | 1337 | net->ipv6.mroute_do_assert = !!v; |
1251 | return 0; | 1338 | return 0; |
1252 | } | 1339 | } |
1253 | 1340 | ||
@@ -1260,10 +1347,10 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1260 | v = !!v; | 1347 | v = !!v; |
1261 | rtnl_lock(); | 1348 | rtnl_lock(); |
1262 | ret = 0; | 1349 | ret = 0; |
1263 | if (v != mroute_do_pim) { | 1350 | if (v != net->ipv6.mroute_do_pim) { |
1264 | mroute_do_pim = v; | 1351 | net->ipv6.mroute_do_pim = v; |
1265 | mroute_do_assert = v; | 1352 | net->ipv6.mroute_do_assert = v; |
1266 | if (mroute_do_pim) | 1353 | if (net->ipv6.mroute_do_pim) |
1267 | ret = inet6_add_protocol(&pim6_protocol, | 1354 | ret = inet6_add_protocol(&pim6_protocol, |
1268 | IPPROTO_PIM); | 1355 | IPPROTO_PIM); |
1269 | else | 1356 | else |
@@ -1295,6 +1382,7 @@ int ip6_mroute_getsockopt(struct sock *sk, int optname, char __user *optval, | |||
1295 | { | 1382 | { |
1296 | int olr; | 1383 | int olr; |
1297 | int val; | 1384 | int val; |
1385 | struct net *net = sock_net(sk); | ||
1298 | 1386 | ||
1299 | switch (optname) { | 1387 | switch (optname) { |
1300 | case MRT6_VERSION: | 1388 | case MRT6_VERSION: |
@@ -1302,11 +1390,11 @@ int ip6_mroute_getsockopt(struct sock *sk, int optname, char __user *optval, | |||
1302 | break; | 1390 | break; |
1303 | #ifdef CONFIG_IPV6_PIMSM_V2 | 1391 | #ifdef CONFIG_IPV6_PIMSM_V2 |
1304 | case MRT6_PIM: | 1392 | case MRT6_PIM: |
1305 | val = mroute_do_pim; | 1393 | val = net->ipv6.mroute_do_pim; |
1306 | break; | 1394 | break; |
1307 | #endif | 1395 | #endif |
1308 | case MRT6_ASSERT: | 1396 | case MRT6_ASSERT: |
1309 | val = mroute_do_assert; | 1397 | val = net->ipv6.mroute_do_assert; |
1310 | break; | 1398 | break; |
1311 | default: | 1399 | default: |
1312 | return -ENOPROTOOPT; | 1400 | return -ENOPROTOOPT; |
@@ -1336,16 +1424,17 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg) | |||
1336 | struct sioc_mif_req6 vr; | 1424 | struct sioc_mif_req6 vr; |
1337 | struct mif_device *vif; | 1425 | struct mif_device *vif; |
1338 | struct mfc6_cache *c; | 1426 | struct mfc6_cache *c; |
1427 | struct net *net = sock_net(sk); | ||
1339 | 1428 | ||
1340 | switch (cmd) { | 1429 | switch (cmd) { |
1341 | case SIOCGETMIFCNT_IN6: | 1430 | case SIOCGETMIFCNT_IN6: |
1342 | if (copy_from_user(&vr, arg, sizeof(vr))) | 1431 | if (copy_from_user(&vr, arg, sizeof(vr))) |
1343 | return -EFAULT; | 1432 | return -EFAULT; |
1344 | if (vr.mifi >= maxvif) | 1433 | if (vr.mifi >= net->ipv6.maxvif) |
1345 | return -EINVAL; | 1434 | return -EINVAL; |
1346 | read_lock(&mrt_lock); | 1435 | read_lock(&mrt_lock); |
1347 | vif = &vif6_table[vr.mifi]; | 1436 | vif = &net->ipv6.vif6_table[vr.mifi]; |
1348 | if (MIF_EXISTS(vr.mifi)) { | 1437 | if (MIF_EXISTS(net, vr.mifi)) { |
1349 | vr.icount = vif->pkt_in; | 1438 | vr.icount = vif->pkt_in; |
1350 | vr.ocount = vif->pkt_out; | 1439 | vr.ocount = vif->pkt_out; |
1351 | vr.ibytes = vif->bytes_in; | 1440 | vr.ibytes = vif->bytes_in; |
@@ -1363,7 +1452,7 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg) | |||
1363 | return -EFAULT; | 1452 | return -EFAULT; |
1364 | 1453 | ||
1365 | read_lock(&mrt_lock); | 1454 | read_lock(&mrt_lock); |
1366 | c = ip6mr_cache_find(&sr.src.sin6_addr, &sr.grp.sin6_addr); | 1455 | c = ip6mr_cache_find(net, &sr.src.sin6_addr, &sr.grp.sin6_addr); |
1367 | if (c) { | 1456 | if (c) { |
1368 | sr.pktcnt = c->mfc_un.res.pkt; | 1457 | sr.pktcnt = c->mfc_un.res.pkt; |
1369 | sr.bytecnt = c->mfc_un.res.bytes; | 1458 | sr.bytecnt = c->mfc_un.res.bytes; |
@@ -1396,7 +1485,8 @@ static inline int ip6mr_forward2_finish(struct sk_buff *skb) | |||
1396 | static int ip6mr_forward2(struct sk_buff *skb, struct mfc6_cache *c, int vifi) | 1485 | static int ip6mr_forward2(struct sk_buff *skb, struct mfc6_cache *c, int vifi) |
1397 | { | 1486 | { |
1398 | struct ipv6hdr *ipv6h; | 1487 | struct ipv6hdr *ipv6h; |
1399 | struct mif_device *vif = &vif6_table[vifi]; | 1488 | struct net *net = mfc6_net(c); |
1489 | struct mif_device *vif = &net->ipv6.vif6_table[vifi]; | ||
1400 | struct net_device *dev; | 1490 | struct net_device *dev; |
1401 | struct dst_entry *dst; | 1491 | struct dst_entry *dst; |
1402 | struct flowi fl; | 1492 | struct flowi fl; |
@@ -1410,9 +1500,8 @@ static int ip6mr_forward2(struct sk_buff *skb, struct mfc6_cache *c, int vifi) | |||
1410 | vif->bytes_out += skb->len; | 1500 | vif->bytes_out += skb->len; |
1411 | vif->dev->stats.tx_bytes += skb->len; | 1501 | vif->dev->stats.tx_bytes += skb->len; |
1412 | vif->dev->stats.tx_packets++; | 1502 | vif->dev->stats.tx_packets++; |
1413 | ip6mr_cache_report(skb, vifi, MRT6MSG_WHOLEPKT); | 1503 | ip6mr_cache_report(net, skb, vifi, MRT6MSG_WHOLEPKT); |
1414 | kfree_skb(skb); | 1504 | goto out_free; |
1415 | return 0; | ||
1416 | } | 1505 | } |
1417 | #endif | 1506 | #endif |
1418 | 1507 | ||
@@ -1425,7 +1514,7 @@ static int ip6mr_forward2(struct sk_buff *skb, struct mfc6_cache *c, int vifi) | |||
1425 | } | 1514 | } |
1426 | }; | 1515 | }; |
1427 | 1516 | ||
1428 | dst = ip6_route_output(&init_net, NULL, &fl); | 1517 | dst = ip6_route_output(net, NULL, &fl); |
1429 | if (!dst) | 1518 | if (!dst) |
1430 | goto out_free; | 1519 | goto out_free; |
1431 | 1520 | ||
@@ -1468,9 +1557,10 @@ out_free: | |||
1468 | 1557 | ||
1469 | static int ip6mr_find_vif(struct net_device *dev) | 1558 | static int ip6mr_find_vif(struct net_device *dev) |
1470 | { | 1559 | { |
1560 | struct net *net = dev_net(dev); | ||
1471 | int ct; | 1561 | int ct; |
1472 | for (ct = maxvif - 1; ct >= 0; ct--) { | 1562 | for (ct = net->ipv6.maxvif - 1; ct >= 0; ct--) { |
1473 | if (vif6_table[ct].dev == dev) | 1563 | if (net->ipv6.vif6_table[ct].dev == dev) |
1474 | break; | 1564 | break; |
1475 | } | 1565 | } |
1476 | return ct; | 1566 | return ct; |
@@ -1480,6 +1570,7 @@ static int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache) | |||
1480 | { | 1570 | { |
1481 | int psend = -1; | 1571 | int psend = -1; |
1482 | int vif, ct; | 1572 | int vif, ct; |
1573 | struct net *net = mfc6_net(cache); | ||
1483 | 1574 | ||
1484 | vif = cache->mf6c_parent; | 1575 | vif = cache->mf6c_parent; |
1485 | cache->mfc_un.res.pkt++; | 1576 | cache->mfc_un.res.pkt++; |
@@ -1488,29 +1579,30 @@ static int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache) | |||
1488 | /* | 1579 | /* |
1489 | * Wrong interface: drop packet and (maybe) send PIM assert. | 1580 | * Wrong interface: drop packet and (maybe) send PIM assert. |
1490 | */ | 1581 | */ |
1491 | if (vif6_table[vif].dev != skb->dev) { | 1582 | if (net->ipv6.vif6_table[vif].dev != skb->dev) { |
1492 | int true_vifi; | 1583 | int true_vifi; |
1493 | 1584 | ||
1494 | cache->mfc_un.res.wrong_if++; | 1585 | cache->mfc_un.res.wrong_if++; |
1495 | true_vifi = ip6mr_find_vif(skb->dev); | 1586 | true_vifi = ip6mr_find_vif(skb->dev); |
1496 | 1587 | ||
1497 | if (true_vifi >= 0 && mroute_do_assert && | 1588 | if (true_vifi >= 0 && net->ipv6.mroute_do_assert && |
1498 | /* pimsm uses asserts, when switching from RPT to SPT, | 1589 | /* pimsm uses asserts, when switching from RPT to SPT, |
1499 | so that we cannot check that packet arrived on an oif. | 1590 | so that we cannot check that packet arrived on an oif. |
1500 | It is bad, but otherwise we would need to move pretty | 1591 | It is bad, but otherwise we would need to move pretty |
1501 | large chunk of pimd to kernel. Ough... --ANK | 1592 | large chunk of pimd to kernel. Ough... --ANK |
1502 | */ | 1593 | */ |
1503 | (mroute_do_pim || cache->mfc_un.res.ttls[true_vifi] < 255) && | 1594 | (net->ipv6.mroute_do_pim || |
1595 | cache->mfc_un.res.ttls[true_vifi] < 255) && | ||
1504 | time_after(jiffies, | 1596 | time_after(jiffies, |
1505 | cache->mfc_un.res.last_assert + MFC_ASSERT_THRESH)) { | 1597 | cache->mfc_un.res.last_assert + MFC_ASSERT_THRESH)) { |
1506 | cache->mfc_un.res.last_assert = jiffies; | 1598 | cache->mfc_un.res.last_assert = jiffies; |
1507 | ip6mr_cache_report(skb, true_vifi, MRT6MSG_WRONGMIF); | 1599 | ip6mr_cache_report(net, skb, true_vifi, MRT6MSG_WRONGMIF); |
1508 | } | 1600 | } |
1509 | goto dont_forward; | 1601 | goto dont_forward; |
1510 | } | 1602 | } |
1511 | 1603 | ||
1512 | vif6_table[vif].pkt_in++; | 1604 | net->ipv6.vif6_table[vif].pkt_in++; |
1513 | vif6_table[vif].bytes_in += skb->len; | 1605 | net->ipv6.vif6_table[vif].bytes_in += skb->len; |
1514 | 1606 | ||
1515 | /* | 1607 | /* |
1516 | * Forward the frame | 1608 | * Forward the frame |
@@ -1543,9 +1635,11 @@ dont_forward: | |||
1543 | int ip6_mr_input(struct sk_buff *skb) | 1635 | int ip6_mr_input(struct sk_buff *skb) |
1544 | { | 1636 | { |
1545 | struct mfc6_cache *cache; | 1637 | struct mfc6_cache *cache; |
1638 | struct net *net = dev_net(skb->dev); | ||
1546 | 1639 | ||
1547 | read_lock(&mrt_lock); | 1640 | read_lock(&mrt_lock); |
1548 | cache = ip6mr_cache_find(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr); | 1641 | cache = ip6mr_cache_find(net, |
1642 | &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr); | ||
1549 | 1643 | ||
1550 | /* | 1644 | /* |
1551 | * No usable cache entry | 1645 | * No usable cache entry |
@@ -1555,7 +1649,7 @@ int ip6_mr_input(struct sk_buff *skb) | |||
1555 | 1649 | ||
1556 | vif = ip6mr_find_vif(skb->dev); | 1650 | vif = ip6mr_find_vif(skb->dev); |
1557 | if (vif >= 0) { | 1651 | if (vif >= 0) { |
1558 | int err = ip6mr_cache_unresolved(vif, skb); | 1652 | int err = ip6mr_cache_unresolved(net, vif, skb); |
1559 | read_unlock(&mrt_lock); | 1653 | read_unlock(&mrt_lock); |
1560 | 1654 | ||
1561 | return err; | 1655 | return err; |
@@ -1578,7 +1672,8 @@ ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm) | |||
1578 | { | 1672 | { |
1579 | int ct; | 1673 | int ct; |
1580 | struct rtnexthop *nhp; | 1674 | struct rtnexthop *nhp; |
1581 | struct net_device *dev = vif6_table[c->mf6c_parent].dev; | 1675 | struct net *net = mfc6_net(c); |
1676 | struct net_device *dev = net->ipv6.vif6_table[c->mf6c_parent].dev; | ||
1582 | u8 *b = skb_tail_pointer(skb); | 1677 | u8 *b = skb_tail_pointer(skb); |
1583 | struct rtattr *mp_head; | 1678 | struct rtattr *mp_head; |
1584 | 1679 | ||
@@ -1594,7 +1689,7 @@ ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm) | |||
1594 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); | 1689 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); |
1595 | nhp->rtnh_flags = 0; | 1690 | nhp->rtnh_flags = 0; |
1596 | nhp->rtnh_hops = c->mfc_un.res.ttls[ct]; | 1691 | nhp->rtnh_hops = c->mfc_un.res.ttls[ct]; |
1597 | nhp->rtnh_ifindex = vif6_table[ct].dev->ifindex; | 1692 | nhp->rtnh_ifindex = net->ipv6.vif6_table[ct].dev->ifindex; |
1598 | nhp->rtnh_len = sizeof(*nhp); | 1693 | nhp->rtnh_len = sizeof(*nhp); |
1599 | } | 1694 | } |
1600 | } | 1695 | } |
@@ -1608,14 +1703,15 @@ rtattr_failure: | |||
1608 | return -EMSGSIZE; | 1703 | return -EMSGSIZE; |
1609 | } | 1704 | } |
1610 | 1705 | ||
1611 | int ip6mr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait) | 1706 | int ip6mr_get_route(struct net *net, |
1707 | struct sk_buff *skb, struct rtmsg *rtm, int nowait) | ||
1612 | { | 1708 | { |
1613 | int err; | 1709 | int err; |
1614 | struct mfc6_cache *cache; | 1710 | struct mfc6_cache *cache; |
1615 | struct rt6_info *rt = (struct rt6_info *)skb->dst; | 1711 | struct rt6_info *rt = (struct rt6_info *)skb->dst; |
1616 | 1712 | ||
1617 | read_lock(&mrt_lock); | 1713 | read_lock(&mrt_lock); |
1618 | cache = ip6mr_cache_find(&rt->rt6i_src.addr, &rt->rt6i_dst.addr); | 1714 | cache = ip6mr_cache_find(net, &rt->rt6i_src.addr, &rt->rt6i_dst.addr); |
1619 | 1715 | ||
1620 | if (!cache) { | 1716 | if (!cache) { |
1621 | struct sk_buff *skb2; | 1717 | struct sk_buff *skb2; |
@@ -1658,7 +1754,7 @@ int ip6mr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait) | |||
1658 | ipv6_addr_copy(&iph->saddr, &rt->rt6i_src.addr); | 1754 | ipv6_addr_copy(&iph->saddr, &rt->rt6i_src.addr); |
1659 | ipv6_addr_copy(&iph->daddr, &rt->rt6i_dst.addr); | 1755 | ipv6_addr_copy(&iph->daddr, &rt->rt6i_dst.addr); |
1660 | 1756 | ||
1661 | err = ip6mr_cache_unresolved(vif, skb2); | 1757 | err = ip6mr_cache_unresolved(net, vif, skb2); |
1662 | read_unlock(&mrt_lock); | 1758 | read_unlock(&mrt_lock); |
1663 | 1759 | ||
1664 | return err; | 1760 | return err; |
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index 4545e4306862..3a0b3be7ece5 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c | |||
@@ -63,12 +63,12 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
63 | return; | 63 | return; |
64 | 64 | ||
65 | spi = htonl(ntohs(ipcomph->cpi)); | 65 | spi = htonl(ntohs(ipcomph->cpi)); |
66 | x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6); | 66 | x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6); |
67 | if (!x) | 67 | if (!x) |
68 | return; | 68 | return; |
69 | 69 | ||
70 | printk(KERN_DEBUG "pmtu discovery on SA IPCOMP/%08x/" NIP6_FMT "\n", | 70 | printk(KERN_DEBUG "pmtu discovery on SA IPCOMP/%08x/%pI6\n", |
71 | spi, NIP6(iph->daddr)); | 71 | spi, &iph->daddr); |
72 | xfrm_state_put(x); | 72 | xfrm_state_put(x); |
73 | } | 73 | } |
74 | 74 | ||
@@ -76,7 +76,7 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x) | |||
76 | { | 76 | { |
77 | struct xfrm_state *t = NULL; | 77 | struct xfrm_state *t = NULL; |
78 | 78 | ||
79 | t = xfrm_state_alloc(); | 79 | t = xfrm_state_alloc(&init_net); |
80 | if (!t) | 80 | if (!t) |
81 | goto out; | 81 | goto out; |
82 | 82 | ||
@@ -114,7 +114,7 @@ static int ipcomp6_tunnel_attach(struct xfrm_state *x) | |||
114 | 114 | ||
115 | spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&x->props.saddr); | 115 | spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&x->props.saddr); |
116 | if (spi) | 116 | if (spi) |
117 | t = xfrm_state_lookup((xfrm_address_t *)&x->id.daddr, | 117 | t = xfrm_state_lookup(&init_net, (xfrm_address_t *)&x->id.daddr, |
118 | spi, IPPROTO_IPV6, AF_INET6); | 118 | spi, IPPROTO_IPV6, AF_INET6); |
119 | if (!t) { | 119 | if (!t) { |
120 | t = ipcomp6_tunnel_create(x); | 120 | t = ipcomp6_tunnel_create(x); |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 2aa294be0c79..eeeaad2e8b5c 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -395,6 +395,28 @@ sticky_done: | |||
395 | break; | 395 | break; |
396 | } | 396 | } |
397 | 397 | ||
398 | case IPV6_PKTINFO: | ||
399 | { | ||
400 | struct in6_pktinfo pkt; | ||
401 | |||
402 | if (optlen == 0) | ||
403 | goto e_inval; | ||
404 | else if (optlen < sizeof(struct in6_pktinfo) || optval == NULL) | ||
405 | goto e_inval; | ||
406 | |||
407 | if (copy_from_user(&pkt, optval, optlen)) { | ||
408 | retv = -EFAULT; | ||
409 | break; | ||
410 | } | ||
411 | if (sk->sk_bound_dev_if && pkt.ipi6_ifindex != sk->sk_bound_dev_if) | ||
412 | goto e_inval; | ||
413 | |||
414 | np->sticky_pktinfo.ipi6_ifindex = pkt.ipi6_ifindex; | ||
415 | ipv6_addr_copy(&np->sticky_pktinfo.ipi6_addr, &pkt.ipi6_addr); | ||
416 | retv = 0; | ||
417 | break; | ||
418 | } | ||
419 | |||
398 | case IPV6_2292PKTOPTIONS: | 420 | case IPV6_2292PKTOPTIONS: |
399 | { | 421 | { |
400 | struct ipv6_txoptions *opt = NULL; | 422 | struct ipv6_txoptions *opt = NULL; |
@@ -916,8 +938,10 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
916 | } else { | 938 | } else { |
917 | if (np->rxopt.bits.rxinfo) { | 939 | if (np->rxopt.bits.rxinfo) { |
918 | struct in6_pktinfo src_info; | 940 | struct in6_pktinfo src_info; |
919 | src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : sk->sk_bound_dev_if; | 941 | src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : |
920 | ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr); | 942 | np->sticky_pktinfo.ipi6_ifindex; |
943 | np->mcast_oif? ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr) : | ||
944 | ipv6_addr_copy(&src_info.ipi6_addr, &(np->sticky_pktinfo.ipi6_addr)); | ||
921 | put_cmsg(&msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info); | 945 | put_cmsg(&msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info); |
922 | } | 946 | } |
923 | if (np->rxopt.bits.rxhlim) { | 947 | if (np->rxopt.bits.rxhlim) { |
@@ -926,8 +950,10 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
926 | } | 950 | } |
927 | if (np->rxopt.bits.rxoinfo) { | 951 | if (np->rxopt.bits.rxoinfo) { |
928 | struct in6_pktinfo src_info; | 952 | struct in6_pktinfo src_info; |
929 | src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : sk->sk_bound_dev_if; | 953 | src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : |
930 | ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr); | 954 | np->sticky_pktinfo.ipi6_ifindex; |
955 | np->mcast_oif? ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr) : | ||
956 | ipv6_addr_copy(&src_info.ipi6_addr, &(np->sticky_pktinfo.ipi6_addr)); | ||
931 | put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info); | 957 | put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info); |
932 | } | 958 | } |
933 | if (np->rxopt.bits.rxohlim) { | 959 | if (np->rxopt.bits.rxohlim) { |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index d7b3c6d398ae..a51fb33e6864 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -303,20 +303,23 @@ static struct inet6_dev *ip6_mc_find_dev(struct net *net, | |||
303 | dev = dev_get_by_index(net, ifindex); | 303 | dev = dev_get_by_index(net, ifindex); |
304 | 304 | ||
305 | if (!dev) | 305 | if (!dev) |
306 | return NULL; | 306 | goto nodev; |
307 | idev = in6_dev_get(dev); | 307 | idev = in6_dev_get(dev); |
308 | if (!idev) { | 308 | if (!idev) |
309 | dev_put(dev); | 309 | goto release; |
310 | return NULL; | ||
311 | } | ||
312 | read_lock_bh(&idev->lock); | 310 | read_lock_bh(&idev->lock); |
313 | if (idev->dead) { | 311 | if (idev->dead) |
314 | read_unlock_bh(&idev->lock); | 312 | goto unlock_release; |
315 | in6_dev_put(idev); | 313 | |
316 | dev_put(dev); | ||
317 | return NULL; | ||
318 | } | ||
319 | return idev; | 314 | return idev; |
315 | |||
316 | unlock_release: | ||
317 | read_unlock_bh(&idev->lock); | ||
318 | in6_dev_put(idev); | ||
319 | release: | ||
320 | dev_put(dev); | ||
321 | nodev: | ||
322 | return NULL; | ||
320 | } | 323 | } |
321 | 324 | ||
322 | void ipv6_sock_mc_close(struct sock *sk) | 325 | void ipv6_sock_mc_close(struct sock *sk) |
@@ -1466,7 +1469,7 @@ static void mld_sendpack(struct sk_buff *skb) | |||
1466 | &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, | 1469 | &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, |
1467 | skb->dev->ifindex); | 1470 | skb->dev->ifindex); |
1468 | 1471 | ||
1469 | err = xfrm_lookup(&skb->dst, &fl, NULL, 0); | 1472 | err = xfrm_lookup(net, &skb->dst, &fl, NULL, 0); |
1470 | if (err) | 1473 | if (err) |
1471 | goto err_out; | 1474 | goto err_out; |
1472 | 1475 | ||
@@ -1817,7 +1820,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1817 | 1820 | ||
1818 | hdr->icmp6_cksum = csum_ipv6_magic(saddr, snd_addr, len, | 1821 | hdr->icmp6_cksum = csum_ipv6_magic(saddr, snd_addr, len, |
1819 | IPPROTO_ICMPV6, | 1822 | IPPROTO_ICMPV6, |
1820 | csum_partial((__u8 *) hdr, len, 0)); | 1823 | csum_partial(hdr, len, 0)); |
1821 | 1824 | ||
1822 | idev = in6_dev_get(skb->dev); | 1825 | idev = in6_dev_get(skb->dev); |
1823 | 1826 | ||
@@ -1831,7 +1834,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1831 | &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, | 1834 | &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, |
1832 | skb->dev->ifindex); | 1835 | skb->dev->ifindex); |
1833 | 1836 | ||
1834 | err = xfrm_lookup(&skb->dst, &fl, NULL, 0); | 1837 | err = xfrm_lookup(net, &skb->dst, &fl, NULL, 0); |
1835 | if (err) | 1838 | if (err) |
1836 | goto err_out; | 1839 | goto err_out; |
1837 | 1840 | ||
@@ -2430,9 +2433,9 @@ static int igmp6_mc_seq_show(struct seq_file *seq, void *v) | |||
2430 | struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq); | 2433 | struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq); |
2431 | 2434 | ||
2432 | seq_printf(seq, | 2435 | seq_printf(seq, |
2433 | "%-4d %-15s " NIP6_SEQFMT " %5d %08X %ld\n", | 2436 | "%-4d %-15s %pi6 %5d %08X %ld\n", |
2434 | state->dev->ifindex, state->dev->name, | 2437 | state->dev->ifindex, state->dev->name, |
2435 | NIP6(im->mca_addr), | 2438 | &im->mca_addr, |
2436 | im->mca_users, im->mca_flags, | 2439 | im->mca_users, im->mca_flags, |
2437 | (im->mca_flags&MAF_TIMER_RUNNING) ? | 2440 | (im->mca_flags&MAF_TIMER_RUNNING) ? |
2438 | jiffies_to_clock_t(im->mca_timer.expires-jiffies) : 0); | 2441 | jiffies_to_clock_t(im->mca_timer.expires-jiffies) : 0); |
@@ -2591,10 +2594,10 @@ static int igmp6_mcf_seq_show(struct seq_file *seq, void *v) | |||
2591 | "Source Address", "INC", "EXC"); | 2594 | "Source Address", "INC", "EXC"); |
2592 | } else { | 2595 | } else { |
2593 | seq_printf(seq, | 2596 | seq_printf(seq, |
2594 | "%3d %6.6s " NIP6_SEQFMT " " NIP6_SEQFMT " %6lu %6lu\n", | 2597 | "%3d %6.6s %pi6 %pi6 %6lu %6lu\n", |
2595 | state->dev->ifindex, state->dev->name, | 2598 | state->dev->ifindex, state->dev->name, |
2596 | NIP6(state->im->mca_addr), | 2599 | &state->im->mca_addr, |
2597 | NIP6(psf->sf_addr), | 2600 | &psf->sf_addr, |
2598 | psf->sf_count[MCAST_INCLUDE], | 2601 | psf->sf_count[MCAST_INCLUDE], |
2599 | psf->sf_count[MCAST_EXCLUDE]); | 2602 | psf->sf_count[MCAST_EXCLUDE]); |
2600 | } | 2603 | } |
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c index 31295c8f6196..f995e19c87a9 100644 --- a/net/ipv6/mip6.c +++ b/net/ipv6/mip6.c | |||
@@ -205,6 +205,7 @@ static inline int mip6_report_rl_allow(struct timeval *stamp, | |||
205 | 205 | ||
206 | static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, struct flowi *fl) | 206 | static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, struct flowi *fl) |
207 | { | 207 | { |
208 | struct net *net = xs_net(x); | ||
208 | struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb; | 209 | struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb; |
209 | struct ipv6_destopt_hao *hao = NULL; | 210 | struct ipv6_destopt_hao *hao = NULL; |
210 | struct xfrm_selector sel; | 211 | struct xfrm_selector sel; |
@@ -247,7 +248,7 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, struct | |||
247 | sel.sport_mask = htons(~0); | 248 | sel.sport_mask = htons(~0); |
248 | sel.ifindex = fl->oif; | 249 | sel.ifindex = fl->oif; |
249 | 250 | ||
250 | err = km_report(IPPROTO_DSTOPTS, &sel, | 251 | err = km_report(net, IPPROTO_DSTOPTS, &sel, |
251 | (hao ? (xfrm_address_t *)&hao->addr : NULL)); | 252 | (hao ? (xfrm_address_t *)&hao->addr : NULL)); |
252 | 253 | ||
253 | out: | 254 | out: |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index d0f54d18e19b..3e2970841bd8 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -437,38 +437,20 @@ static void pndisc_destructor(struct pneigh_entry *n) | |||
437 | ipv6_dev_mc_dec(dev, &maddr); | 437 | ipv6_dev_mc_dec(dev, &maddr); |
438 | } | 438 | } |
439 | 439 | ||
440 | /* | 440 | struct sk_buff *ndisc_build_skb(struct net_device *dev, |
441 | * Send a Neighbour Advertisement | 441 | const struct in6_addr *daddr, |
442 | */ | 442 | const struct in6_addr *saddr, |
443 | static void __ndisc_send(struct net_device *dev, | 443 | struct icmp6hdr *icmp6h, |
444 | struct neighbour *neigh, | 444 | const struct in6_addr *target, |
445 | const struct in6_addr *daddr, | 445 | int llinfo) |
446 | const struct in6_addr *saddr, | ||
447 | struct icmp6hdr *icmp6h, const struct in6_addr *target, | ||
448 | int llinfo) | ||
449 | { | 446 | { |
450 | struct flowi fl; | ||
451 | struct dst_entry *dst; | ||
452 | struct net *net = dev_net(dev); | 447 | struct net *net = dev_net(dev); |
453 | struct sock *sk = net->ipv6.ndisc_sk; | 448 | struct sock *sk = net->ipv6.ndisc_sk; |
454 | struct sk_buff *skb; | 449 | struct sk_buff *skb; |
455 | struct icmp6hdr *hdr; | 450 | struct icmp6hdr *hdr; |
456 | struct inet6_dev *idev; | ||
457 | int len; | 451 | int len; |
458 | int err; | 452 | int err; |
459 | u8 *opt, type; | 453 | u8 *opt; |
460 | |||
461 | type = icmp6h->icmp6_type; | ||
462 | |||
463 | icmpv6_flow_init(sk, &fl, type, saddr, daddr, dev->ifindex); | ||
464 | |||
465 | dst = icmp6_dst_alloc(dev, neigh, daddr); | ||
466 | if (!dst) | ||
467 | return; | ||
468 | |||
469 | err = xfrm_lookup(&dst, &fl, NULL, 0); | ||
470 | if (err < 0) | ||
471 | return; | ||
472 | 454 | ||
473 | if (!dev->addr_len) | 455 | if (!dev->addr_len) |
474 | llinfo = 0; | 456 | llinfo = 0; |
@@ -485,8 +467,7 @@ static void __ndisc_send(struct net_device *dev, | |||
485 | ND_PRINTK0(KERN_ERR | 467 | ND_PRINTK0(KERN_ERR |
486 | "ICMPv6 ND: %s() failed to allocate an skb.\n", | 468 | "ICMPv6 ND: %s() failed to allocate an skb.\n", |
487 | __func__); | 469 | __func__); |
488 | dst_release(dst); | 470 | return NULL; |
489 | return; | ||
490 | } | 471 | } |
491 | 472 | ||
492 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 473 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); |
@@ -510,9 +491,45 @@ static void __ndisc_send(struct net_device *dev, | |||
510 | 491 | ||
511 | hdr->icmp6_cksum = csum_ipv6_magic(saddr, daddr, len, | 492 | hdr->icmp6_cksum = csum_ipv6_magic(saddr, daddr, len, |
512 | IPPROTO_ICMPV6, | 493 | IPPROTO_ICMPV6, |
513 | csum_partial((__u8 *) hdr, | 494 | csum_partial(hdr, |
514 | len, 0)); | 495 | len, 0)); |
515 | 496 | ||
497 | return skb; | ||
498 | } | ||
499 | |||
500 | EXPORT_SYMBOL(ndisc_build_skb); | ||
501 | |||
502 | void ndisc_send_skb(struct sk_buff *skb, | ||
503 | struct net_device *dev, | ||
504 | struct neighbour *neigh, | ||
505 | const struct in6_addr *daddr, | ||
506 | const struct in6_addr *saddr, | ||
507 | struct icmp6hdr *icmp6h) | ||
508 | { | ||
509 | struct flowi fl; | ||
510 | struct dst_entry *dst; | ||
511 | struct net *net = dev_net(dev); | ||
512 | struct sock *sk = net->ipv6.ndisc_sk; | ||
513 | struct inet6_dev *idev; | ||
514 | int err; | ||
515 | u8 type; | ||
516 | |||
517 | type = icmp6h->icmp6_type; | ||
518 | |||
519 | icmpv6_flow_init(sk, &fl, type, saddr, daddr, dev->ifindex); | ||
520 | |||
521 | dst = icmp6_dst_alloc(dev, neigh, daddr); | ||
522 | if (!dst) { | ||
523 | kfree_skb(skb); | ||
524 | return; | ||
525 | } | ||
526 | |||
527 | err = xfrm_lookup(net, &dst, &fl, NULL, 0); | ||
528 | if (err < 0) { | ||
529 | kfree_skb(skb); | ||
530 | return; | ||
531 | } | ||
532 | |||
516 | skb->dst = dst; | 533 | skb->dst = dst; |
517 | 534 | ||
518 | idev = in6_dev_get(dst->dev); | 535 | idev = in6_dev_get(dst->dev); |
@@ -529,6 +546,27 @@ static void __ndisc_send(struct net_device *dev, | |||
529 | in6_dev_put(idev); | 546 | in6_dev_put(idev); |
530 | } | 547 | } |
531 | 548 | ||
549 | EXPORT_SYMBOL(ndisc_send_skb); | ||
550 | |||
551 | /* | ||
552 | * Send a Neighbour Discover packet | ||
553 | */ | ||
554 | static void __ndisc_send(struct net_device *dev, | ||
555 | struct neighbour *neigh, | ||
556 | const struct in6_addr *daddr, | ||
557 | const struct in6_addr *saddr, | ||
558 | struct icmp6hdr *icmp6h, const struct in6_addr *target, | ||
559 | int llinfo) | ||
560 | { | ||
561 | struct sk_buff *skb; | ||
562 | |||
563 | skb = ndisc_build_skb(dev, daddr, saddr, icmp6h, target, llinfo); | ||
564 | if (!skb) | ||
565 | return; | ||
566 | |||
567 | ndisc_send_skb(skb, dev, neigh, daddr, saddr, icmp6h); | ||
568 | } | ||
569 | |||
532 | static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, | 570 | static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, |
533 | const struct in6_addr *daddr, | 571 | const struct in6_addr *daddr, |
534 | const struct in6_addr *solicited_addr, | 572 | const struct in6_addr *solicited_addr, |
@@ -647,11 +685,8 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb) | |||
647 | 685 | ||
648 | if ((probes -= neigh->parms->ucast_probes) < 0) { | 686 | if ((probes -= neigh->parms->ucast_probes) < 0) { |
649 | if (!(neigh->nud_state & NUD_VALID)) { | 687 | if (!(neigh->nud_state & NUD_VALID)) { |
650 | ND_PRINTK1(KERN_DEBUG | 688 | ND_PRINTK1(KERN_DEBUG "%s(): trying to ucast probe in NUD_INVALID: %pI6\n", |
651 | "%s(): trying to ucast probe in NUD_INVALID: " | 689 | __func__, target); |
652 | NIP6_FMT "\n", | ||
653 | __func__, | ||
654 | NIP6(*target)); | ||
655 | } | 690 | } |
656 | ndisc_send_ns(dev, neigh, target, target, saddr); | 691 | ndisc_send_ns(dev, neigh, target, target, saddr); |
657 | } else if ((probes -= neigh->parms->app_probes) < 0) { | 692 | } else if ((probes -= neigh->parms->app_probes) < 0) { |
@@ -1494,7 +1529,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | |||
1494 | if (dst == NULL) | 1529 | if (dst == NULL) |
1495 | return; | 1530 | return; |
1496 | 1531 | ||
1497 | err = xfrm_lookup(&dst, &fl, NULL, 0); | 1532 | err = xfrm_lookup(net, &dst, &fl, NULL, 0); |
1498 | if (err) | 1533 | if (err) |
1499 | return; | 1534 | return; |
1500 | 1535 | ||
@@ -1582,7 +1617,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | |||
1582 | 1617 | ||
1583 | icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr, | 1618 | icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr, |
1584 | len, IPPROTO_ICMPV6, | 1619 | len, IPPROTO_ICMPV6, |
1585 | csum_partial((u8 *) icmph, len, 0)); | 1620 | csum_partial(icmph, len, 0)); |
1586 | 1621 | ||
1587 | buff->dst = dst; | 1622 | buff->dst = dst; |
1588 | idev = in6_dev_get(dst->dev); | 1623 | idev = in6_dev_get(dst->dev); |
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index fd5b3a4e3329..834cea69fb53 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c | |||
@@ -29,7 +29,7 @@ int ip6_route_me_harder(struct sk_buff *skb) | |||
29 | #ifdef CONFIG_XFRM | 29 | #ifdef CONFIG_XFRM |
30 | if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && | 30 | if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && |
31 | xfrm_decode_session(skb, &fl, AF_INET6) == 0) | 31 | xfrm_decode_session(skb, &fl, AF_INET6) == 0) |
32 | if (xfrm_lookup(&skb->dst, &fl, skb->sk, 0)) | 32 | if (xfrm_lookup(net, &skb->dst, &fl, skb->sk, 0)) |
33 | return -1; | 33 | return -1; |
34 | #endif | 34 | #endif |
35 | 35 | ||
@@ -56,6 +56,7 @@ EXPORT_SYMBOL(ip6_route_me_harder); | |||
56 | struct ip6_rt_info { | 56 | struct ip6_rt_info { |
57 | struct in6_addr daddr; | 57 | struct in6_addr daddr; |
58 | struct in6_addr saddr; | 58 | struct in6_addr saddr; |
59 | u_int32_t mark; | ||
59 | }; | 60 | }; |
60 | 61 | ||
61 | static void nf_ip6_saveroute(const struct sk_buff *skb, | 62 | static void nf_ip6_saveroute(const struct sk_buff *skb, |
@@ -68,6 +69,7 @@ static void nf_ip6_saveroute(const struct sk_buff *skb, | |||
68 | 69 | ||
69 | rt_info->daddr = iph->daddr; | 70 | rt_info->daddr = iph->daddr; |
70 | rt_info->saddr = iph->saddr; | 71 | rt_info->saddr = iph->saddr; |
72 | rt_info->mark = skb->mark; | ||
71 | } | 73 | } |
72 | } | 74 | } |
73 | 75 | ||
@@ -79,7 +81,8 @@ static int nf_ip6_reroute(struct sk_buff *skb, | |||
79 | if (entry->hook == NF_INET_LOCAL_OUT) { | 81 | if (entry->hook == NF_INET_LOCAL_OUT) { |
80 | struct ipv6hdr *iph = ipv6_hdr(skb); | 82 | struct ipv6hdr *iph = ipv6_hdr(skb); |
81 | if (!ipv6_addr_equal(&iph->daddr, &rt_info->daddr) || | 83 | if (!ipv6_addr_equal(&iph->daddr, &rt_info->daddr) || |
82 | !ipv6_addr_equal(&iph->saddr, &rt_info->saddr)) | 84 | !ipv6_addr_equal(&iph->saddr, &rt_info->saddr) || |
85 | skb->mark != rt_info->mark) | ||
83 | return ip6_route_me_harder(skb); | 86 | return ip6_route_me_harder(skb); |
84 | } | 87 | } |
85 | return 0; | 88 | return 0; |
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c index 871d157cec4e..37adf5abc51e 100644 --- a/net/ipv6/netfilter/ip6t_LOG.c +++ b/net/ipv6/netfilter/ip6t_LOG.c | |||
@@ -61,7 +61,7 @@ static void dump_packet(const struct nf_loginfo *info, | |||
61 | } | 61 | } |
62 | 62 | ||
63 | /* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000 " */ | 63 | /* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000 " */ |
64 | printk("SRC=" NIP6_FMT " DST=" NIP6_FMT " ", NIP6(ih->saddr), NIP6(ih->daddr)); | 64 | printk("SRC=%pI6 DST=%pI6 ", &ih->saddr, &ih->daddr); |
65 | 65 | ||
66 | /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */ | 66 | /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */ |
67 | printk("LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ", | 67 | printk("LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ", |
@@ -424,9 +424,8 @@ ip6t_log_packet(u_int8_t pf, | |||
424 | if (skb->dev->type == ARPHRD_SIT) { | 424 | if (skb->dev->type == ARPHRD_SIT) { |
425 | const struct iphdr *iph = | 425 | const struct iphdr *iph = |
426 | (struct iphdr *)skb_mac_header(skb); | 426 | (struct iphdr *)skb_mac_header(skb); |
427 | printk("TUNNEL=%u.%u.%u.%u->%u.%u.%u.%u ", | 427 | printk("TUNNEL=%pI4->%pI4 ", |
428 | NIPQUAD(iph->saddr), | 428 | &iph->saddr, &iph->daddr); |
429 | NIPQUAD(iph->daddr)); | ||
430 | } | 429 | } |
431 | } else | 430 | } else |
432 | printk(" "); | 431 | printk(" "); |
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index 0981b4ccb8b1..5a2d0a41694a 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c | |||
@@ -97,7 +97,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb) | |||
97 | dst = ip6_route_output(net, NULL, &fl); | 97 | dst = ip6_route_output(net, NULL, &fl); |
98 | if (dst == NULL) | 98 | if (dst == NULL) |
99 | return; | 99 | return; |
100 | if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0)) | 100 | if (dst->error || xfrm_lookup(net, &dst, &fl, NULL, 0)) |
101 | return; | 101 | return; |
102 | 102 | ||
103 | hh_len = (dst->dev->hard_header_len + 15)&~15; | 103 | hh_len = (dst->dev->hard_header_len + 15)&~15; |
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c index b110a8a85a14..40d2e36d8fac 100644 --- a/net/ipv6/netfilter/ip6table_filter.c +++ b/net/ipv6/netfilter/ip6table_filter.c | |||
@@ -61,7 +61,7 @@ static struct xt_table packet_filter = { | |||
61 | 61 | ||
62 | /* The work comes in here from netfilter.c. */ | 62 | /* The work comes in here from netfilter.c. */ |
63 | static unsigned int | 63 | static unsigned int |
64 | ip6t_local_in_hook(unsigned int hook, | 64 | ip6t_in_hook(unsigned int hook, |
65 | struct sk_buff *skb, | 65 | struct sk_buff *skb, |
66 | const struct net_device *in, | 66 | const struct net_device *in, |
67 | const struct net_device *out, | 67 | const struct net_device *out, |
@@ -72,17 +72,6 @@ ip6t_local_in_hook(unsigned int hook, | |||
72 | } | 72 | } |
73 | 73 | ||
74 | static unsigned int | 74 | static unsigned int |
75 | ip6t_forward_hook(unsigned int hook, | ||
76 | struct sk_buff *skb, | ||
77 | const struct net_device *in, | ||
78 | const struct net_device *out, | ||
79 | int (*okfn)(struct sk_buff *)) | ||
80 | { | ||
81 | return ip6t_do_table(skb, hook, in, out, | ||
82 | dev_net(in)->ipv6.ip6table_filter); | ||
83 | } | ||
84 | |||
85 | static unsigned int | ||
86 | ip6t_local_out_hook(unsigned int hook, | 75 | ip6t_local_out_hook(unsigned int hook, |
87 | struct sk_buff *skb, | 76 | struct sk_buff *skb, |
88 | const struct net_device *in, | 77 | const struct net_device *in, |
@@ -105,14 +94,14 @@ ip6t_local_out_hook(unsigned int hook, | |||
105 | 94 | ||
106 | static struct nf_hook_ops ip6t_ops[] __read_mostly = { | 95 | static struct nf_hook_ops ip6t_ops[] __read_mostly = { |
107 | { | 96 | { |
108 | .hook = ip6t_local_in_hook, | 97 | .hook = ip6t_in_hook, |
109 | .owner = THIS_MODULE, | 98 | .owner = THIS_MODULE, |
110 | .pf = PF_INET6, | 99 | .pf = PF_INET6, |
111 | .hooknum = NF_INET_LOCAL_IN, | 100 | .hooknum = NF_INET_LOCAL_IN, |
112 | .priority = NF_IP6_PRI_FILTER, | 101 | .priority = NF_IP6_PRI_FILTER, |
113 | }, | 102 | }, |
114 | { | 103 | { |
115 | .hook = ip6t_forward_hook, | 104 | .hook = ip6t_in_hook, |
116 | .owner = THIS_MODULE, | 105 | .owner = THIS_MODULE, |
117 | .pf = PF_INET6, | 106 | .pf = PF_INET6, |
118 | .hooknum = NF_INET_FORWARD, | 107 | .hooknum = NF_INET_FORWARD, |
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index e91db16611d9..727b9530448a 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
@@ -56,9 +56,8 @@ static bool ipv6_invert_tuple(struct nf_conntrack_tuple *tuple, | |||
56 | static int ipv6_print_tuple(struct seq_file *s, | 56 | static int ipv6_print_tuple(struct seq_file *s, |
57 | const struct nf_conntrack_tuple *tuple) | 57 | const struct nf_conntrack_tuple *tuple) |
58 | { | 58 | { |
59 | return seq_printf(s, "src=" NIP6_FMT " dst=" NIP6_FMT " ", | 59 | return seq_printf(s, "src=%pI6 dst=%pI6 ", |
60 | NIP6(*((struct in6_addr *)tuple->src.u3.ip6)), | 60 | tuple->src.u3.ip6, tuple->dst.u3.ip6); |
61 | NIP6(*((struct in6_addr *)tuple->dst.u3.ip6))); | ||
62 | } | 61 | } |
63 | 62 | ||
64 | /* | 63 | /* |
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index 05726177903f..bd52151d31e9 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | |||
@@ -253,7 +253,7 @@ static struct ctl_table icmpv6_sysctl_table[] = { | |||
253 | .data = &nf_ct_icmpv6_timeout, | 253 | .data = &nf_ct_icmpv6_timeout, |
254 | .maxlen = sizeof(unsigned int), | 254 | .maxlen = sizeof(unsigned int), |
255 | .mode = 0644, | 255 | .mode = 0644, |
256 | .proc_handler = &proc_dointvec_jiffies, | 256 | .proc_handler = proc_dointvec_jiffies, |
257 | }, | 257 | }, |
258 | { | 258 | { |
259 | .ctl_name = 0 | 259 | .ctl_name = 0 |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 9967ac7a01a8..ed4d79a9e4a6 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
@@ -80,7 +80,7 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = { | |||
80 | .data = &nf_init_frags.timeout, | 80 | .data = &nf_init_frags.timeout, |
81 | .maxlen = sizeof(unsigned int), | 81 | .maxlen = sizeof(unsigned int), |
82 | .mode = 0644, | 82 | .mode = 0644, |
83 | .proc_handler = &proc_dointvec_jiffies, | 83 | .proc_handler = proc_dointvec_jiffies, |
84 | }, | 84 | }, |
85 | { | 85 | { |
86 | .ctl_name = NET_NF_CONNTRACK_FRAG6_LOW_THRESH, | 86 | .ctl_name = NET_NF_CONNTRACK_FRAG6_LOW_THRESH, |
@@ -88,7 +88,7 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = { | |||
88 | .data = &nf_init_frags.low_thresh, | 88 | .data = &nf_init_frags.low_thresh, |
89 | .maxlen = sizeof(unsigned int), | 89 | .maxlen = sizeof(unsigned int), |
90 | .mode = 0644, | 90 | .mode = 0644, |
91 | .proc_handler = &proc_dointvec, | 91 | .proc_handler = proc_dointvec, |
92 | }, | 92 | }, |
93 | { | 93 | { |
94 | .ctl_name = NET_NF_CONNTRACK_FRAG6_HIGH_THRESH, | 94 | .ctl_name = NET_NF_CONNTRACK_FRAG6_HIGH_THRESH, |
@@ -96,7 +96,7 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = { | |||
96 | .data = &nf_init_frags.high_thresh, | 96 | .data = &nf_init_frags.high_thresh, |
97 | .maxlen = sizeof(unsigned int), | 97 | .maxlen = sizeof(unsigned int), |
98 | .mode = 0644, | 98 | .mode = 0644, |
99 | .proc_handler = &proc_dointvec, | 99 | .proc_handler = proc_dointvec, |
100 | }, | 100 | }, |
101 | { .ctl_name = 0 } | 101 | { .ctl_name = 0 } |
102 | }; | 102 | }; |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 2ba04d41dc25..61f6827e5906 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -860,7 +860,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
860 | if (final_p) | 860 | if (final_p) |
861 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 861 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
862 | 862 | ||
863 | if ((err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT)) < 0) { | 863 | err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT); |
864 | if (err < 0) { | ||
864 | if (err == -EREMOTE) | 865 | if (err == -EREMOTE) |
865 | err = ip6_dst_blackhole(sk, &dst, &fl); | 866 | err = ip6_dst_blackhole(sk, &dst, &fl); |
866 | if (err < 0) | 867 | if (err < 0) |
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index af12de071f4c..3c575118fca5 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
@@ -642,7 +642,7 @@ static struct ctl_table ip6_frags_ns_ctl_table[] = { | |||
642 | .data = &init_net.ipv6.frags.high_thresh, | 642 | .data = &init_net.ipv6.frags.high_thresh, |
643 | .maxlen = sizeof(int), | 643 | .maxlen = sizeof(int), |
644 | .mode = 0644, | 644 | .mode = 0644, |
645 | .proc_handler = &proc_dointvec | 645 | .proc_handler = proc_dointvec |
646 | }, | 646 | }, |
647 | { | 647 | { |
648 | .ctl_name = NET_IPV6_IP6FRAG_LOW_THRESH, | 648 | .ctl_name = NET_IPV6_IP6FRAG_LOW_THRESH, |
@@ -650,7 +650,7 @@ static struct ctl_table ip6_frags_ns_ctl_table[] = { | |||
650 | .data = &init_net.ipv6.frags.low_thresh, | 650 | .data = &init_net.ipv6.frags.low_thresh, |
651 | .maxlen = sizeof(int), | 651 | .maxlen = sizeof(int), |
652 | .mode = 0644, | 652 | .mode = 0644, |
653 | .proc_handler = &proc_dointvec | 653 | .proc_handler = proc_dointvec |
654 | }, | 654 | }, |
655 | { | 655 | { |
656 | .ctl_name = NET_IPV6_IP6FRAG_TIME, | 656 | .ctl_name = NET_IPV6_IP6FRAG_TIME, |
@@ -658,8 +658,8 @@ static struct ctl_table ip6_frags_ns_ctl_table[] = { | |||
658 | .data = &init_net.ipv6.frags.timeout, | 658 | .data = &init_net.ipv6.frags.timeout, |
659 | .maxlen = sizeof(int), | 659 | .maxlen = sizeof(int), |
660 | .mode = 0644, | 660 | .mode = 0644, |
661 | .proc_handler = &proc_dointvec_jiffies, | 661 | .proc_handler = proc_dointvec_jiffies, |
662 | .strategy = &sysctl_jiffies, | 662 | .strategy = sysctl_jiffies, |
663 | }, | 663 | }, |
664 | { } | 664 | { } |
665 | }; | 665 | }; |
@@ -671,8 +671,8 @@ static struct ctl_table ip6_frags_ctl_table[] = { | |||
671 | .data = &ip6_frags.secret_interval, | 671 | .data = &ip6_frags.secret_interval, |
672 | .maxlen = sizeof(int), | 672 | .maxlen = sizeof(int), |
673 | .mode = 0644, | 673 | .mode = 0644, |
674 | .proc_handler = &proc_dointvec_jiffies, | 674 | .proc_handler = proc_dointvec_jiffies, |
675 | .strategy = &sysctl_jiffies | 675 | .strategy = sysctl_jiffies |
676 | }, | 676 | }, |
677 | { } | 677 | { } |
678 | }; | 678 | }; |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 89dc69924340..18c486cf4987 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -108,7 +108,6 @@ static struct dst_ops ip6_dst_ops_template = { | |||
108 | .link_failure = ip6_link_failure, | 108 | .link_failure = ip6_link_failure, |
109 | .update_pmtu = ip6_rt_update_pmtu, | 109 | .update_pmtu = ip6_rt_update_pmtu, |
110 | .local_out = __ip6_local_out, | 110 | .local_out = __ip6_local_out, |
111 | .entry_size = sizeof(struct rt6_info), | ||
112 | .entries = ATOMIC_INIT(0), | 111 | .entries = ATOMIC_INIT(0), |
113 | }; | 112 | }; |
114 | 113 | ||
@@ -122,7 +121,6 @@ static struct dst_ops ip6_dst_blackhole_ops = { | |||
122 | .destroy = ip6_dst_destroy, | 121 | .destroy = ip6_dst_destroy, |
123 | .check = ip6_dst_check, | 122 | .check = ip6_dst_check, |
124 | .update_pmtu = ip6_rt_blackhole_update_pmtu, | 123 | .update_pmtu = ip6_rt_blackhole_update_pmtu, |
125 | .entry_size = sizeof(struct rt6_info), | ||
126 | .entries = ATOMIC_INIT(0), | 124 | .entries = ATOMIC_INIT(0), |
127 | }; | 125 | }; |
128 | 126 | ||
@@ -2196,7 +2194,7 @@ static int rt6_fill_node(struct net *net, | |||
2196 | if (iif) { | 2194 | if (iif) { |
2197 | #ifdef CONFIG_IPV6_MROUTE | 2195 | #ifdef CONFIG_IPV6_MROUTE |
2198 | if (ipv6_addr_is_multicast(&rt->rt6i_dst.addr)) { | 2196 | if (ipv6_addr_is_multicast(&rt->rt6i_dst.addr)) { |
2199 | int err = ip6mr_get_route(skb, rtm, nowait); | 2197 | int err = ip6mr_get_route(net, skb, rtm, nowait); |
2200 | if (err <= 0) { | 2198 | if (err <= 0) { |
2201 | if (!nowait) { | 2199 | if (!nowait) { |
2202 | if (err == 0) | 2200 | if (err == 0) |
@@ -2408,19 +2406,16 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg) | |||
2408 | { | 2406 | { |
2409 | struct seq_file *m = p_arg; | 2407 | struct seq_file *m = p_arg; |
2410 | 2408 | ||
2411 | seq_printf(m, NIP6_SEQFMT " %02x ", NIP6(rt->rt6i_dst.addr), | 2409 | seq_printf(m, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen); |
2412 | rt->rt6i_dst.plen); | ||
2413 | 2410 | ||
2414 | #ifdef CONFIG_IPV6_SUBTREES | 2411 | #ifdef CONFIG_IPV6_SUBTREES |
2415 | seq_printf(m, NIP6_SEQFMT " %02x ", NIP6(rt->rt6i_src.addr), | 2412 | seq_printf(m, "%pi6 %02x ", &rt->rt6i_src.addr, rt->rt6i_src.plen); |
2416 | rt->rt6i_src.plen); | ||
2417 | #else | 2413 | #else |
2418 | seq_puts(m, "00000000000000000000000000000000 00 "); | 2414 | seq_puts(m, "00000000000000000000000000000000 00 "); |
2419 | #endif | 2415 | #endif |
2420 | 2416 | ||
2421 | if (rt->rt6i_nexthop) { | 2417 | if (rt->rt6i_nexthop) { |
2422 | seq_printf(m, NIP6_SEQFMT, | 2418 | seq_printf(m, "%pi6", rt->rt6i_nexthop->primary_key); |
2423 | NIP6(*((struct in6_addr *)rt->rt6i_nexthop->primary_key))); | ||
2424 | } else { | 2419 | } else { |
2425 | seq_puts(m, "00000000000000000000000000000000"); | 2420 | seq_puts(m, "00000000000000000000000000000000"); |
2426 | } | 2421 | } |
@@ -2502,7 +2497,7 @@ ctl_table ipv6_route_table_template[] = { | |||
2502 | .data = &init_net.ipv6.sysctl.flush_delay, | 2497 | .data = &init_net.ipv6.sysctl.flush_delay, |
2503 | .maxlen = sizeof(int), | 2498 | .maxlen = sizeof(int), |
2504 | .mode = 0200, | 2499 | .mode = 0200, |
2505 | .proc_handler = &ipv6_sysctl_rtcache_flush | 2500 | .proc_handler = ipv6_sysctl_rtcache_flush |
2506 | }, | 2501 | }, |
2507 | { | 2502 | { |
2508 | .ctl_name = NET_IPV6_ROUTE_GC_THRESH, | 2503 | .ctl_name = NET_IPV6_ROUTE_GC_THRESH, |
@@ -2510,7 +2505,7 @@ ctl_table ipv6_route_table_template[] = { | |||
2510 | .data = &ip6_dst_ops_template.gc_thresh, | 2505 | .data = &ip6_dst_ops_template.gc_thresh, |
2511 | .maxlen = sizeof(int), | 2506 | .maxlen = sizeof(int), |
2512 | .mode = 0644, | 2507 | .mode = 0644, |
2513 | .proc_handler = &proc_dointvec, | 2508 | .proc_handler = proc_dointvec, |
2514 | }, | 2509 | }, |
2515 | { | 2510 | { |
2516 | .ctl_name = NET_IPV6_ROUTE_MAX_SIZE, | 2511 | .ctl_name = NET_IPV6_ROUTE_MAX_SIZE, |
@@ -2518,7 +2513,7 @@ ctl_table ipv6_route_table_template[] = { | |||
2518 | .data = &init_net.ipv6.sysctl.ip6_rt_max_size, | 2513 | .data = &init_net.ipv6.sysctl.ip6_rt_max_size, |
2519 | .maxlen = sizeof(int), | 2514 | .maxlen = sizeof(int), |
2520 | .mode = 0644, | 2515 | .mode = 0644, |
2521 | .proc_handler = &proc_dointvec, | 2516 | .proc_handler = proc_dointvec, |
2522 | }, | 2517 | }, |
2523 | { | 2518 | { |
2524 | .ctl_name = NET_IPV6_ROUTE_GC_MIN_INTERVAL, | 2519 | .ctl_name = NET_IPV6_ROUTE_GC_MIN_INTERVAL, |
@@ -2526,8 +2521,8 @@ ctl_table ipv6_route_table_template[] = { | |||
2526 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_min_interval, | 2521 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_min_interval, |
2527 | .maxlen = sizeof(int), | 2522 | .maxlen = sizeof(int), |
2528 | .mode = 0644, | 2523 | .mode = 0644, |
2529 | .proc_handler = &proc_dointvec_jiffies, | 2524 | .proc_handler = proc_dointvec_jiffies, |
2530 | .strategy = &sysctl_jiffies, | 2525 | .strategy = sysctl_jiffies, |
2531 | }, | 2526 | }, |
2532 | { | 2527 | { |
2533 | .ctl_name = NET_IPV6_ROUTE_GC_TIMEOUT, | 2528 | .ctl_name = NET_IPV6_ROUTE_GC_TIMEOUT, |
@@ -2535,8 +2530,8 @@ ctl_table ipv6_route_table_template[] = { | |||
2535 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_timeout, | 2530 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_timeout, |
2536 | .maxlen = sizeof(int), | 2531 | .maxlen = sizeof(int), |
2537 | .mode = 0644, | 2532 | .mode = 0644, |
2538 | .proc_handler = &proc_dointvec_jiffies, | 2533 | .proc_handler = proc_dointvec_jiffies, |
2539 | .strategy = &sysctl_jiffies, | 2534 | .strategy = sysctl_jiffies, |
2540 | }, | 2535 | }, |
2541 | { | 2536 | { |
2542 | .ctl_name = NET_IPV6_ROUTE_GC_INTERVAL, | 2537 | .ctl_name = NET_IPV6_ROUTE_GC_INTERVAL, |
@@ -2544,8 +2539,8 @@ ctl_table ipv6_route_table_template[] = { | |||
2544 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_interval, | 2539 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_interval, |
2545 | .maxlen = sizeof(int), | 2540 | .maxlen = sizeof(int), |
2546 | .mode = 0644, | 2541 | .mode = 0644, |
2547 | .proc_handler = &proc_dointvec_jiffies, | 2542 | .proc_handler = proc_dointvec_jiffies, |
2548 | .strategy = &sysctl_jiffies, | 2543 | .strategy = sysctl_jiffies, |
2549 | }, | 2544 | }, |
2550 | { | 2545 | { |
2551 | .ctl_name = NET_IPV6_ROUTE_GC_ELASTICITY, | 2546 | .ctl_name = NET_IPV6_ROUTE_GC_ELASTICITY, |
@@ -2553,8 +2548,8 @@ ctl_table ipv6_route_table_template[] = { | |||
2553 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_elasticity, | 2548 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_elasticity, |
2554 | .maxlen = sizeof(int), | 2549 | .maxlen = sizeof(int), |
2555 | .mode = 0644, | 2550 | .mode = 0644, |
2556 | .proc_handler = &proc_dointvec_jiffies, | 2551 | .proc_handler = proc_dointvec_jiffies, |
2557 | .strategy = &sysctl_jiffies, | 2552 | .strategy = sysctl_jiffies, |
2558 | }, | 2553 | }, |
2559 | { | 2554 | { |
2560 | .ctl_name = NET_IPV6_ROUTE_MTU_EXPIRES, | 2555 | .ctl_name = NET_IPV6_ROUTE_MTU_EXPIRES, |
@@ -2562,8 +2557,8 @@ ctl_table ipv6_route_table_template[] = { | |||
2562 | .data = &init_net.ipv6.sysctl.ip6_rt_mtu_expires, | 2557 | .data = &init_net.ipv6.sysctl.ip6_rt_mtu_expires, |
2563 | .maxlen = sizeof(int), | 2558 | .maxlen = sizeof(int), |
2564 | .mode = 0644, | 2559 | .mode = 0644, |
2565 | .proc_handler = &proc_dointvec_jiffies, | 2560 | .proc_handler = proc_dointvec_jiffies, |
2566 | .strategy = &sysctl_jiffies, | 2561 | .strategy = sysctl_jiffies, |
2567 | }, | 2562 | }, |
2568 | { | 2563 | { |
2569 | .ctl_name = NET_IPV6_ROUTE_MIN_ADVMSS, | 2564 | .ctl_name = NET_IPV6_ROUTE_MIN_ADVMSS, |
@@ -2571,8 +2566,8 @@ ctl_table ipv6_route_table_template[] = { | |||
2571 | .data = &init_net.ipv6.sysctl.ip6_rt_min_advmss, | 2566 | .data = &init_net.ipv6.sysctl.ip6_rt_min_advmss, |
2572 | .maxlen = sizeof(int), | 2567 | .maxlen = sizeof(int), |
2573 | .mode = 0644, | 2568 | .mode = 0644, |
2574 | .proc_handler = &proc_dointvec_jiffies, | 2569 | .proc_handler = proc_dointvec_jiffies, |
2575 | .strategy = &sysctl_jiffies, | 2570 | .strategy = sysctl_jiffies, |
2576 | }, | 2571 | }, |
2577 | { | 2572 | { |
2578 | .ctl_name = NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS, | 2573 | .ctl_name = NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS, |
@@ -2580,8 +2575,8 @@ ctl_table ipv6_route_table_template[] = { | |||
2580 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_min_interval, | 2575 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_min_interval, |
2581 | .maxlen = sizeof(int), | 2576 | .maxlen = sizeof(int), |
2582 | .mode = 0644, | 2577 | .mode = 0644, |
2583 | .proc_handler = &proc_dointvec_ms_jiffies, | 2578 | .proc_handler = proc_dointvec_ms_jiffies, |
2584 | .strategy = &sysctl_ms_jiffies, | 2579 | .strategy = sysctl_ms_jiffies, |
2585 | }, | 2580 | }, |
2586 | { .ctl_name = 0 } | 2581 | { .ctl_name = 0 } |
2587 | }; | 2582 | }; |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index b7a50e968506..d3467e563f02 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -62,8 +62,8 @@ | |||
62 | #define HASH_SIZE 16 | 62 | #define HASH_SIZE 16 |
63 | #define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) | 63 | #define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) |
64 | 64 | ||
65 | static int ipip6_fb_tunnel_init(struct net_device *dev); | 65 | static void ipip6_fb_tunnel_init(struct net_device *dev); |
66 | static int ipip6_tunnel_init(struct net_device *dev); | 66 | static void ipip6_tunnel_init(struct net_device *dev); |
67 | static void ipip6_tunnel_setup(struct net_device *dev); | 67 | static void ipip6_tunnel_setup(struct net_device *dev); |
68 | 68 | ||
69 | static int sit_net_id; | 69 | static int sit_net_id; |
@@ -188,7 +188,8 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct net *net, | |||
188 | } | 188 | } |
189 | 189 | ||
190 | nt = netdev_priv(dev); | 190 | nt = netdev_priv(dev); |
191 | dev->init = ipip6_tunnel_init; | 191 | ipip6_tunnel_init(dev); |
192 | |||
192 | nt->parms = *parms; | 193 | nt->parms = *parms; |
193 | 194 | ||
194 | if (parms->i_flags & SIT_ISATAP) | 195 | if (parms->i_flags & SIT_ISATAP) |
@@ -926,13 +927,17 @@ static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu) | |||
926 | return 0; | 927 | return 0; |
927 | } | 928 | } |
928 | 929 | ||
930 | static const struct net_device_ops ipip6_netdev_ops = { | ||
931 | .ndo_uninit = ipip6_tunnel_uninit, | ||
932 | .ndo_start_xmit = ipip6_tunnel_xmit, | ||
933 | .ndo_do_ioctl = ipip6_tunnel_ioctl, | ||
934 | .ndo_change_mtu = ipip6_tunnel_change_mtu, | ||
935 | }; | ||
936 | |||
929 | static void ipip6_tunnel_setup(struct net_device *dev) | 937 | static void ipip6_tunnel_setup(struct net_device *dev) |
930 | { | 938 | { |
931 | dev->uninit = ipip6_tunnel_uninit; | 939 | dev->netdev_ops = &ipip6_netdev_ops; |
932 | dev->destructor = free_netdev; | 940 | dev->destructor = free_netdev; |
933 | dev->hard_start_xmit = ipip6_tunnel_xmit; | ||
934 | dev->do_ioctl = ipip6_tunnel_ioctl; | ||
935 | dev->change_mtu = ipip6_tunnel_change_mtu; | ||
936 | 941 | ||
937 | dev->type = ARPHRD_SIT; | 942 | dev->type = ARPHRD_SIT; |
938 | dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr); | 943 | dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr); |
@@ -943,11 +948,9 @@ static void ipip6_tunnel_setup(struct net_device *dev) | |||
943 | dev->features |= NETIF_F_NETNS_LOCAL; | 948 | dev->features |= NETIF_F_NETNS_LOCAL; |
944 | } | 949 | } |
945 | 950 | ||
946 | static int ipip6_tunnel_init(struct net_device *dev) | 951 | static void ipip6_tunnel_init(struct net_device *dev) |
947 | { | 952 | { |
948 | struct ip_tunnel *tunnel; | 953 | struct ip_tunnel *tunnel = netdev_priv(dev); |
949 | |||
950 | tunnel = netdev_priv(dev); | ||
951 | 954 | ||
952 | tunnel->dev = dev; | 955 | tunnel->dev = dev; |
953 | strcpy(tunnel->parms.name, dev->name); | 956 | strcpy(tunnel->parms.name, dev->name); |
@@ -956,11 +959,9 @@ static int ipip6_tunnel_init(struct net_device *dev) | |||
956 | memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); | 959 | memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); |
957 | 960 | ||
958 | ipip6_tunnel_bind_dev(dev); | 961 | ipip6_tunnel_bind_dev(dev); |
959 | |||
960 | return 0; | ||
961 | } | 962 | } |
962 | 963 | ||
963 | static int ipip6_fb_tunnel_init(struct net_device *dev) | 964 | static void ipip6_fb_tunnel_init(struct net_device *dev) |
964 | { | 965 | { |
965 | struct ip_tunnel *tunnel = netdev_priv(dev); | 966 | struct ip_tunnel *tunnel = netdev_priv(dev); |
966 | struct iphdr *iph = &tunnel->parms.iph; | 967 | struct iphdr *iph = &tunnel->parms.iph; |
@@ -977,7 +978,6 @@ static int ipip6_fb_tunnel_init(struct net_device *dev) | |||
977 | 978 | ||
978 | dev_hold(dev); | 979 | dev_hold(dev); |
979 | sitn->tunnels_wc[0] = tunnel; | 980 | sitn->tunnels_wc[0] = tunnel; |
980 | return 0; | ||
981 | } | 981 | } |
982 | 982 | ||
983 | static struct xfrm_tunnel sit_handler = { | 983 | static struct xfrm_tunnel sit_handler = { |
@@ -1025,16 +1025,17 @@ static int sit_init_net(struct net *net) | |||
1025 | err = -ENOMEM; | 1025 | err = -ENOMEM; |
1026 | goto err_alloc_dev; | 1026 | goto err_alloc_dev; |
1027 | } | 1027 | } |
1028 | |||
1029 | sitn->fb_tunnel_dev->init = ipip6_fb_tunnel_init; | ||
1030 | dev_net_set(sitn->fb_tunnel_dev, net); | 1028 | dev_net_set(sitn->fb_tunnel_dev, net); |
1031 | 1029 | ||
1030 | ipip6_fb_tunnel_init(sitn->fb_tunnel_dev); | ||
1031 | |||
1032 | if ((err = register_netdev(sitn->fb_tunnel_dev))) | 1032 | if ((err = register_netdev(sitn->fb_tunnel_dev))) |
1033 | goto err_reg_dev; | 1033 | goto err_reg_dev; |
1034 | 1034 | ||
1035 | return 0; | 1035 | return 0; |
1036 | 1036 | ||
1037 | err_reg_dev: | 1037 | err_reg_dev: |
1038 | dev_put(sitn->fb_tunnel_dev); | ||
1038 | free_netdev(sitn->fb_tunnel_dev); | 1039 | free_netdev(sitn->fb_tunnel_dev); |
1039 | err_alloc_dev: | 1040 | err_alloc_dev: |
1040 | /* nothing */ | 1041 | /* nothing */ |
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 676c80b5b14b..711175e0571f 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c | |||
@@ -259,7 +259,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
259 | 259 | ||
260 | if (final_p) | 260 | if (final_p) |
261 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 261 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
262 | if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0) | 262 | if ((xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0) |
263 | goto out_free; | 263 | goto out_free; |
264 | } | 264 | } |
265 | 265 | ||
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 587f8f60c489..9048fe7e7ea7 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c | |||
@@ -35,7 +35,7 @@ static ctl_table ipv6_table_template[] = { | |||
35 | .data = &init_net.ipv6.sysctl.bindv6only, | 35 | .data = &init_net.ipv6.sysctl.bindv6only, |
36 | .maxlen = sizeof(int), | 36 | .maxlen = sizeof(int), |
37 | .mode = 0644, | 37 | .mode = 0644, |
38 | .proc_handler = &proc_dointvec | 38 | .proc_handler = proc_dointvec |
39 | }, | 39 | }, |
40 | { .ctl_name = 0 } | 40 | { .ctl_name = 0 } |
41 | }; | 41 | }; |
@@ -47,7 +47,7 @@ static ctl_table ipv6_table[] = { | |||
47 | .data = &sysctl_mld_max_msf, | 47 | .data = &sysctl_mld_max_msf, |
48 | .maxlen = sizeof(int), | 48 | .maxlen = sizeof(int), |
49 | .mode = 0644, | 49 | .mode = 0644, |
50 | .proc_handler = &proc_dointvec | 50 | .proc_handler = proc_dointvec |
51 | }, | 51 | }, |
52 | { .ctl_name = 0 } | 52 | { .ctl_name = 0 } |
53 | }; | 53 | }; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index b6b356b7912a..8702b06cb60a 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -260,7 +260,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
260 | if (final_p) | 260 | if (final_p) |
261 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 261 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
262 | 262 | ||
263 | if ((err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT)) < 0) { | 263 | err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT); |
264 | if (err < 0) { | ||
264 | if (err == -EREMOTE) | 265 | if (err == -EREMOTE) |
265 | err = ip6_dst_blackhole(sk, &dst, &fl); | 266 | err = ip6_dst_blackhole(sk, &dst, &fl); |
266 | if (err < 0) | 267 | if (err < 0) |
@@ -390,7 +391,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
390 | goto out; | 391 | goto out; |
391 | } | 392 | } |
392 | 393 | ||
393 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | 394 | if ((err = xfrm_lookup(net, &dst, &fl, sk, 0)) < 0) { |
394 | sk->sk_err_soft = -err; | 395 | sk->sk_err_soft = -err; |
395 | goto out; | 396 | goto out; |
396 | } | 397 | } |
@@ -492,7 +493,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req) | |||
492 | goto done; | 493 | goto done; |
493 | if (final_p) | 494 | if (final_p) |
494 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 495 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
495 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) | 496 | if ((err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0) |
496 | goto done; | 497 | goto done; |
497 | 498 | ||
498 | skb = tcp_make_synack(sk, dst, req); | 499 | skb = tcp_make_synack(sk, dst, req); |
@@ -501,7 +502,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req) | |||
501 | 502 | ||
502 | th->check = tcp_v6_check(th, skb->len, | 503 | th->check = tcp_v6_check(th, skb->len, |
503 | &treq->loc_addr, &treq->rmt_addr, | 504 | &treq->loc_addr, &treq->rmt_addr, |
504 | csum_partial((char *)th, skb->len, skb->csum)); | 505 | csum_partial(th, skb->len, skb->csum)); |
505 | 506 | ||
506 | ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); | 507 | ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); |
507 | err = ip6_xmit(sk, skb, &fl, opt, 0); | 508 | err = ip6_xmit(sk, skb, &fl, opt, 0); |
@@ -872,12 +873,10 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb) | |||
872 | 873 | ||
873 | if (genhash || memcmp(hash_location, newhash, 16) != 0) { | 874 | if (genhash || memcmp(hash_location, newhash, 16) != 0) { |
874 | if (net_ratelimit()) { | 875 | if (net_ratelimit()) { |
875 | printk(KERN_INFO "MD5 Hash %s for " | 876 | printk(KERN_INFO "MD5 Hash %s for (%pI6, %u)->(%pI6, %u)\n", |
876 | "(" NIP6_FMT ", %u)->" | ||
877 | "(" NIP6_FMT ", %u)\n", | ||
878 | genhash ? "failed" : "mismatch", | 877 | genhash ? "failed" : "mismatch", |
879 | NIP6(ip6h->saddr), ntohs(th->source), | 878 | &ip6h->saddr, ntohs(th->source), |
880 | NIP6(ip6h->daddr), ntohs(th->dest)); | 879 | &ip6h->daddr, ntohs(th->dest)); |
881 | } | 880 | } |
882 | return 1; | 881 | return 1; |
883 | } | 882 | } |
@@ -917,7 +916,7 @@ static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb) | |||
917 | skb->csum_offset = offsetof(struct tcphdr, check); | 916 | skb->csum_offset = offsetof(struct tcphdr, check); |
918 | } else { | 917 | } else { |
919 | th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, | 918 | th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, |
920 | csum_partial((char *)th, th->doff<<2, | 919 | csum_partial(th, th->doff<<2, |
921 | skb->csum)); | 920 | skb->csum)); |
922 | } | 921 | } |
923 | } | 922 | } |
@@ -999,7 +998,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | |||
999 | } | 998 | } |
1000 | #endif | 999 | #endif |
1001 | 1000 | ||
1002 | buff->csum = csum_partial((char *)t1, tot_len, 0); | 1001 | buff->csum = csum_partial(t1, tot_len, 0); |
1003 | 1002 | ||
1004 | memset(&fl, 0, sizeof(fl)); | 1003 | memset(&fl, 0, sizeof(fl)); |
1005 | ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr); | 1004 | ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr); |
@@ -1020,7 +1019,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | |||
1020 | * namespace | 1019 | * namespace |
1021 | */ | 1020 | */ |
1022 | if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) { | 1021 | if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) { |
1023 | if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) { | 1022 | if (xfrm_lookup(net, &buff->dst, &fl, NULL, 0) >= 0) { |
1024 | ip6_xmit(ctl_sk, buff, &fl, NULL, 0); | 1023 | ip6_xmit(ctl_sk, buff, &fl, NULL, 0); |
1025 | TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); | 1024 | TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); |
1026 | if (rst) | 1025 | if (rst) |
@@ -1318,7 +1317,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1318 | if (final_p) | 1317 | if (final_p) |
1319 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 1318 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
1320 | 1319 | ||
1321 | if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0) | 1320 | if ((xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0) |
1322 | goto out; | 1321 | goto out; |
1323 | } | 1322 | } |
1324 | 1323 | ||
@@ -1831,7 +1830,7 @@ static int tcp_v6_init_sock(struct sock *sk) | |||
1831 | sk->sk_sndbuf = sysctl_tcp_wmem[1]; | 1830 | sk->sk_sndbuf = sysctl_tcp_wmem[1]; |
1832 | sk->sk_rcvbuf = sysctl_tcp_rmem[1]; | 1831 | sk->sk_rcvbuf = sysctl_tcp_rmem[1]; |
1833 | 1832 | ||
1834 | atomic_inc(&tcp_sockets_allocated); | 1833 | percpu_counter_inc(&tcp_sockets_allocated); |
1835 | 1834 | ||
1836 | return 0; | 1835 | return 0; |
1837 | } | 1836 | } |
@@ -2045,6 +2044,7 @@ struct proto tcpv6_prot = { | |||
2045 | .sysctl_rmem = sysctl_tcp_rmem, | 2044 | .sysctl_rmem = sysctl_tcp_rmem, |
2046 | .max_header = MAX_TCP_HEADER, | 2045 | .max_header = MAX_TCP_HEADER, |
2047 | .obj_size = sizeof(struct tcp6_sock), | 2046 | .obj_size = sizeof(struct tcp6_sock), |
2047 | .slab_flags = SLAB_DESTROY_BY_RCU, | ||
2048 | .twsk_prot = &tcp6_timewait_sock_ops, | 2048 | .twsk_prot = &tcp6_timewait_sock_ops, |
2049 | .rsk_prot = &tcp6_request_sock_ops, | 2049 | .rsk_prot = &tcp6_request_sock_ops, |
2050 | .h.hashinfo = &tcp_hashinfo, | 2050 | .h.hashinfo = &tcp_hashinfo, |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 8b48512ebf6a..84b1a296eecb 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -54,62 +54,91 @@ int udp_v6_get_port(struct sock *sk, unsigned short snum) | |||
54 | return udp_lib_get_port(sk, snum, ipv6_rcv_saddr_equal); | 54 | return udp_lib_get_port(sk, snum, ipv6_rcv_saddr_equal); |
55 | } | 55 | } |
56 | 56 | ||
57 | static inline int compute_score(struct sock *sk, struct net *net, | ||
58 | unsigned short hnum, | ||
59 | struct in6_addr *saddr, __be16 sport, | ||
60 | struct in6_addr *daddr, __be16 dport, | ||
61 | int dif) | ||
62 | { | ||
63 | int score = -1; | ||
64 | |||
65 | if (net_eq(sock_net(sk), net) && sk->sk_hash == hnum && | ||
66 | sk->sk_family == PF_INET6) { | ||
67 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
68 | struct inet_sock *inet = inet_sk(sk); | ||
69 | |||
70 | score = 0; | ||
71 | if (inet->dport) { | ||
72 | if (inet->dport != sport) | ||
73 | return -1; | ||
74 | score++; | ||
75 | } | ||
76 | if (!ipv6_addr_any(&np->rcv_saddr)) { | ||
77 | if (!ipv6_addr_equal(&np->rcv_saddr, daddr)) | ||
78 | return -1; | ||
79 | score++; | ||
80 | } | ||
81 | if (!ipv6_addr_any(&np->daddr)) { | ||
82 | if (!ipv6_addr_equal(&np->daddr, saddr)) | ||
83 | return -1; | ||
84 | score++; | ||
85 | } | ||
86 | if (sk->sk_bound_dev_if) { | ||
87 | if (sk->sk_bound_dev_if != dif) | ||
88 | return -1; | ||
89 | score++; | ||
90 | } | ||
91 | } | ||
92 | return score; | ||
93 | } | ||
94 | |||
57 | static struct sock *__udp6_lib_lookup(struct net *net, | 95 | static struct sock *__udp6_lib_lookup(struct net *net, |
58 | struct in6_addr *saddr, __be16 sport, | 96 | struct in6_addr *saddr, __be16 sport, |
59 | struct in6_addr *daddr, __be16 dport, | 97 | struct in6_addr *daddr, __be16 dport, |
60 | int dif, struct hlist_head udptable[]) | 98 | int dif, struct udp_table *udptable) |
61 | { | 99 | { |
62 | struct sock *sk, *result = NULL; | 100 | struct sock *sk, *result; |
63 | struct hlist_node *node; | 101 | struct hlist_nulls_node *node; |
64 | unsigned short hnum = ntohs(dport); | 102 | unsigned short hnum = ntohs(dport); |
65 | int badness = -1; | 103 | unsigned int hash = udp_hashfn(net, hnum); |
66 | 104 | struct udp_hslot *hslot = &udptable->hash[hash]; | |
67 | read_lock(&udp_hash_lock); | 105 | int score, badness; |
68 | sk_for_each(sk, node, &udptable[udp_hashfn(net, hnum)]) { | 106 | |
69 | struct inet_sock *inet = inet_sk(sk); | 107 | rcu_read_lock(); |
70 | 108 | begin: | |
71 | if (net_eq(sock_net(sk), net) && sk->sk_hash == hnum && | 109 | result = NULL; |
72 | sk->sk_family == PF_INET6) { | 110 | badness = -1; |
73 | struct ipv6_pinfo *np = inet6_sk(sk); | 111 | sk_nulls_for_each_rcu(sk, node, &hslot->head) { |
74 | int score = 0; | 112 | score = compute_score(sk, net, hnum, saddr, sport, daddr, dport, dif); |
75 | if (inet->dport) { | 113 | if (score > badness) { |
76 | if (inet->dport != sport) | 114 | result = sk; |
77 | continue; | 115 | badness = score; |
78 | score++; | ||
79 | } | ||
80 | if (!ipv6_addr_any(&np->rcv_saddr)) { | ||
81 | if (!ipv6_addr_equal(&np->rcv_saddr, daddr)) | ||
82 | continue; | ||
83 | score++; | ||
84 | } | ||
85 | if (!ipv6_addr_any(&np->daddr)) { | ||
86 | if (!ipv6_addr_equal(&np->daddr, saddr)) | ||
87 | continue; | ||
88 | score++; | ||
89 | } | ||
90 | if (sk->sk_bound_dev_if) { | ||
91 | if (sk->sk_bound_dev_if != dif) | ||
92 | continue; | ||
93 | score++; | ||
94 | } | ||
95 | if (score == 4) { | ||
96 | result = sk; | ||
97 | break; | ||
98 | } else if (score > badness) { | ||
99 | result = sk; | ||
100 | badness = score; | ||
101 | } | ||
102 | } | 116 | } |
103 | } | 117 | } |
104 | if (result) | 118 | /* |
105 | sock_hold(result); | 119 | * if the nulls value we got at the end of this lookup is |
106 | read_unlock(&udp_hash_lock); | 120 | * not the expected one, we must restart lookup. |
121 | * We probably met an item that was moved to another chain. | ||
122 | */ | ||
123 | if (get_nulls_value(node) != hash) | ||
124 | goto begin; | ||
125 | |||
126 | if (result) { | ||
127 | if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt))) | ||
128 | result = NULL; | ||
129 | else if (unlikely(compute_score(result, net, hnum, saddr, sport, | ||
130 | daddr, dport, dif) < badness)) { | ||
131 | sock_put(result); | ||
132 | goto begin; | ||
133 | } | ||
134 | } | ||
135 | rcu_read_unlock(); | ||
107 | return result; | 136 | return result; |
108 | } | 137 | } |
109 | 138 | ||
110 | static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb, | 139 | static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb, |
111 | __be16 sport, __be16 dport, | 140 | __be16 sport, __be16 dport, |
112 | struct hlist_head udptable[]) | 141 | struct udp_table *udptable) |
113 | { | 142 | { |
114 | struct sock *sk; | 143 | struct sock *sk; |
115 | struct ipv6hdr *iph = ipv6_hdr(skb); | 144 | struct ipv6hdr *iph = ipv6_hdr(skb); |
@@ -253,7 +282,7 @@ csum_copy_err: | |||
253 | 282 | ||
254 | void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | 283 | void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
255 | int type, int code, int offset, __be32 info, | 284 | int type, int code, int offset, __be32 info, |
256 | struct hlist_head udptable[] ) | 285 | struct udp_table *udptable) |
257 | { | 286 | { |
258 | struct ipv6_pinfo *np; | 287 | struct ipv6_pinfo *np; |
259 | struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data; | 288 | struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data; |
@@ -289,7 +318,7 @@ static __inline__ void udpv6_err(struct sk_buff *skb, | |||
289 | struct inet6_skb_parm *opt, int type, | 318 | struct inet6_skb_parm *opt, int type, |
290 | int code, int offset, __be32 info ) | 319 | int code, int offset, __be32 info ) |
291 | { | 320 | { |
292 | __udp6_lib_err(skb, opt, type, code, offset, info, udp_hash); | 321 | __udp6_lib_err(skb, opt, type, code, offset, info, &udp_table); |
293 | } | 322 | } |
294 | 323 | ||
295 | int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) | 324 | int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) |
@@ -347,11 +376,11 @@ static struct sock *udp_v6_mcast_next(struct net *net, struct sock *sk, | |||
347 | __be16 rmt_port, struct in6_addr *rmt_addr, | 376 | __be16 rmt_port, struct in6_addr *rmt_addr, |
348 | int dif) | 377 | int dif) |
349 | { | 378 | { |
350 | struct hlist_node *node; | 379 | struct hlist_nulls_node *node; |
351 | struct sock *s = sk; | 380 | struct sock *s = sk; |
352 | unsigned short num = ntohs(loc_port); | 381 | unsigned short num = ntohs(loc_port); |
353 | 382 | ||
354 | sk_for_each_from(s, node) { | 383 | sk_nulls_for_each_from(s, node) { |
355 | struct inet_sock *inet = inet_sk(s); | 384 | struct inet_sock *inet = inet_sk(s); |
356 | 385 | ||
357 | if (!net_eq(sock_net(s), net)) | 386 | if (!net_eq(sock_net(s), net)) |
@@ -388,14 +417,15 @@ static struct sock *udp_v6_mcast_next(struct net *net, struct sock *sk, | |||
388 | */ | 417 | */ |
389 | static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, | 418 | static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, |
390 | struct in6_addr *saddr, struct in6_addr *daddr, | 419 | struct in6_addr *saddr, struct in6_addr *daddr, |
391 | struct hlist_head udptable[]) | 420 | struct udp_table *udptable) |
392 | { | 421 | { |
393 | struct sock *sk, *sk2; | 422 | struct sock *sk, *sk2; |
394 | const struct udphdr *uh = udp_hdr(skb); | 423 | const struct udphdr *uh = udp_hdr(skb); |
424 | struct udp_hslot *hslot = &udptable->hash[udp_hashfn(net, ntohs(uh->dest))]; | ||
395 | int dif; | 425 | int dif; |
396 | 426 | ||
397 | read_lock(&udp_hash_lock); | 427 | spin_lock(&hslot->lock); |
398 | sk = sk_head(&udptable[udp_hashfn(net, ntohs(uh->dest))]); | 428 | sk = sk_nulls_head(&hslot->head); |
399 | dif = inet6_iif(skb); | 429 | dif = inet6_iif(skb); |
400 | sk = udp_v6_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif); | 430 | sk = udp_v6_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif); |
401 | if (!sk) { | 431 | if (!sk) { |
@@ -404,7 +434,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, | |||
404 | } | 434 | } |
405 | 435 | ||
406 | sk2 = sk; | 436 | sk2 = sk; |
407 | while ((sk2 = udp_v6_mcast_next(net, sk_next(sk2), uh->dest, daddr, | 437 | while ((sk2 = udp_v6_mcast_next(net, sk_nulls_next(sk2), uh->dest, daddr, |
408 | uh->source, saddr, dif))) { | 438 | uh->source, saddr, dif))) { |
409 | struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC); | 439 | struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC); |
410 | if (buff) { | 440 | if (buff) { |
@@ -423,7 +453,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, | |||
423 | sk_add_backlog(sk, skb); | 453 | sk_add_backlog(sk, skb); |
424 | bh_unlock_sock(sk); | 454 | bh_unlock_sock(sk); |
425 | out: | 455 | out: |
426 | read_unlock(&udp_hash_lock); | 456 | spin_unlock(&hslot->lock); |
427 | return 0; | 457 | return 0; |
428 | } | 458 | } |
429 | 459 | ||
@@ -461,7 +491,7 @@ static inline int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh, | |||
461 | return 0; | 491 | return 0; |
462 | } | 492 | } |
463 | 493 | ||
464 | int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], | 494 | int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, |
465 | int proto) | 495 | int proto) |
466 | { | 496 | { |
467 | struct sock *sk; | 497 | struct sock *sk; |
@@ -558,7 +588,7 @@ discard: | |||
558 | 588 | ||
559 | static __inline__ int udpv6_rcv(struct sk_buff *skb) | 589 | static __inline__ int udpv6_rcv(struct sk_buff *skb) |
560 | { | 590 | { |
561 | return __udp6_lib_rcv(skb, udp_hash, IPPROTO_UDP); | 591 | return __udp6_lib_rcv(skb, &udp_table, IPPROTO_UDP); |
562 | } | 592 | } |
563 | 593 | ||
564 | /* | 594 | /* |
@@ -763,6 +793,9 @@ do_udp_sendmsg: | |||
763 | if (!fl.oif) | 793 | if (!fl.oif) |
764 | fl.oif = sk->sk_bound_dev_if; | 794 | fl.oif = sk->sk_bound_dev_if; |
765 | 795 | ||
796 | if (!fl.oif) | ||
797 | fl.oif = np->sticky_pktinfo.ipi6_ifindex; | ||
798 | |||
766 | if (msg->msg_controllen) { | 799 | if (msg->msg_controllen) { |
767 | opt = &opt_space; | 800 | opt = &opt_space; |
768 | memset(opt, 0, sizeof(struct ipv6_txoptions)); | 801 | memset(opt, 0, sizeof(struct ipv6_txoptions)); |
@@ -819,7 +852,8 @@ do_udp_sendmsg: | |||
819 | if (final_p) | 852 | if (final_p) |
820 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 853 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
821 | 854 | ||
822 | if ((err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT)) < 0) { | 855 | err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT); |
856 | if (err < 0) { | ||
823 | if (err == -EREMOTE) | 857 | if (err == -EREMOTE) |
824 | err = ip6_dst_blackhole(sk, &dst, &fl); | 858 | err = ip6_dst_blackhole(sk, &dst, &fl); |
825 | if (err < 0) | 859 | if (err < 0) |
@@ -1022,7 +1056,7 @@ int udp6_seq_show(struct seq_file *seq, void *v) | |||
1022 | static struct udp_seq_afinfo udp6_seq_afinfo = { | 1056 | static struct udp_seq_afinfo udp6_seq_afinfo = { |
1023 | .name = "udp6", | 1057 | .name = "udp6", |
1024 | .family = AF_INET6, | 1058 | .family = AF_INET6, |
1025 | .hashtable = udp_hash, | 1059 | .udp_table = &udp_table, |
1026 | .seq_fops = { | 1060 | .seq_fops = { |
1027 | .owner = THIS_MODULE, | 1061 | .owner = THIS_MODULE, |
1028 | }, | 1062 | }, |
@@ -1064,7 +1098,8 @@ struct proto udpv6_prot = { | |||
1064 | .sysctl_wmem = &sysctl_udp_wmem_min, | 1098 | .sysctl_wmem = &sysctl_udp_wmem_min, |
1065 | .sysctl_rmem = &sysctl_udp_rmem_min, | 1099 | .sysctl_rmem = &sysctl_udp_rmem_min, |
1066 | .obj_size = sizeof(struct udp6_sock), | 1100 | .obj_size = sizeof(struct udp6_sock), |
1067 | .h.udp_hash = udp_hash, | 1101 | .slab_flags = SLAB_DESTROY_BY_RCU, |
1102 | .h.udp_table = &udp_table, | ||
1068 | #ifdef CONFIG_COMPAT | 1103 | #ifdef CONFIG_COMPAT |
1069 | .compat_setsockopt = compat_udpv6_setsockopt, | 1104 | .compat_setsockopt = compat_udpv6_setsockopt, |
1070 | .compat_getsockopt = compat_udpv6_getsockopt, | 1105 | .compat_getsockopt = compat_udpv6_getsockopt, |
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h index 92dd7da766d8..23779208c334 100644 --- a/net/ipv6/udp_impl.h +++ b/net/ipv6/udp_impl.h | |||
@@ -7,9 +7,9 @@ | |||
7 | #include <net/inet_common.h> | 7 | #include <net/inet_common.h> |
8 | #include <net/transp_v6.h> | 8 | #include <net/transp_v6.h> |
9 | 9 | ||
10 | extern int __udp6_lib_rcv(struct sk_buff *, struct hlist_head [], int ); | 10 | extern int __udp6_lib_rcv(struct sk_buff *, struct udp_table *, int ); |
11 | extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, | 11 | extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, |
12 | int , int , int , __be32 , struct hlist_head []); | 12 | int , int , int , __be32 , struct udp_table *); |
13 | 13 | ||
14 | extern int udp_v6_get_port(struct sock *sk, unsigned short snum); | 14 | extern int udp_v6_get_port(struct sock *sk, unsigned short snum); |
15 | 15 | ||
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c index 3cd1a1ac3d6c..ba162a824585 100644 --- a/net/ipv6/udplite.c +++ b/net/ipv6/udplite.c | |||
@@ -15,14 +15,14 @@ | |||
15 | 15 | ||
16 | static int udplitev6_rcv(struct sk_buff *skb) | 16 | static int udplitev6_rcv(struct sk_buff *skb) |
17 | { | 17 | { |
18 | return __udp6_lib_rcv(skb, udplite_hash, IPPROTO_UDPLITE); | 18 | return __udp6_lib_rcv(skb, &udplite_table, IPPROTO_UDPLITE); |
19 | } | 19 | } |
20 | 20 | ||
21 | static void udplitev6_err(struct sk_buff *skb, | 21 | static void udplitev6_err(struct sk_buff *skb, |
22 | struct inet6_skb_parm *opt, | 22 | struct inet6_skb_parm *opt, |
23 | int type, int code, int offset, __be32 info) | 23 | int type, int code, int offset, __be32 info) |
24 | { | 24 | { |
25 | __udp6_lib_err(skb, opt, type, code, offset, info, udplite_hash); | 25 | __udp6_lib_err(skb, opt, type, code, offset, info, &udplite_table); |
26 | } | 26 | } |
27 | 27 | ||
28 | static struct inet6_protocol udplitev6_protocol = { | 28 | static struct inet6_protocol udplitev6_protocol = { |
@@ -49,7 +49,8 @@ struct proto udplitev6_prot = { | |||
49 | .unhash = udp_lib_unhash, | 49 | .unhash = udp_lib_unhash, |
50 | .get_port = udp_v6_get_port, | 50 | .get_port = udp_v6_get_port, |
51 | .obj_size = sizeof(struct udp6_sock), | 51 | .obj_size = sizeof(struct udp6_sock), |
52 | .h.udp_hash = udplite_hash, | 52 | .slab_flags = SLAB_DESTROY_BY_RCU, |
53 | .h.udp_table = &udplite_table, | ||
53 | #ifdef CONFIG_COMPAT | 54 | #ifdef CONFIG_COMPAT |
54 | .compat_setsockopt = compat_udpv6_setsockopt, | 55 | .compat_setsockopt = compat_udpv6_setsockopt, |
55 | .compat_getsockopt = compat_udpv6_getsockopt, | 56 | .compat_getsockopt = compat_udpv6_getsockopt, |
@@ -95,7 +96,7 @@ void udplitev6_exit(void) | |||
95 | static struct udp_seq_afinfo udplite6_seq_afinfo = { | 96 | static struct udp_seq_afinfo udplite6_seq_afinfo = { |
96 | .name = "udplite6", | 97 | .name = "udplite6", |
97 | .family = AF_INET6, | 98 | .family = AF_INET6, |
98 | .hashtable = udplite_hash, | 99 | .udp_table = &udplite_table, |
99 | .seq_fops = { | 100 | .seq_fops = { |
100 | .owner = THIS_MODULE, | 101 | .owner = THIS_MODULE, |
101 | }, | 102 | }, |
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index a71c7ddcb41e..9084582d236b 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c | |||
@@ -58,6 +58,7 @@ EXPORT_SYMBOL(xfrm6_rcv); | |||
58 | int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, | 58 | int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, |
59 | xfrm_address_t *saddr, u8 proto) | 59 | xfrm_address_t *saddr, u8 proto) |
60 | { | 60 | { |
61 | struct net *net = dev_net(skb->dev); | ||
61 | struct xfrm_state *x = NULL; | 62 | struct xfrm_state *x = NULL; |
62 | int i = 0; | 63 | int i = 0; |
63 | 64 | ||
@@ -67,7 +68,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, | |||
67 | 68 | ||
68 | sp = secpath_dup(skb->sp); | 69 | sp = secpath_dup(skb->sp); |
69 | if (!sp) { | 70 | if (!sp) { |
70 | XFRM_INC_STATS(LINUX_MIB_XFRMINERROR); | 71 | XFRM_INC_STATS(net, LINUX_MIB_XFRMINERROR); |
71 | goto drop; | 72 | goto drop; |
72 | } | 73 | } |
73 | if (skb->sp) | 74 | if (skb->sp) |
@@ -76,7 +77,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, | |||
76 | } | 77 | } |
77 | 78 | ||
78 | if (1 + skb->sp->len == XFRM_MAX_DEPTH) { | 79 | if (1 + skb->sp->len == XFRM_MAX_DEPTH) { |
79 | XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR); | 80 | XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR); |
80 | goto drop; | 81 | goto drop; |
81 | } | 82 | } |
82 | 83 | ||
@@ -100,7 +101,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, | |||
100 | break; | 101 | break; |
101 | } | 102 | } |
102 | 103 | ||
103 | x = xfrm_state_lookup_byaddr(dst, src, proto, AF_INET6); | 104 | x = xfrm_state_lookup_byaddr(net, dst, src, proto, AF_INET6); |
104 | if (!x) | 105 | if (!x) |
105 | continue; | 106 | continue; |
106 | 107 | ||
@@ -122,7 +123,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, | |||
122 | } | 123 | } |
123 | 124 | ||
124 | if (!x) { | 125 | if (!x) { |
125 | XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES); | 126 | XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES); |
126 | xfrm_audit_state_notfound_simple(skb, AF_INET6); | 127 | xfrm_audit_state_notfound_simple(skb, AF_INET6); |
127 | goto drop; | 128 | goto drop; |
128 | } | 129 | } |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 08e4cbbe3f04..97ab068e8ccc 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -27,7 +27,8 @@ | |||
27 | static struct dst_ops xfrm6_dst_ops; | 27 | static struct dst_ops xfrm6_dst_ops; |
28 | static struct xfrm_policy_afinfo xfrm6_policy_afinfo; | 28 | static struct xfrm_policy_afinfo xfrm6_policy_afinfo; |
29 | 29 | ||
30 | static struct dst_entry *xfrm6_dst_lookup(int tos, xfrm_address_t *saddr, | 30 | static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, |
31 | xfrm_address_t *saddr, | ||
31 | xfrm_address_t *daddr) | 32 | xfrm_address_t *daddr) |
32 | { | 33 | { |
33 | struct flowi fl = {}; | 34 | struct flowi fl = {}; |
@@ -38,7 +39,7 @@ static struct dst_entry *xfrm6_dst_lookup(int tos, xfrm_address_t *saddr, | |||
38 | if (saddr) | 39 | if (saddr) |
39 | memcpy(&fl.fl6_src, saddr, sizeof(fl.fl6_src)); | 40 | memcpy(&fl.fl6_src, saddr, sizeof(fl.fl6_src)); |
40 | 41 | ||
41 | dst = ip6_route_output(&init_net, NULL, &fl); | 42 | dst = ip6_route_output(net, NULL, &fl); |
42 | 43 | ||
43 | err = dst->error; | 44 | err = dst->error; |
44 | if (dst->error) { | 45 | if (dst->error) { |
@@ -49,12 +50,13 @@ static struct dst_entry *xfrm6_dst_lookup(int tos, xfrm_address_t *saddr, | |||
49 | return dst; | 50 | return dst; |
50 | } | 51 | } |
51 | 52 | ||
52 | static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr) | 53 | static int xfrm6_get_saddr(struct net *net, |
54 | xfrm_address_t *saddr, xfrm_address_t *daddr) | ||
53 | { | 55 | { |
54 | struct dst_entry *dst; | 56 | struct dst_entry *dst; |
55 | struct net_device *dev; | 57 | struct net_device *dev; |
56 | 58 | ||
57 | dst = xfrm6_dst_lookup(0, NULL, daddr); | 59 | dst = xfrm6_dst_lookup(net, 0, NULL, daddr); |
58 | if (IS_ERR(dst)) | 60 | if (IS_ERR(dst)) |
59 | return -EHOSTUNREACH; | 61 | return -EHOSTUNREACH; |
60 | 62 | ||
@@ -144,6 +146,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev) | |||
144 | static inline void | 146 | static inline void |
145 | _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | 147 | _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) |
146 | { | 148 | { |
149 | int onlyproto = 0; | ||
147 | u16 offset = skb_network_header_len(skb); | 150 | u16 offset = skb_network_header_len(skb); |
148 | struct ipv6hdr *hdr = ipv6_hdr(skb); | 151 | struct ipv6hdr *hdr = ipv6_hdr(skb); |
149 | struct ipv6_opt_hdr *exthdr; | 152 | struct ipv6_opt_hdr *exthdr; |
@@ -159,6 +162,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
159 | exthdr = (struct ipv6_opt_hdr *)(nh + offset); | 162 | exthdr = (struct ipv6_opt_hdr *)(nh + offset); |
160 | 163 | ||
161 | switch (nexthdr) { | 164 | switch (nexthdr) { |
165 | case NEXTHDR_FRAGMENT: | ||
166 | onlyproto = 1; | ||
162 | case NEXTHDR_ROUTING: | 167 | case NEXTHDR_ROUTING: |
163 | case NEXTHDR_HOP: | 168 | case NEXTHDR_HOP: |
164 | case NEXTHDR_DEST: | 169 | case NEXTHDR_DEST: |
@@ -172,7 +177,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
172 | case IPPROTO_TCP: | 177 | case IPPROTO_TCP: |
173 | case IPPROTO_SCTP: | 178 | case IPPROTO_SCTP: |
174 | case IPPROTO_DCCP: | 179 | case IPPROTO_DCCP: |
175 | if (pskb_may_pull(skb, nh + offset + 4 - skb->data)) { | 180 | if (!onlyproto && pskb_may_pull(skb, nh + offset + 4 - skb->data)) { |
176 | __be16 *ports = (__be16 *)exthdr; | 181 | __be16 *ports = (__be16 *)exthdr; |
177 | 182 | ||
178 | fl->fl_ip_sport = ports[!!reverse]; | 183 | fl->fl_ip_sport = ports[!!reverse]; |
@@ -182,7 +187,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
182 | return; | 187 | return; |
183 | 188 | ||
184 | case IPPROTO_ICMPV6: | 189 | case IPPROTO_ICMPV6: |
185 | if (pskb_may_pull(skb, nh + offset + 2 - skb->data)) { | 190 | if (!onlyproto && pskb_may_pull(skb, nh + offset + 2 - skb->data)) { |
186 | u8 *icmp = (u8 *)exthdr; | 191 | u8 *icmp = (u8 *)exthdr; |
187 | 192 | ||
188 | fl->fl_icmp_type = icmp[0]; | 193 | fl->fl_icmp_type = icmp[0]; |
@@ -193,7 +198,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
193 | 198 | ||
194 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 199 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) |
195 | case IPPROTO_MH: | 200 | case IPPROTO_MH: |
196 | if (pskb_may_pull(skb, nh + offset + 3 - skb->data)) { | 201 | if (!onlyproto && pskb_may_pull(skb, nh + offset + 3 - skb->data)) { |
197 | struct ip6_mh *mh; | 202 | struct ip6_mh *mh; |
198 | mh = (struct ip6_mh *)exthdr; | 203 | mh = (struct ip6_mh *)exthdr; |
199 | 204 | ||
@@ -217,7 +222,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
217 | 222 | ||
218 | static inline int xfrm6_garbage_collect(struct dst_ops *ops) | 223 | static inline int xfrm6_garbage_collect(struct dst_ops *ops) |
219 | { | 224 | { |
220 | xfrm6_policy_afinfo.garbage_collect(); | 225 | xfrm6_policy_afinfo.garbage_collect(&init_net); |
221 | return (atomic_read(&xfrm6_dst_ops.entries) > xfrm6_dst_ops.gc_thresh*2); | 226 | return (atomic_read(&xfrm6_dst_ops.entries) > xfrm6_dst_ops.gc_thresh*2); |
222 | } | 227 | } |
223 | 228 | ||
@@ -274,7 +279,6 @@ static struct dst_ops xfrm6_dst_ops = { | |||
274 | .ifdown = xfrm6_dst_ifdown, | 279 | .ifdown = xfrm6_dst_ifdown, |
275 | .local_out = __ip6_local_out, | 280 | .local_out = __ip6_local_out, |
276 | .gc_thresh = 1024, | 281 | .gc_thresh = 1024, |
277 | .entry_size = sizeof(struct xfrm_dst), | ||
278 | .entries = ATOMIC_INIT(0), | 282 | .entries = ATOMIC_INIT(0), |
279 | }; | 283 | }; |
280 | 284 | ||
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index 60c78cfc2737..0e685b05496e 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c | |||
@@ -19,8 +19,6 @@ | |||
19 | #include <net/ipv6.h> | 19 | #include <net/ipv6.h> |
20 | #include <net/addrconf.h> | 20 | #include <net/addrconf.h> |
21 | 21 | ||
22 | static struct xfrm_state_afinfo xfrm6_state_afinfo; | ||
23 | |||
24 | static void | 22 | static void |
25 | __xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl, | 23 | __xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl, |
26 | struct xfrm_tmpl *tmpl, | 24 | struct xfrm_tmpl *tmpl, |
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index c2b278138604..80193db224d9 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c | |||
@@ -345,24 +345,23 @@ static struct xfrm6_tunnel xfrm46_tunnel_handler = { | |||
345 | static int __init xfrm6_tunnel_init(void) | 345 | static int __init xfrm6_tunnel_init(void) |
346 | { | 346 | { |
347 | if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0) | 347 | if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0) |
348 | return -EAGAIN; | 348 | goto err; |
349 | 349 | if (xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6)) | |
350 | if (xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6)) { | 350 | goto unreg; |
351 | xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); | 351 | if (xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET)) |
352 | return -EAGAIN; | 352 | goto dereg6; |
353 | } | 353 | if (xfrm6_tunnel_spi_init() < 0) |
354 | if (xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET)) { | 354 | goto dereg46; |
355 | xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); | ||
356 | xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); | ||
357 | return -EAGAIN; | ||
358 | } | ||
359 | if (xfrm6_tunnel_spi_init() < 0) { | ||
360 | xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET); | ||
361 | xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); | ||
362 | xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); | ||
363 | return -EAGAIN; | ||
364 | } | ||
365 | return 0; | 355 | return 0; |
356 | |||
357 | dereg46: | ||
358 | xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET); | ||
359 | dereg6: | ||
360 | xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); | ||
361 | unreg: | ||
362 | xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); | ||
363 | err: | ||
364 | return -EAGAIN; | ||
366 | } | 365 | } |
367 | 366 | ||
368 | static void __exit xfrm6_tunnel_fini(void) | 367 | static void __exit xfrm6_tunnel_fini(void) |