diff options
Diffstat (limited to 'net')
51 files changed, 388 insertions, 124 deletions
diff --git a/net/atm/br2684.c b/net/atm/br2684.c index 2252c2085dac..52cfd0c3ea71 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c | |||
| @@ -242,8 +242,6 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct net_device *dev, | |||
| 242 | if (brdev->payload == p_bridged) { | 242 | if (brdev->payload == p_bridged) { |
| 243 | skb_push(skb, 2); | 243 | skb_push(skb, 2); |
| 244 | memset(skb->data, 0, 2); | 244 | memset(skb->data, 0, 2); |
| 245 | } else { /* p_routed */ | ||
| 246 | skb_pull(skb, ETH_HLEN); | ||
| 247 | } | 245 | } |
| 248 | } | 246 | } |
| 249 | skb_debug(skb); | 247 | skb_debug(skb); |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 3176e2e13d9b..2cdf0070419f 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
| @@ -417,6 +417,7 @@ put_back: | |||
| 417 | int br_del_if(struct net_bridge *br, struct net_device *dev) | 417 | int br_del_if(struct net_bridge *br, struct net_device *dev) |
| 418 | { | 418 | { |
| 419 | struct net_bridge_port *p; | 419 | struct net_bridge_port *p; |
| 420 | bool changed_addr; | ||
| 420 | 421 | ||
| 421 | p = br_port_get_rtnl(dev); | 422 | p = br_port_get_rtnl(dev); |
| 422 | if (!p || p->br != br) | 423 | if (!p || p->br != br) |
| @@ -425,9 +426,12 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) | |||
| 425 | del_nbp(p); | 426 | del_nbp(p); |
| 426 | 427 | ||
| 427 | spin_lock_bh(&br->lock); | 428 | spin_lock_bh(&br->lock); |
| 428 | br_stp_recalculate_bridge_id(br); | 429 | changed_addr = br_stp_recalculate_bridge_id(br); |
| 429 | spin_unlock_bh(&br->lock); | 430 | spin_unlock_bh(&br->lock); |
| 430 | 431 | ||
| 432 | if (changed_addr) | ||
| 433 | call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev); | ||
| 434 | |||
| 431 | netdev_update_features(br->dev); | 435 | netdev_update_features(br->dev); |
| 432 | 436 | ||
| 433 | return 0; | 437 | return 0; |
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c index 6545ee9591d1..a76b62135558 100644 --- a/net/bridge/br_notify.c +++ b/net/bridge/br_notify.c | |||
| @@ -34,6 +34,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v | |||
| 34 | struct net_device *dev = ptr; | 34 | struct net_device *dev = ptr; |
| 35 | struct net_bridge_port *p; | 35 | struct net_bridge_port *p; |
| 36 | struct net_bridge *br; | 36 | struct net_bridge *br; |
| 37 | bool changed_addr; | ||
| 37 | int err; | 38 | int err; |
| 38 | 39 | ||
| 39 | /* register of bridge completed, add sysfs entries */ | 40 | /* register of bridge completed, add sysfs entries */ |
| @@ -57,8 +58,12 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v | |||
| 57 | case NETDEV_CHANGEADDR: | 58 | case NETDEV_CHANGEADDR: |
| 58 | spin_lock_bh(&br->lock); | 59 | spin_lock_bh(&br->lock); |
| 59 | br_fdb_changeaddr(p, dev->dev_addr); | 60 | br_fdb_changeaddr(p, dev->dev_addr); |
| 60 | br_stp_recalculate_bridge_id(br); | 61 | changed_addr = br_stp_recalculate_bridge_id(br); |
| 61 | spin_unlock_bh(&br->lock); | 62 | spin_unlock_bh(&br->lock); |
| 63 | |||
| 64 | if (changed_addr) | ||
| 65 | call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev); | ||
| 66 | |||
| 62 | break; | 67 | break; |
| 63 | 68 | ||
| 64 | case NETDEV_CHANGE: | 69 | case NETDEV_CHANGE: |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 2b5ca1a0054d..5864cc491369 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
| @@ -1198,7 +1198,8 @@ ebt_register_table(struct net *net, const struct ebt_table *input_table) | |||
| 1198 | 1198 | ||
| 1199 | if (table->check && table->check(newinfo, table->valid_hooks)) { | 1199 | if (table->check && table->check(newinfo, table->valid_hooks)) { |
| 1200 | BUGPRINT("The table doesn't like its own initial data, lol\n"); | 1200 | BUGPRINT("The table doesn't like its own initial data, lol\n"); |
| 1201 | return ERR_PTR(-EINVAL); | 1201 | ret = -EINVAL; |
| 1202 | goto free_chainstack; | ||
| 1202 | } | 1203 | } |
| 1203 | 1204 | ||
| 1204 | table->private = newinfo; | 1205 | table->private = newinfo; |
diff --git a/net/core/Makefile b/net/core/Makefile index 8a04dd22cf77..0d357b1c4e57 100644 --- a/net/core/Makefile +++ b/net/core/Makefile | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ | 5 | obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ |
| 6 | gen_stats.o gen_estimator.o net_namespace.o | 6 | gen_stats.o gen_estimator.o net_namespace.o secure_seq.o |
| 7 | 7 | ||
| 8 | obj-$(CONFIG_SYSCTL) += sysctl_net_core.o | 8 | obj-$(CONFIG_SYSCTL) += sysctl_net_core.o |
| 9 | 9 | ||
diff --git a/net/core/scm.c b/net/core/scm.c index 4c1ef026d695..811b53fb330e 100644 --- a/net/core/scm.c +++ b/net/core/scm.c | |||
| @@ -192,7 +192,7 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) | |||
| 192 | goto error; | 192 | goto error; |
| 193 | 193 | ||
| 194 | cred->uid = cred->euid = p->creds.uid; | 194 | cred->uid = cred->euid = p->creds.uid; |
| 195 | cred->gid = cred->egid = p->creds.uid; | 195 | cred->gid = cred->egid = p->creds.gid; |
| 196 | put_cred(p->cred); | 196 | put_cred(p->cred); |
| 197 | p->cred = cred; | 197 | p->cred = cred; |
| 198 | } | 198 | } |
diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c new file mode 100644 index 000000000000..45329d7c9dd9 --- /dev/null +++ b/net/core/secure_seq.c | |||
| @@ -0,0 +1,184 @@ | |||
| 1 | #include <linux/kernel.h> | ||
| 2 | #include <linux/init.h> | ||
| 3 | #include <linux/cryptohash.h> | ||
| 4 | #include <linux/module.h> | ||
| 5 | #include <linux/cache.h> | ||
| 6 | #include <linux/random.h> | ||
| 7 | #include <linux/hrtimer.h> | ||
| 8 | #include <linux/ktime.h> | ||
| 9 | #include <linux/string.h> | ||
| 10 | |||
| 11 | #include <net/secure_seq.h> | ||
| 12 | |||
| 13 | static u32 net_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; | ||
| 14 | |||
| 15 | static int __init net_secret_init(void) | ||
| 16 | { | ||
| 17 | get_random_bytes(net_secret, sizeof(net_secret)); | ||
| 18 | return 0; | ||
| 19 | } | ||
| 20 | late_initcall(net_secret_init); | ||
| 21 | |||
| 22 | static u32 seq_scale(u32 seq) | ||
| 23 | { | ||
| 24 | /* | ||
| 25 | * As close as possible to RFC 793, which | ||
| 26 | * suggests using a 250 kHz clock. | ||
| 27 | * Further reading shows this assumes 2 Mb/s networks. | ||
| 28 | * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate. | ||
| 29 | * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but | ||
| 30 | * we also need to limit the resolution so that the u32 seq | ||
| 31 | * overlaps less than one time per MSL (2 minutes). | ||
| 32 | * Choosing a clock of 64 ns period is OK. (period of 274 s) | ||
| 33 | */ | ||
| 34 | return seq + (ktime_to_ns(ktime_get_real()) >> 6); | ||
| 35 | } | ||
| 36 | |||
| 37 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
| 38 | __u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, | ||
| 39 | __be16 sport, __be16 dport) | ||
| 40 | { | ||
| 41 | u32 secret[MD5_MESSAGE_BYTES / 4]; | ||
| 42 | u32 hash[MD5_DIGEST_WORDS]; | ||
| 43 | u32 i; | ||
| 44 | |||
| 45 | memcpy(hash, saddr, 16); | ||
| 46 | for (i = 0; i < 4; i++) | ||
| 47 | secret[i] = net_secret[i] + daddr[i]; | ||
| 48 | secret[4] = net_secret[4] + | ||
| 49 | (((__force u16)sport << 16) + (__force u16)dport); | ||
| 50 | for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) | ||
| 51 | secret[i] = net_secret[i]; | ||
| 52 | |||
| 53 | md5_transform(hash, secret); | ||
| 54 | |||
| 55 | return seq_scale(hash[0]); | ||
| 56 | } | ||
| 57 | EXPORT_SYMBOL(secure_tcpv6_sequence_number); | ||
| 58 | |||
| 59 | u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, | ||
| 60 | __be16 dport) | ||
| 61 | { | ||
| 62 | u32 secret[MD5_MESSAGE_BYTES / 4]; | ||
| 63 | u32 hash[MD5_DIGEST_WORDS]; | ||
| 64 | u32 i; | ||
| 65 | |||
| 66 | memcpy(hash, saddr, 16); | ||
| 67 | for (i = 0; i < 4; i++) | ||
| 68 | secret[i] = net_secret[i] + (__force u32) daddr[i]; | ||
| 69 | secret[4] = net_secret[4] + (__force u32)dport; | ||
| 70 | for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) | ||
| 71 | secret[i] = net_secret[i]; | ||
| 72 | |||
| 73 | md5_transform(hash, secret); | ||
| 74 | |||
| 75 | return hash[0]; | ||
| 76 | } | ||
| 77 | #endif | ||
| 78 | |||
| 79 | #ifdef CONFIG_INET | ||
| 80 | __u32 secure_ip_id(__be32 daddr) | ||
| 81 | { | ||
| 82 | u32 hash[MD5_DIGEST_WORDS]; | ||
| 83 | |||
| 84 | hash[0] = (__force __u32) daddr; | ||
| 85 | hash[1] = net_secret[13]; | ||
| 86 | hash[2] = net_secret[14]; | ||
| 87 | hash[3] = net_secret[15]; | ||
| 88 | |||
| 89 | md5_transform(hash, net_secret); | ||
| 90 | |||
| 91 | return hash[0]; | ||
| 92 | } | ||
| 93 | |||
| 94 | __u32 secure_ipv6_id(const __be32 daddr[4]) | ||
| 95 | { | ||
| 96 | __u32 hash[4]; | ||
| 97 | |||
| 98 | memcpy(hash, daddr, 16); | ||
| 99 | md5_transform(hash, net_secret); | ||
| 100 | |||
| 101 | return hash[0]; | ||
| 102 | } | ||
| 103 | |||
| 104 | __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, | ||
| 105 | __be16 sport, __be16 dport) | ||
| 106 | { | ||
| 107 | u32 hash[MD5_DIGEST_WORDS]; | ||
| 108 | |||
| 109 | hash[0] = (__force u32)saddr; | ||
| 110 | hash[1] = (__force u32)daddr; | ||
| 111 | hash[2] = ((__force u16)sport << 16) + (__force u16)dport; | ||
| 112 | hash[3] = net_secret[15]; | ||
| 113 | |||
| 114 | md5_transform(hash, net_secret); | ||
| 115 | |||
| 116 | return seq_scale(hash[0]); | ||
| 117 | } | ||
| 118 | |||
| 119 | u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) | ||
| 120 | { | ||
| 121 | u32 hash[MD5_DIGEST_WORDS]; | ||
| 122 | |||
| 123 | hash[0] = (__force u32)saddr; | ||
| 124 | hash[1] = (__force u32)daddr; | ||
| 125 | hash[2] = (__force u32)dport ^ net_secret[14]; | ||
| 126 | hash[3] = net_secret[15]; | ||
| 127 | |||
| 128 | md5_transform(hash, net_secret); | ||
| 129 | |||
| 130 | return hash[0]; | ||
| 131 | } | ||
| 132 | EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral); | ||
| 133 | #endif | ||
| 134 | |||
| 135 | #if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) | ||
| 136 | u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, | ||
| 137 | __be16 sport, __be16 dport) | ||
| 138 | { | ||
| 139 | u32 hash[MD5_DIGEST_WORDS]; | ||
| 140 | u64 seq; | ||
| 141 | |||
| 142 | hash[0] = (__force u32)saddr; | ||
| 143 | hash[1] = (__force u32)daddr; | ||
| 144 | hash[2] = ((__force u16)sport << 16) + (__force u16)dport; | ||
| 145 | hash[3] = net_secret[15]; | ||
| 146 | |||
| 147 | md5_transform(hash, net_secret); | ||
| 148 | |||
| 149 | seq = hash[0] | (((u64)hash[1]) << 32); | ||
| 150 | seq += ktime_to_ns(ktime_get_real()); | ||
| 151 | seq &= (1ull << 48) - 1; | ||
| 152 | |||
| 153 | return seq; | ||
| 154 | } | ||
| 155 | EXPORT_SYMBOL(secure_dccp_sequence_number); | ||
| 156 | |||
| 157 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
| 158 | u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, | ||
| 159 | __be16 sport, __be16 dport) | ||
| 160 | { | ||
| 161 | u32 secret[MD5_MESSAGE_BYTES / 4]; | ||
| 162 | u32 hash[MD5_DIGEST_WORDS]; | ||
| 163 | u64 seq; | ||
| 164 | u32 i; | ||
| 165 | |||
| 166 | memcpy(hash, saddr, 16); | ||
| 167 | for (i = 0; i < 4; i++) | ||
| 168 | secret[i] = net_secret[i] + daddr[i]; | ||
| 169 | secret[4] = net_secret[4] + | ||
| 170 | (((__force u16)sport << 16) + (__force u16)dport); | ||
| 171 | for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) | ||
| 172 | secret[i] = net_secret[i]; | ||
| 173 | |||
| 174 | md5_transform(hash, secret); | ||
| 175 | |||
| 176 | seq = hash[0] | (((u64)hash[1]) << 32); | ||
| 177 | seq += ktime_to_ns(ktime_get_real()); | ||
| 178 | seq &= (1ull << 48) - 1; | ||
| 179 | |||
| 180 | return seq; | ||
| 181 | } | ||
| 182 | EXPORT_SYMBOL(secure_dccpv6_sequence_number); | ||
| 183 | #endif | ||
| 184 | #endif | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 2beda824636e..27002dffe7ed 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -1369,8 +1369,21 @@ pull_pages: | |||
| 1369 | } | 1369 | } |
| 1370 | EXPORT_SYMBOL(__pskb_pull_tail); | 1370 | EXPORT_SYMBOL(__pskb_pull_tail); |
| 1371 | 1371 | ||
| 1372 | /* Copy some data bits from skb to kernel buffer. */ | 1372 | /** |
| 1373 | 1373 | * skb_copy_bits - copy bits from skb to kernel buffer | |
| 1374 | * @skb: source skb | ||
| 1375 | * @offset: offset in source | ||
| 1376 | * @to: destination buffer | ||
| 1377 | * @len: number of bytes to copy | ||
| 1378 | * | ||
| 1379 | * Copy the specified number of bytes from the source skb to the | ||
| 1380 | * destination buffer. | ||
| 1381 | * | ||
| 1382 | * CAUTION ! : | ||
| 1383 | * If its prototype is ever changed, | ||
| 1384 | * check arch/{*}/net/{*}.S files, | ||
| 1385 | * since it is called from BPF assembly code. | ||
| 1386 | */ | ||
| 1374 | int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) | 1387 | int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) |
| 1375 | { | 1388 | { |
| 1376 | int start = skb_headlen(skb); | 1389 | int start = skb_headlen(skb); |
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 8c36adfd1919..332639b56f4d 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <net/timewait_sock.h> | 26 | #include <net/timewait_sock.h> |
| 27 | #include <net/tcp_states.h> | 27 | #include <net/tcp_states.h> |
| 28 | #include <net/xfrm.h> | 28 | #include <net/xfrm.h> |
| 29 | #include <net/secure_seq.h> | ||
| 29 | 30 | ||
| 30 | #include "ackvec.h" | 31 | #include "ackvec.h" |
| 31 | #include "ccid.h" | 32 | #include "ccid.h" |
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 8dc4348774a5..b74f76117dcf 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <net/transp_v6.h> | 29 | #include <net/transp_v6.h> |
| 30 | #include <net/ip6_checksum.h> | 30 | #include <net/ip6_checksum.h> |
| 31 | #include <net/xfrm.h> | 31 | #include <net/xfrm.h> |
| 32 | #include <net/secure_seq.h> | ||
| 32 | 33 | ||
| 33 | #include "dccp.h" | 34 | #include "dccp.h" |
| 34 | #include "ipv6.h" | 35 | #include "ipv6.h" |
| @@ -69,13 +70,7 @@ static inline void dccp_v6_send_check(struct sock *sk, struct sk_buff *skb) | |||
| 69 | dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr); | 70 | dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr); |
| 70 | } | 71 | } |
| 71 | 72 | ||
| 72 | static inline __u32 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, | 73 | static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb) |
| 73 | __be16 sport, __be16 dport ) | ||
| 74 | { | ||
| 75 | return secure_tcpv6_sequence_number(saddr, daddr, sport, dport); | ||
| 76 | } | ||
| 77 | |||
| 78 | static inline __u32 dccp_v6_init_sequence(struct sk_buff *skb) | ||
| 79 | { | 74 | { |
| 80 | return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, | 75 | return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, |
| 81 | ipv6_hdr(skb)->saddr.s6_addr32, | 76 | ipv6_hdr(skb)->saddr.s6_addr32, |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index f1d27f6c9351..283c0a26e03f 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
| @@ -1718,7 +1718,7 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode, | |||
| 1718 | 1718 | ||
| 1719 | pmc->sfcount[sfmode]--; | 1719 | pmc->sfcount[sfmode]--; |
| 1720 | for (j=0; j<i; j++) | 1720 | for (j=0; j<i; j++) |
| 1721 | (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[i]); | 1721 | (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[j]); |
| 1722 | } else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) { | 1722 | } else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) { |
| 1723 | #ifdef CONFIG_IP_MULTICAST | 1723 | #ifdef CONFIG_IP_MULTICAST |
| 1724 | struct ip_sf_list *psf; | 1724 | struct ip_sf_list *psf; |
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 3c0369a3a663..984ec656b03b 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | 21 | ||
| 22 | #include <net/inet_connection_sock.h> | 22 | #include <net/inet_connection_sock.h> |
| 23 | #include <net/inet_hashtables.h> | 23 | #include <net/inet_hashtables.h> |
| 24 | #include <net/secure_seq.h> | ||
| 24 | #include <net/ip.h> | 25 | #include <net/ip.h> |
| 25 | 26 | ||
| 26 | /* | 27 | /* |
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index e38213817d0a..86f13c67ea85 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/net.h> | 19 | #include <linux/net.h> |
| 20 | #include <net/ip.h> | 20 | #include <net/ip.h> |
| 21 | #include <net/inetpeer.h> | 21 | #include <net/inetpeer.h> |
| 22 | #include <net/secure_seq.h> | ||
| 22 | 23 | ||
| 23 | /* | 24 | /* |
| 24 | * Theory of operations. | 25 | * Theory of operations. |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index ccaaa851ab42..8c6563361ab5 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
| @@ -122,6 +122,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb) | |||
| 122 | newskb->pkt_type = PACKET_LOOPBACK; | 122 | newskb->pkt_type = PACKET_LOOPBACK; |
| 123 | newskb->ip_summed = CHECKSUM_UNNECESSARY; | 123 | newskb->ip_summed = CHECKSUM_UNNECESSARY; |
| 124 | WARN_ON(!skb_dst(newskb)); | 124 | WARN_ON(!skb_dst(newskb)); |
| 125 | skb_dst_force(newskb); | ||
| 125 | netif_rx_ni(newskb); | 126 | netif_rx_ni(newskb); |
| 126 | return 0; | 127 | return 0; |
| 127 | } | 128 | } |
| @@ -204,9 +205,15 @@ static inline int ip_finish_output2(struct sk_buff *skb) | |||
| 204 | skb = skb2; | 205 | skb = skb2; |
| 205 | } | 206 | } |
| 206 | 207 | ||
| 208 | rcu_read_lock(); | ||
| 207 | neigh = dst_get_neighbour(dst); | 209 | neigh = dst_get_neighbour(dst); |
| 208 | if (neigh) | 210 | if (neigh) { |
| 209 | return neigh_output(neigh, skb); | 211 | int res = neigh_output(neigh, skb); |
| 212 | |||
| 213 | rcu_read_unlock(); | ||
| 214 | return res; | ||
| 215 | } | ||
| 216 | rcu_read_unlock(); | ||
| 210 | 217 | ||
| 211 | if (net_ratelimit()) | 218 | if (net_ratelimit()) |
| 212 | printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n"); | 219 | printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n"); |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index ab0c9efd1efa..8905e92f896a 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
| @@ -1067,7 +1067,7 @@ EXPORT_SYMBOL(compat_ip_setsockopt); | |||
| 1067 | */ | 1067 | */ |
| 1068 | 1068 | ||
| 1069 | static int do_ip_getsockopt(struct sock *sk, int level, int optname, | 1069 | static int do_ip_getsockopt(struct sock *sk, int level, int optname, |
| 1070 | char __user *optval, int __user *optlen) | 1070 | char __user *optval, int __user *optlen, unsigned flags) |
| 1071 | { | 1071 | { |
| 1072 | struct inet_sock *inet = inet_sk(sk); | 1072 | struct inet_sock *inet = inet_sk(sk); |
| 1073 | int val; | 1073 | int val; |
| @@ -1240,7 +1240,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, | |||
| 1240 | 1240 | ||
| 1241 | msg.msg_control = optval; | 1241 | msg.msg_control = optval; |
| 1242 | msg.msg_controllen = len; | 1242 | msg.msg_controllen = len; |
| 1243 | msg.msg_flags = 0; | 1243 | msg.msg_flags = flags; |
| 1244 | 1244 | ||
| 1245 | if (inet->cmsg_flags & IP_CMSG_PKTINFO) { | 1245 | if (inet->cmsg_flags & IP_CMSG_PKTINFO) { |
| 1246 | struct in_pktinfo info; | 1246 | struct in_pktinfo info; |
| @@ -1294,7 +1294,7 @@ int ip_getsockopt(struct sock *sk, int level, | |||
| 1294 | { | 1294 | { |
| 1295 | int err; | 1295 | int err; |
| 1296 | 1296 | ||
| 1297 | err = do_ip_getsockopt(sk, level, optname, optval, optlen); | 1297 | err = do_ip_getsockopt(sk, level, optname, optval, optlen, 0); |
| 1298 | #ifdef CONFIG_NETFILTER | 1298 | #ifdef CONFIG_NETFILTER |
| 1299 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | 1299 | /* we need to exclude all possible ENOPROTOOPTs except default case */ |
| 1300 | if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS && | 1300 | if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS && |
| @@ -1327,7 +1327,8 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname, | |||
| 1327 | return compat_mc_getsockopt(sk, level, optname, optval, optlen, | 1327 | return compat_mc_getsockopt(sk, level, optname, optval, optlen, |
| 1328 | ip_getsockopt); | 1328 | ip_getsockopt); |
| 1329 | 1329 | ||
| 1330 | err = do_ip_getsockopt(sk, level, optname, optval, optlen); | 1330 | err = do_ip_getsockopt(sk, level, optname, optval, optlen, |
| 1331 | MSG_CMSG_COMPAT); | ||
| 1331 | 1332 | ||
| 1332 | #ifdef CONFIG_NETFILTER | 1333 | #ifdef CONFIG_NETFILTER |
| 1333 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | 1334 | /* we need to exclude all possible ENOPROTOOPTs except default case */ |
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index 2e97e3ec1eb7..929b27bdeb79 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c | |||
| @@ -18,17 +18,15 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
| 18 | struct rtable *rt; | 18 | struct rtable *rt; |
| 19 | struct flowi4 fl4 = {}; | 19 | struct flowi4 fl4 = {}; |
| 20 | __be32 saddr = iph->saddr; | 20 | __be32 saddr = iph->saddr; |
| 21 | __u8 flags = 0; | 21 | __u8 flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; |
| 22 | unsigned int hh_len; | 22 | unsigned int hh_len; |
| 23 | 23 | ||
| 24 | if (!skb->sk && addr_type != RTN_LOCAL) { | 24 | if (addr_type == RTN_UNSPEC) |
| 25 | if (addr_type == RTN_UNSPEC) | 25 | addr_type = inet_addr_type(net, saddr); |
| 26 | addr_type = inet_addr_type(net, saddr); | 26 | if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST) |
| 27 | if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST) | 27 | flags |= FLOWI_FLAG_ANYSRC; |
| 28 | flags |= FLOWI_FLAG_ANYSRC; | 28 | else |
| 29 | else | 29 | saddr = 0; |
| 30 | saddr = 0; | ||
| 31 | } | ||
| 32 | 30 | ||
| 33 | /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause | 31 | /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause |
| 34 | * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. | 32 | * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. |
| @@ -38,7 +36,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
| 38 | fl4.flowi4_tos = RT_TOS(iph->tos); | 36 | fl4.flowi4_tos = RT_TOS(iph->tos); |
| 39 | fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; | 37 | fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; |
| 40 | fl4.flowi4_mark = skb->mark; | 38 | fl4.flowi4_mark = skb->mark; |
| 41 | fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : flags; | 39 | fl4.flowi4_flags = flags; |
| 42 | rt = ip_route_output_key(net, &fl4); | 40 | rt = ip_route_output_key(net, &fl4); |
| 43 | if (IS_ERR(rt)) | 41 | if (IS_ERR(rt)) |
| 44 | return -1; | 42 | return -1; |
diff --git a/net/ipv4/netfilter/nf_nat_proto_common.c b/net/ipv4/netfilter/nf_nat_proto_common.c index 3e61faf23a9a..f52d41ea0690 100644 --- a/net/ipv4/netfilter/nf_nat_proto_common.c +++ b/net/ipv4/netfilter/nf_nat_proto_common.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/ip.h> | 12 | #include <linux/ip.h> |
| 13 | 13 | ||
| 14 | #include <linux/netfilter.h> | 14 | #include <linux/netfilter.h> |
| 15 | #include <net/secure_seq.h> | ||
| 15 | #include <net/netfilter/nf_nat.h> | 16 | #include <net/netfilter/nf_nat.h> |
| 16 | #include <net/netfilter/nf_nat_core.h> | 17 | #include <net/netfilter/nf_nat_core.h> |
| 17 | #include <net/netfilter/nf_nat_rule.h> | 18 | #include <net/netfilter/nf_nat_rule.h> |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 1457acb39cec..61714bd52925 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
| @@ -563,7 +563,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 563 | flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, | 563 | flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, |
| 564 | RT_SCOPE_UNIVERSE, | 564 | RT_SCOPE_UNIVERSE, |
| 565 | inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, | 565 | inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, |
| 566 | FLOWI_FLAG_CAN_SLEEP, daddr, saddr, 0, 0); | 566 | inet_sk_flowi_flags(sk) | FLOWI_FLAG_CAN_SLEEP, |
| 567 | daddr, saddr, 0, 0); | ||
| 567 | 568 | ||
| 568 | if (!inet->hdrincl) { | 569 | if (!inet->hdrincl) { |
| 569 | err = raw_probe_proto_opt(&fl4, msg); | 570 | err = raw_probe_proto_opt(&fl4, msg); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 1730689f560e..075212e41b83 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -109,6 +109,7 @@ | |||
| 109 | #include <linux/sysctl.h> | 109 | #include <linux/sysctl.h> |
| 110 | #endif | 110 | #endif |
| 111 | #include <net/atmclip.h> | 111 | #include <net/atmclip.h> |
| 112 | #include <net/secure_seq.h> | ||
| 112 | 113 | ||
| 113 | #define RT_FL_TOS(oldflp4) \ | 114 | #define RT_FL_TOS(oldflp4) \ |
| 114 | ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))) | 115 | ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))) |
| @@ -721,7 +722,7 @@ static inline bool compare_hash_inputs(const struct rtable *rt1, | |||
| 721 | { | 722 | { |
| 722 | return ((((__force u32)rt1->rt_key_dst ^ (__force u32)rt2->rt_key_dst) | | 723 | return ((((__force u32)rt1->rt_key_dst ^ (__force u32)rt2->rt_key_dst) | |
| 723 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | | 724 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | |
| 724 | (rt1->rt_iif ^ rt2->rt_iif)) == 0); | 725 | (rt1->rt_route_iif ^ rt2->rt_route_iif)) == 0); |
| 725 | } | 726 | } |
| 726 | 727 | ||
| 727 | static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) | 728 | static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) |
| @@ -730,8 +731,8 @@ static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) | |||
| 730 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | | 731 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | |
| 731 | (rt1->rt_mark ^ rt2->rt_mark) | | 732 | (rt1->rt_mark ^ rt2->rt_mark) | |
| 732 | (rt1->rt_key_tos ^ rt2->rt_key_tos) | | 733 | (rt1->rt_key_tos ^ rt2->rt_key_tos) | |
| 733 | (rt1->rt_oif ^ rt2->rt_oif) | | 734 | (rt1->rt_route_iif ^ rt2->rt_route_iif) | |
| 734 | (rt1->rt_iif ^ rt2->rt_iif)) == 0; | 735 | (rt1->rt_oif ^ rt2->rt_oif)) == 0; |
| 735 | } | 736 | } |
| 736 | 737 | ||
| 737 | static inline int compare_netns(struct rtable *rt1, struct rtable *rt2) | 738 | static inline int compare_netns(struct rtable *rt1, struct rtable *rt2) |
| @@ -1628,16 +1629,18 @@ static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) | |||
| 1628 | { | 1629 | { |
| 1629 | struct rtable *rt = (struct rtable *) dst; | 1630 | struct rtable *rt = (struct rtable *) dst; |
| 1630 | __be32 orig_gw = rt->rt_gateway; | 1631 | __be32 orig_gw = rt->rt_gateway; |
| 1631 | struct neighbour *n; | 1632 | struct neighbour *n, *old_n; |
| 1632 | 1633 | ||
| 1633 | dst_confirm(&rt->dst); | 1634 | dst_confirm(&rt->dst); |
| 1634 | 1635 | ||
| 1635 | neigh_release(dst_get_neighbour(&rt->dst)); | ||
| 1636 | dst_set_neighbour(&rt->dst, NULL); | ||
| 1637 | |||
| 1638 | rt->rt_gateway = peer->redirect_learned.a4; | 1636 | rt->rt_gateway = peer->redirect_learned.a4; |
| 1639 | rt_bind_neighbour(rt); | 1637 | |
| 1640 | n = dst_get_neighbour(&rt->dst); | 1638 | n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway); |
| 1639 | if (IS_ERR(n)) | ||
| 1640 | return PTR_ERR(n); | ||
| 1641 | old_n = xchg(&rt->dst._neighbour, n); | ||
| 1642 | if (old_n) | ||
| 1643 | neigh_release(old_n); | ||
| 1641 | if (!n || !(n->nud_state & NUD_VALID)) { | 1644 | if (!n || !(n->nud_state & NUD_VALID)) { |
| 1642 | if (n) | 1645 | if (n) |
| 1643 | neigh_event_send(n, NULL); | 1646 | neigh_event_send(n, NULL); |
| @@ -2317,8 +2320,7 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
| 2317 | rth = rcu_dereference(rth->dst.rt_next)) { | 2320 | rth = rcu_dereference(rth->dst.rt_next)) { |
| 2318 | if ((((__force u32)rth->rt_key_dst ^ (__force u32)daddr) | | 2321 | if ((((__force u32)rth->rt_key_dst ^ (__force u32)daddr) | |
| 2319 | ((__force u32)rth->rt_key_src ^ (__force u32)saddr) | | 2322 | ((__force u32)rth->rt_key_src ^ (__force u32)saddr) | |
| 2320 | (rth->rt_iif ^ iif) | | 2323 | (rth->rt_route_iif ^ iif) | |
| 2321 | rth->rt_oif | | ||
| 2322 | (rth->rt_key_tos ^ tos)) == 0 && | 2324 | (rth->rt_key_tos ^ tos)) == 0 && |
| 2323 | rth->rt_mark == skb->mark && | 2325 | rth->rt_mark == skb->mark && |
| 2324 | net_eq(dev_net(rth->dst.dev), net) && | 2326 | net_eq(dev_net(rth->dst.dev), net) && |
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 92bb9434b338..3bc5c8f7c71b 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
| @@ -276,7 +276,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
| 276 | int mss; | 276 | int mss; |
| 277 | struct rtable *rt; | 277 | struct rtable *rt; |
| 278 | __u8 rcv_wscale; | 278 | __u8 rcv_wscale; |
| 279 | bool ecn_ok; | 279 | bool ecn_ok = false; |
| 280 | 280 | ||
| 281 | if (!sysctl_tcp_syncookies || !th->ack || th->rst) | 281 | if (!sysctl_tcp_syncookies || !th->ack || th->rst) |
| 282 | goto out; | 282 | goto out; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 955b8e65b69e..1c12b8ec849d 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -72,6 +72,7 @@ | |||
| 72 | #include <net/timewait_sock.h> | 72 | #include <net/timewait_sock.h> |
| 73 | #include <net/xfrm.h> | 73 | #include <net/xfrm.h> |
| 74 | #include <net/netdma.h> | 74 | #include <net/netdma.h> |
| 75 | #include <net/secure_seq.h> | ||
| 75 | 76 | ||
| 76 | #include <linux/inet.h> | 77 | #include <linux/inet.h> |
| 77 | #include <linux/ipv6.h> | 78 | #include <linux/ipv6.h> |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index a55500cc0b29..f012ebd87b43 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -656,7 +656,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, | |||
| 656 | * layer address of our nexhop router | 656 | * layer address of our nexhop router |
| 657 | */ | 657 | */ |
| 658 | 658 | ||
| 659 | if (dst_get_neighbour(&rt->dst) == NULL) | 659 | if (dst_get_neighbour_raw(&rt->dst) == NULL) |
| 660 | ifa->flags &= ~IFA_F_OPTIMISTIC; | 660 | ifa->flags &= ~IFA_F_OPTIMISTIC; |
| 661 | 661 | ||
| 662 | ifa->idev = idev; | 662 | ifa->idev = idev; |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 16560336eb72..9ef1831746ef 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
| @@ -33,6 +33,11 @@ | |||
| 33 | #include <linux/errqueue.h> | 33 | #include <linux/errqueue.h> |
| 34 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
| 35 | 35 | ||
| 36 | static inline int ipv6_mapped_addr_any(const struct in6_addr *a) | ||
| 37 | { | ||
| 38 | return (ipv6_addr_v4mapped(a) && (a->s6_addr32[3] == 0)); | ||
| 39 | } | ||
| 40 | |||
| 36 | int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | 41 | int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
| 37 | { | 42 | { |
| 38 | struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; | 43 | struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; |
| @@ -102,10 +107,12 @@ ipv4_connected: | |||
| 102 | 107 | ||
| 103 | ipv6_addr_set_v4mapped(inet->inet_daddr, &np->daddr); | 108 | ipv6_addr_set_v4mapped(inet->inet_daddr, &np->daddr); |
| 104 | 109 | ||
| 105 | if (ipv6_addr_any(&np->saddr)) | 110 | if (ipv6_addr_any(&np->saddr) || |
| 111 | ipv6_mapped_addr_any(&np->saddr)) | ||
| 106 | ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr); | 112 | ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr); |
| 107 | 113 | ||
| 108 | if (ipv6_addr_any(&np->rcv_saddr)) { | 114 | if (ipv6_addr_any(&np->rcv_saddr) || |
| 115 | ipv6_mapped_addr_any(&np->rcv_saddr)) { | ||
| 109 | ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, | 116 | ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, |
| 110 | &np->rcv_saddr); | 117 | &np->rcv_saddr); |
| 111 | if (sk->sk_prot->rehash) | 118 | if (sk->sk_prot->rehash) |
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index b53197233709..73f1a00a96af 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <net/inet_connection_sock.h> | 20 | #include <net/inet_connection_sock.h> |
| 21 | #include <net/inet_hashtables.h> | 21 | #include <net/inet_hashtables.h> |
| 22 | #include <net/inet6_hashtables.h> | 22 | #include <net/inet6_hashtables.h> |
| 23 | #include <net/secure_seq.h> | ||
| 23 | #include <net/ip.h> | 24 | #include <net/ip.h> |
| 24 | 25 | ||
| 25 | int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw) | 26 | int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw) |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 54a4678955bf..320d91d20ad7 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
| @@ -1455,7 +1455,7 @@ static int fib6_age(struct rt6_info *rt, void *arg) | |||
| 1455 | RT6_TRACE("aging clone %p\n", rt); | 1455 | RT6_TRACE("aging clone %p\n", rt); |
| 1456 | return -1; | 1456 | return -1; |
| 1457 | } else if ((rt->rt6i_flags & RTF_GATEWAY) && | 1457 | } else if ((rt->rt6i_flags & RTF_GATEWAY) && |
| 1458 | (!(dst_get_neighbour(&rt->dst)->flags & NTF_ROUTER))) { | 1458 | (!(dst_get_neighbour_raw(&rt->dst)->flags & NTF_ROUTER))) { |
| 1459 | RT6_TRACE("purging route %p via non-router but gateway\n", | 1459 | RT6_TRACE("purging route %p via non-router but gateway\n", |
| 1460 | rt); | 1460 | rt); |
| 1461 | return -1; | 1461 | return -1; |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 32e5339db0c8..4c882cf4e8a1 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -135,10 +135,15 @@ static int ip6_finish_output2(struct sk_buff *skb) | |||
| 135 | skb->len); | 135 | skb->len); |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | rcu_read_lock(); | ||
| 138 | neigh = dst_get_neighbour(dst); | 139 | neigh = dst_get_neighbour(dst); |
| 139 | if (neigh) | 140 | if (neigh) { |
| 140 | return neigh_output(neigh, skb); | 141 | int res = neigh_output(neigh, skb); |
| 141 | 142 | ||
| 143 | rcu_read_unlock(); | ||
| 144 | return res; | ||
| 145 | } | ||
| 146 | rcu_read_unlock(); | ||
| 142 | IP6_INC_STATS_BH(dev_net(dst->dev), | 147 | IP6_INC_STATS_BH(dev_net(dst->dev), |
| 143 | ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); | 148 | ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); |
| 144 | kfree_skb(skb); | 149 | kfree_skb(skb); |
| @@ -975,12 +980,14 @@ static int ip6_dst_lookup_tail(struct sock *sk, | |||
| 975 | * dst entry and replace it instead with the | 980 | * dst entry and replace it instead with the |
| 976 | * dst entry of the nexthop router | 981 | * dst entry of the nexthop router |
| 977 | */ | 982 | */ |
| 983 | rcu_read_lock(); | ||
| 978 | n = dst_get_neighbour(*dst); | 984 | n = dst_get_neighbour(*dst); |
| 979 | if (n && !(n->nud_state & NUD_VALID)) { | 985 | if (n && !(n->nud_state & NUD_VALID)) { |
| 980 | struct inet6_ifaddr *ifp; | 986 | struct inet6_ifaddr *ifp; |
| 981 | struct flowi6 fl_gw6; | 987 | struct flowi6 fl_gw6; |
| 982 | int redirect; | 988 | int redirect; |
| 983 | 989 | ||
| 990 | rcu_read_unlock(); | ||
| 984 | ifp = ipv6_get_ifaddr(net, &fl6->saddr, | 991 | ifp = ipv6_get_ifaddr(net, &fl6->saddr, |
| 985 | (*dst)->dev, 1); | 992 | (*dst)->dev, 1); |
| 986 | 993 | ||
| @@ -1000,6 +1007,8 @@ static int ip6_dst_lookup_tail(struct sock *sk, | |||
| 1000 | if ((err = (*dst)->error)) | 1007 | if ((err = (*dst)->error)) |
| 1001 | goto out_err_release; | 1008 | goto out_err_release; |
| 1002 | } | 1009 | } |
| 1010 | } else { | ||
| 1011 | rcu_read_unlock(); | ||
| 1003 | } | 1012 | } |
| 1004 | #endif | 1013 | #endif |
| 1005 | 1014 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index e8987da06667..9e69eb0ec6dd 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -364,7 +364,7 @@ out: | |||
| 364 | #ifdef CONFIG_IPV6_ROUTER_PREF | 364 | #ifdef CONFIG_IPV6_ROUTER_PREF |
| 365 | static void rt6_probe(struct rt6_info *rt) | 365 | static void rt6_probe(struct rt6_info *rt) |
| 366 | { | 366 | { |
| 367 | struct neighbour *neigh = rt ? dst_get_neighbour(&rt->dst) : NULL; | 367 | struct neighbour *neigh; |
| 368 | /* | 368 | /* |
| 369 | * Okay, this does not seem to be appropriate | 369 | * Okay, this does not seem to be appropriate |
| 370 | * for now, however, we need to check if it | 370 | * for now, however, we need to check if it |
| @@ -373,8 +373,10 @@ static void rt6_probe(struct rt6_info *rt) | |||
| 373 | * Router Reachability Probe MUST be rate-limited | 373 | * Router Reachability Probe MUST be rate-limited |
| 374 | * to no more than one per minute. | 374 | * to no more than one per minute. |
| 375 | */ | 375 | */ |
| 376 | rcu_read_lock(); | ||
| 377 | neigh = rt ? dst_get_neighbour(&rt->dst) : NULL; | ||
| 376 | if (!neigh || (neigh->nud_state & NUD_VALID)) | 378 | if (!neigh || (neigh->nud_state & NUD_VALID)) |
| 377 | return; | 379 | goto out; |
| 378 | read_lock_bh(&neigh->lock); | 380 | read_lock_bh(&neigh->lock); |
| 379 | if (!(neigh->nud_state & NUD_VALID) && | 381 | if (!(neigh->nud_state & NUD_VALID) && |
| 380 | time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { | 382 | time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { |
| @@ -387,8 +389,11 @@ static void rt6_probe(struct rt6_info *rt) | |||
| 387 | target = (struct in6_addr *)&neigh->primary_key; | 389 | target = (struct in6_addr *)&neigh->primary_key; |
| 388 | addrconf_addr_solict_mult(target, &mcaddr); | 390 | addrconf_addr_solict_mult(target, &mcaddr); |
| 389 | ndisc_send_ns(rt->rt6i_dev, NULL, target, &mcaddr, NULL); | 391 | ndisc_send_ns(rt->rt6i_dev, NULL, target, &mcaddr, NULL); |
| 390 | } else | 392 | } else { |
| 391 | read_unlock_bh(&neigh->lock); | 393 | read_unlock_bh(&neigh->lock); |
| 394 | } | ||
| 395 | out: | ||
| 396 | rcu_read_unlock(); | ||
| 392 | } | 397 | } |
| 393 | #else | 398 | #else |
| 394 | static inline void rt6_probe(struct rt6_info *rt) | 399 | static inline void rt6_probe(struct rt6_info *rt) |
| @@ -412,8 +417,11 @@ static inline int rt6_check_dev(struct rt6_info *rt, int oif) | |||
| 412 | 417 | ||
| 413 | static inline int rt6_check_neigh(struct rt6_info *rt) | 418 | static inline int rt6_check_neigh(struct rt6_info *rt) |
| 414 | { | 419 | { |
| 415 | struct neighbour *neigh = dst_get_neighbour(&rt->dst); | 420 | struct neighbour *neigh; |
| 416 | int m; | 421 | int m; |
| 422 | |||
| 423 | rcu_read_lock(); | ||
| 424 | neigh = dst_get_neighbour(&rt->dst); | ||
| 417 | if (rt->rt6i_flags & RTF_NONEXTHOP || | 425 | if (rt->rt6i_flags & RTF_NONEXTHOP || |
| 418 | !(rt->rt6i_flags & RTF_GATEWAY)) | 426 | !(rt->rt6i_flags & RTF_GATEWAY)) |
| 419 | m = 1; | 427 | m = 1; |
| @@ -430,6 +438,7 @@ static inline int rt6_check_neigh(struct rt6_info *rt) | |||
| 430 | read_unlock_bh(&neigh->lock); | 438 | read_unlock_bh(&neigh->lock); |
| 431 | } else | 439 | } else |
| 432 | m = 0; | 440 | m = 0; |
| 441 | rcu_read_unlock(); | ||
| 433 | return m; | 442 | return m; |
| 434 | } | 443 | } |
| 435 | 444 | ||
| @@ -769,7 +778,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, | |||
| 769 | rt->rt6i_dst.plen = 128; | 778 | rt->rt6i_dst.plen = 128; |
| 770 | rt->rt6i_flags |= RTF_CACHE; | 779 | rt->rt6i_flags |= RTF_CACHE; |
| 771 | rt->dst.flags |= DST_HOST; | 780 | rt->dst.flags |= DST_HOST; |
| 772 | dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour(&ort->dst))); | 781 | dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour_raw(&ort->dst))); |
| 773 | } | 782 | } |
| 774 | return rt; | 783 | return rt; |
| 775 | } | 784 | } |
| @@ -803,7 +812,7 @@ restart: | |||
| 803 | dst_hold(&rt->dst); | 812 | dst_hold(&rt->dst); |
| 804 | read_unlock_bh(&table->tb6_lock); | 813 | read_unlock_bh(&table->tb6_lock); |
| 805 | 814 | ||
| 806 | if (!dst_get_neighbour(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) | 815 | if (!dst_get_neighbour_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) |
| 807 | nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); | 816 | nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); |
| 808 | else if (!(rt->dst.flags & DST_HOST)) | 817 | else if (!(rt->dst.flags & DST_HOST)) |
| 809 | nrt = rt6_alloc_clone(rt, &fl6->daddr); | 818 | nrt = rt6_alloc_clone(rt, &fl6->daddr); |
| @@ -1587,7 +1596,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src, | |||
| 1587 | dst_confirm(&rt->dst); | 1596 | dst_confirm(&rt->dst); |
| 1588 | 1597 | ||
| 1589 | /* Duplicate redirect: silently ignore. */ | 1598 | /* Duplicate redirect: silently ignore. */ |
| 1590 | if (neigh == dst_get_neighbour(&rt->dst)) | 1599 | if (neigh == dst_get_neighbour_raw(&rt->dst)) |
| 1591 | goto out; | 1600 | goto out; |
| 1592 | 1601 | ||
| 1593 | nrt = ip6_rt_copy(rt, dest); | 1602 | nrt = ip6_rt_copy(rt, dest); |
| @@ -1682,7 +1691,7 @@ again: | |||
| 1682 | 1. It is connected route. Action: COW | 1691 | 1. It is connected route. Action: COW |
| 1683 | 2. It is gatewayed route or NONEXTHOP route. Action: clone it. | 1692 | 2. It is gatewayed route or NONEXTHOP route. Action: clone it. |
| 1684 | */ | 1693 | */ |
| 1685 | if (!dst_get_neighbour(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) | 1694 | if (!dst_get_neighbour_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) |
| 1686 | nrt = rt6_alloc_cow(rt, daddr, saddr); | 1695 | nrt = rt6_alloc_cow(rt, daddr, saddr); |
| 1687 | else | 1696 | else |
| 1688 | nrt = rt6_alloc_clone(rt, daddr); | 1697 | nrt = rt6_alloc_clone(rt, daddr); |
| @@ -2326,6 +2335,7 @@ static int rt6_fill_node(struct net *net, | |||
| 2326 | struct nlmsghdr *nlh; | 2335 | struct nlmsghdr *nlh; |
| 2327 | long expires; | 2336 | long expires; |
| 2328 | u32 table; | 2337 | u32 table; |
| 2338 | struct neighbour *n; | ||
| 2329 | 2339 | ||
| 2330 | if (prefix) { /* user wants prefix routes only */ | 2340 | if (prefix) { /* user wants prefix routes only */ |
| 2331 | if (!(rt->rt6i_flags & RTF_PREFIX_RT)) { | 2341 | if (!(rt->rt6i_flags & RTF_PREFIX_RT)) { |
| @@ -2414,8 +2424,11 @@ static int rt6_fill_node(struct net *net, | |||
| 2414 | if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) | 2424 | if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) |
| 2415 | goto nla_put_failure; | 2425 | goto nla_put_failure; |
| 2416 | 2426 | ||
| 2417 | if (dst_get_neighbour(&rt->dst)) | 2427 | rcu_read_lock(); |
| 2418 | NLA_PUT(skb, RTA_GATEWAY, 16, &dst_get_neighbour(&rt->dst)->primary_key); | 2428 | n = dst_get_neighbour(&rt->dst); |
| 2429 | if (n) | ||
| 2430 | NLA_PUT(skb, RTA_GATEWAY, 16, &n->primary_key); | ||
| 2431 | rcu_read_unlock(); | ||
| 2419 | 2432 | ||
| 2420 | if (rt->dst.dev) | 2433 | if (rt->dst.dev) |
| 2421 | NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex); | 2434 | NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex); |
| @@ -2608,12 +2621,14 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg) | |||
| 2608 | #else | 2621 | #else |
| 2609 | seq_puts(m, "00000000000000000000000000000000 00 "); | 2622 | seq_puts(m, "00000000000000000000000000000000 00 "); |
| 2610 | #endif | 2623 | #endif |
| 2624 | rcu_read_lock(); | ||
| 2611 | n = dst_get_neighbour(&rt->dst); | 2625 | n = dst_get_neighbour(&rt->dst); |
| 2612 | if (n) { | 2626 | if (n) { |
| 2613 | seq_printf(m, "%pi6", n->primary_key); | 2627 | seq_printf(m, "%pi6", n->primary_key); |
| 2614 | } else { | 2628 | } else { |
| 2615 | seq_puts(m, "00000000000000000000000000000000"); | 2629 | seq_puts(m, "00000000000000000000000000000000"); |
| 2616 | } | 2630 | } |
| 2631 | rcu_read_unlock(); | ||
| 2617 | seq_printf(m, " %08x %08x %08x %08x %8s\n", | 2632 | seq_printf(m, " %08x %08x %08x %08x %8s\n", |
| 2618 | rt->rt6i_metric, atomic_read(&rt->dst.__refcnt), | 2633 | rt->rt6i_metric, atomic_read(&rt->dst.__refcnt), |
| 2619 | rt->dst.__use, rt->rt6i_flags, | 2634 | rt->dst.__use, rt->rt6i_flags, |
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 89d5bf806222..ac838965ff34 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c | |||
| @@ -165,7 +165,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
| 165 | int mss; | 165 | int mss; |
| 166 | struct dst_entry *dst; | 166 | struct dst_entry *dst; |
| 167 | __u8 rcv_wscale; | 167 | __u8 rcv_wscale; |
| 168 | bool ecn_ok; | 168 | bool ecn_ok = false; |
| 169 | 169 | ||
| 170 | if (!sysctl_tcp_syncookies || !th->ack || th->rst) | 170 | if (!sysctl_tcp_syncookies || !th->ack || th->rst) |
| 171 | goto out; | 171 | goto out; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 78aa53492b3e..d1fb63f4aeb7 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -61,6 +61,7 @@ | |||
| 61 | #include <net/timewait_sock.h> | 61 | #include <net/timewait_sock.h> |
| 62 | #include <net/netdma.h> | 62 | #include <net/netdma.h> |
| 63 | #include <net/inet_common.h> | 63 | #include <net/inet_common.h> |
| 64 | #include <net/secure_seq.h> | ||
| 64 | 65 | ||
| 65 | #include <asm/uaccess.h> | 66 | #include <asm/uaccess.h> |
| 66 | 67 | ||
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index be43fd805bd0..2b771dc708a3 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
| @@ -3771,6 +3771,7 @@ err_sock: | |||
| 3771 | void ip_vs_control_cleanup(void) | 3771 | void ip_vs_control_cleanup(void) |
| 3772 | { | 3772 | { |
| 3773 | EnterFunction(2); | 3773 | EnterFunction(2); |
| 3774 | unregister_netdevice_notifier(&ip_vs_dst_notifier); | ||
| 3774 | ip_vs_genl_unregister(); | 3775 | ip_vs_genl_unregister(); |
| 3775 | nf_unregister_sockopt(&ip_vs_sockopts); | 3776 | nf_unregister_sockopt(&ip_vs_sockopts); |
| 3776 | LeaveFunction(2); | 3777 | LeaveFunction(2); |
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index 5b466cd1272f..84d0fd47636a 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c | |||
| @@ -312,6 +312,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) | |||
| 312 | } | 312 | } |
| 313 | break; | 313 | break; |
| 314 | case NF_STOLEN: | 314 | case NF_STOLEN: |
| 315 | break; | ||
| 315 | default: | 316 | default: |
| 316 | kfree_skb(skb); | 317 | kfree_skb(skb); |
| 317 | } | 318 | } |
diff --git a/net/netlabel/Makefile b/net/netlabel/Makefile index ea750e9df65f..d2732fc952e2 100644 --- a/net/netlabel/Makefile +++ b/net/netlabel/Makefile | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | # | 1 | # |
| 2 | # Makefile for the NetLabel subsystem. | 2 | # Makefile for the NetLabel subsystem. |
| 3 | # | 3 | # |
| 4 | # Feb 9, 2006, Paul Moore <paul.moore@hp.com> | ||
| 5 | # | ||
| 6 | 4 | ||
| 7 | # base objects | 5 | # base objects |
| 8 | obj-y := netlabel_user.o netlabel_kapi.o | 6 | obj-y := netlabel_user.o netlabel_kapi.o |
diff --git a/net/netlabel/netlabel_addrlist.c b/net/netlabel/netlabel_addrlist.c index c0519139679e..96b749dacc34 100644 --- a/net/netlabel/netlabel_addrlist.c +++ b/net/netlabel/netlabel_addrlist.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * system manages static and dynamic label mappings for network protocols such | 6 | * system manages static and dynamic label mappings for network protocols such |
| 7 | * as CIPSO and RIPSO. | 7 | * as CIPSO and RIPSO. |
| 8 | * | 8 | * |
| 9 | * Author: Paul Moore <paul.moore@hp.com> | 9 | * Author: Paul Moore <paul@paul-moore.com> |
| 10 | * | 10 | * |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
diff --git a/net/netlabel/netlabel_addrlist.h b/net/netlabel/netlabel_addrlist.h index 2b9644e19de0..fdbc1d2c7352 100644 --- a/net/netlabel/netlabel_addrlist.h +++ b/net/netlabel/netlabel_addrlist.h | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * system manages static and dynamic label mappings for network protocols such | 6 | * system manages static and dynamic label mappings for network protocols such |
| 7 | * as CIPSO and RIPSO. | 7 | * as CIPSO and RIPSO. |
| 8 | * | 8 | * |
| 9 | * Author: Paul Moore <paul.moore@hp.com> | 9 | * Author: Paul Moore <paul@paul-moore.com> |
| 10 | * | 10 | * |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index dd53a36d89af..6bf878335d94 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * NetLabel system manages static and dynamic label mappings for network | 5 | * NetLabel system manages static and dynamic label mappings for network |
| 6 | * protocols such as CIPSO and RIPSO. | 6 | * protocols such as CIPSO and RIPSO. |
| 7 | * | 7 | * |
| 8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
| 9 | * | 9 | * |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
diff --git a/net/netlabel/netlabel_cipso_v4.h b/net/netlabel/netlabel_cipso_v4.h index af7f3355103e..d24d774bfd62 100644 --- a/net/netlabel/netlabel_cipso_v4.h +++ b/net/netlabel/netlabel_cipso_v4.h | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * NetLabel system manages static and dynamic label mappings for network | 5 | * NetLabel system manages static and dynamic label mappings for network |
| 6 | * protocols such as CIPSO and RIPSO. | 6 | * protocols such as CIPSO and RIPSO. |
| 7 | * | 7 | * |
| 8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
| 9 | * | 9 | * |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index 2aa975e5452d..7d8083cde34f 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * system manages static and dynamic label mappings for network protocols such | 6 | * system manages static and dynamic label mappings for network protocols such |
| 7 | * as CIPSO and RIPSO. | 7 | * as CIPSO and RIPSO. |
| 8 | * | 8 | * |
| 9 | * Author: Paul Moore <paul.moore@hp.com> | 9 | * Author: Paul Moore <paul@paul-moore.com> |
| 10 | * | 10 | * |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
diff --git a/net/netlabel/netlabel_domainhash.h b/net/netlabel/netlabel_domainhash.h index 0261dda3f2d2..bfcc0f7024c5 100644 --- a/net/netlabel/netlabel_domainhash.h +++ b/net/netlabel/netlabel_domainhash.h | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * system manages static and dynamic label mappings for network protocols such | 6 | * system manages static and dynamic label mappings for network protocols such |
| 7 | * as CIPSO and RIPSO. | 7 | * as CIPSO and RIPSO. |
| 8 | * | 8 | * |
| 9 | * Author: Paul Moore <paul.moore@hp.com> | 9 | * Author: Paul Moore <paul@paul-moore.com> |
| 10 | * | 10 | * |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index b528dd928d3c..9c24de10a657 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * system manages static and dynamic label mappings for network protocols such | 5 | * system manages static and dynamic label mappings for network protocols such |
| 6 | * as CIPSO and RIPSO. | 6 | * as CIPSO and RIPSO. |
| 7 | * | 7 | * |
| 8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
| 9 | * | 9 | * |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| @@ -341,11 +341,11 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, | |||
| 341 | 341 | ||
| 342 | entry = kzalloc(sizeof(*entry), GFP_ATOMIC); | 342 | entry = kzalloc(sizeof(*entry), GFP_ATOMIC); |
| 343 | if (entry == NULL) | 343 | if (entry == NULL) |
| 344 | return -ENOMEM; | 344 | goto out_entry; |
| 345 | if (domain != NULL) { | 345 | if (domain != NULL) { |
| 346 | entry->domain = kstrdup(domain, GFP_ATOMIC); | 346 | entry->domain = kstrdup(domain, GFP_ATOMIC); |
| 347 | if (entry->domain == NULL) | 347 | if (entry->domain == NULL) |
| 348 | goto cfg_cipsov4_map_add_failure; | 348 | goto out_domain; |
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | if (addr == NULL && mask == NULL) { | 351 | if (addr == NULL && mask == NULL) { |
| @@ -354,13 +354,13 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, | |||
| 354 | } else if (addr != NULL && mask != NULL) { | 354 | } else if (addr != NULL && mask != NULL) { |
| 355 | addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); | 355 | addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); |
| 356 | if (addrmap == NULL) | 356 | if (addrmap == NULL) |
| 357 | goto cfg_cipsov4_map_add_failure; | 357 | goto out_addrmap; |
| 358 | INIT_LIST_HEAD(&addrmap->list4); | 358 | INIT_LIST_HEAD(&addrmap->list4); |
| 359 | INIT_LIST_HEAD(&addrmap->list6); | 359 | INIT_LIST_HEAD(&addrmap->list6); |
| 360 | 360 | ||
| 361 | addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC); | 361 | addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC); |
| 362 | if (addrinfo == NULL) | 362 | if (addrinfo == NULL) |
| 363 | goto cfg_cipsov4_map_add_failure; | 363 | goto out_addrinfo; |
| 364 | addrinfo->type_def.cipsov4 = doi_def; | 364 | addrinfo->type_def.cipsov4 = doi_def; |
| 365 | addrinfo->type = NETLBL_NLTYPE_CIPSOV4; | 365 | addrinfo->type = NETLBL_NLTYPE_CIPSOV4; |
| 366 | addrinfo->list.addr = addr->s_addr & mask->s_addr; | 366 | addrinfo->list.addr = addr->s_addr & mask->s_addr; |
| @@ -374,7 +374,7 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, | |||
| 374 | entry->type = NETLBL_NLTYPE_ADDRSELECT; | 374 | entry->type = NETLBL_NLTYPE_ADDRSELECT; |
| 375 | } else { | 375 | } else { |
| 376 | ret_val = -EINVAL; | 376 | ret_val = -EINVAL; |
| 377 | goto cfg_cipsov4_map_add_failure; | 377 | goto out_addrmap; |
| 378 | } | 378 | } |
| 379 | 379 | ||
| 380 | ret_val = netlbl_domhsh_add(entry, audit_info); | 380 | ret_val = netlbl_domhsh_add(entry, audit_info); |
| @@ -384,11 +384,15 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, | |||
| 384 | return 0; | 384 | return 0; |
| 385 | 385 | ||
| 386 | cfg_cipsov4_map_add_failure: | 386 | cfg_cipsov4_map_add_failure: |
| 387 | cipso_v4_doi_putdef(doi_def); | 387 | kfree(addrinfo); |
| 388 | out_addrinfo: | ||
| 389 | kfree(addrmap); | ||
| 390 | out_addrmap: | ||
| 388 | kfree(entry->domain); | 391 | kfree(entry->domain); |
| 392 | out_domain: | ||
| 389 | kfree(entry); | 393 | kfree(entry); |
| 390 | kfree(addrmap); | 394 | out_entry: |
| 391 | kfree(addrinfo); | 395 | cipso_v4_doi_putdef(doi_def); |
| 392 | return ret_val; | 396 | return ret_val; |
| 393 | } | 397 | } |
| 394 | 398 | ||
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index dff8a0809245..bfa555869775 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * NetLabel system manages static and dynamic label mappings for network | 5 | * NetLabel system manages static and dynamic label mappings for network |
| 6 | * protocols such as CIPSO and RIPSO. | 6 | * protocols such as CIPSO and RIPSO. |
| 7 | * | 7 | * |
| 8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
| 9 | * | 9 | * |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
diff --git a/net/netlabel/netlabel_mgmt.h b/net/netlabel/netlabel_mgmt.h index 8db37f4c10f7..5a9f31ce5799 100644 --- a/net/netlabel/netlabel_mgmt.h +++ b/net/netlabel/netlabel_mgmt.h | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * NetLabel system manages static and dynamic label mappings for network | 5 | * NetLabel system manages static and dynamic label mappings for network |
| 6 | * protocols such as CIPSO and RIPSO. | 6 | * protocols such as CIPSO and RIPSO. |
| 7 | * | 7 | * |
| 8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
| 9 | * | 9 | * |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index f1ecf848e3ac..e6e823656f9d 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * NetLabel system. The NetLabel system manages static and dynamic label | 5 | * NetLabel system. The NetLabel system manages static and dynamic label |
| 6 | * mappings for network protocols such as CIPSO and RIPSO. | 6 | * mappings for network protocols such as CIPSO and RIPSO. |
| 7 | * | 7 | * |
| 8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
| 9 | * | 9 | * |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
diff --git a/net/netlabel/netlabel_unlabeled.h b/net/netlabel/netlabel_unlabeled.h index 0bc8dc3f9e3c..700af49022a0 100644 --- a/net/netlabel/netlabel_unlabeled.h +++ b/net/netlabel/netlabel_unlabeled.h | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * NetLabel system. The NetLabel system manages static and dynamic label | 5 | * NetLabel system. The NetLabel system manages static and dynamic label |
| 6 | * mappings for network protocols such as CIPSO and RIPSO. | 6 | * mappings for network protocols such as CIPSO and RIPSO. |
| 7 | * | 7 | * |
| 8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
| 9 | * | 9 | * |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index a3fd75ac3fa5..9fae63f10298 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * NetLabel system manages static and dynamic label mappings for network | 5 | * NetLabel system manages static and dynamic label mappings for network |
| 6 | * protocols such as CIPSO and RIPSO. | 6 | * protocols such as CIPSO and RIPSO. |
| 7 | * | 7 | * |
| 8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
| 9 | * | 9 | * |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h index f4fc4c9ad567..81969785e279 100644 --- a/net/netlabel/netlabel_user.h +++ b/net/netlabel/netlabel_user.h | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * NetLabel system manages static and dynamic label mappings for network | 5 | * NetLabel system manages static and dynamic label mappings for network |
| 6 | * protocols such as CIPSO and RIPSO. | 6 | * protocols such as CIPSO and RIPSO. |
| 7 | * | 7 | * |
| 8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
| 9 | * | 9 | * |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 2a318f2dc3e5..b5d56a22b1d2 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c | |||
| @@ -112,7 +112,7 @@ static struct sk_buff *prio_dequeue(struct Qdisc *sch) | |||
| 112 | 112 | ||
| 113 | for (prio = 0; prio < q->bands; prio++) { | 113 | for (prio = 0; prio < q->bands; prio++) { |
| 114 | struct Qdisc *qdisc = q->queues[prio]; | 114 | struct Qdisc *qdisc = q->queues[prio]; |
| 115 | struct sk_buff *skb = qdisc->dequeue(qdisc); | 115 | struct sk_buff *skb = qdisc_dequeue_peeked(qdisc); |
| 116 | if (skb) { | 116 | if (skb) { |
| 117 | qdisc_bstats_update(sch, skb); | 117 | qdisc_bstats_update(sch, skb); |
| 118 | sch->q.qlen--; | 118 | sch->q.qlen--; |
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 4536ee64383e..4f5510e2bd6f 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
| @@ -410,7 +410,12 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 410 | /* Return Congestion Notification only if we dropped a packet | 410 | /* Return Congestion Notification only if we dropped a packet |
| 411 | * from this flow. | 411 | * from this flow. |
| 412 | */ | 412 | */ |
| 413 | return (qlen != slot->qlen) ? NET_XMIT_CN : NET_XMIT_SUCCESS; | 413 | if (qlen != slot->qlen) |
| 414 | return NET_XMIT_CN; | ||
| 415 | |||
| 416 | /* As we dropped a packet, better let upper stack know this */ | ||
| 417 | qdisc_tree_decrease_qlen(sch, 1); | ||
| 418 | return NET_XMIT_SUCCESS; | ||
| 414 | } | 419 | } |
| 415 | 420 | ||
| 416 | static struct sk_buff * | 421 | static struct sk_buff * |
diff --git a/net/socket.c b/net/socket.c index b1cbbcd92558..24a77400b65e 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -1871,8 +1871,14 @@ SYSCALL_DEFINE2(shutdown, int, fd, int, how) | |||
| 1871 | #define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen) | 1871 | #define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen) |
| 1872 | #define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags) | 1872 | #define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags) |
| 1873 | 1873 | ||
| 1874 | struct used_address { | ||
| 1875 | struct sockaddr_storage name; | ||
| 1876 | unsigned int name_len; | ||
| 1877 | }; | ||
| 1878 | |||
| 1874 | static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, | 1879 | static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, |
| 1875 | struct msghdr *msg_sys, unsigned flags, int nosec) | 1880 | struct msghdr *msg_sys, unsigned flags, |
| 1881 | struct used_address *used_address) | ||
| 1876 | { | 1882 | { |
| 1877 | struct compat_msghdr __user *msg_compat = | 1883 | struct compat_msghdr __user *msg_compat = |
| 1878 | (struct compat_msghdr __user *)msg; | 1884 | (struct compat_msghdr __user *)msg; |
| @@ -1953,8 +1959,28 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, | |||
| 1953 | 1959 | ||
| 1954 | if (sock->file->f_flags & O_NONBLOCK) | 1960 | if (sock->file->f_flags & O_NONBLOCK) |
| 1955 | msg_sys->msg_flags |= MSG_DONTWAIT; | 1961 | msg_sys->msg_flags |= MSG_DONTWAIT; |
| 1956 | err = (nosec ? sock_sendmsg_nosec : sock_sendmsg)(sock, msg_sys, | 1962 | /* |
| 1957 | total_len); | 1963 | * If this is sendmmsg() and current destination address is same as |
| 1964 | * previously succeeded address, omit asking LSM's decision. | ||
| 1965 | * used_address->name_len is initialized to UINT_MAX so that the first | ||
| 1966 | * destination address never matches. | ||
| 1967 | */ | ||
| 1968 | if (used_address && used_address->name_len == msg_sys->msg_namelen && | ||
| 1969 | !memcmp(&used_address->name, msg->msg_name, | ||
| 1970 | used_address->name_len)) { | ||
| 1971 | err = sock_sendmsg_nosec(sock, msg_sys, total_len); | ||
| 1972 | goto out_freectl; | ||
| 1973 | } | ||
| 1974 | err = sock_sendmsg(sock, msg_sys, total_len); | ||
| 1975 | /* | ||
| 1976 | * If this is sendmmsg() and sending to current destination address was | ||
| 1977 | * successful, remember it. | ||
| 1978 | */ | ||
| 1979 | if (used_address && err >= 0) { | ||
| 1980 | used_address->name_len = msg_sys->msg_namelen; | ||
| 1981 | memcpy(&used_address->name, msg->msg_name, | ||
| 1982 | used_address->name_len); | ||
| 1983 | } | ||
| 1958 | 1984 | ||
| 1959 | out_freectl: | 1985 | out_freectl: |
| 1960 | if (ctl_buf != ctl) | 1986 | if (ctl_buf != ctl) |
| @@ -1979,7 +2005,7 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) | |||
| 1979 | if (!sock) | 2005 | if (!sock) |
| 1980 | goto out; | 2006 | goto out; |
| 1981 | 2007 | ||
| 1982 | err = __sys_sendmsg(sock, msg, &msg_sys, flags, 0); | 2008 | err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL); |
| 1983 | 2009 | ||
| 1984 | fput_light(sock->file, fput_needed); | 2010 | fput_light(sock->file, fput_needed); |
| 1985 | out: | 2011 | out: |
| @@ -1998,6 +2024,10 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
| 1998 | struct mmsghdr __user *entry; | 2024 | struct mmsghdr __user *entry; |
| 1999 | struct compat_mmsghdr __user *compat_entry; | 2025 | struct compat_mmsghdr __user *compat_entry; |
| 2000 | struct msghdr msg_sys; | 2026 | struct msghdr msg_sys; |
| 2027 | struct used_address used_address; | ||
| 2028 | |||
| 2029 | if (vlen > UIO_MAXIOV) | ||
| 2030 | vlen = UIO_MAXIOV; | ||
| 2001 | 2031 | ||
| 2002 | datagrams = 0; | 2032 | datagrams = 0; |
| 2003 | 2033 | ||
| @@ -2005,27 +2035,22 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
| 2005 | if (!sock) | 2035 | if (!sock) |
| 2006 | return err; | 2036 | return err; |
| 2007 | 2037 | ||
| 2008 | err = sock_error(sock->sk); | 2038 | used_address.name_len = UINT_MAX; |
| 2009 | if (err) | ||
| 2010 | goto out_put; | ||
| 2011 | |||
| 2012 | entry = mmsg; | 2039 | entry = mmsg; |
| 2013 | compat_entry = (struct compat_mmsghdr __user *)mmsg; | 2040 | compat_entry = (struct compat_mmsghdr __user *)mmsg; |
| 2041 | err = 0; | ||
| 2014 | 2042 | ||
| 2015 | while (datagrams < vlen) { | 2043 | while (datagrams < vlen) { |
| 2016 | /* | ||
| 2017 | * No need to ask LSM for more than the first datagram. | ||
| 2018 | */ | ||
| 2019 | if (MSG_CMSG_COMPAT & flags) { | 2044 | if (MSG_CMSG_COMPAT & flags) { |
| 2020 | err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, | 2045 | err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, |
| 2021 | &msg_sys, flags, datagrams); | 2046 | &msg_sys, flags, &used_address); |
| 2022 | if (err < 0) | 2047 | if (err < 0) |
| 2023 | break; | 2048 | break; |
| 2024 | err = __put_user(err, &compat_entry->msg_len); | 2049 | err = __put_user(err, &compat_entry->msg_len); |
| 2025 | ++compat_entry; | 2050 | ++compat_entry; |
| 2026 | } else { | 2051 | } else { |
| 2027 | err = __sys_sendmsg(sock, (struct msghdr __user *)entry, | 2052 | err = __sys_sendmsg(sock, (struct msghdr __user *)entry, |
| 2028 | &msg_sys, flags, datagrams); | 2053 | &msg_sys, flags, &used_address); |
| 2029 | if (err < 0) | 2054 | if (err < 0) |
| 2030 | break; | 2055 | break; |
| 2031 | err = put_user(err, &entry->msg_len); | 2056 | err = put_user(err, &entry->msg_len); |
| @@ -2037,29 +2062,11 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
| 2037 | ++datagrams; | 2062 | ++datagrams; |
| 2038 | } | 2063 | } |
| 2039 | 2064 | ||
| 2040 | out_put: | ||
| 2041 | fput_light(sock->file, fput_needed); | 2065 | fput_light(sock->file, fput_needed); |
| 2042 | 2066 | ||
| 2043 | if (err == 0) | 2067 | /* We only return an error if no datagrams were able to be sent */ |
| 2044 | return datagrams; | 2068 | if (datagrams != 0) |
| 2045 | |||
| 2046 | if (datagrams != 0) { | ||
| 2047 | /* | ||
| 2048 | * We may send less entries than requested (vlen) if the | ||
| 2049 | * sock is non blocking... | ||
| 2050 | */ | ||
| 2051 | if (err != -EAGAIN) { | ||
| 2052 | /* | ||
| 2053 | * ... or if sendmsg returns an error after we | ||
| 2054 | * send some datagrams, where we record the | ||
| 2055 | * error to return on the next call or if the | ||
| 2056 | * app asks about it using getsockopt(SO_ERROR). | ||
| 2057 | */ | ||
| 2058 | sock->sk->sk_err = -err; | ||
| 2059 | } | ||
| 2060 | |||
| 2061 | return datagrams; | 2069 | return datagrams; |
| 2062 | } | ||
| 2063 | 2070 | ||
| 2064 | return err; | 2071 | return err; |
| 2065 | } | 2072 | } |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 9b6a4d1ea8f8..f4385e45a5fc 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
| @@ -187,6 +187,7 @@ EXPORT_SYMBOL_GPL(xprt_load_transport); | |||
| 187 | /** | 187 | /** |
| 188 | * xprt_reserve_xprt - serialize write access to transports | 188 | * xprt_reserve_xprt - serialize write access to transports |
| 189 | * @task: task that is requesting access to the transport | 189 | * @task: task that is requesting access to the transport |
| 190 | * @xprt: pointer to the target transport | ||
| 190 | * | 191 | * |
| 191 | * This prevents mixing the payload of separate requests, and prevents | 192 | * This prevents mixing the payload of separate requests, and prevents |
| 192 | * transport connects from colliding with writes. No congestion control | 193 | * transport connects from colliding with writes. No congestion control |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 28d2aa109bee..e83e7fee3bc0 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -3464,7 +3464,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
| 3464 | tmp) { | 3464 | tmp) { |
| 3465 | enum ieee80211_band band = nla_type(attr); | 3465 | enum ieee80211_band band = nla_type(attr); |
| 3466 | 3466 | ||
| 3467 | if (band < 0 || band > IEEE80211_NUM_BANDS) { | 3467 | if (band < 0 || band >= IEEE80211_NUM_BANDS) { |
| 3468 | err = -EINVAL; | 3468 | err = -EINVAL; |
| 3469 | goto out_free; | 3469 | goto out_free; |
| 3470 | } | 3470 | } |
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c index 58064d9e565d..791ab2e77f3f 100644 --- a/net/xfrm/xfrm_algo.c +++ b/net/xfrm/xfrm_algo.c | |||
| @@ -462,8 +462,8 @@ static struct xfrm_algo_desc ealg_list[] = { | |||
| 462 | .desc = { | 462 | .desc = { |
| 463 | .sadb_alg_id = SADB_X_EALG_AESCTR, | 463 | .sadb_alg_id = SADB_X_EALG_AESCTR, |
| 464 | .sadb_alg_ivlen = 8, | 464 | .sadb_alg_ivlen = 8, |
| 465 | .sadb_alg_minbits = 128, | 465 | .sadb_alg_minbits = 160, |
| 466 | .sadb_alg_maxbits = 256 | 466 | .sadb_alg_maxbits = 288 |
| 467 | } | 467 | } |
| 468 | }, | 468 | }, |
| 469 | }; | 469 | }; |
