git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
ipv6: stop sending PTB packets for MTU < 1280
[pandora-kernel.git]
/
net
/
ipv6
/
raw.c
diff --git
a/net/ipv6/raw.c
b/net/ipv6/raw.c
index
6f7824e
..
9287f3e
100644
(file)
--- a/
net/ipv6/raw.c
+++ b/
net/ipv6/raw.c
@@
-61,6
+61,7
@@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/export.h>
static struct raw_hashinfo raw_v6_hashinfo = {
.lock = __RW_LOCK_UNLOCKED(raw_v6_hashinfo.lock),
static struct raw_hashinfo raw_v6_hashinfo = {
.lock = __RW_LOCK_UNLOCKED(raw_v6_hashinfo.lock),
@@
-106,21
+107,20
@@
found:
* 0 - deliver
* 1 - block
*/
* 0 - deliver
* 1 - block
*/
-static
__inline__ int icmpv6_filter(struct sock *sk,
struct sk_buff *skb)
+static
int icmpv6_filter(const struct sock *sk, const
struct sk_buff *skb)
{
{
- struct icmp6hdr *icmph;
- struct raw6_sock *rp = raw6_sk(sk);
-
- if (pskb_may_pull(skb, sizeof(struct icmp6hdr))) {
- __u32 *data = &rp->filter.data[0];
- int bit_nr;
+ struct icmp6hdr *_hdr;
+ const struct icmp6hdr *hdr;
- icmph = (struct icmp6hdr *) skb->data;
- bit_nr = icmph->icmp6_type;
+ hdr = skb_header_pointer(skb, skb_transport_offset(skb),
+ sizeof(_hdr), &_hdr);
+ if (hdr) {
+ const __u32 *data = &raw6_sk(sk)->filter.data[0];
+ unsigned int type = hdr->icmp6_type;
- return (data[
bit_nr >> 5] & (1 << (bit_nr
& 31))) != 0;
+ return (data[
type >> 5] & (1U << (type
& 31))) != 0;
}
}
- return
0
;
+ return
1
;
}
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
}
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
@@
-130,7
+130,7
@@
static mh_filter_t __rcu *mh_filter __read_mostly;
int rawv6_mh_filter_register(mh_filter_t filter)
{
int rawv6_mh_filter_register(mh_filter_t filter)
{
-
RCU_INIT_POINTER
(mh_filter, filter);
+
rcu_assign_pointer
(mh_filter, filter);
return 0;
}
EXPORT_SYMBOL(rawv6_mh_filter_register);
return 0;
}
EXPORT_SYMBOL(rawv6_mh_filter_register);
@@
-456,14
+456,11
@@
static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
if (flags & MSG_OOB)
return -EOPNOTSUPP;
if (flags & MSG_OOB)
return -EOPNOTSUPP;
- if (addr_len)
- *addr_len=sizeof(*sin6);
-
if (flags & MSG_ERRQUEUE)
if (flags & MSG_ERRQUEUE)
- return ipv6_recv_error(sk, msg, len);
+ return ipv6_recv_error(sk, msg, len
, addr_len
);
if (np->rxpmtu && np->rxopt.bits.rxpmtu)
if (np->rxpmtu && np->rxopt.bits.rxpmtu)
- return ipv6_recv_rxpmtu(sk, msg, len);
+ return ipv6_recv_rxpmtu(sk, msg, len
, addr_len
);
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb)
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb)
@@
-498,6
+495,7
@@
static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
sin6->sin6_scope_id = 0;
if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
sin6->sin6_scope_id = IP6CB(skb)->iif;
sin6->sin6_scope_id = 0;
if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
sin6->sin6_scope_id = IP6CB(skb)->iif;
+ *addr_len = sizeof(*sin6);
}
sock_recv_ts_and_drops(msg, sk, skb);
}
sock_recv_ts_and_drops(msg, sk, skb);
@@
-609,6
+607,8
@@
static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
struct sk_buff *skb;
int err;
struct rt6_info *rt = (struct rt6_info *)*dstp;
struct sk_buff *skb;
int err;
struct rt6_info *rt = (struct rt6_info *)*dstp;
+ int hlen = LL_RESERVED_SPACE(rt->dst.dev);
+ int tlen = rt->dst.dev->needed_tailroom;
if (length > rt->dst.dev->mtu) {
ipv6_local_error(sk, EMSGSIZE, fl6, rt->dst.dev->mtu);
if (length > rt->dst.dev->mtu) {
ipv6_local_error(sk, EMSGSIZE, fl6, rt->dst.dev->mtu);
@@
-618,11
+618,11
@@
static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
goto out;
skb = sock_alloc_send_skb(sk,
goto out;
skb = sock_alloc_send_skb(sk,
- length +
LL_ALLOCATED_SPACE(rt->dst.dev)
+ 15,
+ length +
hlen + tlen
+ 15,
flags & MSG_DONTWAIT, &err);
if (skb == NULL)
goto error;
flags & MSG_DONTWAIT, &err);
if (skb == NULL)
goto error;
- skb_reserve(skb,
LL_RESERVED_SPACE(rt->dst.dev)
);
+ skb_reserve(skb,
hlen
);
skb->priority = sk->sk_priority;
skb->mark = sk->sk_mark;
skb->priority = sk->sk_priority;
skb->mark = sk->sk_mark;