diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/core/Makefile | 2 | ||||
-rw-r--r-- | net/core/dev.c | 19 | ||||
-rw-r--r-- | net/core/neighbour.c | 14 | ||||
-rw-r--r-- | net/core/netevent.c | 69 | ||||
-rw-r--r-- | net/core/skbuff.c | 45 | ||||
-rw-r--r-- | net/dccp/ipv6.c | 4 | ||||
-rw-r--r-- | net/decnet/dn_route.c | 9 | ||||
-rw-r--r-- | net/ipv4/ip_output.c | 7 | ||||
-rw-r--r-- | net/ipv4/ip_sockglue.c | 9 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_sip.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_hashlimit.c | 3 | ||||
-rw-r--r-- | net/ipv4/route.c | 8 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 5 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_minisocks.c | 4 | ||||
-rw-r--r-- | net/ipv4/tcp_probe.c | 2 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 174 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 2 | ||||
-rw-r--r-- | net/ipv6/inet6_connection_sock.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 129 | ||||
-rw-r--r-- | net/ipv6/route.c | 7 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 6 | ||||
-rw-r--r-- | net/ipv6/udp.c | 2 | ||||
-rw-r--r-- | net/ipv6/xfrm6_output.c | 2 | ||||
-rw-r--r-- | net/netfilter/xt_SECMARK.c | 2 | ||||
-rw-r--r-- | net/netfilter/xt_string.c | 5 | ||||
-rw-r--r-- | net/unix/af_unix.c | 17 |
27 files changed, 430 insertions, 122 deletions
diff --git a/net/core/Makefile b/net/core/Makefile index e9bd2467d5a9..2645ba428d48 100644 --- a/net/core/Makefile +++ b/net/core/Makefile | |||
@@ -7,7 +7,7 @@ obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ | |||
7 | 7 | ||
8 | obj-$(CONFIG_SYSCTL) += sysctl_net_core.o | 8 | obj-$(CONFIG_SYSCTL) += sysctl_net_core.o |
9 | 9 | ||
10 | obj-y += dev.o ethtool.o dev_mcast.o dst.o \ | 10 | obj-y += dev.o ethtool.o dev_mcast.o dst.o netevent.o \ |
11 | neighbour.o rtnetlink.o utils.o link_watch.o filter.o | 11 | neighbour.o rtnetlink.o utils.o link_watch.o filter.o |
12 | 12 | ||
13 | obj-$(CONFIG_XFRM) += flow.o | 13 | obj-$(CONFIG_XFRM) += flow.o |
diff --git a/net/core/dev.c b/net/core/dev.c index 4d2b5167d7f5..d95e2626d944 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1166,11 +1166,6 @@ int skb_checksum_help(struct sk_buff *skb, int inward) | |||
1166 | goto out_set_summed; | 1166 | goto out_set_summed; |
1167 | 1167 | ||
1168 | if (unlikely(skb_shinfo(skb)->gso_size)) { | 1168 | if (unlikely(skb_shinfo(skb)->gso_size)) { |
1169 | static int warned; | ||
1170 | |||
1171 | WARN_ON(!warned); | ||
1172 | warned = 1; | ||
1173 | |||
1174 | /* Let GSO fix up the checksum. */ | 1169 | /* Let GSO fix up the checksum. */ |
1175 | goto out_set_summed; | 1170 | goto out_set_summed; |
1176 | } | 1171 | } |
@@ -1220,11 +1215,6 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) | |||
1220 | __skb_pull(skb, skb->mac_len); | 1215 | __skb_pull(skb, skb->mac_len); |
1221 | 1216 | ||
1222 | if (unlikely(skb->ip_summed != CHECKSUM_HW)) { | 1217 | if (unlikely(skb->ip_summed != CHECKSUM_HW)) { |
1223 | static int warned; | ||
1224 | |||
1225 | WARN_ON(!warned); | ||
1226 | warned = 1; | ||
1227 | |||
1228 | if (skb_header_cloned(skb) && | 1218 | if (skb_header_cloned(skb) && |
1229 | (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) | 1219 | (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) |
1230 | return ERR_PTR(err); | 1220 | return ERR_PTR(err); |
@@ -3429,12 +3419,9 @@ static void net_dma_rebalance(void) | |||
3429 | unsigned int cpu, i, n; | 3419 | unsigned int cpu, i, n; |
3430 | struct dma_chan *chan; | 3420 | struct dma_chan *chan; |
3431 | 3421 | ||
3432 | lock_cpu_hotplug(); | ||
3433 | |||
3434 | if (net_dma_count == 0) { | 3422 | if (net_dma_count == 0) { |
3435 | for_each_online_cpu(cpu) | 3423 | for_each_online_cpu(cpu) |
3436 | rcu_assign_pointer(per_cpu(softnet_data.net_dma, cpu), NULL); | 3424 | rcu_assign_pointer(per_cpu(softnet_data, cpu).net_dma, NULL); |
3437 | unlock_cpu_hotplug(); | ||
3438 | return; | 3425 | return; |
3439 | } | 3426 | } |
3440 | 3427 | ||
@@ -3447,15 +3434,13 @@ static void net_dma_rebalance(void) | |||
3447 | + (i < (num_online_cpus() % net_dma_count) ? 1 : 0)); | 3434 | + (i < (num_online_cpus() % net_dma_count) ? 1 : 0)); |
3448 | 3435 | ||
3449 | while(n) { | 3436 | while(n) { |
3450 | per_cpu(softnet_data.net_dma, cpu) = chan; | 3437 | per_cpu(softnet_data, cpu).net_dma = chan; |
3451 | cpu = next_cpu(cpu, cpu_online_map); | 3438 | cpu = next_cpu(cpu, cpu_online_map); |
3452 | n--; | 3439 | n--; |
3453 | } | 3440 | } |
3454 | i++; | 3441 | i++; |
3455 | } | 3442 | } |
3456 | rcu_read_unlock(); | 3443 | rcu_read_unlock(); |
3457 | |||
3458 | unlock_cpu_hotplug(); | ||
3459 | } | 3444 | } |
3460 | 3445 | ||
3461 | /** | 3446 | /** |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 7ad681f5e712..5130d2efdbbe 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <net/neighbour.h> | 29 | #include <net/neighbour.h> |
30 | #include <net/dst.h> | 30 | #include <net/dst.h> |
31 | #include <net/sock.h> | 31 | #include <net/sock.h> |
32 | #include <net/netevent.h> | ||
32 | #include <linux/rtnetlink.h> | 33 | #include <linux/rtnetlink.h> |
33 | #include <linux/random.h> | 34 | #include <linux/random.h> |
34 | #include <linux/string.h> | 35 | #include <linux/string.h> |
@@ -754,6 +755,7 @@ static void neigh_timer_handler(unsigned long arg) | |||
754 | neigh->nud_state = NUD_STALE; | 755 | neigh->nud_state = NUD_STALE; |
755 | neigh->updated = jiffies; | 756 | neigh->updated = jiffies; |
756 | neigh_suspect(neigh); | 757 | neigh_suspect(neigh); |
758 | notify = 1; | ||
757 | } | 759 | } |
758 | } else if (state & NUD_DELAY) { | 760 | } else if (state & NUD_DELAY) { |
759 | if (time_before_eq(now, | 761 | if (time_before_eq(now, |
@@ -762,6 +764,7 @@ static void neigh_timer_handler(unsigned long arg) | |||
762 | neigh->nud_state = NUD_REACHABLE; | 764 | neigh->nud_state = NUD_REACHABLE; |
763 | neigh->updated = jiffies; | 765 | neigh->updated = jiffies; |
764 | neigh_connect(neigh); | 766 | neigh_connect(neigh); |
767 | notify = 1; | ||
765 | next = neigh->confirmed + neigh->parms->reachable_time; | 768 | next = neigh->confirmed + neigh->parms->reachable_time; |
766 | } else { | 769 | } else { |
767 | NEIGH_PRINTK2("neigh %p is probed.\n", neigh); | 770 | NEIGH_PRINTK2("neigh %p is probed.\n", neigh); |
@@ -819,6 +822,8 @@ static void neigh_timer_handler(unsigned long arg) | |||
819 | out: | 822 | out: |
820 | write_unlock(&neigh->lock); | 823 | write_unlock(&neigh->lock); |
821 | } | 824 | } |
825 | if (notify) | ||
826 | call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh); | ||
822 | 827 | ||
823 | #ifdef CONFIG_ARPD | 828 | #ifdef CONFIG_ARPD |
824 | if (notify && neigh->parms->app_probes) | 829 | if (notify && neigh->parms->app_probes) |
@@ -926,9 +931,7 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, | |||
926 | { | 931 | { |
927 | u8 old; | 932 | u8 old; |
928 | int err; | 933 | int err; |
929 | #ifdef CONFIG_ARPD | ||
930 | int notify = 0; | 934 | int notify = 0; |
931 | #endif | ||
932 | struct net_device *dev; | 935 | struct net_device *dev; |
933 | int update_isrouter = 0; | 936 | int update_isrouter = 0; |
934 | 937 | ||
@@ -948,9 +951,7 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, | |||
948 | neigh_suspect(neigh); | 951 | neigh_suspect(neigh); |
949 | neigh->nud_state = new; | 952 | neigh->nud_state = new; |
950 | err = 0; | 953 | err = 0; |
951 | #ifdef CONFIG_ARPD | ||
952 | notify = old & NUD_VALID; | 954 | notify = old & NUD_VALID; |
953 | #endif | ||
954 | goto out; | 955 | goto out; |
955 | } | 956 | } |
956 | 957 | ||
@@ -1022,9 +1023,7 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, | |||
1022 | if (!(new & NUD_CONNECTED)) | 1023 | if (!(new & NUD_CONNECTED)) |
1023 | neigh->confirmed = jiffies - | 1024 | neigh->confirmed = jiffies - |
1024 | (neigh->parms->base_reachable_time << 1); | 1025 | (neigh->parms->base_reachable_time << 1); |
1025 | #ifdef CONFIG_ARPD | ||
1026 | notify = 1; | 1026 | notify = 1; |
1027 | #endif | ||
1028 | } | 1027 | } |
1029 | if (new == old) | 1028 | if (new == old) |
1030 | goto out; | 1029 | goto out; |
@@ -1056,6 +1055,9 @@ out: | |||
1056 | (neigh->flags & ~NTF_ROUTER); | 1055 | (neigh->flags & ~NTF_ROUTER); |
1057 | } | 1056 | } |
1058 | write_unlock_bh(&neigh->lock); | 1057 | write_unlock_bh(&neigh->lock); |
1058 | |||
1059 | if (notify) | ||
1060 | call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh); | ||
1059 | #ifdef CONFIG_ARPD | 1061 | #ifdef CONFIG_ARPD |
1060 | if (notify && neigh->parms->app_probes) | 1062 | if (notify && neigh->parms->app_probes) |
1061 | neigh_app_notify(neigh); | 1063 | neigh_app_notify(neigh); |
diff --git a/net/core/netevent.c b/net/core/netevent.c new file mode 100644 index 000000000000..35d02c38554e --- /dev/null +++ b/net/core/netevent.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * Network event notifiers | ||
3 | * | ||
4 | * Authors: | ||
5 | * Tom Tucker <tom@opengridcomputing.com> | ||
6 | * Steve Wise <swise@opengridcomputing.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version | ||
11 | * 2 of the License, or (at your option) any later version. | ||
12 | * | ||
13 | * Fixes: | ||
14 | */ | ||
15 | |||
16 | #include <linux/rtnetlink.h> | ||
17 | #include <linux/notifier.h> | ||
18 | |||
19 | static ATOMIC_NOTIFIER_HEAD(netevent_notif_chain); | ||
20 | |||
21 | /** | ||
22 | * register_netevent_notifier - register a netevent notifier block | ||
23 | * @nb: notifier | ||
24 | * | ||
25 | * Register a notifier to be called when a netevent occurs. | ||
26 | * The notifier passed is linked into the kernel structures and must | ||
27 | * not be reused until it has been unregistered. A negative errno code | ||
28 | * is returned on a failure. | ||
29 | */ | ||
30 | int register_netevent_notifier(struct notifier_block *nb) | ||
31 | { | ||
32 | int err; | ||
33 | |||
34 | err = atomic_notifier_chain_register(&netevent_notif_chain, nb); | ||
35 | return err; | ||
36 | } | ||
37 | |||
38 | /** | ||
39 | * netevent_unregister_notifier - unregister a netevent notifier block | ||
40 | * @nb: notifier | ||
41 | * | ||
42 | * Unregister a notifier previously registered by | ||
43 | * register_neigh_notifier(). The notifier is unlinked into the | ||
44 | * kernel structures and may then be reused. A negative errno code | ||
45 | * is returned on a failure. | ||
46 | */ | ||
47 | |||
48 | int unregister_netevent_notifier(struct notifier_block *nb) | ||
49 | { | ||
50 | return atomic_notifier_chain_unregister(&netevent_notif_chain, nb); | ||
51 | } | ||
52 | |||
53 | /** | ||
54 | * call_netevent_notifiers - call all netevent notifier blocks | ||
55 | * @val: value passed unmodified to notifier function | ||
56 | * @v: pointer passed unmodified to notifier function | ||
57 | * | ||
58 | * Call all neighbour notifier blocks. Parameters and return value | ||
59 | * are as for notifier_call_chain(). | ||
60 | */ | ||
61 | |||
62 | int call_netevent_notifiers(unsigned long val, void *v) | ||
63 | { | ||
64 | return atomic_notifier_call_chain(&netevent_notif_chain, val, v); | ||
65 | } | ||
66 | |||
67 | EXPORT_SYMBOL_GPL(register_netevent_notifier); | ||
68 | EXPORT_SYMBOL_GPL(unregister_netevent_notifier); | ||
69 | EXPORT_SYMBOL_GPL(call_netevent_notifiers); | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 476aa3978504..022d8894c11d 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -71,13 +71,6 @@ static kmem_cache_t *skbuff_head_cache __read_mostly; | |||
71 | static kmem_cache_t *skbuff_fclone_cache __read_mostly; | 71 | static kmem_cache_t *skbuff_fclone_cache __read_mostly; |
72 | 72 | ||
73 | /* | 73 | /* |
74 | * lockdep: lock class key used by skb_queue_head_init(): | ||
75 | */ | ||
76 | struct lock_class_key skb_queue_lock_key; | ||
77 | |||
78 | EXPORT_SYMBOL(skb_queue_lock_key); | ||
79 | |||
80 | /* | ||
81 | * Keep out-of-line to prevent kernel bloat. | 74 | * Keep out-of-line to prevent kernel bloat. |
82 | * __builtin_return_address is not used because it is not always | 75 | * __builtin_return_address is not used because it is not always |
83 | * reliable. | 76 | * reliable. |
@@ -256,6 +249,29 @@ nodata: | |||
256 | goto out; | 249 | goto out; |
257 | } | 250 | } |
258 | 251 | ||
252 | /** | ||
253 | * __netdev_alloc_skb - allocate an skbuff for rx on a specific device | ||
254 | * @dev: network device to receive on | ||
255 | * @length: length to allocate | ||
256 | * @gfp_mask: get_free_pages mask, passed to alloc_skb | ||
257 | * | ||
258 | * Allocate a new &sk_buff and assign it a usage count of one. The | ||
259 | * buffer has unspecified headroom built in. Users should allocate | ||
260 | * the headroom they think they need without accounting for the | ||
261 | * built in space. The built in space is used for optimisations. | ||
262 | * | ||
263 | * %NULL is returned if there is no free memory. | ||
264 | */ | ||
265 | struct sk_buff *__netdev_alloc_skb(struct net_device *dev, | ||
266 | unsigned int length, gfp_t gfp_mask) | ||
267 | { | ||
268 | struct sk_buff *skb; | ||
269 | |||
270 | skb = alloc_skb(length + NET_SKB_PAD, gfp_mask); | ||
271 | if (likely(skb)) | ||
272 | skb_reserve(skb, NET_SKB_PAD); | ||
273 | return skb; | ||
274 | } | ||
259 | 275 | ||
260 | static void skb_drop_list(struct sk_buff **listp) | 276 | static void skb_drop_list(struct sk_buff **listp) |
261 | { | 277 | { |
@@ -846,7 +862,11 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len) | |||
846 | unlikely((err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))) | 862 | unlikely((err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))) |
847 | return err; | 863 | return err; |
848 | 864 | ||
849 | for (i = 0; i < nfrags; i++) { | 865 | i = 0; |
866 | if (offset >= len) | ||
867 | goto drop_pages; | ||
868 | |||
869 | for (; i < nfrags; i++) { | ||
850 | int end = offset + skb_shinfo(skb)->frags[i].size; | 870 | int end = offset + skb_shinfo(skb)->frags[i].size; |
851 | 871 | ||
852 | if (end < len) { | 872 | if (end < len) { |
@@ -854,9 +874,9 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len) | |||
854 | continue; | 874 | continue; |
855 | } | 875 | } |
856 | 876 | ||
857 | if (len > offset) | 877 | skb_shinfo(skb)->frags[i++].size = len - offset; |
858 | skb_shinfo(skb)->frags[i++].size = len - offset; | ||
859 | 878 | ||
879 | drop_pages: | ||
860 | skb_shinfo(skb)->nr_frags = i; | 880 | skb_shinfo(skb)->nr_frags = i; |
861 | 881 | ||
862 | for (; i < nfrags; i++) | 882 | for (; i < nfrags; i++) |
@@ -864,7 +884,7 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len) | |||
864 | 884 | ||
865 | if (skb_shinfo(skb)->frag_list) | 885 | if (skb_shinfo(skb)->frag_list) |
866 | skb_drop_fraglist(skb); | 886 | skb_drop_fraglist(skb); |
867 | break; | 887 | goto done; |
868 | } | 888 | } |
869 | 889 | ||
870 | for (fragp = &skb_shinfo(skb)->frag_list; (frag = *fragp); | 890 | for (fragp = &skb_shinfo(skb)->frag_list; (frag = *fragp); |
@@ -879,6 +899,7 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len) | |||
879 | return -ENOMEM; | 899 | return -ENOMEM; |
880 | 900 | ||
881 | nfrag->next = frag->next; | 901 | nfrag->next = frag->next; |
902 | kfree_skb(frag); | ||
882 | frag = nfrag; | 903 | frag = nfrag; |
883 | *fragp = frag; | 904 | *fragp = frag; |
884 | } | 905 | } |
@@ -897,6 +918,7 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len) | |||
897 | break; | 918 | break; |
898 | } | 919 | } |
899 | 920 | ||
921 | done: | ||
900 | if (len > skb_headlen(skb)) { | 922 | if (len > skb_headlen(skb)) { |
901 | skb->data_len -= skb->len - len; | 923 | skb->data_len -= skb->len - len; |
902 | skb->len = len; | 924 | skb->len = len; |
@@ -2042,6 +2064,7 @@ EXPORT_SYMBOL(__kfree_skb); | |||
2042 | EXPORT_SYMBOL(kfree_skb); | 2064 | EXPORT_SYMBOL(kfree_skb); |
2043 | EXPORT_SYMBOL(__pskb_pull_tail); | 2065 | EXPORT_SYMBOL(__pskb_pull_tail); |
2044 | EXPORT_SYMBOL(__alloc_skb); | 2066 | EXPORT_SYMBOL(__alloc_skb); |
2067 | EXPORT_SYMBOL(__netdev_alloc_skb); | ||
2045 | EXPORT_SYMBOL(pskb_copy); | 2068 | EXPORT_SYMBOL(pskb_copy); |
2046 | EXPORT_SYMBOL(pskb_expand_head); | 2069 | EXPORT_SYMBOL(pskb_expand_head); |
2047 | EXPORT_SYMBOL(skb_checksum); | 2070 | EXPORT_SYMBOL(skb_checksum); |
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 9f3d4d7cd0bf..610c722ac27f 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -230,7 +230,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
230 | ipv6_addr_copy(&np->saddr, saddr); | 230 | ipv6_addr_copy(&np->saddr, saddr); |
231 | inet->rcv_saddr = LOOPBACK4_IPV6; | 231 | inet->rcv_saddr = LOOPBACK4_IPV6; |
232 | 232 | ||
233 | ip6_dst_store(sk, dst, NULL); | 233 | __ip6_dst_store(sk, dst, NULL); |
234 | 234 | ||
235 | icsk->icsk_ext_hdr_len = 0; | 235 | icsk->icsk_ext_hdr_len = 0; |
236 | if (np->opt != NULL) | 236 | if (np->opt != NULL) |
@@ -863,7 +863,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | |||
863 | * comment in that function for the gory details. -acme | 863 | * comment in that function for the gory details. -acme |
864 | */ | 864 | */ |
865 | 865 | ||
866 | ip6_dst_store(newsk, dst, NULL); | 866 | __ip6_dst_store(newsk, dst, NULL); |
867 | newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM | | 867 | newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM | |
868 | NETIF_F_TSO); | 868 | NETIF_F_TSO); |
869 | newdp6 = (struct dccp6_sock *)newsk; | 869 | newdp6 = (struct dccp6_sock *)newsk; |
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 1355614ec11b..743e9fcf7c5a 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c | |||
@@ -925,8 +925,13 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old | |||
925 | for(dev_out = dev_base; dev_out; dev_out = dev_out->next) { | 925 | for(dev_out = dev_base; dev_out; dev_out = dev_out->next) { |
926 | if (!dev_out->dn_ptr) | 926 | if (!dev_out->dn_ptr) |
927 | continue; | 927 | continue; |
928 | if (dn_dev_islocal(dev_out, oldflp->fld_src)) | 928 | if (!dn_dev_islocal(dev_out, oldflp->fld_src)) |
929 | break; | 929 | continue; |
930 | if ((dev_out->flags & IFF_LOOPBACK) && | ||
931 | oldflp->fld_dst && | ||
932 | !dn_dev_islocal(dev_out, oldflp->fld_dst)) | ||
933 | continue; | ||
934 | break; | ||
930 | } | 935 | } |
931 | read_unlock(&dev_base_lock); | 936 | read_unlock(&dev_base_lock); |
932 | if (dev_out == NULL) | 937 | if (dev_out == NULL) |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 7c9f9a6421b8..9bf307a29783 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -526,6 +526,8 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) | |||
526 | 526 | ||
527 | err = output(skb); | 527 | err = output(skb); |
528 | 528 | ||
529 | if (!err) | ||
530 | IP_INC_STATS(IPSTATS_MIB_FRAGCREATES); | ||
529 | if (err || !frag) | 531 | if (err || !frag) |
530 | break; | 532 | break; |
531 | 533 | ||
@@ -649,9 +651,6 @@ slow_path: | |||
649 | /* | 651 | /* |
650 | * Put this fragment into the sending queue. | 652 | * Put this fragment into the sending queue. |
651 | */ | 653 | */ |
652 | |||
653 | IP_INC_STATS(IPSTATS_MIB_FRAGCREATES); | ||
654 | |||
655 | iph->tot_len = htons(len + hlen); | 654 | iph->tot_len = htons(len + hlen); |
656 | 655 | ||
657 | ip_send_check(iph); | 656 | ip_send_check(iph); |
@@ -659,6 +658,8 @@ slow_path: | |||
659 | err = output(skb2); | 658 | err = output(skb2); |
660 | if (err) | 659 | if (err) |
661 | goto fail; | 660 | goto fail; |
661 | |||
662 | IP_INC_STATS(IPSTATS_MIB_FRAGCREATES); | ||
662 | } | 663 | } |
663 | kfree_skb(skb); | 664 | kfree_skb(skb); |
664 | IP_INC_STATS(IPSTATS_MIB_FRAGOKS); | 665 | IP_INC_STATS(IPSTATS_MIB_FRAGOKS); |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 84f43a3c9098..2d05c4133d3e 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
@@ -112,14 +112,19 @@ static void ip_cmsg_recv_retopts(struct msghdr *msg, struct sk_buff *skb) | |||
112 | static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) | 112 | static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) |
113 | { | 113 | { |
114 | char *secdata; | 114 | char *secdata; |
115 | u32 seclen; | 115 | u32 seclen, secid; |
116 | int err; | 116 | int err; |
117 | 117 | ||
118 | err = security_socket_getpeersec_dgram(skb, &secdata, &seclen); | 118 | err = security_socket_getpeersec_dgram(NULL, skb, &secid); |
119 | if (err) | ||
120 | return; | ||
121 | |||
122 | err = security_secid_to_secctx(secid, &secdata, &seclen); | ||
119 | if (err) | 123 | if (err) |
120 | return; | 124 | return; |
121 | 125 | ||
122 | put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata); | 126 | put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata); |
127 | security_release_secctx(secdata, seclen); | ||
123 | } | 128 | } |
124 | 129 | ||
125 | 130 | ||
diff --git a/net/ipv4/netfilter/ip_conntrack_sip.c b/net/ipv4/netfilter/ip_conntrack_sip.c index fc87ce0da40d..4f222d6be009 100644 --- a/net/ipv4/netfilter/ip_conntrack_sip.c +++ b/net/ipv4/netfilter/ip_conntrack_sip.c | |||
@@ -442,7 +442,7 @@ static int __init init(void) | |||
442 | sip[i].tuple.src.u.udp.port = htons(ports[i]); | 442 | sip[i].tuple.src.u.udp.port = htons(ports[i]); |
443 | sip[i].mask.src.u.udp.port = 0xFFFF; | 443 | sip[i].mask.src.u.udp.port = 0xFFFF; |
444 | sip[i].mask.dst.protonum = 0xFF; | 444 | sip[i].mask.dst.protonum = 0xFF; |
445 | sip[i].max_expected = 1; | 445 | sip[i].max_expected = 2; |
446 | sip[i].timeout = 3 * 60; /* 3 minutes */ | 446 | sip[i].timeout = 3 * 60; /* 3 minutes */ |
447 | sip[i].me = THIS_MODULE; | 447 | sip[i].me = THIS_MODULE; |
448 | sip[i].help = sip_help; | 448 | sip[i].help = sip_help; |
diff --git a/net/ipv4/netfilter/ipt_hashlimit.c b/net/ipv4/netfilter/ipt_hashlimit.c index 92980ab8ce48..6b662449e825 100644 --- a/net/ipv4/netfilter/ipt_hashlimit.c +++ b/net/ipv4/netfilter/ipt_hashlimit.c | |||
@@ -508,6 +508,9 @@ hashlimit_checkentry(const char *tablename, | |||
508 | if (!r->cfg.expire) | 508 | if (!r->cfg.expire) |
509 | return 0; | 509 | return 0; |
510 | 510 | ||
511 | if (r->name[sizeof(r->name) - 1] != '\0') | ||
512 | return 0; | ||
513 | |||
511 | /* This is the best we've got: We cannot release and re-grab lock, | 514 | /* This is the best we've got: We cannot release and re-grab lock, |
512 | * since checkentry() is called before ip_tables.c grabs ipt_mutex. | 515 | * since checkentry() is called before ip_tables.c grabs ipt_mutex. |
513 | * We also cannot grab the hashtable spinlock, since htable_create will | 516 | * We also cannot grab the hashtable spinlock, since htable_create will |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 2dc6dbb28467..19bd49d69d9f 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -104,6 +104,7 @@ | |||
104 | #include <net/icmp.h> | 104 | #include <net/icmp.h> |
105 | #include <net/xfrm.h> | 105 | #include <net/xfrm.h> |
106 | #include <net/ip_mp_alg.h> | 106 | #include <net/ip_mp_alg.h> |
107 | #include <net/netevent.h> | ||
107 | #ifdef CONFIG_SYSCTL | 108 | #ifdef CONFIG_SYSCTL |
108 | #include <linux/sysctl.h> | 109 | #include <linux/sysctl.h> |
109 | #endif | 110 | #endif |
@@ -1125,6 +1126,7 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw, | |||
1125 | struct rtable *rth, **rthp; | 1126 | struct rtable *rth, **rthp; |
1126 | u32 skeys[2] = { saddr, 0 }; | 1127 | u32 skeys[2] = { saddr, 0 }; |
1127 | int ikeys[2] = { dev->ifindex, 0 }; | 1128 | int ikeys[2] = { dev->ifindex, 0 }; |
1129 | struct netevent_redirect netevent; | ||
1128 | 1130 | ||
1129 | if (!in_dev) | 1131 | if (!in_dev) |
1130 | return; | 1132 | return; |
@@ -1216,6 +1218,11 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw, | |||
1216 | rt_drop(rt); | 1218 | rt_drop(rt); |
1217 | goto do_next; | 1219 | goto do_next; |
1218 | } | 1220 | } |
1221 | |||
1222 | netevent.old = &rth->u.dst; | ||
1223 | netevent.new = &rt->u.dst; | ||
1224 | call_netevent_notifiers(NETEVENT_REDIRECT, | ||
1225 | &netevent); | ||
1219 | 1226 | ||
1220 | rt_del(hash, rth); | 1227 | rt_del(hash, rth); |
1221 | if (!rt_intern_hash(hash, rt, &rt)) | 1228 | if (!rt_intern_hash(hash, rt, &rt)) |
@@ -1452,6 +1459,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
1452 | } | 1459 | } |
1453 | dst->metrics[RTAX_MTU-1] = mtu; | 1460 | dst->metrics[RTAX_MTU-1] = mtu; |
1454 | dst_set_expires(dst, ip_rt_mtu_expires); | 1461 | dst_set_expires(dst, ip_rt_mtu_expires); |
1462 | call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst); | ||
1455 | } | 1463 | } |
1456 | } | 1464 | } |
1457 | 1465 | ||
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index f6a2d9223d07..934396bb1376 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -1132,7 +1132,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1132 | tp->ucopy.dma_chan = NULL; | 1132 | tp->ucopy.dma_chan = NULL; |
1133 | preempt_disable(); | 1133 | preempt_disable(); |
1134 | if ((len > sysctl_tcp_dma_copybreak) && !(flags & MSG_PEEK) && | 1134 | if ((len > sysctl_tcp_dma_copybreak) && !(flags & MSG_PEEK) && |
1135 | !sysctl_tcp_low_latency && __get_cpu_var(softnet_data.net_dma)) { | 1135 | !sysctl_tcp_low_latency && __get_cpu_var(softnet_data).net_dma) { |
1136 | preempt_enable_no_resched(); | 1136 | preempt_enable_no_resched(); |
1137 | tp->ucopy.pinned_list = dma_pin_iovec_pages(msg->msg_iov, len); | 1137 | tp->ucopy.pinned_list = dma_pin_iovec_pages(msg->msg_iov, len); |
1138 | } else | 1138 | } else |
@@ -1659,7 +1659,8 @@ adjudge_to_death: | |||
1659 | const int tmo = tcp_fin_time(sk); | 1659 | const int tmo = tcp_fin_time(sk); |
1660 | 1660 | ||
1661 | if (tmo > TCP_TIMEWAIT_LEN) { | 1661 | if (tmo > TCP_TIMEWAIT_LEN) { |
1662 | inet_csk_reset_keepalive_timer(sk, tcp_fin_time(sk)); | 1662 | inet_csk_reset_keepalive_timer(sk, |
1663 | tmo - TCP_TIMEWAIT_LEN); | ||
1663 | } else { | 1664 | } else { |
1664 | tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); | 1665 | tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); |
1665 | goto out; | 1666 | goto out; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index f6f39e814291..4b04c3edd4a9 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -438,7 +438,6 @@ void tcp_v4_err(struct sk_buff *skb, u32 info) | |||
438 | It can f.e. if SYNs crossed. | 438 | It can f.e. if SYNs crossed. |
439 | */ | 439 | */ |
440 | if (!sock_owned_by_user(sk)) { | 440 | if (!sock_owned_by_user(sk)) { |
441 | TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS); | ||
442 | sk->sk_err = err; | 441 | sk->sk_err = err; |
443 | 442 | ||
444 | sk->sk_error_report(sk); | 443 | sk->sk_error_report(sk); |
@@ -874,7 +873,6 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
874 | drop_and_free: | 873 | drop_and_free: |
875 | reqsk_free(req); | 874 | reqsk_free(req); |
876 | drop: | 875 | drop: |
877 | TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS); | ||
878 | return 0; | 876 | return 0; |
879 | } | 877 | } |
880 | 878 | ||
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 0ccb7cb22b15..624e2b2c7f53 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -589,8 +589,10 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb, | |||
589 | /* RFC793: "second check the RST bit" and | 589 | /* RFC793: "second check the RST bit" and |
590 | * "fourth, check the SYN bit" | 590 | * "fourth, check the SYN bit" |
591 | */ | 591 | */ |
592 | if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN)) | 592 | if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN)) { |
593 | TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS); | ||
593 | goto embryonic_reset; | 594 | goto embryonic_reset; |
595 | } | ||
594 | 596 | ||
595 | /* ACK sequence verified above, just make sure ACK is | 597 | /* ACK sequence verified above, just make sure ACK is |
596 | * set. If ACK not set, just silently drop the packet. | 598 | * set. If ACK not set, just silently drop the packet. |
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c index d7d517a3a238..b3435324b573 100644 --- a/net/ipv4/tcp_probe.c +++ b/net/ipv4/tcp_probe.c | |||
@@ -114,7 +114,7 @@ static int tcpprobe_open(struct inode * inode, struct file * file) | |||
114 | static ssize_t tcpprobe_read(struct file *file, char __user *buf, | 114 | static ssize_t tcpprobe_read(struct file *file, char __user *buf, |
115 | size_t len, loff_t *ppos) | 115 | size_t len, loff_t *ppos) |
116 | { | 116 | { |
117 | int error = 0, cnt; | 117 | int error = 0, cnt = 0; |
118 | unsigned char *tbuf; | 118 | unsigned char *tbuf; |
119 | 119 | ||
120 | if (!buf || len < 0) | 120 | if (!buf || len < 0) |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 2316a4315a18..8ea1e36bf8eb 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -1869,15 +1869,21 @@ err_exit: | |||
1869 | /* | 1869 | /* |
1870 | * Manual configuration of address on an interface | 1870 | * Manual configuration of address on an interface |
1871 | */ | 1871 | */ |
1872 | static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen) | 1872 | static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, |
1873 | __u32 prefered_lft, __u32 valid_lft) | ||
1873 | { | 1874 | { |
1874 | struct inet6_ifaddr *ifp; | 1875 | struct inet6_ifaddr *ifp; |
1875 | struct inet6_dev *idev; | 1876 | struct inet6_dev *idev; |
1876 | struct net_device *dev; | 1877 | struct net_device *dev; |
1878 | __u8 ifa_flags = 0; | ||
1877 | int scope; | 1879 | int scope; |
1878 | 1880 | ||
1879 | ASSERT_RTNL(); | 1881 | ASSERT_RTNL(); |
1880 | 1882 | ||
1883 | /* check the lifetime */ | ||
1884 | if (!valid_lft || prefered_lft > valid_lft) | ||
1885 | return -EINVAL; | ||
1886 | |||
1881 | if ((dev = __dev_get_by_index(ifindex)) == NULL) | 1887 | if ((dev = __dev_get_by_index(ifindex)) == NULL) |
1882 | return -ENODEV; | 1888 | return -ENODEV; |
1883 | 1889 | ||
@@ -1889,10 +1895,29 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen) | |||
1889 | 1895 | ||
1890 | scope = ipv6_addr_scope(pfx); | 1896 | scope = ipv6_addr_scope(pfx); |
1891 | 1897 | ||
1892 | ifp = ipv6_add_addr(idev, pfx, plen, scope, IFA_F_PERMANENT); | 1898 | if (valid_lft == INFINITY_LIFE_TIME) |
1899 | ifa_flags |= IFA_F_PERMANENT; | ||
1900 | else if (valid_lft >= 0x7FFFFFFF/HZ) | ||
1901 | valid_lft = 0x7FFFFFFF/HZ; | ||
1902 | |||
1903 | if (prefered_lft == 0) | ||
1904 | ifa_flags |= IFA_F_DEPRECATED; | ||
1905 | else if ((prefered_lft >= 0x7FFFFFFF/HZ) && | ||
1906 | (prefered_lft != INFINITY_LIFE_TIME)) | ||
1907 | prefered_lft = 0x7FFFFFFF/HZ; | ||
1908 | |||
1909 | ifp = ipv6_add_addr(idev, pfx, plen, scope, ifa_flags); | ||
1910 | |||
1893 | if (!IS_ERR(ifp)) { | 1911 | if (!IS_ERR(ifp)) { |
1912 | spin_lock(&ifp->lock); | ||
1913 | ifp->valid_lft = valid_lft; | ||
1914 | ifp->prefered_lft = prefered_lft; | ||
1915 | ifp->tstamp = jiffies; | ||
1916 | spin_unlock(&ifp->lock); | ||
1917 | |||
1894 | addrconf_dad_start(ifp, 0); | 1918 | addrconf_dad_start(ifp, 0); |
1895 | in6_ifa_put(ifp); | 1919 | in6_ifa_put(ifp); |
1920 | addrconf_verify(0); | ||
1896 | return 0; | 1921 | return 0; |
1897 | } | 1922 | } |
1898 | 1923 | ||
@@ -1945,7 +1970,8 @@ int addrconf_add_ifaddr(void __user *arg) | |||
1945 | return -EFAULT; | 1970 | return -EFAULT; |
1946 | 1971 | ||
1947 | rtnl_lock(); | 1972 | rtnl_lock(); |
1948 | err = inet6_addr_add(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen); | 1973 | err = inet6_addr_add(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen, |
1974 | INFINITY_LIFE_TIME, INFINITY_LIFE_TIME); | ||
1949 | rtnl_unlock(); | 1975 | rtnl_unlock(); |
1950 | return err; | 1976 | return err; |
1951 | } | 1977 | } |
@@ -2771,12 +2797,16 @@ restart: | |||
2771 | ifp->idev->nd_parms->retrans_time / HZ; | 2797 | ifp->idev->nd_parms->retrans_time / HZ; |
2772 | #endif | 2798 | #endif |
2773 | 2799 | ||
2774 | if (age >= ifp->valid_lft) { | 2800 | if (ifp->valid_lft != INFINITY_LIFE_TIME && |
2801 | age >= ifp->valid_lft) { | ||
2775 | spin_unlock(&ifp->lock); | 2802 | spin_unlock(&ifp->lock); |
2776 | in6_ifa_hold(ifp); | 2803 | in6_ifa_hold(ifp); |
2777 | read_unlock(&addrconf_hash_lock); | 2804 | read_unlock(&addrconf_hash_lock); |
2778 | ipv6_del_addr(ifp); | 2805 | ipv6_del_addr(ifp); |
2779 | goto restart; | 2806 | goto restart; |
2807 | } else if (ifp->prefered_lft == INFINITY_LIFE_TIME) { | ||
2808 | spin_unlock(&ifp->lock); | ||
2809 | continue; | ||
2780 | } else if (age >= ifp->prefered_lft) { | 2810 | } else if (age >= ifp->prefered_lft) { |
2781 | /* jiffies - ifp->tsamp > age >= ifp->prefered_lft */ | 2811 | /* jiffies - ifp->tsamp > age >= ifp->prefered_lft */ |
2782 | int deprecate = 0; | 2812 | int deprecate = 0; |
@@ -2853,7 +2883,8 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
2853 | pfx = RTA_DATA(rta[IFA_ADDRESS-1]); | 2883 | pfx = RTA_DATA(rta[IFA_ADDRESS-1]); |
2854 | } | 2884 | } |
2855 | if (rta[IFA_LOCAL-1]) { | 2885 | if (rta[IFA_LOCAL-1]) { |
2856 | if (pfx && memcmp(pfx, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*pfx))) | 2886 | if (RTA_PAYLOAD(rta[IFA_LOCAL-1]) < sizeof(*pfx) || |
2887 | (pfx && memcmp(pfx, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*pfx)))) | ||
2857 | return -EINVAL; | 2888 | return -EINVAL; |
2858 | pfx = RTA_DATA(rta[IFA_LOCAL-1]); | 2889 | pfx = RTA_DATA(rta[IFA_LOCAL-1]); |
2859 | } | 2890 | } |
@@ -2864,11 +2895,61 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
2864 | } | 2895 | } |
2865 | 2896 | ||
2866 | static int | 2897 | static int |
2898 | inet6_addr_modify(int ifindex, struct in6_addr *pfx, | ||
2899 | __u32 prefered_lft, __u32 valid_lft) | ||
2900 | { | ||
2901 | struct inet6_ifaddr *ifp = NULL; | ||
2902 | struct net_device *dev; | ||
2903 | int ifa_flags = 0; | ||
2904 | |||
2905 | if ((dev = __dev_get_by_index(ifindex)) == NULL) | ||
2906 | return -ENODEV; | ||
2907 | |||
2908 | if (!(dev->flags&IFF_UP)) | ||
2909 | return -ENETDOWN; | ||
2910 | |||
2911 | if (!valid_lft || (prefered_lft > valid_lft)) | ||
2912 | return -EINVAL; | ||
2913 | |||
2914 | ifp = ipv6_get_ifaddr(pfx, dev, 1); | ||
2915 | if (ifp == NULL) | ||
2916 | return -ENOENT; | ||
2917 | |||
2918 | if (valid_lft == INFINITY_LIFE_TIME) | ||
2919 | ifa_flags = IFA_F_PERMANENT; | ||
2920 | else if (valid_lft >= 0x7FFFFFFF/HZ) | ||
2921 | valid_lft = 0x7FFFFFFF/HZ; | ||
2922 | |||
2923 | if (prefered_lft == 0) | ||
2924 | ifa_flags = IFA_F_DEPRECATED; | ||
2925 | else if ((prefered_lft >= 0x7FFFFFFF/HZ) && | ||
2926 | (prefered_lft != INFINITY_LIFE_TIME)) | ||
2927 | prefered_lft = 0x7FFFFFFF/HZ; | ||
2928 | |||
2929 | spin_lock_bh(&ifp->lock); | ||
2930 | ifp->flags = (ifp->flags & ~(IFA_F_DEPRECATED|IFA_F_PERMANENT)) | ifa_flags; | ||
2931 | |||
2932 | ifp->tstamp = jiffies; | ||
2933 | ifp->valid_lft = valid_lft; | ||
2934 | ifp->prefered_lft = prefered_lft; | ||
2935 | |||
2936 | spin_unlock_bh(&ifp->lock); | ||
2937 | if (!(ifp->flags&IFA_F_TENTATIVE)) | ||
2938 | ipv6_ifa_notify(0, ifp); | ||
2939 | in6_ifa_put(ifp); | ||
2940 | |||
2941 | addrconf_verify(0); | ||
2942 | |||
2943 | return 0; | ||
2944 | } | ||
2945 | |||
2946 | static int | ||
2867 | inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 2947 | inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) |
2868 | { | 2948 | { |
2869 | struct rtattr **rta = arg; | 2949 | struct rtattr **rta = arg; |
2870 | struct ifaddrmsg *ifm = NLMSG_DATA(nlh); | 2950 | struct ifaddrmsg *ifm = NLMSG_DATA(nlh); |
2871 | struct in6_addr *pfx; | 2951 | struct in6_addr *pfx; |
2952 | __u32 valid_lft = INFINITY_LIFE_TIME, prefered_lft = INFINITY_LIFE_TIME; | ||
2872 | 2953 | ||
2873 | pfx = NULL; | 2954 | pfx = NULL; |
2874 | if (rta[IFA_ADDRESS-1]) { | 2955 | if (rta[IFA_ADDRESS-1]) { |
@@ -2877,14 +2958,34 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
2877 | pfx = RTA_DATA(rta[IFA_ADDRESS-1]); | 2958 | pfx = RTA_DATA(rta[IFA_ADDRESS-1]); |
2878 | } | 2959 | } |
2879 | if (rta[IFA_LOCAL-1]) { | 2960 | if (rta[IFA_LOCAL-1]) { |
2880 | if (pfx && memcmp(pfx, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*pfx))) | 2961 | if (RTA_PAYLOAD(rta[IFA_LOCAL-1]) < sizeof(*pfx) || |
2962 | (pfx && memcmp(pfx, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*pfx)))) | ||
2881 | return -EINVAL; | 2963 | return -EINVAL; |
2882 | pfx = RTA_DATA(rta[IFA_LOCAL-1]); | 2964 | pfx = RTA_DATA(rta[IFA_LOCAL-1]); |
2883 | } | 2965 | } |
2884 | if (pfx == NULL) | 2966 | if (pfx == NULL) |
2885 | return -EINVAL; | 2967 | return -EINVAL; |
2886 | 2968 | ||
2887 | return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen); | 2969 | if (rta[IFA_CACHEINFO-1]) { |
2970 | struct ifa_cacheinfo *ci; | ||
2971 | if (RTA_PAYLOAD(rta[IFA_CACHEINFO-1]) < sizeof(*ci)) | ||
2972 | return -EINVAL; | ||
2973 | ci = RTA_DATA(rta[IFA_CACHEINFO-1]); | ||
2974 | valid_lft = ci->ifa_valid; | ||
2975 | prefered_lft = ci->ifa_prefered; | ||
2976 | } | ||
2977 | |||
2978 | if (nlh->nlmsg_flags & NLM_F_REPLACE) { | ||
2979 | int ret; | ||
2980 | ret = inet6_addr_modify(ifm->ifa_index, pfx, | ||
2981 | prefered_lft, valid_lft); | ||
2982 | if (ret == 0 || !(nlh->nlmsg_flags & NLM_F_CREATE)) | ||
2983 | return ret; | ||
2984 | } | ||
2985 | |||
2986 | return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen, | ||
2987 | prefered_lft, valid_lft); | ||
2988 | |||
2888 | } | 2989 | } |
2889 | 2990 | ||
2890 | /* Maximum length of ifa_cacheinfo attributes */ | 2991 | /* Maximum length of ifa_cacheinfo attributes */ |
@@ -3121,6 +3222,62 @@ static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb) | |||
3121 | return inet6_dump_addr(skb, cb, type); | 3222 | return inet6_dump_addr(skb, cb, type); |
3122 | } | 3223 | } |
3123 | 3224 | ||
3225 | static int inet6_rtm_getaddr(struct sk_buff *in_skb, | ||
3226 | struct nlmsghdr* nlh, void *arg) | ||
3227 | { | ||
3228 | struct rtattr **rta = arg; | ||
3229 | struct ifaddrmsg *ifm = NLMSG_DATA(nlh); | ||
3230 | struct in6_addr *addr = NULL; | ||
3231 | struct net_device *dev = NULL; | ||
3232 | struct inet6_ifaddr *ifa; | ||
3233 | struct sk_buff *skb; | ||
3234 | int size = NLMSG_SPACE(sizeof(struct ifaddrmsg) + INET6_IFADDR_RTA_SPACE); | ||
3235 | int err; | ||
3236 | |||
3237 | if (rta[IFA_ADDRESS-1]) { | ||
3238 | if (RTA_PAYLOAD(rta[IFA_ADDRESS-1]) < sizeof(*addr)) | ||
3239 | return -EINVAL; | ||
3240 | addr = RTA_DATA(rta[IFA_ADDRESS-1]); | ||
3241 | } | ||
3242 | if (rta[IFA_LOCAL-1]) { | ||
3243 | if (RTA_PAYLOAD(rta[IFA_LOCAL-1]) < sizeof(*addr) || | ||
3244 | (addr && memcmp(addr, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*addr)))) | ||
3245 | return -EINVAL; | ||
3246 | addr = RTA_DATA(rta[IFA_LOCAL-1]); | ||
3247 | } | ||
3248 | if (addr == NULL) | ||
3249 | return -EINVAL; | ||
3250 | |||
3251 | if (ifm->ifa_index) | ||
3252 | dev = __dev_get_by_index(ifm->ifa_index); | ||
3253 | |||
3254 | if ((ifa = ipv6_get_ifaddr(addr, dev, 1)) == NULL) | ||
3255 | return -EADDRNOTAVAIL; | ||
3256 | |||
3257 | if ((skb = alloc_skb(size, GFP_KERNEL)) == NULL) { | ||
3258 | err = -ENOBUFS; | ||
3259 | goto out; | ||
3260 | } | ||
3261 | |||
3262 | NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid; | ||
3263 | err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid, | ||
3264 | nlh->nlmsg_seq, RTM_NEWADDR, 0); | ||
3265 | if (err < 0) { | ||
3266 | err = -EMSGSIZE; | ||
3267 | goto out_free; | ||
3268 | } | ||
3269 | |||
3270 | err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); | ||
3271 | if (err > 0) | ||
3272 | err = 0; | ||
3273 | out: | ||
3274 | in6_ifa_put(ifa); | ||
3275 | return err; | ||
3276 | out_free: | ||
3277 | kfree_skb(skb); | ||
3278 | goto out; | ||
3279 | } | ||
3280 | |||
3124 | static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) | 3281 | static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) |
3125 | { | 3282 | { |
3126 | struct sk_buff *skb; | 3283 | struct sk_buff *skb; |
@@ -3363,7 +3520,8 @@ static struct rtnetlink_link inet6_rtnetlink_table[RTM_NR_MSGTYPES] = { | |||
3363 | [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, }, | 3520 | [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, }, |
3364 | [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, }, | 3521 | [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, }, |
3365 | [RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, }, | 3522 | [RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, }, |
3366 | [RTM_GETADDR - RTM_BASE] = { .dumpit = inet6_dump_ifaddr, }, | 3523 | [RTM_GETADDR - RTM_BASE] = { .doit = inet6_rtm_getaddr, |
3524 | .dumpit = inet6_dump_ifaddr, }, | ||
3367 | [RTM_GETMULTICAST - RTM_BASE] = { .dumpit = inet6_dump_ifmcaddr, }, | 3525 | [RTM_GETMULTICAST - RTM_BASE] = { .dumpit = inet6_dump_ifmcaddr, }, |
3368 | [RTM_GETANYCAST - RTM_BASE] = { .dumpit = inet6_dump_ifacaddr, }, | 3526 | [RTM_GETANYCAST - RTM_BASE] = { .dumpit = inet6_dump_ifacaddr, }, |
3369 | [RTM_NEWROUTE - RTM_BASE] = { .doit = inet6_rtm_newroute, }, | 3527 | [RTM_NEWROUTE - RTM_BASE] = { .doit = inet6_rtm_newroute, }, |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 5a0ba58b86cc..ac85e9c532c2 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -658,7 +658,7 @@ int inet6_sk_rebuild_header(struct sock *sk) | |||
658 | return err; | 658 | return err; |
659 | } | 659 | } |
660 | 660 | ||
661 | ip6_dst_store(sk, dst, NULL); | 661 | __ip6_dst_store(sk, dst, NULL); |
662 | } | 662 | } |
663 | 663 | ||
664 | return 0; | 664 | return 0; |
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 5c950cc79d80..bf491077b822 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
@@ -185,7 +185,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) | |||
185 | return err; | 185 | return err; |
186 | } | 186 | } |
187 | 187 | ||
188 | ip6_dst_store(sk, dst, NULL); | 188 | __ip6_dst_store(sk, dst, NULL); |
189 | } | 189 | } |
190 | 190 | ||
191 | skb->dst = dst_clone(dst); | 191 | skb->dst = dst_clone(dst); |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 3bc74ce78800..69451af6abe7 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -356,6 +356,7 @@ int ip6_forward(struct sk_buff *skb) | |||
356 | skb->dev = dst->dev; | 356 | skb->dev = dst->dev; |
357 | icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, | 357 | icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, |
358 | 0, skb->dev); | 358 | 0, skb->dev); |
359 | IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); | ||
359 | 360 | ||
360 | kfree_skb(skb); | 361 | kfree_skb(skb); |
361 | return -ETIMEDOUT; | 362 | return -ETIMEDOUT; |
@@ -595,6 +596,9 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
595 | } | 596 | } |
596 | 597 | ||
597 | err = output(skb); | 598 | err = output(skb); |
599 | if(!err) | ||
600 | IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES); | ||
601 | |||
598 | if (err || !frag) | 602 | if (err || !frag) |
599 | break; | 603 | break; |
600 | 604 | ||
@@ -706,12 +710,11 @@ slow_path: | |||
706 | /* | 710 | /* |
707 | * Put this fragment into the sending queue. | 711 | * Put this fragment into the sending queue. |
708 | */ | 712 | */ |
709 | |||
710 | IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES); | ||
711 | |||
712 | err = output(frag); | 713 | err = output(frag); |
713 | if (err) | 714 | if (err) |
714 | goto fail; | 715 | goto fail; |
716 | |||
717 | IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES); | ||
715 | } | 718 | } |
716 | kfree_skb(skb); | 719 | kfree_skb(skb); |
717 | IP6_INC_STATS(IPSTATS_MIB_FRAGOKS); | 720 | IP6_INC_STATS(IPSTATS_MIB_FRAGOKS); |
@@ -723,48 +726,51 @@ fail: | |||
723 | return err; | 726 | return err; |
724 | } | 727 | } |
725 | 728 | ||
726 | int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl) | 729 | static struct dst_entry *ip6_sk_dst_check(struct sock *sk, |
730 | struct dst_entry *dst, | ||
731 | struct flowi *fl) | ||
727 | { | 732 | { |
728 | int err = 0; | 733 | struct ipv6_pinfo *np = inet6_sk(sk); |
734 | struct rt6_info *rt = (struct rt6_info *)dst; | ||
729 | 735 | ||
730 | *dst = NULL; | 736 | if (!dst) |
731 | if (sk) { | 737 | goto out; |
732 | struct ipv6_pinfo *np = inet6_sk(sk); | 738 | |
733 | 739 | /* Yes, checking route validity in not connected | |
734 | *dst = sk_dst_check(sk, np->dst_cookie); | 740 | * case is not very simple. Take into account, |
735 | if (*dst) { | 741 | * that we do not support routing by source, TOS, |
736 | struct rt6_info *rt = (struct rt6_info*)*dst; | 742 | * and MSG_DONTROUTE --ANK (980726) |
737 | 743 | * | |
738 | /* Yes, checking route validity in not connected | 744 | * 1. If route was host route, check that |
739 | * case is not very simple. Take into account, | 745 | * cached destination is current. |
740 | * that we do not support routing by source, TOS, | 746 | * If it is network route, we still may |
741 | * and MSG_DONTROUTE --ANK (980726) | 747 | * check its validity using saved pointer |
742 | * | 748 | * to the last used address: daddr_cache. |
743 | * 1. If route was host route, check that | 749 | * We do not want to save whole address now, |
744 | * cached destination is current. | 750 | * (because main consumer of this service |
745 | * If it is network route, we still may | 751 | * is tcp, which has not this problem), |
746 | * check its validity using saved pointer | 752 | * so that the last trick works only on connected |
747 | * to the last used address: daddr_cache. | 753 | * sockets. |
748 | * We do not want to save whole address now, | 754 | * 2. oif also should be the same. |
749 | * (because main consumer of this service | 755 | */ |
750 | * is tcp, which has not this problem), | 756 | if (((rt->rt6i_dst.plen != 128 || |
751 | * so that the last trick works only on connected | 757 | !ipv6_addr_equal(&fl->fl6_dst, &rt->rt6i_dst.addr)) |
752 | * sockets. | 758 | && (np->daddr_cache == NULL || |
753 | * 2. oif also should be the same. | 759 | !ipv6_addr_equal(&fl->fl6_dst, np->daddr_cache))) |
754 | */ | 760 | || (fl->oif && fl->oif != dst->dev->ifindex)) { |
755 | if (((rt->rt6i_dst.plen != 128 || | 761 | dst_release(dst); |
756 | !ipv6_addr_equal(&fl->fl6_dst, | 762 | dst = NULL; |
757 | &rt->rt6i_dst.addr)) | ||
758 | && (np->daddr_cache == NULL || | ||
759 | !ipv6_addr_equal(&fl->fl6_dst, | ||
760 | np->daddr_cache))) | ||
761 | || (fl->oif && fl->oif != (*dst)->dev->ifindex)) { | ||
762 | dst_release(*dst); | ||
763 | *dst = NULL; | ||
764 | } | ||
765 | } | ||
766 | } | 763 | } |
767 | 764 | ||
765 | out: | ||
766 | return dst; | ||
767 | } | ||
768 | |||
769 | static int ip6_dst_lookup_tail(struct sock *sk, | ||
770 | struct dst_entry **dst, struct flowi *fl) | ||
771 | { | ||
772 | int err; | ||
773 | |||
768 | if (*dst == NULL) | 774 | if (*dst == NULL) |
769 | *dst = ip6_route_output(sk, fl); | 775 | *dst = ip6_route_output(sk, fl); |
770 | 776 | ||
@@ -773,7 +779,6 @@ int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl) | |||
773 | 779 | ||
774 | if (ipv6_addr_any(&fl->fl6_src)) { | 780 | if (ipv6_addr_any(&fl->fl6_src)) { |
775 | err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src); | 781 | err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src); |
776 | |||
777 | if (err) | 782 | if (err) |
778 | goto out_err_release; | 783 | goto out_err_release; |
779 | } | 784 | } |
@@ -786,8 +791,48 @@ out_err_release: | |||
786 | return err; | 791 | return err; |
787 | } | 792 | } |
788 | 793 | ||
794 | /** | ||
795 | * ip6_dst_lookup - perform route lookup on flow | ||
796 | * @sk: socket which provides route info | ||
797 | * @dst: pointer to dst_entry * for result | ||
798 | * @fl: flow to lookup | ||
799 | * | ||
800 | * This function performs a route lookup on the given flow. | ||
801 | * | ||
802 | * It returns zero on success, or a standard errno code on error. | ||
803 | */ | ||
804 | int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl) | ||
805 | { | ||
806 | *dst = NULL; | ||
807 | return ip6_dst_lookup_tail(sk, dst, fl); | ||
808 | } | ||
789 | EXPORT_SYMBOL_GPL(ip6_dst_lookup); | 809 | EXPORT_SYMBOL_GPL(ip6_dst_lookup); |
790 | 810 | ||
811 | /** | ||
812 | * ip6_sk_dst_lookup - perform socket cached route lookup on flow | ||
813 | * @sk: socket which provides the dst cache and route info | ||
814 | * @dst: pointer to dst_entry * for result | ||
815 | * @fl: flow to lookup | ||
816 | * | ||
817 | * This function performs a route lookup on the given flow with the | ||
818 | * possibility of using the cached route in the socket if it is valid. | ||
819 | * It will take the socket dst lock when operating on the dst cache. | ||
820 | * As a result, this function can only be used in process context. | ||
821 | * | ||
822 | * It returns zero on success, or a standard errno code on error. | ||
823 | */ | ||
824 | int ip6_sk_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl) | ||
825 | { | ||
826 | *dst = NULL; | ||
827 | if (sk) { | ||
828 | *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie); | ||
829 | *dst = ip6_sk_dst_check(sk, *dst, fl); | ||
830 | } | ||
831 | |||
832 | return ip6_dst_lookup_tail(sk, dst, fl); | ||
833 | } | ||
834 | EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup); | ||
835 | |||
791 | static inline int ip6_ufo_append_data(struct sock *sk, | 836 | static inline int ip6_ufo_append_data(struct sock *sk, |
792 | int getfrag(void *from, char *to, int offset, int len, | 837 | int getfrag(void *from, char *to, int offset, int len, |
793 | int odd, struct sk_buff *skb), | 838 | int odd, struct sk_buff *skb), |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 87c39c978cd0..4b163711f3a8 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #include <linux/rtnetlink.h> | 53 | #include <linux/rtnetlink.h> |
54 | #include <net/dst.h> | 54 | #include <net/dst.h> |
55 | #include <net/xfrm.h> | 55 | #include <net/xfrm.h> |
56 | #include <net/netevent.h> | ||
56 | 57 | ||
57 | #include <asm/uaccess.h> | 58 | #include <asm/uaccess.h> |
58 | 59 | ||
@@ -742,6 +743,7 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
742 | dst->metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; | 743 | dst->metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; |
743 | } | 744 | } |
744 | dst->metrics[RTAX_MTU-1] = mtu; | 745 | dst->metrics[RTAX_MTU-1] = mtu; |
746 | call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst); | ||
745 | } | 747 | } |
746 | } | 748 | } |
747 | 749 | ||
@@ -1155,6 +1157,7 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *saddr, | |||
1155 | struct rt6_info *rt, *nrt = NULL; | 1157 | struct rt6_info *rt, *nrt = NULL; |
1156 | int strict; | 1158 | int strict; |
1157 | struct fib6_node *fn; | 1159 | struct fib6_node *fn; |
1160 | struct netevent_redirect netevent; | ||
1158 | 1161 | ||
1159 | /* | 1162 | /* |
1160 | * Get the "current" route for this destination and | 1163 | * Get the "current" route for this destination and |
@@ -1252,6 +1255,10 @@ restart: | |||
1252 | if (ip6_ins_rt(nrt, NULL, NULL, NULL)) | 1255 | if (ip6_ins_rt(nrt, NULL, NULL, NULL)) |
1253 | goto out; | 1256 | goto out; |
1254 | 1257 | ||
1258 | netevent.old = &rt->u.dst; | ||
1259 | netevent.new = &nrt->u.dst; | ||
1260 | call_netevent_notifiers(NETEVENT_REDIRECT, &netevent); | ||
1261 | |||
1255 | if (rt->rt6i_flags&RTF_CACHE) { | 1262 | if (rt->rt6i_flags&RTF_CACHE) { |
1256 | ip6_del_rt(rt, NULL, NULL, NULL); | 1263 | ip6_del_rt(rt, NULL, NULL, NULL); |
1257 | return; | 1264 | return; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 923989d0520d..b843a650be71 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -270,7 +270,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
270 | inet->rcv_saddr = LOOPBACK4_IPV6; | 270 | inet->rcv_saddr = LOOPBACK4_IPV6; |
271 | 271 | ||
272 | sk->sk_gso_type = SKB_GSO_TCPV6; | 272 | sk->sk_gso_type = SKB_GSO_TCPV6; |
273 | ip6_dst_store(sk, dst, NULL); | 273 | __ip6_dst_store(sk, dst, NULL); |
274 | 274 | ||
275 | icsk->icsk_ext_hdr_len = 0; | 275 | icsk->icsk_ext_hdr_len = 0; |
276 | if (np->opt) | 276 | if (np->opt) |
@@ -427,7 +427,6 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
427 | case TCP_SYN_RECV: /* Cannot happen. | 427 | case TCP_SYN_RECV: /* Cannot happen. |
428 | It can, it SYNs are crossed. --ANK */ | 428 | It can, it SYNs are crossed. --ANK */ |
429 | if (!sock_owned_by_user(sk)) { | 429 | if (!sock_owned_by_user(sk)) { |
430 | TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS); | ||
431 | sk->sk_err = err; | 430 | sk->sk_err = err; |
432 | sk->sk_error_report(sk); /* Wake people up to see the error (see connect in sock.c) */ | 431 | sk->sk_error_report(sk); /* Wake people up to see the error (see connect in sock.c) */ |
433 | 432 | ||
@@ -831,7 +830,6 @@ drop: | |||
831 | if (req) | 830 | if (req) |
832 | reqsk_free(req); | 831 | reqsk_free(req); |
833 | 832 | ||
834 | TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS); | ||
835 | return 0; /* don't send reset */ | 833 | return 0; /* don't send reset */ |
836 | } | 834 | } |
837 | 835 | ||
@@ -947,7 +945,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
947 | */ | 945 | */ |
948 | 946 | ||
949 | sk->sk_gso_type = SKB_GSO_TCPV6; | 947 | sk->sk_gso_type = SKB_GSO_TCPV6; |
950 | ip6_dst_store(newsk, dst, NULL); | 948 | __ip6_dst_store(newsk, dst, NULL); |
951 | 949 | ||
952 | newtcp6sk = (struct tcp6_sock *)newsk; | 950 | newtcp6sk = (struct tcp6_sock *)newsk; |
953 | inet_sk(newsk)->pinet6 = &newtcp6sk->inet6; | 951 | inet_sk(newsk)->pinet6 = &newtcp6sk->inet6; |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index ccc57f434cd3..3d54f246411e 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -782,7 +782,7 @@ do_udp_sendmsg: | |||
782 | connected = 0; | 782 | connected = 0; |
783 | } | 783 | } |
784 | 784 | ||
785 | err = ip6_dst_lookup(sk, &dst, fl); | 785 | err = ip6_sk_dst_lookup(sk, &dst, fl); |
786 | if (err) | 786 | if (err) |
787 | goto out; | 787 | goto out; |
788 | if (final_p) | 788 | if (final_p) |
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index 0eea60ea9ebc..c8c8b44a0f58 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c | |||
@@ -125,7 +125,7 @@ static int xfrm6_output_finish(struct sk_buff *skb) | |||
125 | if (!skb_is_gso(skb)) | 125 | if (!skb_is_gso(skb)) |
126 | return xfrm6_output_finish2(skb); | 126 | return xfrm6_output_finish2(skb); |
127 | 127 | ||
128 | skb->protocol = htons(ETH_P_IP); | 128 | skb->protocol = htons(ETH_P_IPV6); |
129 | segs = skb_gso_segment(skb, 0); | 129 | segs = skb_gso_segment(skb, 0); |
130 | kfree_skb(skb); | 130 | kfree_skb(skb); |
131 | if (unlikely(IS_ERR(segs))) | 131 | if (unlikely(IS_ERR(segs))) |
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c index c2ce9c4011cc..de9537ad9a7c 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c | |||
@@ -57,6 +57,8 @@ static int checkentry_selinux(struct xt_secmark_target_info *info) | |||
57 | { | 57 | { |
58 | int err; | 58 | int err; |
59 | struct xt_secmark_target_selinux_info *sel = &info->u.sel; | 59 | struct xt_secmark_target_selinux_info *sel = &info->u.sel; |
60 | |||
61 | sel->selctx[SECMARK_SELCTX_MAX - 1] = '\0'; | ||
60 | 62 | ||
61 | err = selinux_string_to_sid(sel->selctx, &sel->selsid); | 63 | err = selinux_string_to_sid(sel->selctx, &sel->selsid); |
62 | if (err) { | 64 | if (err) { |
diff --git a/net/netfilter/xt_string.c b/net/netfilter/xt_string.c index 0ebb6ac2c8c7..d8e3891b5f8b 100644 --- a/net/netfilter/xt_string.c +++ b/net/netfilter/xt_string.c | |||
@@ -55,7 +55,10 @@ static int checkentry(const char *tablename, | |||
55 | /* Damn, can't handle this case properly with iptables... */ | 55 | /* Damn, can't handle this case properly with iptables... */ |
56 | if (conf->from_offset > conf->to_offset) | 56 | if (conf->from_offset > conf->to_offset) |
57 | return 0; | 57 | return 0; |
58 | 58 | if (conf->algo[XT_STRING_MAX_ALGO_NAME_SIZE - 1] != '\0') | |
59 | return 0; | ||
60 | if (conf->patlen > XT_STRING_MAX_PATTERN_SIZE) | ||
61 | return 0; | ||
59 | ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen, | 62 | ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen, |
60 | GFP_KERNEL, TS_AUTOLOAD); | 63 | GFP_KERNEL, TS_AUTOLOAD); |
61 | if (IS_ERR(ts_conf)) | 64 | if (IS_ERR(ts_conf)) |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 6f2909279268..de6ec519272e 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -128,23 +128,17 @@ static atomic_t unix_nr_socks = ATOMIC_INIT(0); | |||
128 | #define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash != UNIX_HASH_SIZE) | 128 | #define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash != UNIX_HASH_SIZE) |
129 | 129 | ||
130 | #ifdef CONFIG_SECURITY_NETWORK | 130 | #ifdef CONFIG_SECURITY_NETWORK |
131 | static void unix_get_peersec_dgram(struct sk_buff *skb) | 131 | static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb) |
132 | { | 132 | { |
133 | int err; | 133 | memcpy(UNIXSID(skb), &scm->secid, sizeof(u32)); |
134 | |||
135 | err = security_socket_getpeersec_dgram(skb, UNIXSECDATA(skb), | ||
136 | UNIXSECLEN(skb)); | ||
137 | if (err) | ||
138 | *(UNIXSECDATA(skb)) = NULL; | ||
139 | } | 134 | } |
140 | 135 | ||
141 | static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb) | 136 | static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb) |
142 | { | 137 | { |
143 | scm->secdata = *UNIXSECDATA(skb); | 138 | scm->secid = *UNIXSID(skb); |
144 | scm->seclen = *UNIXSECLEN(skb); | ||
145 | } | 139 | } |
146 | #else | 140 | #else |
147 | static inline void unix_get_peersec_dgram(struct sk_buff *skb) | 141 | static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb) |
148 | { } | 142 | { } |
149 | 143 | ||
150 | static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb) | 144 | static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb) |
@@ -1322,8 +1316,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1322 | memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); | 1316 | memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); |
1323 | if (siocb->scm->fp) | 1317 | if (siocb->scm->fp) |
1324 | unix_attach_fds(siocb->scm, skb); | 1318 | unix_attach_fds(siocb->scm, skb); |
1325 | 1319 | unix_get_secdata(siocb->scm, skb); | |
1326 | unix_get_peersec_dgram(skb); | ||
1327 | 1320 | ||
1328 | skb->h.raw = skb->data; | 1321 | skb->h.raw = skb->data; |
1329 | err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len); | 1322 | err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len); |