Changeset 2296
- Timestamp:
- 04/26/07 23:46:12 (5 years ago)
- Files:
-
- trunk/net80211/ieee80211_input.c (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/net80211/ieee80211_input.c
r2069 r2296 126 126 127 127 #ifdef ATH_SUPERG_FF 128 static voidathff_decap(struct sk_buff *);128 static int athff_decap(struct sk_buff *); 129 129 #endif 130 130 #ifdef USE_HEADERLEN_RESV … … 690 690 struct ether_header *eh_tmp; 691 691 struct athl2p_tunnel_hdr *ath_hdr; 692 int frame_len;692 unsigned int frame_len; 693 693 694 694 /* NB: assumes linear (i.e., non-fragmented) skb */ … … 715 715 /* move past the tunneled header, with alignment */ 716 716 skb_pull(skb, roundup(sizeof(struct athl2p_tunnel_hdr) - 2, 4) + 2); 717 eh_tmp = (struct ether_header *)skb->data; 718 719 /* ether_type must be length as FF frames are always LLC/SNAP encap'd */ 720 frame_len = ntohs(eh_tmp->ether_type); 717 721 718 722 skb1 = skb_clone(skb, GFP_ATOMIC); /* XXX: GFP_ATOMIC is overkill? */ 719 eh_tmp = (struct ether_header *)skb->data; 720 721 /* ether_type must be length*/ 722 frame_len = ntohs(eh_tmp->ether_type); 723 724 /* we now have 802.3 MAC hdr followed by 802.2 LLC/SNAP. convert to DIX */ 723 724 /* we now have 802.3 MAC hdr followed by 802.2 LLC/SNAP; convert to EthernetII. 725 * Not that the frame is at least IEEE80211_MIN_LEN, due to the driver code. */ 725 726 athff_decap(skb); 726 727 … … 730 731 /* prepare second tunneled frame */ 731 732 skb_pull(skb1, roundup(sizeof(struct ether_header) + frame_len, 4)); 732 eh_tmp = (struct ether_header *)skb1->data; 733 frame_len = ntohs(eh_tmp->ether_type); 734 athff_decap(skb1); 733 734 /* Fail if there is no space left for at least the necessary headers */ 735 if (athff_decap(skb1)) 736 { 737 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, 738 ni->ni_macaddr, "data", "%s", "Decapsulation error"); 739 vap->iv_stats.is_rx_decap++; 740 IEEE80211_NODE_STAT(ni, rx_decap); 741 goto err; 742 } 735 743 736 744 /* deliver the frames */ … … 1153 1161 } 1154 1162 1163 /* This function removes the 802.11 header, including LLC/SNAP headers and 1164 * replaces it with an Ethernet II header. */ 1155 1165 static struct sk_buff * 1156 1166 ieee80211_decap(struct ieee80211vap *vap, struct sk_buff *skb, int hdrlen) … … 1161 1171 __be16 ether_type = 0; 1162 1172 1163 memcpy(&wh, skb->data, hdrlen); /* Only copy hdrlen over */ 1173 memcpy(&wh, skb->data, hdrlen); /* Make a copy of the variably sized .11 header */ 1174 1164 1175 llc = (struct llc *) skb_pull(skb, hdrlen); 1165 1176 if (skb->len >= LLC_SNAPFRAMELEN && … … 1167 1178 llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 && 1168 1179 llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0) { 1180 1169 1181 ether_type = llc->llc_un.type_snap.ether_type; 1170 1182 skb_pull(skb, LLC_SNAPFRAMELEN); 1171 1183 llc = NULL; 1172 1184 } 1185 1173 1186 eh = (struct ether_header *) skb_push(skb, sizeof(struct ether_header)); 1174 1187 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) { … … 1190 1203 break; 1191 1204 } 1205 1206 if (llc != NULL) 1207 eh->ether_type = ether_type; 1208 else 1209 eh->ether_type = htons(skb->len - sizeof(*eh)); 1210 1192 1211 if (!ALIGNED_POINTER(skb->data + sizeof(*eh), u_int32_t)) { 1193 struct sk_buff * n;1194 1195 /* XXX does this always work? */1196 n= skb_copy(skb, GFP_ATOMIC);1212 struct sk_buff *tskb; 1213 1214 /* XXX: does this always work? */ 1215 tskb = skb_copy(skb, GFP_ATOMIC); 1197 1216 dev_kfree_skb(skb); 1198 if (n == NULL) 1199 return NULL; 1200 skb = n; 1201 eh = (struct ether_header *) skb->data; 1202 } 1203 if (llc != NULL) 1204 eh->ether_type = htons(skb->len - sizeof(*eh)); 1205 else 1206 eh->ether_type = ether_type; 1217 skb = tskb; 1218 } 1207 1219 return skb; 1208 1220 } … … 3665 3677 3666 3678 #ifdef ATH_SUPERG_FF 3667 static void3679 static int 3668 3680 athff_decap(struct sk_buff *skb) 3669 3681 { 3670 3682 struct ether_header eh_src, *eh_dst; 3671 3683 struct llc *llc; 3684 3685 if (skb->len < (sizeof(struct ether_header) + LLC_SNAPFRAMELEN)) 3686 return -1; 3672 3687 3673 3688 memcpy(&eh_src, skb->data, sizeof(struct ether_header)); … … 3678 3693 eh_dst = (struct ether_header *) skb_push(skb, sizeof(struct ether_header)); 3679 3694 memcpy(eh_dst, &eh_src, sizeof(struct ether_header)); 3695 3696 return 0; 3680 3697 } 3681 3698 #endif
