1 2 3#include <linux/etherdevice.h> 4#include <linux/slab.h> 5#include <linux/wlp.h> 6 7#include "wlp-internal.h" 8 9/* 10 * Direct incoming association msg to correct parsing routine 11 * 12 * We only expect D1, E1, C1, C3 messages as new. All other incoming 13 * association messages should form part of an established session that is 14 * handled elsewhere. 15 * The handling of these messages often require calling sleeping functions 16 * - this cannot be done in interrupt context. We use the kernel's 17 * workqueue to handle these messages. 18 */ 19static 20void wlp_direct_assoc_frame(struct wlp *wlp, struct sk_buff *skb, 21 struct uwb_dev_addr *src) 22{ 23 struct device *dev = &wlp->rc->uwb_dev.dev; 24 struct wlp_frame_assoc *assoc = (void *) skb->data; 25 struct wlp_assoc_frame_ctx *frame_ctx; 26 27 frame_ctx = kmalloc(sizeof(*frame_ctx), GFP_ATOMIC); 28 if (frame_ctx == NULL) { 29 dev_err(dev, "WLP: Unable to allocate memory for association " 30 "frame handling.\n"); 31 kfree_skb(skb); 32 return; 33 } 34 frame_ctx->wlp = wlp; 35 frame_ctx->skb = skb; 36 frame_ctx->src = *src; 37 switch (assoc->type) { 38 case WLP_ASSOC_D1: 39 INIT_WORK(&frame_ctx->ws, wlp_handle_d1_frame); 40 schedule_work(&frame_ctx->ws); 41 break; 42 case WLP_ASSOC_E1: 43 kfree_skb(skb); /* Temporary until we handle it */ 44 kfree(frame_ctx); /* Temporary until we handle it */ 45 break; 46 case WLP_ASSOC_C1: 47 INIT_WORK(&frame_ctx->ws, wlp_handle_c1_frame); 48 schedule_work(&frame_ctx->ws); 49 break; 50 case WLP_ASSOC_C3: 51 INIT_WORK(&frame_ctx->ws, wlp_handle_c3_frame); 52 schedule_work(&frame_ctx->ws); 53 break; 54 default: 55 dev_err(dev, "Received unexpected association frame. " 56 "Type = %d \n", assoc->type); 57 kfree_skb(skb); 58 kfree(frame_ctx); 59 break; 60 } 61} 62 63/* 64 * Process incoming association frame 65 * 66 * Although it could be possible to deal with some incoming association 67 * messages without creating a new session we are keeping things simple. We 68 * do not accept new association messages if there is a session in progress 69 * and the messages do not belong to that session. 70 * 71 * If an association message arrives that causes the creation of a session 72 * (WLP_ASSOC_E1) while we are in the process of creating a session then we 73 * rely on the neighbor mutex to protect the data. That is, the new session 74 * will not be started until the previous is completed. 75 */ 76static 77void wlp_receive_assoc_frame(struct wlp *wlp, struct sk_buff *skb, 78 struct uwb_dev_addr *src) 79{ 80 struct device *dev = &wlp->rc->uwb_dev.dev; 81 struct wlp_frame_assoc *assoc = (void *) skb->data; 82 struct wlp_session *session = wlp->session; 83 u8 version; 84 85 if (wlp_get_version(wlp, &assoc->version, &version, 86 sizeof(assoc->version)) < 0) 87 goto error; 88 if (version != WLP_VERSION) { 89 dev_err(dev, "Unsupported WLP version in association " 90 "message.\n"); 91 goto error; 92 } 93 if (session != NULL) { 94 /* Function that created this session is still holding the 95 * &wlp->mutex to protect this session. */ 96 if (assoc->type == session->exp_message || 97 assoc->type == WLP_ASSOC_F0) { 98 if (!memcmp(&session->neighbor_addr, src, 99 sizeof(*src))) { 100 session->data = skb; 101 (session->cb)(wlp); 102 } else { 103 dev_err(dev, "Received expected message from " 104 "unexpected source. Expected message " 105 "%d or F0 from %02x:%02x, but received " 106 "it from %02x:%02x. Dropping.\n", 107 session->exp_message, 108 session->neighbor_addr.data[1], 109 session->neighbor_addr.data[0], 110 src->data[1], src->data[0]); 111 goto error; 112 } 113 } else { 114 dev_err(dev, "Association already in progress. " 115 "Dropping.\n"); 116 goto error; 117 } 118 } else { 119 wlp_direct_assoc_frame(wlp, skb, src); 120 } 121 return; 122error: 123 kfree_skb(skb); 124} 125 126/* 127 * Verify incoming frame is from connected neighbor, prep to pass to WLP client 128 * 129 * Verification proceeds according to WLP 0.99 [7.3.1]. The source address 130 * is used to determine which neighbor is sending the frame and the WSS tag 131 * is used to know to which WSS the frame belongs (we only support one WSS 132 * so this test is straight forward). 133 * With the WSS found we need to ensure that we are connected before 134 * allowing the exchange of data frames. 135 */ 136static 137int wlp_verify_prep_rx_frame(struct wlp *wlp, struct sk_buff *skb, 138 struct uwb_dev_addr *src) 139{ 140 struct device *dev = &wlp->rc->uwb_dev.dev; 141 int result = -EINVAL; 142 struct wlp_eda_node eda_entry; 143 struct wlp_frame_std_abbrv_hdr *hdr = (void *) skb->data; 144 145 /*verify*/ 146 result = wlp_copy_eda_node(&wlp->eda, src, &eda_entry); 147 if (result < 0) { 148 if (printk_ratelimit()) 149 dev_err(dev, "WLP: Incoming frame is from unknown " 150 "neighbor %02x:%02x.\n", src->data[1], 151 src->data[0]); 152 goto out; 153 } 154 if (hdr->tag != eda_entry.tag) { 155 if (printk_ratelimit()) 156 dev_err(dev, "WLP: Tag of incoming frame from " 157 "%02x:%02x does not match expected tag. " 158 "Received 0x%02x, expected 0x%02x. \n", 159 src->data[1], src->data[0], hdr->tag, 160 eda_entry.tag); 161 result = -EINVAL; 162 goto out; 163 } 164 if (eda_entry.state != WLP_WSS_CONNECTED) { 165 if (printk_ratelimit()) 166 dev_err(dev, "WLP: Incoming frame from " 167 "%02x:%02x does is not from connected WSS.\n", 168 src->data[1], src->data[0]); 169 result = -EINVAL; 170 goto out; 171 } 172 /*prep*/ 173 skb_pull(skb, sizeof(*hdr)); 174out: 175 return result; 176} 177 178/* 179 * Receive a WLP frame from device 180 * 181 * @returns: 1 if calling function should free the skb 182 * 0 if it successfully handled skb and freed it 183 * 0 if error occured, will free skb in this case 184 */ 185int wlp_receive_frame(struct device *dev, struct wlp *wlp, struct sk_buff *skb, 186 struct uwb_dev_addr *src) 187{ 188 unsigned len = skb->len; 189 void *ptr = skb->data; 190 struct wlp_frame_hdr *hdr; 191 int result = 0; 192 193 if (len < sizeof(*hdr)) { 194 dev_err(dev, "Not enough data to parse WLP header.\n"); 195 result = -EINVAL; 196 goto out; 197 } 198 hdr = ptr; 199 if (le16_to_cpu(hdr->mux_hdr) != WLP_PROTOCOL_ID) { 200 dev_err(dev, "Not a WLP frame type.\n"); 201 result = -EINVAL; 202 goto out; 203 } 204 switch (hdr->type) { 205 case WLP_FRAME_STANDARD: 206 if (len < sizeof(struct wlp_frame_std_abbrv_hdr)) { 207 dev_err(dev, "Not enough data to parse Standard " 208 "WLP header.\n"); 209 goto out; 210 } 211 result = wlp_verify_prep_rx_frame(wlp, skb, src); 212 if (result < 0) { 213 if (printk_ratelimit()) 214 dev_err(dev, "WLP: Verification of frame " 215 "from neighbor %02x:%02x failed.\n", 216 src->data[1], src->data[0]); 217 goto out; 218 } 219 result = 1; 220 break; 221 case WLP_FRAME_ABBREVIATED: 222 dev_err(dev, "Abbreviated frame received. FIXME?\n"); 223 kfree_skb(skb); 224 break; 225 case WLP_FRAME_CONTROL: 226 dev_err(dev, "Control frame received. FIXME?\n"); 227 kfree_skb(skb); 228 break; 229 case WLP_FRAME_ASSOCIATION: 230 if (len < sizeof(struct wlp_frame_assoc)) { 231 dev_err(dev, "Not enough data to parse Association " 232 "WLP header.\n"); 233 goto out; 234 } 235 wlp_receive_assoc_frame(wlp, skb, src); 236 break; 237 default: 238 dev_err(dev, "Invalid frame received.\n"); 239 result = -EINVAL; 240 break; 241 } 242out: 243 if (result < 0) { 244 kfree_skb(skb); 245 result = 0; 246 } 247 return result; 248} 249EXPORT_SYMBOL_GPL(wlp_receive_frame); 250 251 252/* 253 * Verify frame from network stack, prepare for further transmission 254 * 255 * @skb: the socket buffer that needs to be prepared for transmission (it 256 * is in need of a WLP header). If this is a broadcast frame we take 257 * over the entire transmission. 258 * If it is a unicast the WSS connection should already be established 259 * and transmission will be done by the calling function. 260 * @dst: On return this will contain the device address to which the 261 * frame is destined. 262 * @returns: 0 on success no tx : WLP header successfully applied to skb buffer, 263 * calling function can proceed with tx 264 * 1 on success with tx : WLP will take over transmission of this 265 * frame 266 * <0 on error 267 * 268 * The network stack (WLP client) is attempting to transmit a frame. We can 269 * only transmit data if a local WSS is at least active (connection will be 270 * done here if this is a broadcast frame and neighbor also has the WSS 271 * active). 272 * 273 * The frame can be either broadcast or unicast. Broadcast in a WSS is 274 * supported via multicast, but we don't support multicast yet (until 275 * devices start to support MAB IEs). If a broadcast frame needs to be 276 * transmitted it is treated as a unicast frame to each neighbor. In this 277 * case the WLP takes over transmission of the skb and returns 1 278 * to the caller to indicate so. Also, in this case, if a neighbor has the 279 * same WSS activated but is not connected then the WSS connection will be 280 * done at this time. The neighbor's virtual address will be learned at 281 * this time. 282 * 283 * The destination address in a unicast frame is the virtual address of the 284 * neighbor. This address only becomes known when a WSS connection is 285 * established. We thus rely on a broadcast frame to trigger the setup of 286 * WSS connections to all neighbors before we are able to send unicast 287 * frames to them. This seems reasonable as IP would usually use ARP first 288 * before any unicast frames are sent. 289 * 290 * If we are already connected to the neighbor (neighbor's virtual address 291 * is known) we just prepare the WLP header and the caller will continue to 292 * send the frame. 293 * 294 * A failure in this function usually indicates something that cannot be 295 * fixed automatically. So, if this function fails (@return < 0) the calling 296 * function should not retry to send the frame as it will very likely keep 297 * failing. 298 * 299 */ 300int wlp_prepare_tx_frame(struct device *dev, struct wlp *wlp, 301 struct sk_buff *skb, struct uwb_dev_addr *dst) 302{ 303 int result = -EINVAL; 304 struct ethhdr *eth_hdr = (void *) skb->data; 305 306 if (is_multicast_ether_addr(eth_hdr->h_dest)) { 307 result = wlp_eda_for_each(&wlp->eda, wlp_wss_send_copy, skb); 308 if (result < 0) { 309 if (printk_ratelimit()) 310 dev_err(dev, "Unable to handle broadcast " 311 "frame from WLP client.\n"); 312 goto out; 313 } 314 dev_kfree_skb_irq(skb); 315 result = 1; 316 /* Frame will be transmitted by WLP. */ 317 } else { 318 result = wlp_eda_for_virtual(&wlp->eda, eth_hdr->h_dest, dst, 319 wlp_wss_prep_hdr, skb); 320 if (unlikely(result < 0)) { 321 if (printk_ratelimit()) 322 dev_err(dev, "Unable to prepare " 323 "skb for transmission. \n"); 324 goto out; 325 } 326 } 327out: 328 return result; 329} 330EXPORT_SYMBOL_GPL(wlp_prepare_tx_frame); 331