diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2010-12-09 12:17:25 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2010-12-09 12:17:25 -0500 |
commit | d834a9dcecae834cd6b2bc5e50e1907738d9cf6a (patch) | |
tree | 0589d753465d3fe359ba451ba6cb7798df03aaa2 /net/can/raw.c | |
parent | a38c5380ef9f088be9f49b6e4c5d80af8b1b5cd4 (diff) | |
parent | f658bcfb2607bf0808966a69cf74135ce98e5c2d (diff) |
Merge branch 'x86/amd-nb' into x86/apic-cleanups
Reason: apic cleanup series depends on x86/apic, x86/amd-nb x86/platform
Conflicts:
arch/x86/include/asm/io_apic.h
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'net/can/raw.c')
-rw-r--r-- | net/can/raw.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/net/can/raw.c b/net/can/raw.c index a10e3338f084..e88f610fdb7b 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
@@ -90,23 +90,39 @@ struct raw_sock { | |||
90 | can_err_mask_t err_mask; | 90 | can_err_mask_t err_mask; |
91 | }; | 91 | }; |
92 | 92 | ||
93 | /* | ||
94 | * Return pointer to store the extra msg flags for raw_recvmsg(). | ||
95 | * We use the space of one unsigned int beyond the 'struct sockaddr_can' | ||
96 | * in skb->cb. | ||
97 | */ | ||
98 | static inline unsigned int *raw_flags(struct sk_buff *skb) | ||
99 | { | ||
100 | BUILD_BUG_ON(sizeof(skb->cb) <= (sizeof(struct sockaddr_can) + | ||
101 | sizeof(unsigned int))); | ||
102 | |||
103 | /* return pointer after struct sockaddr_can */ | ||
104 | return (unsigned int *)(&((struct sockaddr_can *)skb->cb)[1]); | ||
105 | } | ||
106 | |||
93 | static inline struct raw_sock *raw_sk(const struct sock *sk) | 107 | static inline struct raw_sock *raw_sk(const struct sock *sk) |
94 | { | 108 | { |
95 | return (struct raw_sock *)sk; | 109 | return (struct raw_sock *)sk; |
96 | } | 110 | } |
97 | 111 | ||
98 | static void raw_rcv(struct sk_buff *skb, void *data) | 112 | static void raw_rcv(struct sk_buff *oskb, void *data) |
99 | { | 113 | { |
100 | struct sock *sk = (struct sock *)data; | 114 | struct sock *sk = (struct sock *)data; |
101 | struct raw_sock *ro = raw_sk(sk); | 115 | struct raw_sock *ro = raw_sk(sk); |
102 | struct sockaddr_can *addr; | 116 | struct sockaddr_can *addr; |
117 | struct sk_buff *skb; | ||
118 | unsigned int *pflags; | ||
103 | 119 | ||
104 | /* check the received tx sock reference */ | 120 | /* check the received tx sock reference */ |
105 | if (!ro->recv_own_msgs && skb->sk == sk) | 121 | if (!ro->recv_own_msgs && oskb->sk == sk) |
106 | return; | 122 | return; |
107 | 123 | ||
108 | /* clone the given skb to be able to enqueue it into the rcv queue */ | 124 | /* clone the given skb to be able to enqueue it into the rcv queue */ |
109 | skb = skb_clone(skb, GFP_ATOMIC); | 125 | skb = skb_clone(oskb, GFP_ATOMIC); |
110 | if (!skb) | 126 | if (!skb) |
111 | return; | 127 | return; |
112 | 128 | ||
@@ -123,6 +139,14 @@ static void raw_rcv(struct sk_buff *skb, void *data) | |||
123 | addr->can_family = AF_CAN; | 139 | addr->can_family = AF_CAN; |
124 | addr->can_ifindex = skb->dev->ifindex; | 140 | addr->can_ifindex = skb->dev->ifindex; |
125 | 141 | ||
142 | /* add CAN specific message flags for raw_recvmsg() */ | ||
143 | pflags = raw_flags(skb); | ||
144 | *pflags = 0; | ||
145 | if (oskb->sk) | ||
146 | *pflags |= MSG_DONTROUTE; | ||
147 | if (oskb->sk == sk) | ||
148 | *pflags |= MSG_CONFIRM; | ||
149 | |||
126 | if (sock_queue_rcv_skb(sk, skb) < 0) | 150 | if (sock_queue_rcv_skb(sk, skb) < 0) |
127 | kfree_skb(skb); | 151 | kfree_skb(skb); |
128 | } | 152 | } |
@@ -647,12 +671,12 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
647 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); | 671 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); |
648 | if (err < 0) | 672 | if (err < 0) |
649 | goto free_skb; | 673 | goto free_skb; |
650 | err = sock_tx_timestamp(msg, sk, skb_tx(skb)); | 674 | err = sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); |
651 | if (err < 0) | 675 | if (err < 0) |
652 | goto free_skb; | 676 | goto free_skb; |
653 | 677 | ||
654 | /* to be able to check the received tx sock reference in raw_rcv() */ | 678 | /* to be able to check the received tx sock reference in raw_rcv() */ |
655 | skb_tx(skb)->prevent_sk_orphan = 1; | 679 | skb_shinfo(skb)->tx_flags |= SKBTX_DRV_NEEDS_SK_REF; |
656 | 680 | ||
657 | skb->dev = dev; | 681 | skb->dev = dev; |
658 | skb->sk = sk; | 682 | skb->sk = sk; |
@@ -707,6 +731,9 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
707 | memcpy(msg->msg_name, skb->cb, msg->msg_namelen); | 731 | memcpy(msg->msg_name, skb->cb, msg->msg_namelen); |
708 | } | 732 | } |
709 | 733 | ||
734 | /* assign the flags that have been recorded in raw_rcv() */ | ||
735 | msg->msg_flags |= *(raw_flags(skb)); | ||
736 | |||
710 | skb_free_datagram(sk, skb); | 737 | skb_free_datagram(sk, skb); |
711 | 738 | ||
712 | return size; | 739 | return size; |