1// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) 2/* 3 * 4 * Ether/802.11 conversions and packet buffer routines 5 * 6 * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. 7 * -------------------------------------------------------------------- 8 * 9 * linux-wlan 10 * 11 * -------------------------------------------------------------------- 12 * 13 * Inquiries regarding the linux-wlan Open Source project can be 14 * made directly to: 15 * 16 * AbsoluteValue Systems Inc. 17 * info@linux-wlan.com 18 * http://www.linux-wlan.com 19 * 20 * -------------------------------------------------------------------- 21 * 22 * Portions of the development of this software were funded by 23 * Intersil Corporation as part of PRISM(R) chipset product development. 24 * 25 * -------------------------------------------------------------------- 26 * 27 * This file defines the functions that perform Ethernet to/from 28 * 802.11 frame conversions. 29 * 30 * -------------------------------------------------------------------- 31 * 32 *================================================================ 33 */ 34 35#include <linux/module.h> 36#include <linux/kernel.h> 37#include <linux/sched.h> 38#include <linux/types.h> 39#include <linux/skbuff.h> 40#include <linux/slab.h> 41#include <linux/wireless.h> 42#include <linux/netdevice.h> 43#include <linux/etherdevice.h> 44#include <linux/if_ether.h> 45#include <linux/byteorder/generic.h> 46 47#include <asm/byteorder.h> 48 49#include "p80211types.h" 50#include "p80211hdr.h" 51#include "p80211conv.h" 52#include "p80211mgmt.h" 53#include "p80211msg.h" 54#include "p80211netdev.h" 55#include "p80211ioctl.h" 56#include "p80211req.h" 57 58static const u8 oui_rfc1042[] = { 0x00, 0x00, 0x00 }; 59static const u8 oui_8021h[] = { 0x00, 0x00, 0xf8 }; 60 61/*---------------------------------------------------------------- 62 * p80211pb_ether_to_80211 63 * 64 * Uses the contents of the ether frame and the etherconv setting 65 * to build the elements of the 802.11 frame. 66 * 67 * We don't actually set 68 * up the frame header here. That's the MAC's job. We're only handling 69 * conversion of DIXII or 802.3+LLC frames to something that works 70 * with 802.11. 71 * 72 * Note -- 802.11 header is NOT part of the skb. Likewise, the 802.11 73 * FCS is also not present and will need to be added elsewhere. 74 * 75 * Arguments: 76 * ethconv Conversion type to perform 77 * skb skbuff containing the ether frame 78 * p80211_hdr 802.11 header 79 * 80 * Returns: 81 * 0 on success, non-zero otherwise 82 * 83 * Call context: 84 * May be called in interrupt or non-interrupt context 85 *---------------------------------------------------------------- 86 */ 87int skb_ether_to_p80211(struct wlandevice *wlandev, u32 ethconv, 88 struct sk_buff *skb, struct p80211_hdr *p80211_hdr, 89 struct p80211_metawep *p80211_wep) 90{ 91 __le16 fc; 92 u16 proto; 93 struct wlan_ethhdr e_hdr; 94 struct wlan_llc *e_llc; 95 struct wlan_snap *e_snap; 96 int foo; 97 98 memcpy(&e_hdr, skb->data, sizeof(e_hdr)); 99 100 if (skb->len <= 0) { 101 pr_debug("zero-length skb!\n"); 102 return 1; 103 } 104 105 if (ethconv == WLAN_ETHCONV_ENCAP) { /* simplest case */ 106 pr_debug("ENCAP len: %d\n", skb->len); 107 /* here, we don't care what kind of ether frm. Just stick it */ 108 /* in the 80211 payload */ 109 /* which is to say, leave the skb alone. */ 110 } else { 111 /* step 1: classify ether frame, DIX or 802.3? */ 112 proto = ntohs(e_hdr.type); 113 if (proto <= ETH_DATA_LEN) { 114 pr_debug("802.3 len: %d\n", skb->len); 115 /* codes <= 1500 reserved for 802.3 lengths */ 116 /* it's 802.3, pass ether payload unchanged, */ 117 118 /* trim off ethernet header */ 119 skb_pull(skb, ETH_HLEN); 120 121 /* leave off any PAD octets. */ 122 skb_trim(skb, proto); 123 } else { 124 pr_debug("DIXII len: %d\n", skb->len); 125 /* it's DIXII, time for some conversion */ 126 127 /* trim off ethernet header */ 128 skb_pull(skb, ETH_HLEN); 129 130 /* tack on SNAP */ 131 e_snap = skb_push(skb, sizeof(struct wlan_snap)); 132 e_snap->type = htons(proto); 133 if (ethconv == WLAN_ETHCONV_8021h && 134 p80211_stt_findproto(proto)) { 135 memcpy(e_snap->oui, oui_8021h, 136 WLAN_IEEE_OUI_LEN); 137 } else { 138 memcpy(e_snap->oui, oui_rfc1042, 139 WLAN_IEEE_OUI_LEN); 140 } 141 142 /* tack on llc */ 143 e_llc = skb_push(skb, sizeof(struct wlan_llc)); 144 e_llc->dsap = 0xAA; /* SNAP, see IEEE 802 */ 145 e_llc->ssap = 0xAA; 146 e_llc->ctl = 0x03; 147 } 148 } 149 150 /* Set up the 802.11 header */ 151 /* It's a data frame */ 152 fc = cpu_to_le16(WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) | 153 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY)); 154 155 switch (wlandev->macmode) { 156 case WLAN_MACMODE_IBSS_STA: 157 memcpy(p80211_hdr->address1, &e_hdr.daddr, ETH_ALEN); 158 memcpy(p80211_hdr->address2, wlandev->netdev->dev_addr, ETH_ALEN); 159 memcpy(p80211_hdr->address3, wlandev->bssid, ETH_ALEN); 160 break; 161 case WLAN_MACMODE_ESS_STA: 162 fc |= cpu_to_le16(WLAN_SET_FC_TODS(1)); 163 memcpy(p80211_hdr->address1, wlandev->bssid, ETH_ALEN); 164 memcpy(p80211_hdr->address2, wlandev->netdev->dev_addr, ETH_ALEN); 165 memcpy(p80211_hdr->address3, &e_hdr.daddr, ETH_ALEN); 166 break; 167 case WLAN_MACMODE_ESS_AP: 168 fc |= cpu_to_le16(WLAN_SET_FC_FROMDS(1)); 169 memcpy(p80211_hdr->address1, &e_hdr.daddr, ETH_ALEN); 170 memcpy(p80211_hdr->address2, wlandev->bssid, ETH_ALEN); 171 memcpy(p80211_hdr->address3, &e_hdr.saddr, ETH_ALEN); 172 break; 173 default: 174 netdev_err(wlandev->netdev, 175 "Error: Converting eth to wlan in unknown mode.\n"); 176 return 1; 177 } 178 179 p80211_wep->data = NULL; 180 181 if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && 182 (wlandev->hostwep & HOSTWEP_ENCRYPT)) { 183 /* XXXX need to pick keynum other than default? */ 184 185 p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC); 186 if (!p80211_wep->data) 187 return -ENOMEM; 188 foo = wep_encrypt(wlandev, skb->data, p80211_wep->data, 189 skb->len, 190 wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK, 191 p80211_wep->iv, p80211_wep->icv); 192 if (foo) { 193 netdev_warn(wlandev->netdev, 194 "Host en-WEP failed, dropping frame (%d).\n", 195 foo); 196 kfree(p80211_wep->data); 197 return 2; 198 } 199 fc |= cpu_to_le16(WLAN_SET_FC_ISWEP(1)); 200 } 201 202 /* skb->nh.raw = skb->data; */ 203 204 p80211_hdr->frame_control = fc; 205 p80211_hdr->duration_id = 0; 206 p80211_hdr->sequence_control = 0; 207 208 return 0; 209} 210 211/* jkriegl: from orinoco, modified */ 212static void orinoco_spy_gather(struct wlandevice *wlandev, char *mac, 213 struct p80211_rxmeta *rxmeta) 214{ 215 int i; 216 217 /* Gather wireless spy statistics: for each packet, compare the 218 * source address with out list, and if match, get the stats... 219 */ 220 221 for (i = 0; i < wlandev->spy_number; i++) { 222 if (!memcmp(wlandev->spy_address[i], mac, ETH_ALEN)) { 223 wlandev->spy_stat[i].level = rxmeta->signal; 224 wlandev->spy_stat[i].noise = rxmeta->noise; 225 wlandev->spy_stat[i].qual = 226 (rxmeta->signal > 227 rxmeta->noise) ? (rxmeta->signal - 228 rxmeta->noise) : 0; 229 wlandev->spy_stat[i].updated = 0x7; 230 } 231 } 232} 233 234/*---------------------------------------------------------------- 235 * p80211pb_80211_to_ether 236 * 237 * Uses the contents of a received 802.11 frame and the etherconv 238 * setting to build an ether frame. 239 * 240 * This function extracts the src and dest address from the 802.11 241 * frame to use in the construction of the eth frame. 242 * 243 * Arguments: 244 * ethconv Conversion type to perform 245 * skb Packet buffer containing the 802.11 frame 246 * 247 * Returns: 248 * 0 on success, non-zero otherwise 249 * 250 * Call context: 251 * May be called in interrupt or non-interrupt context 252 *---------------------------------------------------------------- 253 */ 254int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv, 255 struct sk_buff *skb) 256{ 257 struct net_device *netdev = wlandev->netdev; 258 u16 fc; 259 unsigned int payload_length; 260 unsigned int payload_offset; 261 u8 daddr[ETH_ALEN]; 262 u8 saddr[ETH_ALEN]; 263 struct p80211_hdr *w_hdr; 264 struct wlan_ethhdr *e_hdr; 265 struct wlan_llc *e_llc; 266 struct wlan_snap *e_snap; 267 268 int foo; 269 270 payload_length = skb->len - WLAN_HDR_A3_LEN - WLAN_CRC_LEN; 271 payload_offset = WLAN_HDR_A3_LEN; 272 273 w_hdr = (struct p80211_hdr *)skb->data; 274 275 /* setup some vars for convenience */ 276 fc = le16_to_cpu(w_hdr->frame_control); 277 if ((WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 0)) { 278 ether_addr_copy(daddr, w_hdr->address1); 279 ether_addr_copy(saddr, w_hdr->address2); 280 } else if ((WLAN_GET_FC_TODS(fc) == 0) && 281 (WLAN_GET_FC_FROMDS(fc) == 1)) { 282 ether_addr_copy(daddr, w_hdr->address1); 283 ether_addr_copy(saddr, w_hdr->address3); 284 } else if ((WLAN_GET_FC_TODS(fc) == 1) && 285 (WLAN_GET_FC_FROMDS(fc) == 0)) { 286 ether_addr_copy(daddr, w_hdr->address3); 287 ether_addr_copy(saddr, w_hdr->address2); 288 } else { 289 payload_offset = WLAN_HDR_A4_LEN; 290 if (payload_length < WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN) { 291 netdev_err(netdev, "A4 frame too short!\n"); 292 return 1; 293 } 294 payload_length -= (WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN); 295 ether_addr_copy(daddr, w_hdr->address3); 296 ether_addr_copy(saddr, w_hdr->address4); 297 } 298 299 /* perform de-wep if necessary.. */ 300 if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && 301 WLAN_GET_FC_ISWEP(fc) && 302 (wlandev->hostwep & HOSTWEP_DECRYPT)) { 303 if (payload_length <= 8) { 304 netdev_err(netdev, 305 "WEP frame too short (%u).\n", skb->len); 306 return 1; 307 } 308 foo = wep_decrypt(wlandev, skb->data + payload_offset + 4, 309 payload_length - 8, -1, 310 skb->data + payload_offset, 311 skb->data + payload_offset + 312 payload_length - 4); 313 if (foo) { 314 /* de-wep failed, drop skb. */ 315 netdev_dbg(netdev, "Host de-WEP failed, dropping frame (%d).\n", 316 foo); 317 wlandev->rx.decrypt_err++; 318 return 2; 319 } 320 321 /* subtract the IV+ICV length off the payload */ 322 payload_length -= 8; 323 /* chop off the IV */ 324 skb_pull(skb, 4); 325 /* chop off the ICV. */ 326 skb_trim(skb, skb->len - 4); 327 328 wlandev->rx.decrypt++; 329 } 330 331 e_hdr = (struct wlan_ethhdr *)(skb->data + payload_offset); 332 333 e_llc = (struct wlan_llc *)(skb->data + payload_offset); 334 e_snap = 335 (struct wlan_snap *)(skb->data + payload_offset + 336 sizeof(struct wlan_llc)); 337 338 /* Test for the various encodings */ 339 if ((payload_length >= sizeof(struct wlan_ethhdr)) && 340 (e_llc->dsap != 0xaa || e_llc->ssap != 0xaa) && 341 ((!ether_addr_equal_unaligned(daddr, e_hdr->daddr)) || 342 (!ether_addr_equal_unaligned(saddr, e_hdr->saddr)))) { 343 netdev_dbg(netdev, "802.3 ENCAP len: %d\n", payload_length); 344 /* 802.3 Encapsulated */ 345 /* Test for an overlength frame */ 346 if (payload_length > (netdev->mtu + ETH_HLEN)) { 347 /* A bogus length ethfrm has been encap'd. */ 348 /* Is someone trying an oflow attack? */ 349 netdev_err(netdev, "ENCAP frame too large (%d > %d)\n", 350 payload_length, netdev->mtu + ETH_HLEN); 351 return 1; 352 } 353 354 /* Chop off the 802.11 header. it's already sane. */ 355 skb_pull(skb, payload_offset); 356 /* chop off the 802.11 CRC */ 357 skb_trim(skb, skb->len - WLAN_CRC_LEN); 358 359 } else if ((payload_length >= sizeof(struct wlan_llc) + 360 sizeof(struct wlan_snap)) && 361 (e_llc->dsap == 0xaa) && 362 (e_llc->ssap == 0xaa) && 363 (e_llc->ctl == 0x03) && 364 (((memcmp(e_snap->oui, oui_rfc1042, 365 WLAN_IEEE_OUI_LEN) == 0) && 366 (ethconv == WLAN_ETHCONV_8021h) && 367 (p80211_stt_findproto(be16_to_cpu(e_snap->type)))) || 368 (memcmp(e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN) != 369 0))) { 370 netdev_dbg(netdev, "SNAP+RFC1042 len: %d\n", payload_length); 371 /* it's a SNAP + RFC1042 frame && protocol is in STT */ 372 /* build 802.3 + RFC1042 */ 373 374 /* Test for an overlength frame */ 375 if (payload_length > netdev->mtu) { 376 /* A bogus length ethfrm has been sent. */ 377 /* Is someone trying an oflow attack? */ 378 netdev_err(netdev, "SNAP frame too large (%d > %d)\n", 379 payload_length, netdev->mtu); 380 return 1; 381 } 382 383 /* chop 802.11 header from skb. */ 384 skb_pull(skb, payload_offset); 385 386 /* create 802.3 header at beginning of skb. */ 387 e_hdr = skb_push(skb, ETH_HLEN); 388 ether_addr_copy(e_hdr->daddr, daddr); 389 ether_addr_copy(e_hdr->saddr, saddr); 390 e_hdr->type = htons(payload_length); 391 392 /* chop off the 802.11 CRC */ 393 skb_trim(skb, skb->len - WLAN_CRC_LEN); 394 395 } else if ((payload_length >= sizeof(struct wlan_llc) + 396 sizeof(struct wlan_snap)) && 397 (e_llc->dsap == 0xaa) && 398 (e_llc->ssap == 0xaa) && 399 (e_llc->ctl == 0x03)) { 400 netdev_dbg(netdev, "802.1h/RFC1042 len: %d\n", payload_length); 401 /* it's an 802.1h frame || (an RFC1042 && protocol not in STT) 402 * build a DIXII + RFC894 403 */ 404 405 /* Test for an overlength frame */ 406 if ((payload_length - sizeof(struct wlan_llc) - 407 sizeof(struct wlan_snap)) 408 > netdev->mtu) { 409 /* A bogus length ethfrm has been sent. */ 410 /* Is someone trying an oflow attack? */ 411 netdev_err(netdev, "DIXII frame too large (%ld > %d)\n", 412 (long)(payload_length - 413 sizeof(struct wlan_llc) - 414 sizeof(struct wlan_snap)), netdev->mtu); 415 return 1; 416 } 417 418 /* chop 802.11 header from skb. */ 419 skb_pull(skb, payload_offset); 420 421 /* chop llc header from skb. */ 422 skb_pull(skb, sizeof(struct wlan_llc)); 423 424 /* chop snap header from skb. */ 425 skb_pull(skb, sizeof(struct wlan_snap)); 426 427 /* create 802.3 header at beginning of skb. */ 428 e_hdr = skb_push(skb, ETH_HLEN); 429 e_hdr->type = e_snap->type; 430 ether_addr_copy(e_hdr->daddr, daddr); 431 ether_addr_copy(e_hdr->saddr, saddr); 432 433 /* chop off the 802.11 CRC */ 434 skb_trim(skb, skb->len - WLAN_CRC_LEN); 435 } else { 436 netdev_dbg(netdev, "NON-ENCAP len: %d\n", payload_length); 437 /* any NON-ENCAP */ 438 /* it's a generic 80211+LLC or IPX 'Raw 802.3' */ 439 /* build an 802.3 frame */ 440 /* allocate space and setup hostbuf */ 441 442 /* Test for an overlength frame */ 443 if (payload_length > netdev->mtu) { 444 /* A bogus length ethfrm has been sent. */ 445 /* Is someone trying an oflow attack? */ 446 netdev_err(netdev, "OTHER frame too large (%d > %d)\n", 447 payload_length, netdev->mtu); 448 return 1; 449 } 450 451 /* Chop off the 802.11 header. */ 452 skb_pull(skb, payload_offset); 453 454 /* create 802.3 header at beginning of skb. */ 455 e_hdr = skb_push(skb, ETH_HLEN); 456 ether_addr_copy(e_hdr->daddr, daddr); 457 ether_addr_copy(e_hdr->saddr, saddr); 458 e_hdr->type = htons(payload_length); 459 460 /* chop off the 802.11 CRC */ 461 skb_trim(skb, skb->len - WLAN_CRC_LEN); 462 } 463 464 /* 465 * Note that eth_type_trans() expects an skb w/ skb->data pointing 466 * at the MAC header, it then sets the following skb members: 467 * skb->mac_header, 468 * skb->data, and 469 * skb->pkt_type. 470 * It then _returns_ the value that _we're_ supposed to stuff in 471 * skb->protocol. This is nuts. 472 */ 473 skb->protocol = eth_type_trans(skb, netdev); 474 475 /* jkriegl: process signal and noise as set in hfa384x_int_rx() */ 476 /* jkriegl: only process signal/noise if requested by iwspy */ 477 if (wlandev->spy_number) 478 orinoco_spy_gather(wlandev, eth_hdr(skb)->h_source, 479 p80211skb_rxmeta(skb)); 480 481 /* Free the metadata */ 482 p80211skb_rxmeta_detach(skb); 483 484 return 0; 485} 486 487/*---------------------------------------------------------------- 488 * p80211_stt_findproto 489 * 490 * Searches the 802.1h Selective Translation Table for a given 491 * protocol. 492 * 493 * Arguments: 494 * proto protocol number (in host order) to search for. 495 * 496 * Returns: 497 * 1 - if the table is empty or a match is found. 498 * 0 - if the table is non-empty and a match is not found. 499 * 500 * Call context: 501 * May be called in interrupt or non-interrupt context 502 *---------------------------------------------------------------- 503 */ 504int p80211_stt_findproto(u16 proto) 505{ 506 /* Always return found for now. This is the behavior used by the */ 507 /* Zoom Win95 driver when 802.1h mode is selected */ 508 /* TODO: If necessary, add an actual search we'll probably 509 * need this to match the CMAC's way of doing things. 510 * Need to do some testing to confirm. 511 */ 512 513 if (proto == ETH_P_AARP) /* APPLETALK */ 514 return 1; 515 516 return 0; 517} 518 519/*---------------------------------------------------------------- 520 * p80211skb_rxmeta_detach 521 * 522 * Disconnects the frmmeta and rxmeta from an skb. 523 * 524 * Arguments: 525 * wlandev The wlandev this skb belongs to. 526 * skb The skb we're attaching to. 527 * 528 * Returns: 529 * 0 on success, non-zero otherwise 530 * 531 * Call context: 532 * May be called in interrupt or non-interrupt context 533 *---------------------------------------------------------------- 534 */ 535void p80211skb_rxmeta_detach(struct sk_buff *skb) 536{ 537 struct p80211_rxmeta *rxmeta; 538 struct p80211_frmmeta *frmmeta; 539 540 /* Sanity checks */ 541 if (!skb) { /* bad skb */ 542 pr_debug("Called w/ null skb.\n"); 543 return; 544 } 545 frmmeta = p80211skb_frmmeta(skb); 546 if (!frmmeta) { /* no magic */ 547 pr_debug("Called w/ bad frmmeta magic.\n"); 548 return; 549 } 550 rxmeta = frmmeta->rx; 551 if (!rxmeta) { /* bad meta ptr */ 552 pr_debug("Called w/ bad rxmeta ptr.\n"); 553 return; 554 } 555 556 /* Free rxmeta */ 557 kfree(rxmeta); 558 559 /* Clear skb->cb */ 560 memset(skb->cb, 0, sizeof(skb->cb)); 561} 562 563/*---------------------------------------------------------------- 564 * p80211skb_rxmeta_attach 565 * 566 * Allocates a p80211rxmeta structure, initializes it, and attaches 567 * it to an skb. 568 * 569 * Arguments: 570 * wlandev The wlandev this skb belongs to. 571 * skb The skb we're attaching to. 572 * 573 * Returns: 574 * 0 on success, non-zero otherwise 575 * 576 * Call context: 577 * May be called in interrupt or non-interrupt context 578 *---------------------------------------------------------------- 579 */ 580int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb) 581{ 582 int result = 0; 583 struct p80211_rxmeta *rxmeta; 584 struct p80211_frmmeta *frmmeta; 585 586 /* If these already have metadata, we error out! */ 587 if (p80211skb_rxmeta(skb)) { 588 netdev_err(wlandev->netdev, 589 "%s: RXmeta already attached!\n", wlandev->name); 590 result = 0; 591 goto exit; 592 } 593 594 /* Allocate the rxmeta */ 595 rxmeta = kzalloc(sizeof(*rxmeta), GFP_ATOMIC); 596 597 if (!rxmeta) { 598 result = 1; 599 goto exit; 600 } 601 602 /* Initialize the rxmeta */ 603 rxmeta->wlandev = wlandev; 604 rxmeta->hosttime = jiffies; 605 606 /* Overlay a frmmeta_t onto skb->cb */ 607 memset(skb->cb, 0, sizeof(struct p80211_frmmeta)); 608 frmmeta = (struct p80211_frmmeta *)(skb->cb); 609 frmmeta->magic = P80211_FRMMETA_MAGIC; 610 frmmeta->rx = rxmeta; 611exit: 612 return result; 613} 614 615/*---------------------------------------------------------------- 616 * p80211skb_free 617 * 618 * Frees an entire p80211skb by checking and freeing the meta struct 619 * and then freeing the skb. 620 * 621 * Arguments: 622 * wlandev The wlandev this skb belongs to. 623 * skb The skb we're attaching to. 624 * 625 * Returns: 626 * 0 on success, non-zero otherwise 627 * 628 * Call context: 629 * May be called in interrupt or non-interrupt context 630 *---------------------------------------------------------------- 631 */ 632void p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb) 633{ 634 struct p80211_frmmeta *meta; 635 636 meta = p80211skb_frmmeta(skb); 637 if (meta && meta->rx) 638 p80211skb_rxmeta_detach(skb); 639 else 640 netdev_err(wlandev->netdev, 641 "Freeing an skb (%p) w/ no frmmeta.\n", skb); 642 dev_kfree_skb(skb); 643} 644