22
22
#include "smc_clc.h"
23
23
#include "smc_ib.h"
24
24
25
+ /* check if received message has a correct header length and contains valid
26
+ * heading and trailing eyecatchers
27
+ */
28
+ static bool smc_clc_msg_hdr_valid (struct smc_clc_msg_hdr * clcm )
29
+ {
30
+ struct smc_clc_msg_proposal_prefix * pclc_prfx ;
31
+ struct smc_clc_msg_accept_confirm * clc ;
32
+ struct smc_clc_msg_proposal * pclc ;
33
+ struct smc_clc_msg_decline * dclc ;
34
+ struct smc_clc_msg_trail * trl ;
35
+
36
+ if (memcmp (clcm -> eyecatcher , SMC_EYECATCHER , sizeof (SMC_EYECATCHER )))
37
+ return false;
38
+ switch (clcm -> type ) {
39
+ case SMC_CLC_PROPOSAL :
40
+ pclc = (struct smc_clc_msg_proposal * )clcm ;
41
+ pclc_prfx = smc_clc_proposal_get_prefix (pclc );
42
+ if (ntohs (pclc -> hdr .length ) !=
43
+ sizeof (* pclc ) + ntohs (pclc -> iparea_offset ) +
44
+ sizeof (* pclc_prfx ) +
45
+ pclc_prfx -> ipv6_prefixes_cnt *
46
+ sizeof (struct smc_clc_ipv6_prefix ) +
47
+ sizeof (* trl ))
48
+ return false;
49
+ trl = (struct smc_clc_msg_trail * )
50
+ ((u8 * )pclc + ntohs (pclc -> hdr .length ) - sizeof (* trl ));
51
+ break ;
52
+ case SMC_CLC_ACCEPT :
53
+ case SMC_CLC_CONFIRM :
54
+ clc = (struct smc_clc_msg_accept_confirm * )clcm ;
55
+ if (ntohs (clc -> hdr .length ) != sizeof (* clc ))
56
+ return false;
57
+ trl = & clc -> trl ;
58
+ break ;
59
+ case SMC_CLC_DECLINE :
60
+ dclc = (struct smc_clc_msg_decline * )clcm ;
61
+ if (ntohs (dclc -> hdr .length ) != sizeof (* dclc ))
62
+ return false;
63
+ trl = & dclc -> trl ;
64
+ break ;
65
+ default :
66
+ return false;
67
+ }
68
+ if (memcmp (trl -> eyecatcher , SMC_EYECATCHER , sizeof (SMC_EYECATCHER )))
69
+ return false;
70
+ return true;
71
+ }
72
+
25
73
/* Wait for data on the tcp-socket, analyze received data
26
74
* Returns:
27
75
* 0 if success and it was not a decline that we received.
@@ -72,9 +120,7 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
72
120
}
73
121
datlen = ntohs (clcm -> length );
74
122
if ((len < sizeof (struct smc_clc_msg_hdr )) ||
75
- (datlen < sizeof (struct smc_clc_msg_decline )) ||
76
- (datlen > sizeof (struct smc_clc_msg_accept_confirm )) ||
77
- memcmp (clcm -> eyecatcher , SMC_EYECATCHER , sizeof (SMC_EYECATCHER )) ||
123
+ (datlen > buflen ) ||
78
124
((clcm -> type != SMC_CLC_DECLINE ) &&
79
125
(clcm -> type != expected_type ))) {
80
126
smc -> sk .sk_err = EPROTO ;
@@ -89,7 +135,7 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
89
135
krflags = MSG_WAITALL ;
90
136
smc -> clcsock -> sk -> sk_rcvtimeo = CLC_WAIT_TIME ;
91
137
len = kernel_recvmsg (smc -> clcsock , & msg , & vec , 1 , datlen , krflags );
92
- if (len < datlen ) {
138
+ if (len < datlen || ! smc_clc_msg_hdr_valid ( clcm ) ) {
93
139
smc -> sk .sk_err = EPROTO ;
94
140
reason_code = - EPROTO ;
95
141
goto out ;
@@ -141,33 +187,43 @@ int smc_clc_send_proposal(struct smc_sock *smc,
141
187
struct smc_ib_device * smcibdev ,
142
188
u8 ibport )
143
189
{
190
+ struct smc_clc_msg_proposal_prefix pclc_prfx ;
144
191
struct smc_clc_msg_proposal pclc ;
192
+ struct smc_clc_msg_trail trl ;
145
193
int reason_code = 0 ;
194
+ struct kvec vec [3 ];
146
195
struct msghdr msg ;
147
- struct kvec vec ;
148
- int len , rc ;
196
+ int len , plen , rc ;
149
197
150
198
/* send SMC Proposal CLC message */
199
+ plen = sizeof (pclc ) + sizeof (pclc_prfx ) + sizeof (trl );
151
200
memset (& pclc , 0 , sizeof (pclc ));
152
201
memcpy (pclc .hdr .eyecatcher , SMC_EYECATCHER , sizeof (SMC_EYECATCHER ));
153
202
pclc .hdr .type = SMC_CLC_PROPOSAL ;
154
- pclc .hdr .length = htons (sizeof ( pclc ) );
203
+ pclc .hdr .length = htons (plen );
155
204
pclc .hdr .version = SMC_CLC_V1 ; /* SMC version */
156
205
memcpy (pclc .lcl .id_for_peer , local_systemid , sizeof (local_systemid ));
157
206
memcpy (& pclc .lcl .gid , & smcibdev -> gid [ibport - 1 ], SMC_GID_SIZE );
158
207
memcpy (& pclc .lcl .mac , & smcibdev -> mac [ibport - 1 ], ETH_ALEN );
208
+ pclc .iparea_offset = htons (0 );
159
209
210
+ memset (& pclc_prfx , 0 , sizeof (pclc_prfx ));
160
211
/* determine subnet and mask from internal TCP socket */
161
- rc = smc_netinfo_by_tcpsk (smc -> clcsock , & pclc .outgoing_subnet ,
162
- & pclc .prefix_len );
212
+ rc = smc_netinfo_by_tcpsk (smc -> clcsock , & pclc_prfx .outgoing_subnet ,
213
+ & pclc_prfx .prefix_len );
163
214
if (rc )
164
215
return SMC_CLC_DECL_CNFERR ; /* configuration error */
165
- memcpy (pclc .trl .eyecatcher , SMC_EYECATCHER , sizeof (SMC_EYECATCHER ));
216
+ pclc_prfx .ipv6_prefixes_cnt = 0 ;
217
+ memcpy (trl .eyecatcher , SMC_EYECATCHER , sizeof (SMC_EYECATCHER ));
166
218
memset (& msg , 0 , sizeof (msg ));
167
- vec .iov_base = & pclc ;
168
- vec .iov_len = sizeof (pclc );
219
+ vec [0 ].iov_base = & pclc ;
220
+ vec [0 ].iov_len = sizeof (pclc );
221
+ vec [1 ].iov_base = & pclc_prfx ;
222
+ vec [1 ].iov_len = sizeof (pclc_prfx );
223
+ vec [2 ].iov_base = & trl ;
224
+ vec [2 ].iov_len = sizeof (trl );
169
225
/* due to the few bytes needed for clc-handshake this cannot block */
170
- len = kernel_sendmsg (smc -> clcsock , & msg , & vec , 1 , sizeof ( pclc ) );
226
+ len = kernel_sendmsg (smc -> clcsock , & msg , vec , 3 , plen );
171
227
if (len < sizeof (pclc )) {
172
228
if (len >= 0 ) {
173
229
reason_code = - ENETUNREACH ;
0 commit comments