diff options
Diffstat (limited to 'net/ipv6/raw.c')
-rw-r--r-- | net/ipv6/raw.c | 95 |
1 files changed, 52 insertions, 43 deletions
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 4ae1b19ada5..1f8f6275a7e 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -1,9 +1,9 @@ /* * RAW sockets for IPv6 - * Linux INET6 implementation + * Linux INET6 implementation * * Authors: - * Pedro Roque <roque@di.fc.ul.pt> + * Pedro Roque <roque@di.fc.ul.pt> * * Adapted from linux/net/ipv4/raw.c * @@ -11,7 +11,7 @@ * * Fixes: * Hideaki YOSHIFUJI : sin6_scope_id support - * YOSHIFUJI,H.@USAGI : raw checksum (RFC2292(bis) compliance) + * YOSHIFUJI,H.@USAGI : raw checksum (RFC2292(bis) compliance) * Kazunori MIYAZAWA @USAGI: change process style to use ip6_append_data * * This program is free software; you can redistribute it and/or @@ -71,12 +71,12 @@ static void raw_v6_hash(struct sock *sk) write_lock_bh(&raw_v6_lock); sk_add_node(sk, list); sock_prot_inc_use(sk->sk_prot); - write_unlock_bh(&raw_v6_lock); + write_unlock_bh(&raw_v6_lock); } static void raw_v6_unhash(struct sock *sk) { - write_lock_bh(&raw_v6_lock); + write_lock_bh(&raw_v6_lock); if (sk_del_node_init(sk)) sock_prot_dec_use(sk->sk_prot); write_unlock_bh(&raw_v6_lock); @@ -250,7 +250,7 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) */ sk->sk_bound_dev_if = addr->sin6_scope_id; } - + /* Binding to link-local address requires an interface */ if (!sk->sk_bound_dev_if) goto out; @@ -261,7 +261,7 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) goto out; } } - + /* ipv4 addr of the socket is invalid. Only the * unspecified and mapped address have a v4 equivalent. */ @@ -324,7 +324,7 @@ void rawv6_err(struct sock *sk, struct sk_buff *skb, static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb) { - if ((raw6_sk(sk)->checksum || sk->sk_filter) && + if ((raw6_sk(sk)->checksum || sk->sk_filter) && skb_checksum_complete(skb)) { /* FIXME: increment a raw6 drops counter here */ kfree_skb(skb); @@ -342,10 +342,10 @@ static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb) } /* - * This is next to useless... + * This is next to useless... * if we demultiplex in network layer we don't need the extra call - * just to queue the skb... - * maybe we could have the network decide upon a hint if it + * just to queue the skb... + * maybe we could have the network decide upon a hint if it * should call raw_rcv for demultiplexing */ int rawv6_rcv(struct sock *sk, struct sk_buff *skb) @@ -353,17 +353,17 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb) struct inet_sock *inet = inet_sk(sk); struct raw6_sock *rp = raw6_sk(sk); - if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) { - kfree_skb(skb); - return NET_RX_DROP; - } + if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) { + kfree_skb(skb); + return NET_RX_DROP; + } if (!rp->checksum) skb->ip_summed = CHECKSUM_UNNECESSARY; if (skb->ip_summed == CHECKSUM_COMPLETE) { skb_postpull_rcsum(skb, skb->nh.raw, - skb->h.raw - skb->nh.raw); + skb->h.raw - skb->nh.raw); if (!csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr, skb->len, inet->num, skb->csum)) @@ -404,8 +404,8 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, if (flags & MSG_OOB) return -EOPNOTSUPP; - - if (addr_len) + + if (addr_len) *addr_len=sizeof(*sin6); if (flags & MSG_ERRQUEUE) @@ -416,10 +416,10 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, goto out; copied = skb->len; - if (copied > len) { - copied = len; - msg->msg_flags |= MSG_TRUNC; - } + if (copied > len) { + copied = len; + msg->msg_flags |= MSG_TRUNC; + } if (skb->ip_summed==CHECKSUM_UNNECESSARY) { err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); @@ -549,7 +549,7 @@ out: } static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, - struct flowi *fl, struct rt6_info *rt, + struct flowi *fl, struct rt6_info *rt, unsigned int flags) { struct ipv6_pinfo *np = inet6_sk(sk); @@ -570,7 +570,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, skb = sock_alloc_send_skb(sk, length+hh_len+15, flags&MSG_DONTWAIT, &err); if (skb == NULL) - goto error; + goto error; skb_reserve(skb, hh_len); skb->priority = sk->sk_priority; @@ -600,7 +600,7 @@ error_fault: kfree_skb(skb); error: IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); - return err; + return err; } static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) @@ -694,19 +694,19 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, return -EMSGSIZE; /* Mirror BSD error message compatibility */ - if (msg->msg_flags & MSG_OOB) + if (msg->msg_flags & MSG_OOB) return -EOPNOTSUPP; /* - * Get and verify the address. + * Get and verify the address. */ memset(&fl, 0, sizeof(fl)); if (sin6) { - if (addr_len < SIN6_LEN_RFC2133) + if (addr_len < SIN6_LEN_RFC2133) return -EINVAL; - if (sin6->sin6_family && sin6->sin6_family != AF_INET6) + if (sin6->sin6_family && sin6->sin6_family != AF_INET6) return(-EAFNOSUPPORT); /* port is the proto value [0..255] carried in nexthdr */ @@ -744,17 +744,17 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL) fl.oif = sin6->sin6_scope_id; } else { - if (sk->sk_state != TCP_ESTABLISHED) + if (sk->sk_state != TCP_ESTABLISHED) return -EDESTADDRREQ; - + proto = inet->num; daddr = &np->daddr; fl.fl6_flowlabel = np->flow_label; } if (ipv6_addr_any(daddr)) { - /* - * unspecified destination address + /* + * unspecified destination address * treated as error... is this correct ? */ fl6_sock_release(flowlabel); @@ -792,7 +792,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, err = rawv6_probe_proto_opt(&fl, msg); if (err) goto out; - + ipv6_addr_copy(&fl.fl6_dst, daddr); if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) ipv6_addr_copy(&fl.fl6_src, &np->saddr); @@ -815,7 +815,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, if (final_p) ipv6_addr_copy(&fl.fl6_dst, final_p); - if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) + if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0) goto out; if (hlimit < 0) { @@ -856,7 +856,7 @@ done: dst_release(dst); if (!inet->hdrincl) release_sock(sk); -out: +out: fl6_sock_release(flowlabel); return err<0?err:len; do_confirm: @@ -867,7 +867,7 @@ do_confirm: goto done; } -static int rawv6_seticmpfilter(struct sock *sk, int level, int optname, +static int rawv6_seticmpfilter(struct sock *sk, int level, int optname, char __user *optval, int optlen) { switch (optname) { @@ -884,7 +884,7 @@ static int rawv6_seticmpfilter(struct sock *sk, int level, int optname, return 0; } -static int rawv6_geticmpfilter(struct sock *sk, int level, int optname, +static int rawv6_geticmpfilter(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen) { int len; @@ -916,7 +916,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname, struct raw6_sock *rp = raw6_sk(sk); int val; - if (get_user(val, (int __user *)optval)) + if (get_user(val, (int __user *)optval)) return -EFAULT; switch (optname) { @@ -1094,10 +1094,19 @@ static void rawv6_close(struct sock *sk, long timeout) static int rawv6_init_sk(struct sock *sk) { - if (inet_sk(sk)->num == IPPROTO_ICMPV6) { - struct raw6_sock *rp = raw6_sk(sk); + struct raw6_sock *rp = raw6_sk(sk); + + switch (inet_sk(sk)->num) { + case IPPROTO_ICMPV6: rp->checksum = 1; rp->offset = 2; + break; + case IPPROTO_MH: + rp->checksum = 1; + rp->offset = 4; + break; + default: + break; } return(0); } @@ -1215,7 +1224,7 @@ static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i) src->s6_addr32[2], src->s6_addr32[3], srcp, dest->s6_addr32[0], dest->s6_addr32[1], dest->s6_addr32[2], dest->s6_addr32[3], destp, - sp->sk_state, + sp->sk_state, atomic_read(&sp->sk_wmem_alloc), atomic_read(&sp->sk_rmem_alloc), 0, 0L, 0, @@ -1264,7 +1273,7 @@ out_kfree: goto out; } -static struct file_operations raw6_seq_fops = { +static const struct file_operations raw6_seq_fops = { .owner = THIS_MODULE, .open = raw6_seq_open, .read = seq_read, |