diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/8021q/vlan_dev.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_probe.c | 19 | ||||
-rw-r--r-- | net/ipv4/xfrm4_policy.c | 14 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_reasm.c | 1 | ||||
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 25 | ||||
-rw-r--r-- | net/mac80211/driver-trace.h | 2 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 75 | ||||
-rw-r--r-- | net/xfrm/xfrm_state.c | 6 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 14 |
9 files changed, 110 insertions, 48 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 77a49ffdd0ef..a9e1f1785614 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -163,7 +163,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, | |||
163 | goto err_unlock; | 163 | goto err_unlock; |
164 | } | 164 | } |
165 | 165 | ||
166 | rx_stats = per_cpu_ptr(vlan_dev_info(dev)->vlan_rx_stats, | 166 | rx_stats = per_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats, |
167 | smp_processor_id()); | 167 | smp_processor_id()); |
168 | rx_stats->rx_packets++; | 168 | rx_stats->rx_packets++; |
169 | rx_stats->rx_bytes += skb->len; | 169 | rx_stats->rx_bytes += skb->len; |
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c index bb110c5ce1d2..9bc805df95d2 100644 --- a/net/ipv4/tcp_probe.c +++ b/net/ipv4/tcp_probe.c | |||
@@ -39,9 +39,9 @@ static int port __read_mostly = 0; | |||
39 | MODULE_PARM_DESC(port, "Port to match (0=all)"); | 39 | MODULE_PARM_DESC(port, "Port to match (0=all)"); |
40 | module_param(port, int, 0); | 40 | module_param(port, int, 0); |
41 | 41 | ||
42 | static int bufsize __read_mostly = 4096; | 42 | static unsigned int bufsize __read_mostly = 4096; |
43 | MODULE_PARM_DESC(bufsize, "Log buffer size in packets (4096)"); | 43 | MODULE_PARM_DESC(bufsize, "Log buffer size in packets (4096)"); |
44 | module_param(bufsize, int, 0); | 44 | module_param(bufsize, uint, 0); |
45 | 45 | ||
46 | static int full __read_mostly; | 46 | static int full __read_mostly; |
47 | MODULE_PARM_DESC(full, "Full log (1=every ack packet received, 0=only cwnd changes)"); | 47 | MODULE_PARM_DESC(full, "Full log (1=every ack packet received, 0=only cwnd changes)"); |
@@ -75,12 +75,12 @@ static struct { | |||
75 | 75 | ||
76 | static inline int tcp_probe_used(void) | 76 | static inline int tcp_probe_used(void) |
77 | { | 77 | { |
78 | return (tcp_probe.head - tcp_probe.tail) % bufsize; | 78 | return (tcp_probe.head - tcp_probe.tail) & (bufsize - 1); |
79 | } | 79 | } |
80 | 80 | ||
81 | static inline int tcp_probe_avail(void) | 81 | static inline int tcp_probe_avail(void) |
82 | { | 82 | { |
83 | return bufsize - tcp_probe_used(); | 83 | return bufsize - tcp_probe_used() - 1; |
84 | } | 84 | } |
85 | 85 | ||
86 | /* | 86 | /* |
@@ -116,7 +116,7 @@ static int jtcp_rcv_established(struct sock *sk, struct sk_buff *skb, | |||
116 | p->ssthresh = tcp_current_ssthresh(sk); | 116 | p->ssthresh = tcp_current_ssthresh(sk); |
117 | p->srtt = tp->srtt >> 3; | 117 | p->srtt = tp->srtt >> 3; |
118 | 118 | ||
119 | tcp_probe.head = (tcp_probe.head + 1) % bufsize; | 119 | tcp_probe.head = (tcp_probe.head + 1) & (bufsize - 1); |
120 | } | 120 | } |
121 | tcp_probe.lastcwnd = tp->snd_cwnd; | 121 | tcp_probe.lastcwnd = tp->snd_cwnd; |
122 | spin_unlock(&tcp_probe.lock); | 122 | spin_unlock(&tcp_probe.lock); |
@@ -149,7 +149,7 @@ static int tcpprobe_open(struct inode * inode, struct file * file) | |||
149 | static int tcpprobe_sprint(char *tbuf, int n) | 149 | static int tcpprobe_sprint(char *tbuf, int n) |
150 | { | 150 | { |
151 | const struct tcp_log *p | 151 | const struct tcp_log *p |
152 | = tcp_probe.log + tcp_probe.tail % bufsize; | 152 | = tcp_probe.log + tcp_probe.tail; |
153 | struct timespec tv | 153 | struct timespec tv |
154 | = ktime_to_timespec(ktime_sub(p->tstamp, tcp_probe.start)); | 154 | = ktime_to_timespec(ktime_sub(p->tstamp, tcp_probe.start)); |
155 | 155 | ||
@@ -192,7 +192,7 @@ static ssize_t tcpprobe_read(struct file *file, char __user *buf, | |||
192 | width = tcpprobe_sprint(tbuf, sizeof(tbuf)); | 192 | width = tcpprobe_sprint(tbuf, sizeof(tbuf)); |
193 | 193 | ||
194 | if (cnt + width < len) | 194 | if (cnt + width < len) |
195 | tcp_probe.tail = (tcp_probe.tail + 1) % bufsize; | 195 | tcp_probe.tail = (tcp_probe.tail + 1) & (bufsize - 1); |
196 | 196 | ||
197 | spin_unlock_bh(&tcp_probe.lock); | 197 | spin_unlock_bh(&tcp_probe.lock); |
198 | 198 | ||
@@ -222,9 +222,10 @@ static __init int tcpprobe_init(void) | |||
222 | init_waitqueue_head(&tcp_probe.wait); | 222 | init_waitqueue_head(&tcp_probe.wait); |
223 | spin_lock_init(&tcp_probe.lock); | 223 | spin_lock_init(&tcp_probe.lock); |
224 | 224 | ||
225 | if (bufsize < 0) | 225 | if (bufsize == 0) |
226 | return -EINVAL; | 226 | return -EINVAL; |
227 | 227 | ||
228 | bufsize = roundup_pow_of_two(bufsize); | ||
228 | tcp_probe.log = kcalloc(bufsize, sizeof(struct tcp_log), GFP_KERNEL); | 229 | tcp_probe.log = kcalloc(bufsize, sizeof(struct tcp_log), GFP_KERNEL); |
229 | if (!tcp_probe.log) | 230 | if (!tcp_probe.log) |
230 | goto err0; | 231 | goto err0; |
@@ -236,7 +237,7 @@ static __init int tcpprobe_init(void) | |||
236 | if (ret) | 237 | if (ret) |
237 | goto err1; | 238 | goto err1; |
238 | 239 | ||
239 | pr_info("TCP probe registered (port=%d)\n", port); | 240 | pr_info("TCP probe registered (port=%d) bufsize=%u\n", port, bufsize); |
240 | return 0; | 241 | return 0; |
241 | err1: | 242 | err1: |
242 | proc_net_remove(&init_net, procname); | 243 | proc_net_remove(&init_net, procname); |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 8c08a28d8f83..67107d63c1cd 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <net/xfrm.h> | 15 | #include <net/xfrm.h> |
16 | #include <net/ip.h> | 16 | #include <net/ip.h> |
17 | 17 | ||
18 | static struct dst_ops xfrm4_dst_ops; | ||
19 | static struct xfrm_policy_afinfo xfrm4_policy_afinfo; | 18 | static struct xfrm_policy_afinfo xfrm4_policy_afinfo; |
20 | 19 | ||
21 | static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, | 20 | static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, |
@@ -190,8 +189,10 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
190 | 189 | ||
191 | static inline int xfrm4_garbage_collect(struct dst_ops *ops) | 190 | static inline int xfrm4_garbage_collect(struct dst_ops *ops) |
192 | { | 191 | { |
193 | xfrm4_policy_afinfo.garbage_collect(&init_net); | 192 | struct net *net = container_of(ops, struct net, xfrm.xfrm4_dst_ops); |
194 | return (atomic_read(&xfrm4_dst_ops.entries) > xfrm4_dst_ops.gc_thresh*2); | 193 | |
194 | xfrm4_policy_afinfo.garbage_collect(net); | ||
195 | return (atomic_read(&ops->entries) > ops->gc_thresh * 2); | ||
195 | } | 196 | } |
196 | 197 | ||
197 | static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu) | 198 | static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu) |
@@ -268,7 +269,7 @@ static struct xfrm_policy_afinfo xfrm4_policy_afinfo = { | |||
268 | static struct ctl_table xfrm4_policy_table[] = { | 269 | static struct ctl_table xfrm4_policy_table[] = { |
269 | { | 270 | { |
270 | .procname = "xfrm4_gc_thresh", | 271 | .procname = "xfrm4_gc_thresh", |
271 | .data = &xfrm4_dst_ops.gc_thresh, | 272 | .data = &init_net.xfrm.xfrm4_dst_ops.gc_thresh, |
272 | .maxlen = sizeof(int), | 273 | .maxlen = sizeof(int), |
273 | .mode = 0644, | 274 | .mode = 0644, |
274 | .proc_handler = proc_dointvec, | 275 | .proc_handler = proc_dointvec, |
@@ -295,8 +296,6 @@ static void __exit xfrm4_policy_fini(void) | |||
295 | 296 | ||
296 | void __init xfrm4_init(int rt_max_size) | 297 | void __init xfrm4_init(int rt_max_size) |
297 | { | 298 | { |
298 | xfrm4_state_init(); | ||
299 | xfrm4_policy_init(); | ||
300 | /* | 299 | /* |
301 | * Select a default value for the gc_thresh based on the main route | 300 | * Select a default value for the gc_thresh based on the main route |
302 | * table hash size. It seems to me the worst case scenario is when | 301 | * table hash size. It seems to me the worst case scenario is when |
@@ -308,6 +307,9 @@ void __init xfrm4_init(int rt_max_size) | |||
308 | * and start cleaning when were 1/2 full | 307 | * and start cleaning when were 1/2 full |
309 | */ | 308 | */ |
310 | xfrm4_dst_ops.gc_thresh = rt_max_size/2; | 309 | xfrm4_dst_ops.gc_thresh = rt_max_size/2; |
310 | |||
311 | xfrm4_state_init(); | ||
312 | xfrm4_policy_init(); | ||
311 | #ifdef CONFIG_SYSCTL | 313 | #ifdef CONFIG_SYSCTL |
312 | sysctl_hdr = register_net_sysctl_table(&init_net, net_ipv4_ctl_path, | 314 | sysctl_hdr = register_net_sysctl_table(&init_net, net_ipv4_ctl_path, |
313 | xfrm4_policy_table); | 315 | xfrm4_policy_table); |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 312c20adc83f..624a54832a7c 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
@@ -63,6 +63,7 @@ struct nf_ct_frag6_queue | |||
63 | struct inet_frag_queue q; | 63 | struct inet_frag_queue q; |
64 | 64 | ||
65 | __be32 id; /* fragment id */ | 65 | __be32 id; /* fragment id */ |
66 | u32 user; | ||
66 | struct in6_addr saddr; | 67 | struct in6_addr saddr; |
67 | struct in6_addr daddr; | 68 | struct in6_addr daddr; |
68 | 69 | ||
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 7254e3f899a7..dbdc696f5fc5 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <net/mip6.h> | 24 | #include <net/mip6.h> |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | static struct dst_ops xfrm6_dst_ops; | ||
28 | static struct xfrm_policy_afinfo xfrm6_policy_afinfo; | 27 | static struct xfrm_policy_afinfo xfrm6_policy_afinfo; |
29 | 28 | ||
30 | static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, | 29 | static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, |
@@ -224,8 +223,10 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
224 | 223 | ||
225 | static inline int xfrm6_garbage_collect(struct dst_ops *ops) | 224 | static inline int xfrm6_garbage_collect(struct dst_ops *ops) |
226 | { | 225 | { |
227 | xfrm6_policy_afinfo.garbage_collect(&init_net); | 226 | struct net *net = container_of(ops, struct net, xfrm.xfrm6_dst_ops); |
228 | return (atomic_read(&xfrm6_dst_ops.entries) > xfrm6_dst_ops.gc_thresh*2); | 227 | |
228 | xfrm6_policy_afinfo.garbage_collect(net); | ||
229 | return (atomic_read(&ops->entries) > ops->gc_thresh * 2); | ||
229 | } | 230 | } |
230 | 231 | ||
231 | static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu) | 232 | static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu) |
@@ -310,7 +311,7 @@ static void xfrm6_policy_fini(void) | |||
310 | static struct ctl_table xfrm6_policy_table[] = { | 311 | static struct ctl_table xfrm6_policy_table[] = { |
311 | { | 312 | { |
312 | .procname = "xfrm6_gc_thresh", | 313 | .procname = "xfrm6_gc_thresh", |
313 | .data = &xfrm6_dst_ops.gc_thresh, | 314 | .data = &init_net.xfrm.xfrm6_dst_ops.gc_thresh, |
314 | .maxlen = sizeof(int), | 315 | .maxlen = sizeof(int), |
315 | .mode = 0644, | 316 | .mode = 0644, |
316 | .proc_handler = proc_dointvec, | 317 | .proc_handler = proc_dointvec, |
@@ -326,13 +327,6 @@ int __init xfrm6_init(void) | |||
326 | int ret; | 327 | int ret; |
327 | unsigned int gc_thresh; | 328 | unsigned int gc_thresh; |
328 | 329 | ||
329 | ret = xfrm6_policy_init(); | ||
330 | if (ret) | ||
331 | goto out; | ||
332 | |||
333 | ret = xfrm6_state_init(); | ||
334 | if (ret) | ||
335 | goto out_policy; | ||
336 | /* | 330 | /* |
337 | * We need a good default value for the xfrm6 gc threshold. | 331 | * We need a good default value for the xfrm6 gc threshold. |
338 | * In ipv4 we set it to the route hash table size * 8, which | 332 | * In ipv4 we set it to the route hash table size * 8, which |
@@ -346,6 +340,15 @@ int __init xfrm6_init(void) | |||
346 | */ | 340 | */ |
347 | gc_thresh = FIB6_TABLE_HASHSZ * 8; | 341 | gc_thresh = FIB6_TABLE_HASHSZ * 8; |
348 | xfrm6_dst_ops.gc_thresh = (gc_thresh < 1024) ? 1024 : gc_thresh; | 342 | xfrm6_dst_ops.gc_thresh = (gc_thresh < 1024) ? 1024 : gc_thresh; |
343 | |||
344 | ret = xfrm6_policy_init(); | ||
345 | if (ret) | ||
346 | goto out; | ||
347 | |||
348 | ret = xfrm6_state_init(); | ||
349 | if (ret) | ||
350 | goto out_policy; | ||
351 | |||
349 | #ifdef CONFIG_SYSCTL | 352 | #ifdef CONFIG_SYSCTL |
350 | sysctl_hdr = register_net_sysctl_table(&init_net, net_ipv6_ctl_path, | 353 | sysctl_hdr = register_net_sysctl_table(&init_net, net_ipv6_ctl_path, |
351 | xfrm6_policy_table); | 354 | xfrm6_policy_table); |
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 0ea258123b8e..d6bd9f517401 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -705,7 +705,7 @@ TRACE_EVENT(drv_ampdu_action, | |||
705 | __entry->ret = ret; | 705 | __entry->ret = ret; |
706 | __entry->action = action; | 706 | __entry->action = action; |
707 | __entry->tid = tid; | 707 | __entry->tid = tid; |
708 | __entry->ssn = *ssn; | 708 | __entry->ssn = ssn ? *ssn : 0; |
709 | ), | 709 | ), |
710 | 710 | ||
711 | TP_printk( | 711 | TP_printk( |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 4725a549ad4d..0ecb16a9a883 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -469,16 +469,16 @@ static inline int xfrm_byidx_should_resize(struct net *net, int total) | |||
469 | return 0; | 469 | return 0; |
470 | } | 470 | } |
471 | 471 | ||
472 | void xfrm_spd_getinfo(struct xfrmk_spdinfo *si) | 472 | void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si) |
473 | { | 473 | { |
474 | read_lock_bh(&xfrm_policy_lock); | 474 | read_lock_bh(&xfrm_policy_lock); |
475 | si->incnt = init_net.xfrm.policy_count[XFRM_POLICY_IN]; | 475 | si->incnt = net->xfrm.policy_count[XFRM_POLICY_IN]; |
476 | si->outcnt = init_net.xfrm.policy_count[XFRM_POLICY_OUT]; | 476 | si->outcnt = net->xfrm.policy_count[XFRM_POLICY_OUT]; |
477 | si->fwdcnt = init_net.xfrm.policy_count[XFRM_POLICY_FWD]; | 477 | si->fwdcnt = net->xfrm.policy_count[XFRM_POLICY_FWD]; |
478 | si->inscnt = init_net.xfrm.policy_count[XFRM_POLICY_IN+XFRM_POLICY_MAX]; | 478 | si->inscnt = net->xfrm.policy_count[XFRM_POLICY_IN+XFRM_POLICY_MAX]; |
479 | si->outscnt = init_net.xfrm.policy_count[XFRM_POLICY_OUT+XFRM_POLICY_MAX]; | 479 | si->outscnt = net->xfrm.policy_count[XFRM_POLICY_OUT+XFRM_POLICY_MAX]; |
480 | si->fwdscnt = init_net.xfrm.policy_count[XFRM_POLICY_FWD+XFRM_POLICY_MAX]; | 480 | si->fwdscnt = net->xfrm.policy_count[XFRM_POLICY_FWD+XFRM_POLICY_MAX]; |
481 | si->spdhcnt = init_net.xfrm.policy_idx_hmask; | 481 | si->spdhcnt = net->xfrm.policy_idx_hmask; |
482 | si->spdhmcnt = xfrm_policy_hashmax; | 482 | si->spdhmcnt = xfrm_policy_hashmax; |
483 | read_unlock_bh(&xfrm_policy_lock); | 483 | read_unlock_bh(&xfrm_policy_lock); |
484 | } | 484 | } |
@@ -1309,15 +1309,28 @@ static inline int xfrm_get_tos(struct flowi *fl, int family) | |||
1309 | return tos; | 1309 | return tos; |
1310 | } | 1310 | } |
1311 | 1311 | ||
1312 | static inline struct xfrm_dst *xfrm_alloc_dst(int family) | 1312 | static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family) |
1313 | { | 1313 | { |
1314 | struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family); | 1314 | struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family); |
1315 | struct dst_ops *dst_ops; | ||
1315 | struct xfrm_dst *xdst; | 1316 | struct xfrm_dst *xdst; |
1316 | 1317 | ||
1317 | if (!afinfo) | 1318 | if (!afinfo) |
1318 | return ERR_PTR(-EINVAL); | 1319 | return ERR_PTR(-EINVAL); |
1319 | 1320 | ||
1320 | xdst = dst_alloc(afinfo->dst_ops) ?: ERR_PTR(-ENOBUFS); | 1321 | switch (family) { |
1322 | case AF_INET: | ||
1323 | dst_ops = &net->xfrm.xfrm4_dst_ops; | ||
1324 | break; | ||
1325 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
1326 | case AF_INET6: | ||
1327 | dst_ops = &net->xfrm.xfrm6_dst_ops; | ||
1328 | break; | ||
1329 | #endif | ||
1330 | default: | ||
1331 | BUG(); | ||
1332 | } | ||
1333 | xdst = dst_alloc(dst_ops) ?: ERR_PTR(-ENOBUFS); | ||
1321 | 1334 | ||
1322 | xfrm_policy_put_afinfo(afinfo); | 1335 | xfrm_policy_put_afinfo(afinfo); |
1323 | 1336 | ||
@@ -1366,6 +1379,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, | |||
1366 | struct flowi *fl, | 1379 | struct flowi *fl, |
1367 | struct dst_entry *dst) | 1380 | struct dst_entry *dst) |
1368 | { | 1381 | { |
1382 | struct net *net = xp_net(policy); | ||
1369 | unsigned long now = jiffies; | 1383 | unsigned long now = jiffies; |
1370 | struct net_device *dev; | 1384 | struct net_device *dev; |
1371 | struct dst_entry *dst_prev = NULL; | 1385 | struct dst_entry *dst_prev = NULL; |
@@ -1389,7 +1403,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, | |||
1389 | dst_hold(dst); | 1403 | dst_hold(dst); |
1390 | 1404 | ||
1391 | for (; i < nx; i++) { | 1405 | for (; i < nx; i++) { |
1392 | struct xfrm_dst *xdst = xfrm_alloc_dst(family); | 1406 | struct xfrm_dst *xdst = xfrm_alloc_dst(net, family); |
1393 | struct dst_entry *dst1 = &xdst->u.dst; | 1407 | struct dst_entry *dst1 = &xdst->u.dst; |
1394 | 1408 | ||
1395 | err = PTR_ERR(xdst); | 1409 | err = PTR_ERR(xdst); |
@@ -2279,6 +2293,7 @@ EXPORT_SYMBOL(xfrm_bundle_ok); | |||
2279 | 2293 | ||
2280 | int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) | 2294 | int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) |
2281 | { | 2295 | { |
2296 | struct net *net; | ||
2282 | int err = 0; | 2297 | int err = 0; |
2283 | if (unlikely(afinfo == NULL)) | 2298 | if (unlikely(afinfo == NULL)) |
2284 | return -EINVAL; | 2299 | return -EINVAL; |
@@ -2302,6 +2317,27 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) | |||
2302 | xfrm_policy_afinfo[afinfo->family] = afinfo; | 2317 | xfrm_policy_afinfo[afinfo->family] = afinfo; |
2303 | } | 2318 | } |
2304 | write_unlock_bh(&xfrm_policy_afinfo_lock); | 2319 | write_unlock_bh(&xfrm_policy_afinfo_lock); |
2320 | |||
2321 | rtnl_lock(); | ||
2322 | for_each_net(net) { | ||
2323 | struct dst_ops *xfrm_dst_ops; | ||
2324 | |||
2325 | switch (afinfo->family) { | ||
2326 | case AF_INET: | ||
2327 | xfrm_dst_ops = &net->xfrm.xfrm4_dst_ops; | ||
2328 | break; | ||
2329 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
2330 | case AF_INET6: | ||
2331 | xfrm_dst_ops = &net->xfrm.xfrm6_dst_ops; | ||
2332 | break; | ||
2333 | #endif | ||
2334 | default: | ||
2335 | BUG(); | ||
2336 | } | ||
2337 | *xfrm_dst_ops = *afinfo->dst_ops; | ||
2338 | } | ||
2339 | rtnl_unlock(); | ||
2340 | |||
2305 | return err; | 2341 | return err; |
2306 | } | 2342 | } |
2307 | EXPORT_SYMBOL(xfrm_policy_register_afinfo); | 2343 | EXPORT_SYMBOL(xfrm_policy_register_afinfo); |
@@ -2332,6 +2368,22 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo) | |||
2332 | } | 2368 | } |
2333 | EXPORT_SYMBOL(xfrm_policy_unregister_afinfo); | 2369 | EXPORT_SYMBOL(xfrm_policy_unregister_afinfo); |
2334 | 2370 | ||
2371 | static void __net_init xfrm_dst_ops_init(struct net *net) | ||
2372 | { | ||
2373 | struct xfrm_policy_afinfo *afinfo; | ||
2374 | |||
2375 | read_lock_bh(&xfrm_policy_afinfo_lock); | ||
2376 | afinfo = xfrm_policy_afinfo[AF_INET]; | ||
2377 | if (afinfo) | ||
2378 | net->xfrm.xfrm4_dst_ops = *afinfo->dst_ops; | ||
2379 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
2380 | afinfo = xfrm_policy_afinfo[AF_INET6]; | ||
2381 | if (afinfo) | ||
2382 | net->xfrm.xfrm6_dst_ops = *afinfo->dst_ops; | ||
2383 | #endif | ||
2384 | read_unlock_bh(&xfrm_policy_afinfo_lock); | ||
2385 | } | ||
2386 | |||
2335 | static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family) | 2387 | static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family) |
2336 | { | 2388 | { |
2337 | struct xfrm_policy_afinfo *afinfo; | 2389 | struct xfrm_policy_afinfo *afinfo; |
@@ -2494,6 +2546,7 @@ static int __net_init xfrm_net_init(struct net *net) | |||
2494 | rv = xfrm_policy_init(net); | 2546 | rv = xfrm_policy_init(net); |
2495 | if (rv < 0) | 2547 | if (rv < 0) |
2496 | goto out_policy; | 2548 | goto out_policy; |
2549 | xfrm_dst_ops_init(net); | ||
2497 | rv = xfrm_sysctl_init(net); | 2550 | rv = xfrm_sysctl_init(net); |
2498 | if (rv < 0) | 2551 | if (rv < 0) |
2499 | goto out_sysctl; | 2552 | goto out_sysctl; |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index d847f1a52b44..b36cc344474b 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -641,11 +641,11 @@ out: | |||
641 | } | 641 | } |
642 | EXPORT_SYMBOL(xfrm_state_flush); | 642 | EXPORT_SYMBOL(xfrm_state_flush); |
643 | 643 | ||
644 | void xfrm_sad_getinfo(struct xfrmk_sadinfo *si) | 644 | void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si) |
645 | { | 645 | { |
646 | spin_lock_bh(&xfrm_state_lock); | 646 | spin_lock_bh(&xfrm_state_lock); |
647 | si->sadcnt = init_net.xfrm.state_num; | 647 | si->sadcnt = net->xfrm.state_num; |
648 | si->sadhcnt = init_net.xfrm.state_hmask; | 648 | si->sadhcnt = net->xfrm.state_hmask; |
649 | si->sadhmcnt = xfrm_state_hashmax; | 649 | si->sadhmcnt = xfrm_state_hashmax; |
650 | spin_unlock_bh(&xfrm_state_lock); | 650 | spin_unlock_bh(&xfrm_state_lock); |
651 | } | 651 | } |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 1ada6186933c..d5a712976004 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -781,7 +781,8 @@ static inline size_t xfrm_spdinfo_msgsize(void) | |||
781 | + nla_total_size(sizeof(struct xfrmu_spdhinfo)); | 781 | + nla_total_size(sizeof(struct xfrmu_spdhinfo)); |
782 | } | 782 | } |
783 | 783 | ||
784 | static int build_spdinfo(struct sk_buff *skb, u32 pid, u32 seq, u32 flags) | 784 | static int build_spdinfo(struct sk_buff *skb, struct net *net, |
785 | u32 pid, u32 seq, u32 flags) | ||
785 | { | 786 | { |
786 | struct xfrmk_spdinfo si; | 787 | struct xfrmk_spdinfo si; |
787 | struct xfrmu_spdinfo spc; | 788 | struct xfrmu_spdinfo spc; |
@@ -795,7 +796,7 @@ static int build_spdinfo(struct sk_buff *skb, u32 pid, u32 seq, u32 flags) | |||
795 | 796 | ||
796 | f = nlmsg_data(nlh); | 797 | f = nlmsg_data(nlh); |
797 | *f = flags; | 798 | *f = flags; |
798 | xfrm_spd_getinfo(&si); | 799 | xfrm_spd_getinfo(net, &si); |
799 | spc.incnt = si.incnt; | 800 | spc.incnt = si.incnt; |
800 | spc.outcnt = si.outcnt; | 801 | spc.outcnt = si.outcnt; |
801 | spc.fwdcnt = si.fwdcnt; | 802 | spc.fwdcnt = si.fwdcnt; |
@@ -828,7 +829,7 @@ static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
828 | if (r_skb == NULL) | 829 | if (r_skb == NULL) |
829 | return -ENOMEM; | 830 | return -ENOMEM; |
830 | 831 | ||
831 | if (build_spdinfo(r_skb, spid, seq, *flags) < 0) | 832 | if (build_spdinfo(r_skb, net, spid, seq, *flags) < 0) |
832 | BUG(); | 833 | BUG(); |
833 | 834 | ||
834 | return nlmsg_unicast(net->xfrm.nlsk, r_skb, spid); | 835 | return nlmsg_unicast(net->xfrm.nlsk, r_skb, spid); |
@@ -841,7 +842,8 @@ static inline size_t xfrm_sadinfo_msgsize(void) | |||
841 | + nla_total_size(4); /* XFRMA_SAD_CNT */ | 842 | + nla_total_size(4); /* XFRMA_SAD_CNT */ |
842 | } | 843 | } |
843 | 844 | ||
844 | static int build_sadinfo(struct sk_buff *skb, u32 pid, u32 seq, u32 flags) | 845 | static int build_sadinfo(struct sk_buff *skb, struct net *net, |
846 | u32 pid, u32 seq, u32 flags) | ||
845 | { | 847 | { |
846 | struct xfrmk_sadinfo si; | 848 | struct xfrmk_sadinfo si; |
847 | struct xfrmu_sadhinfo sh; | 849 | struct xfrmu_sadhinfo sh; |
@@ -854,7 +856,7 @@ static int build_sadinfo(struct sk_buff *skb, u32 pid, u32 seq, u32 flags) | |||
854 | 856 | ||
855 | f = nlmsg_data(nlh); | 857 | f = nlmsg_data(nlh); |
856 | *f = flags; | 858 | *f = flags; |
857 | xfrm_sad_getinfo(&si); | 859 | xfrm_sad_getinfo(net, &si); |
858 | 860 | ||
859 | sh.sadhmcnt = si.sadhmcnt; | 861 | sh.sadhmcnt = si.sadhmcnt; |
860 | sh.sadhcnt = si.sadhcnt; | 862 | sh.sadhcnt = si.sadhcnt; |
@@ -882,7 +884,7 @@ static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
882 | if (r_skb == NULL) | 884 | if (r_skb == NULL) |
883 | return -ENOMEM; | 885 | return -ENOMEM; |
884 | 886 | ||
885 | if (build_sadinfo(r_skb, spid, seq, *flags) < 0) | 887 | if (build_sadinfo(r_skb, net, spid, seq, *flags) < 0) |
886 | BUG(); | 888 | BUG(); |
887 | 889 | ||
888 | return nlmsg_unicast(net->xfrm.nlsk, r_skb, spid); | 890 | return nlmsg_unicast(net->xfrm.nlsk, r_skb, spid); |