Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Phonet: factor common code to send control messages

With the addition of the pipe controller, there is now quite a bit
of repetitive code for small signaling messages. Lets factor it.

Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Rémi Denis-Courmont and committed by
David S. Miller
44c9ab16 0ebbf318

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