diff options
Diffstat (limited to 'net/phonet')
-rw-r--r-- | net/phonet/pep.c | 225 |
1 files changed, 73 insertions, 152 deletions
diff --git a/net/phonet/pep.c b/net/phonet/pep.c index 40952c7d4308..610794a416e8 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c | |||
@@ -77,24 +77,34 @@ static unsigned char *pep_get_sb(struct sk_buff *skb, u8 *ptype, u8 *plen, | |||
77 | return data; | 77 | return data; |
78 | } | 78 | } |
79 | 79 | ||
80 | static int pep_reply(struct sock *sk, struct sk_buff *oskb, | 80 | static struct sk_buff *pep_alloc_skb(struct sock *sk, const void *payload, |
81 | u8 code, const void *data, int len, gfp_t priority) | 81 | int len, gfp_t priority) |
82 | { | ||
83 | struct sk_buff *skb = alloc_skb(MAX_PNPIPE_HEADER + len, priority); | ||
84 | if (!skb) | ||
85 | return NULL; | ||
86 | skb_set_owner_w(skb, sk); | ||
87 | |||
88 | skb_reserve(skb, MAX_PNPIPE_HEADER); | ||
89 | __skb_put(skb, len); | ||
90 | skb_copy_to_linear_data(skb, payload, len); | ||
91 | __skb_push(skb, sizeof(struct pnpipehdr)); | ||
92 | skb_reset_transport_header(skb); | ||
93 | return skb; | ||
94 | } | ||
95 | |||
96 | static int pep_reply(struct sock *sk, struct sk_buff *oskb, u8 code, | ||
97 | const void *data, int len, gfp_t priority) | ||
82 | { | 98 | { |
83 | const struct pnpipehdr *oph = pnp_hdr(oskb); | 99 | const struct pnpipehdr *oph = pnp_hdr(oskb); |
84 | struct pnpipehdr *ph; | 100 | struct pnpipehdr *ph; |
85 | struct sk_buff *skb; | 101 | struct sk_buff *skb; |
86 | struct sockaddr_pn peer; | 102 | struct sockaddr_pn peer; |
87 | 103 | ||
88 | skb = alloc_skb(MAX_PNPIPE_HEADER + len, priority); | 104 | skb = pep_alloc_skb(sk, data, len, priority); |
89 | if (!skb) | 105 | if (!skb) |
90 | return -ENOMEM; | 106 | return -ENOMEM; |
91 | skb_set_owner_w(skb, sk); | ||
92 | 107 | ||
93 | skb_reserve(skb, MAX_PNPIPE_HEADER); | ||
94 | __skb_put(skb, len); | ||
95 | skb_copy_to_linear_data(skb, data, len); | ||
96 | __skb_push(skb, sizeof(*ph)); | ||
97 | skb_reset_transport_header(skb); | ||
98 | ph = pnp_hdr(skb); | 108 | ph = pnp_hdr(skb); |
99 | ph->utid = oph->utid; | 109 | ph->utid = oph->utid; |
100 | ph->message_id = oph->message_id + 1; /* REQ -> RESP */ | 110 | ph->message_id = oph->message_id + 1; /* REQ -> RESP */ |
@@ -105,135 +115,69 @@ static int pep_reply(struct sock *sk, struct sk_buff *oskb, | |||
105 | return pn_skb_send(sk, skb, &peer); | 115 | return pn_skb_send(sk, skb, &peer); |
106 | } | 116 | } |
107 | 117 | ||
108 | #define PAD 0x00 | 118 | static int pep_indicate(struct sock *sk, u8 id, u8 code, |
109 | 119 | const void *data, int len, gfp_t priority) | |
110 | #ifdef CONFIG_PHONET_PIPECTRLR | ||
111 | static int pipe_handler_send_req(struct sock *sk, u8 msg_id, gfp_t priority) | ||
112 | { | 120 | { |
113 | int len; | 121 | struct pep_sock *pn = pep_sk(sk); |
114 | struct pnpipehdr *ph; | 122 | struct pnpipehdr *ph; |
115 | struct sk_buff *skb; | 123 | struct sk_buff *skb; |
116 | struct pep_sock *pn = pep_sk(sk); | ||
117 | |||
118 | static const u8 data[4] = { | ||
119 | PAD, PAD, PAD, PAD, | ||
120 | }; | ||
121 | 124 | ||
122 | switch (msg_id) { | 125 | skb = pep_alloc_skb(sk, data, len, priority); |
123 | case PNS_PEP_CONNECT_REQ: | ||
124 | len = sizeof(data); | ||
125 | break; | ||
126 | |||
127 | case PNS_PEP_DISCONNECT_REQ: | ||
128 | case PNS_PEP_ENABLE_REQ: | ||
129 | case PNS_PEP_DISABLE_REQ: | ||
130 | len = 0; | ||
131 | break; | ||
132 | |||
133 | default: | ||
134 | return -EINVAL; | ||
135 | } | ||
136 | |||
137 | skb = alloc_skb(MAX_PNPIPE_HEADER + len, priority); | ||
138 | if (!skb) | 126 | if (!skb) |
139 | return -ENOMEM; | 127 | return -ENOMEM; |
140 | skb_set_owner_w(skb, sk); | ||
141 | 128 | ||
142 | skb_reserve(skb, MAX_PNPIPE_HEADER); | ||
143 | if (len) { | ||
144 | __skb_put(skb, len); | ||
145 | skb_copy_to_linear_data(skb, data, len); | ||
146 | } | ||
147 | __skb_push(skb, sizeof(*ph)); | ||
148 | skb_reset_transport_header(skb); | ||
149 | ph = pnp_hdr(skb); | 129 | ph = pnp_hdr(skb); |
150 | ph->utid = msg_id; /* whatever */ | 130 | ph->utid = 0; |
151 | ph->message_id = msg_id; | 131 | ph->message_id = id; |
152 | ph->pipe_handle = pn->pipe_handle; | 132 | ph->pipe_handle = pn->pipe_handle; |
153 | ph->error_code = PN_PIPE_NO_ERROR; | 133 | ph->data[0] = code; |
154 | |||
155 | return pn_skb_send(sk, skb, NULL); | 134 | return pn_skb_send(sk, skb, NULL); |
156 | } | 135 | } |
157 | 136 | ||
158 | static int pipe_handler_send_created_ind(struct sock *sk, u8 msg_id) | 137 | #define PAD 0x00 |
138 | |||
139 | #ifdef CONFIG_PHONET_PIPECTRLR | ||
140 | static int pipe_handler_request(struct sock *sk, u8 id, u8 code, | ||
141 | const void *data, int len) | ||
159 | { | 142 | { |
160 | int err_code; | 143 | struct pep_sock *pn = pep_sk(sk); |
161 | struct pnpipehdr *ph; | 144 | struct pnpipehdr *ph; |
162 | struct sk_buff *skb; | 145 | struct sk_buff *skb; |
163 | 146 | ||
164 | struct pep_sock *pn = pep_sk(sk); | 147 | skb = pep_alloc_skb(sk, data, len, GFP_KERNEL); |
165 | static u8 data[4] = { | ||
166 | 0x03, 0x04, | ||
167 | }; | ||
168 | data[2] = pn->tx_fc; | ||
169 | data[3] = pn->rx_fc; | ||
170 | |||
171 | /* | ||
172 | * actually, below is number of sub-blocks and not error code. | ||
173 | * Pipe_created_ind message format does not have any | ||
174 | * error code field. However, the Phonet stack will always send | ||
175 | * an error code as part of pnpipehdr. So, use that err_code to | ||
176 | * specify the number of sub-blocks. | ||
177 | */ | ||
178 | err_code = 0x01; | ||
179 | |||
180 | skb = alloc_skb(MAX_PNPIPE_HEADER + sizeof(data), GFP_ATOMIC); | ||
181 | if (!skb) | 148 | if (!skb) |
182 | return -ENOMEM; | 149 | return -ENOMEM; |
183 | skb_set_owner_w(skb, sk); | ||
184 | 150 | ||
185 | skb_reserve(skb, MAX_PNPIPE_HEADER); | ||
186 | __skb_put(skb, sizeof(data)); | ||
187 | skb_copy_to_linear_data(skb, data, sizeof(data)); | ||
188 | __skb_push(skb, sizeof(*ph)); | ||
189 | skb_reset_transport_header(skb); | ||
190 | ph = pnp_hdr(skb); | 151 | ph = pnp_hdr(skb); |
191 | ph->utid = 0; | 152 | ph->utid = id; /* whatever */ |
192 | ph->message_id = msg_id; | 153 | ph->message_id = id; |
193 | ph->pipe_handle = pn->pipe_handle; | 154 | ph->pipe_handle = pn->pipe_handle; |
194 | ph->error_code = err_code; | 155 | ph->data[0] = code; |
195 | |||
196 | return pn_skb_send(sk, skb, NULL); | 156 | return pn_skb_send(sk, skb, NULL); |
197 | } | 157 | } |
198 | 158 | ||
199 | static int pipe_handler_send_ind(struct sock *sk, u8 msg_id) | 159 | static int pipe_handler_send_created_ind(struct sock *sk) |
200 | { | 160 | { |
201 | int err_code; | ||
202 | struct pnpipehdr *ph; | ||
203 | struct sk_buff *skb; | ||
204 | struct pep_sock *pn = pep_sk(sk); | 161 | struct pep_sock *pn = pep_sk(sk); |
162 | u8 data[4] = { | ||
163 | PN_PIPE_SB_NEGOTIATED_FC, pep_sb_size(2), | ||
164 | pn->tx_fc, pn->rx_fc, | ||
165 | }; | ||
205 | 166 | ||
206 | /* | 167 | return pep_indicate(sk, PNS_PIPE_CREATED_IND, 1 /* sub-blocks */, |
207 | * actually, below is a filler. | 168 | data, 4, GFP_ATOMIC); |
208 | * Pipe_enabled/disabled_ind message format does not have any | 169 | } |
209 | * error code field. However, the Phonet stack will always send | ||
210 | * an error code as part of pnpipehdr. So, use that err_code to | ||
211 | * specify the filler value. | ||
212 | */ | ||
213 | err_code = 0x0; | ||
214 | |||
215 | skb = alloc_skb(MAX_PNPIPE_HEADER, GFP_ATOMIC); | ||
216 | if (!skb) | ||
217 | return -ENOMEM; | ||
218 | skb_set_owner_w(skb, sk); | ||
219 | |||
220 | skb_reserve(skb, MAX_PNPIPE_HEADER); | ||
221 | __skb_push(skb, sizeof(*ph)); | ||
222 | skb_reset_transport_header(skb); | ||
223 | ph = pnp_hdr(skb); | ||
224 | ph->utid = 0; | ||
225 | ph->message_id = msg_id; | ||
226 | ph->pipe_handle = pn->pipe_handle; | ||
227 | ph->error_code = err_code; | ||
228 | 170 | ||
229 | return pn_skb_send(sk, skb, NULL); | 171 | static int pipe_handler_send_ind(struct sock *sk, u8 id) |
172 | { | ||
173 | return pep_indicate(sk, id, PAD, NULL, 0, GFP_ATOMIC); | ||
230 | } | 174 | } |
231 | 175 | ||
232 | static int pipe_handler_enable_pipe(struct sock *sk, int enable) | 176 | static int pipe_handler_enable_pipe(struct sock *sk, int enable) |
233 | { | 177 | { |
234 | u8 id = enable ? PNS_PEP_ENABLE_REQ : PNS_PEP_DISABLE_REQ; | 178 | u8 id = enable ? PNS_PEP_ENABLE_REQ : PNS_PEP_DISABLE_REQ; |
235 | 179 | ||
236 | return pipe_handler_send_req(sk, id, GFP_KERNEL); | 180 | return pipe_handler_request(sk, id, PAD, NULL, 0); |
237 | } | 181 | } |
238 | #endif | 182 | #endif |
239 | 183 | ||
@@ -274,23 +218,21 @@ static int pep_ctrlreq_error(struct sock *sk, struct sk_buff *oskb, u8 code, | |||
274 | struct sk_buff *skb; | 218 | struct sk_buff *skb; |
275 | struct pnpipehdr *ph; | 219 | struct pnpipehdr *ph; |
276 | struct sockaddr_pn dst; | 220 | struct sockaddr_pn dst; |
221 | u8 data[4] = { | ||
222 | oph->data[0], /* PEP type */ | ||
223 | code, /* error code, at an unusual offset */ | ||
224 | PAD, PAD, | ||
225 | }; | ||
277 | 226 | ||
278 | skb = alloc_skb(MAX_PNPIPE_HEADER + 4, priority); | 227 | skb = pep_alloc_skb(sk, data, 4, priority); |
279 | if (!skb) | 228 | if (!skb) |
280 | return -ENOMEM; | 229 | return -ENOMEM; |
281 | skb_set_owner_w(skb, sk); | ||
282 | |||
283 | skb_reserve(skb, MAX_PHONET_HEADER); | ||
284 | ph = (struct pnpipehdr *)skb_put(skb, sizeof(*ph) + 4); | ||
285 | 230 | ||
231 | ph = pnp_hdr(skb); | ||
286 | ph->utid = oph->utid; | 232 | ph->utid = oph->utid; |
287 | ph->message_id = PNS_PEP_CTRL_RESP; | 233 | ph->message_id = PNS_PEP_CTRL_RESP; |
288 | ph->pipe_handle = oph->pipe_handle; | 234 | ph->pipe_handle = oph->pipe_handle; |
289 | ph->data[0] = oph->data[1]; /* CTRL id */ | 235 | ph->data[0] = oph->data[1]; /* CTRL id */ |
290 | ph->data[1] = oph->data[0]; /* PEP type */ | ||
291 | ph->data[2] = code; /* error code, at an usual offset */ | ||
292 | ph->data[3] = PAD; | ||
293 | ph->data[4] = PAD; | ||
294 | 236 | ||
295 | pn_skb_get_src_sockaddr(oskb, &dst); | 237 | pn_skb_get_src_sockaddr(oskb, &dst); |
296 | return pn_skb_send(sk, skb, &dst); | 238 | return pn_skb_send(sk, skb, &dst); |
@@ -298,34 +240,15 @@ static int pep_ctrlreq_error(struct sock *sk, struct sk_buff *oskb, u8 code, | |||
298 | 240 | ||
299 | static int pipe_snd_status(struct sock *sk, u8 type, u8 status, gfp_t priority) | 241 | static int pipe_snd_status(struct sock *sk, u8 type, u8 status, gfp_t priority) |
300 | { | 242 | { |
301 | struct pep_sock *pn = pep_sk(sk); | 243 | u8 data[4] = { type, PAD, PAD, status }; |
302 | struct pnpipehdr *ph; | ||
303 | struct sk_buff *skb; | ||
304 | 244 | ||
305 | skb = alloc_skb(MAX_PNPIPE_HEADER + 4, priority); | 245 | return pep_indicate(sk, PNS_PEP_STATUS_IND, PN_PEP_TYPE_COMMON, |
306 | if (!skb) | 246 | data, 4, priority); |
307 | return -ENOMEM; | ||
308 | skb_set_owner_w(skb, sk); | ||
309 | |||
310 | skb_reserve(skb, MAX_PNPIPE_HEADER + 4); | ||
311 | __skb_push(skb, sizeof(*ph) + 4); | ||
312 | skb_reset_transport_header(skb); | ||
313 | ph = pnp_hdr(skb); | ||
314 | ph->utid = 0; | ||
315 | ph->message_id = PNS_PEP_STATUS_IND; | ||
316 | ph->pipe_handle = pn->pipe_handle; | ||
317 | ph->pep_type = PN_PEP_TYPE_COMMON; | ||
318 | ph->data[1] = type; | ||
319 | ph->data[2] = PAD; | ||
320 | ph->data[3] = PAD; | ||
321 | ph->data[4] = status; | ||
322 | |||
323 | return pn_skb_send(sk, skb, NULL); | ||
324 | } | 247 | } |
325 | 248 | ||
326 | /* Send our RX flow control information to the sender. | 249 | /* Send our RX flow control information to the sender. |
327 | * Socket must be locked. */ | 250 | * Socket must be locked. */ |
328 | static void pipe_grant_credits(struct sock *sk) | 251 | static void pipe_grant_credits(struct sock *sk, gfp_t priority) |
329 | { | 252 | { |
330 | struct pep_sock *pn = pep_sk(sk); | 253 | struct pep_sock *pn = pep_sk(sk); |
331 | 254 | ||
@@ -335,16 +258,16 @@ static void pipe_grant_credits(struct sock *sk) | |||
335 | case PN_LEGACY_FLOW_CONTROL: /* TODO */ | 258 | case PN_LEGACY_FLOW_CONTROL: /* TODO */ |
336 | break; | 259 | break; |
337 | case PN_ONE_CREDIT_FLOW_CONTROL: | 260 | case PN_ONE_CREDIT_FLOW_CONTROL: |
338 | pipe_snd_status(sk, PN_PEP_IND_FLOW_CONTROL, | 261 | if (pipe_snd_status(sk, PN_PEP_IND_FLOW_CONTROL, |
339 | PEP_IND_READY, GFP_ATOMIC); | 262 | PEP_IND_READY, priority) == 0) |
340 | pn->rx_credits = 1; | 263 | pn->rx_credits = 1; |
341 | break; | 264 | break; |
342 | case PN_MULTI_CREDIT_FLOW_CONTROL: | 265 | case PN_MULTI_CREDIT_FLOW_CONTROL: |
343 | if ((pn->rx_credits + CREDITS_THR) > CREDITS_MAX) | 266 | if ((pn->rx_credits + CREDITS_THR) > CREDITS_MAX) |
344 | break; | 267 | break; |
345 | if (pipe_snd_status(sk, PN_PEP_IND_ID_MCFC_GRANT_CREDITS, | 268 | if (pipe_snd_status(sk, PN_PEP_IND_ID_MCFC_GRANT_CREDITS, |
346 | CREDITS_MAX - pn->rx_credits, | 269 | CREDITS_MAX - pn->rx_credits, |
347 | GFP_ATOMIC) == 0) | 270 | priority) == 0) |
348 | pn->rx_credits = CREDITS_MAX; | 271 | pn->rx_credits = CREDITS_MAX; |
349 | break; | 272 | break; |
350 | } | 273 | } |
@@ -474,7 +397,7 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
474 | if (sk->sk_state == TCP_ESTABLISHED) | 397 | if (sk->sk_state == TCP_ESTABLISHED) |
475 | break; /* Nothing to do */ | 398 | break; /* Nothing to do */ |
476 | sk->sk_state = TCP_ESTABLISHED; | 399 | sk->sk_state = TCP_ESTABLISHED; |
477 | pipe_grant_credits(sk); | 400 | pipe_grant_credits(sk, GFP_ATOMIC); |
478 | break; | 401 | break; |
479 | #endif | 402 | #endif |
480 | 403 | ||
@@ -561,7 +484,7 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
561 | if (sk->sk_state == TCP_ESTABLISHED) | 484 | if (sk->sk_state == TCP_ESTABLISHED) |
562 | break; /* Nothing to do */ | 485 | break; /* Nothing to do */ |
563 | sk->sk_state = TCP_ESTABLISHED; | 486 | sk->sk_state = TCP_ESTABLISHED; |
564 | pipe_grant_credits(sk); | 487 | pipe_grant_credits(sk, GFP_ATOMIC); |
565 | break; | 488 | break; |
566 | 489 | ||
567 | case PNS_PIPE_DISABLED_IND: | 490 | case PNS_PIPE_DISABLED_IND: |
@@ -655,7 +578,7 @@ static int pep_connresp_rcv(struct sock *sk, struct sk_buff *skb) | |||
655 | pn->rx_credits = 0; | 578 | pn->rx_credits = 0; |
656 | sk->sk_state_change(sk); | 579 | sk->sk_state_change(sk); |
657 | 580 | ||
658 | return pipe_handler_send_created_ind(sk, PNS_PIPE_CREATED_IND); | 581 | return pipe_handler_send_created_ind(sk); |
659 | } | 582 | } |
660 | #endif | 583 | #endif |
661 | 584 | ||
@@ -853,19 +776,15 @@ static int pipe_do_remove(struct sock *sk) | |||
853 | struct pnpipehdr *ph; | 776 | struct pnpipehdr *ph; |
854 | struct sk_buff *skb; | 777 | struct sk_buff *skb; |
855 | 778 | ||
856 | skb = alloc_skb(MAX_PNPIPE_HEADER, GFP_KERNEL); | 779 | skb = pep_alloc_skb(sk, NULL, 0, GFP_KERNEL); |
857 | if (!skb) | 780 | if (!skb) |
858 | return -ENOMEM; | 781 | return -ENOMEM; |
859 | 782 | ||
860 | skb_reserve(skb, MAX_PNPIPE_HEADER); | ||
861 | __skb_push(skb, sizeof(*ph)); | ||
862 | skb_reset_transport_header(skb); | ||
863 | ph = pnp_hdr(skb); | 783 | ph = pnp_hdr(skb); |
864 | ph->utid = 0; | 784 | ph->utid = 0; |
865 | ph->message_id = PNS_PIPE_REMOVE_REQ; | 785 | ph->message_id = PNS_PIPE_REMOVE_REQ; |
866 | ph->pipe_handle = pn->pipe_handle; | 786 | ph->pipe_handle = pn->pipe_handle; |
867 | ph->data[0] = PAD; | 787 | ph->data[0] = PAD; |
868 | |||
869 | return pn_skb_send(sk, skb, NULL); | 788 | return pn_skb_send(sk, skb, NULL); |
870 | } | 789 | } |
871 | #endif | 790 | #endif |
@@ -894,7 +813,7 @@ static void pep_sock_close(struct sock *sk, long timeout) | |||
894 | pipe_do_remove(sk); | 813 | pipe_do_remove(sk); |
895 | #else | 814 | #else |
896 | /* send pep disconnect request */ | 815 | /* send pep disconnect request */ |
897 | pipe_handler_send_req(sk, PNS_PEP_DISCONNECT_REQ, GFP_KERNEL); | 816 | pipe_handler_request(sk, PNS_PEP_DISCONNECT_REQ, PAD, NULL, 0); |
898 | sk->sk_state = TCP_CLOSE; | 817 | sk->sk_state = TCP_CLOSE; |
899 | #endif | 818 | #endif |
900 | } | 819 | } |
@@ -980,10 +899,12 @@ static int pep_sock_connect(struct sock *sk, struct sockaddr *addr, int len) | |||
980 | { | 899 | { |
981 | struct pep_sock *pn = pep_sk(sk); | 900 | struct pep_sock *pn = pep_sk(sk); |
982 | const struct sockaddr_pn *spn = (struct sockaddr_pn *)addr; | 901 | const struct sockaddr_pn *spn = (struct sockaddr_pn *)addr; |
902 | u8 data[4] = { 0 /* sub-blocks */, PAD, PAD, PAD }; | ||
983 | 903 | ||
984 | pn->pn_sk.dobject = pn_sockaddr_get_object(spn); | 904 | pn->pn_sk.dobject = pn_sockaddr_get_object(spn); |
985 | pn->pn_sk.resource = pn_sockaddr_get_resource(spn); | 905 | pn->pn_sk.resource = pn_sockaddr_get_resource(spn); |
986 | return pipe_handler_send_req(sk, PNS_PEP_CONNECT_REQ, GFP_KERNEL); | 906 | return pipe_handler_request(sk, PNS_PEP_CONNECT_REQ, |
907 | PN_PIPE_DISABLE, data, 4); | ||
987 | } | 908 | } |
988 | #endif | 909 | #endif |
989 | 910 | ||
@@ -1280,7 +1201,7 @@ struct sk_buff *pep_read(struct sock *sk) | |||
1280 | struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue); | 1201 | struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue); |
1281 | 1202 | ||
1282 | if (sk->sk_state == TCP_ESTABLISHED) | 1203 | if (sk->sk_state == TCP_ESTABLISHED) |
1283 | pipe_grant_credits(sk); | 1204 | pipe_grant_credits(sk, GFP_ATOMIC); |
1284 | return skb; | 1205 | return skb; |
1285 | } | 1206 | } |
1286 | 1207 | ||
@@ -1325,7 +1246,7 @@ static int pep_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
1325 | } | 1246 | } |
1326 | 1247 | ||
1327 | if (sk->sk_state == TCP_ESTABLISHED) | 1248 | if (sk->sk_state == TCP_ESTABLISHED) |
1328 | pipe_grant_credits(sk); | 1249 | pipe_grant_credits(sk, GFP_KERNEL); |
1329 | release_sock(sk); | 1250 | release_sock(sk); |
1330 | copy: | 1251 | copy: |
1331 | msg->msg_flags |= MSG_EOR; | 1252 | msg->msg_flags |= MSG_EOR; |