浏览代码

qcacld-3.0: IPv6 packets classification support

Enable classification of IPv6 frames based on the
traffic class field in the IPv6 header.

Change-Id: I4114cb972f61b75da35a225c07f7628d748a744c
CRs-Fixed: 921955
Govind Singh 9 年之前
父节点
当前提交
b7ab577111
共有 3 个文件被更改,包括 101 次插入166 次删除
  1. 0 6
      core/hdd/inc/wlan_hdd_cfg.h
  2. 0 9
      core/hdd/src/wlan_hdd_cfg.c
  3. 101 151
      core/hdd/src/wlan_hdd_wmm.c

+ 0 - 6
core/hdd/inc/wlan_hdd_cfg.h

@@ -684,11 +684,6 @@ typedef enum {
 #define CFG_ROAM_SCAN_OFFLOAD_ENABLED_MAX                   (1)
 #define CFG_ROAM_SCAN_OFFLOAD_ENABLED_DEFAULT               (1)
 
-#define CFG_QOS_WMM_PKT_CLASSIFY_BASIS_NAME                "PktClassificationBasis"     /* DSCP or 802.1Q */
-#define CFG_QOS_WMM_PKT_CLASSIFY_BASIS_MIN                  (0)
-#define CFG_QOS_WMM_PKT_CLASSIFY_BASIS_MAX                  (1)
-#define CFG_QOS_WMM_PKT_CLASSIFY_BASIS_DEFAULT              (0) /* DSCP */
-
 /* default TSPEC parameters for AC_VO */
 #define CFG_QOS_WMM_INFRA_DIR_AC_VO_NAME                   "InfraDirAcVo"
 #define CFG_QOS_WMM_INFRA_DIR_AC_VO_MIN                     (0)
@@ -2918,7 +2913,6 @@ struct hdd_config {
 	bool isOkcIniFeatureEnabled;
 #endif
 	bool isRoamOffloadScanEnabled;
-	hdd_wmm_classification_t PktClassificationBasis;        /* DSCP or 802.1Q */
 	bool bImplicitQosEnabled;
 
 	/* default TSPEC parameters for AC_VO */

+ 0 - 9
core/hdd/src/wlan_hdd_cfg.c

@@ -1095,12 +1095,6 @@ REG_TABLE_ENTRY g_registry_table[] = {
 			     CFG_ROAM_SCAN_OFFLOAD_ENABLED_MIN,
 			     CFG_ROAM_SCAN_OFFLOAD_ENABLED_MAX,
 			     cb_notify_update_roam_scan_offload_enabled, 0),
-	REG_VARIABLE(CFG_QOS_WMM_PKT_CLASSIFY_BASIS_NAME, WLAN_PARAM_Integer,
-		     struct hdd_config, PktClassificationBasis,
-		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
-		     CFG_QOS_WMM_PKT_CLASSIFY_BASIS_DEFAULT,
-		     CFG_QOS_WMM_PKT_CLASSIFY_BASIS_MIN,
-		     CFG_QOS_WMM_PKT_CLASSIFY_BASIS_MAX),
 
 	REG_VARIABLE(CFG_QOS_WMM_INFRA_DIR_AC_VO_NAME, WLAN_PARAM_Integer,
 		     struct hdd_config, InfraDirAcVo,
@@ -4472,9 +4466,6 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
 	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
 		  "Name = [UapsdMask] Value = [0x%x] ",
 		  pHddCtx->config->UapsdMask);
-	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
-		  "Name = [PktClassificationBasis] Value = [%u] ",
-		  pHddCtx->config->PktClassificationBasis);
 	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
 		  "Name = [ImplicitQosIsEnabled] Value = [%u]",
 		  (int)pHddCtx->config->bImplicitQosEnabled);

+ 101 - 151
core/hdd/src/wlan_hdd_wmm.c

@@ -54,6 +54,7 @@
 #include <linux/if_vlan.h>
 #include <linux/ip.h>
 #include <linux/semaphore.h>
+#include <linux/ipv6.h>
 #include <wlan_hdd_tx_rx.h>
 #include <wlan_hdd_wmm.h>
 #include <wlan_hdd_ether.h>
@@ -1548,29 +1549,27 @@ CDF_STATUS hdd_wmm_adapter_close(hdd_adapter_t *pAdapter)
 
 /**
  * hdd_wmm_classify_pkt() - Function which will classify an OS packet
- * into a WMM AC based on either 802.1Q or DSCP
+ * into a WMM AC based on DSCP
  *
- * @pAdapter: [in]  adapter upon which the packet is being transmitted
- * @skb: [in] the actual OS packet (sk_buff) being transmitted
- * @pAcType: [out] WMM AC type of the OS packet
- * @pUserPri: [out] User Priority of the OS packet
+ * @adapter: adapter upon which the packet is being transmitted
+ * @skb: pointer to network buffer
+ * @user_pri: user priority of the OS packet
+ * @is_eapol: eapol packet flag
  *
  * Return: None
  */
 static
-void hdd_wmm_classify_pkt(hdd_adapter_t *pAdapter,
+void hdd_wmm_classify_pkt(hdd_adapter_t *adapter,
 			  struct sk_buff *skb,
-			  sme_ac_enum_type *pAcType,
-			  sme_QosWmmUpType *pUserPri,
+			  sme_QosWmmUpType *user_pri,
 			  bool *is_eapol)
 {
-	unsigned char *pPkt;
-	union generic_ethhdr *pHdr;
-	struct iphdr *pIpHdr;
-	unsigned char tos;
 	unsigned char dscp;
-	sme_QosWmmUpType userPri;
-	sme_ac_enum_type acType;
+	unsigned char tos;
+	union generic_ethhdr *eth_hdr;
+	struct iphdr *ip_hdr;
+	struct ipv6hdr *ipv6hdr;
+	unsigned char *pkt;
 
 	/* this code is executed for every packet therefore
 	 * all debug code is kept conditional
@@ -1581,158 +1580,118 @@ void hdd_wmm_classify_pkt(hdd_adapter_t *pAdapter,
 		  "%s: Entered", __func__);
 #endif /* HDD_WMM_DEBUG */
 
-	pPkt = skb->data;
-	pHdr = (union generic_ethhdr *)pPkt;
+	pkt = skb->data;
+	eth_hdr = (union generic_ethhdr *)pkt;
 
 #ifdef HDD_WMM_DEBUG
 	CDF_TRACE(CDF_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
-		  "%s: proto/length is 0x%04x", __func__, pHdr->eth_II.h_proto);
+		  "%s: proto is 0x%04x", __func__, skb->protocol);
 #endif /* HDD_WMM_DEBUG */
 
-	if (HDD_WMM_CLASSIFICATION_DSCP ==
-	    (WLAN_HDD_GET_CTX(pAdapter))->config->PktClassificationBasis) {
-		if (pHdr->eth_II.h_proto == htons(ETH_P_IP)) {
-			/* case 1: Ethernet II IP packet */
-			pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)];
-			tos = pIpHdr->tos;
+	if (eth_hdr->eth_II.h_proto == htons(ETH_P_IP)) {
+		/* case 1: Ethernet II IP packet */
+		ip_hdr = (struct iphdr *)&pkt[sizeof(eth_hdr->eth_II)];
+		tos = ip_hdr->tos;
 #ifdef HDD_WMM_DEBUG
-			CDF_TRACE(CDF_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
-				  "%s: Ethernet II IP Packet, tos is %d",
-				  __func__, tos);
+		CDF_TRACE(CDF_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
+				"%s: Ethernet II IP Packet, tos is %d",
+				__func__, tos);
 #endif /* HDD_WMM_DEBUG */
 
-		} else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
-			   (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
-			   (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
-			   (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
-			   (pHdr->eth_8023.h_proto == htons(ETH_P_IP))) {
-			/* case 2: 802.3 LLC/SNAP IP packet */
-			pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
-			tos = pIpHdr->tos;
+	} else if (eth_hdr->eth_II.h_proto == htons(ETH_P_IPV6)) {
+		ipv6hdr = ipv6_hdr(skb);
+		tos = ntohs(*(const __be16 *)ipv6hdr) >> 4;
 #ifdef HDD_WMM_DEBUG
-			CDF_TRACE(CDF_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
-				  "%s: 802.3 LLC/SNAP IP Packet, tos is %d",
-				  __func__, tos);
+		CDF_TRACE(CDF_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
+				"%s: Ethernet II IPv6 Packet, tos is %d",
+				__func__, tos);
 #endif /* HDD_WMM_DEBUG */
-		} else if (pHdr->eth_II.h_proto == htons(ETH_P_8021Q)) {
-			/* VLAN tagged */
-
-			if (pHdr->eth_IIv.h_vlan_encapsulated_proto ==
-			    htons(ETH_P_IP)) {
-				/* case 3: Ethernet II vlan-tagged IP packet */
-				pIpHdr =
-					(struct iphdr *)
-					&pPkt[sizeof(pHdr->eth_IIv)];
-				tos = pIpHdr->tos;
+	} else if ((ntohs(eth_hdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
+		  (eth_hdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
+		  (eth_hdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
+		  (eth_hdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
+		  (eth_hdr->eth_8023.h_proto == htons(ETH_P_IP))) {
+		/* case 2: 802.3 LLC/SNAP IP packet */
+		ip_hdr = (struct iphdr *)&pkt[sizeof(eth_hdr->eth_8023)];
+		tos = ip_hdr->tos;
 #ifdef HDD_WMM_DEBUG
-				CDF_TRACE(CDF_MODULE_ID_HDD,
-					  WMM_TRACE_LEVEL_INFO_LOW,
-					  "%s: Ethernet II VLAN tagged IP Packet, tos is %d",
-					  __func__, tos);
+		CDF_TRACE(CDF_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
+				"%s: 802.3 LLC/SNAP IP Packet, tos is %d",
+				__func__, tos);
 #endif /* HDD_WMM_DEBUG */
-			} else
-			if ((ntohs(pHdr->eth_IIv.h_vlan_encapsulated_proto)
-			     < WLAN_MIN_PROTO)
-			    && (pHdr->eth_8023v.h_snap.dsap ==
-				WLAN_SNAP_DSAP)
-			    && (pHdr->eth_8023v.h_snap.ssap ==
-				WLAN_SNAP_SSAP)
-			    && (pHdr->eth_8023v.h_snap.ctrl ==
-				WLAN_SNAP_CTRL)
-			    && (pHdr->eth_8023v.h_proto ==
-				htons(ETH_P_IP))) {
-				/* case 4: 802.3 LLC/SNAP vlan-tagged IP packet */
-				pIpHdr =
-					(struct iphdr *)
-					&pPkt[sizeof(pHdr->eth_8023v)];
-				tos = pIpHdr->tos;
+	} else if (eth_hdr->eth_II.h_proto == htons(ETH_P_8021Q)) {
+		/* VLAN tagged */
+
+		if (eth_hdr->eth_IIv.h_vlan_encapsulated_proto ==
+			htons(ETH_P_IP)) {
+			/* case 3: Ethernet II vlan-tagged IP packet */
+			ip_hdr =
+				(struct iphdr *)
+				&pkt[sizeof(eth_hdr->eth_IIv)];
+			tos = ip_hdr->tos;
 #ifdef HDD_WMM_DEBUG
-				CDF_TRACE(CDF_MODULE_ID_HDD,
-					  WMM_TRACE_LEVEL_INFO_LOW,
-					  "%s: 802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
-					  __func__, tos);
+			CDF_TRACE(CDF_MODULE_ID_HDD,
+				WMM_TRACE_LEVEL_INFO_LOW,
+				"%s: Ethernet II VLAN tagged IP Packet, tos is %d",
+				__func__, tos);
 #endif /* HDD_WMM_DEBUG */
-			} else {
-				/* default */
+		} else
+		if ((ntohs(eth_hdr->eth_IIv.h_vlan_encapsulated_proto)
+			< WLAN_MIN_PROTO)
+		    && (eth_hdr->eth_8023v.h_snap.dsap ==
+			WLAN_SNAP_DSAP)
+			&& (eth_hdr->eth_8023v.h_snap.ssap ==
+			WLAN_SNAP_SSAP)
+			&& (eth_hdr->eth_8023v.h_snap.ctrl ==
+			WLAN_SNAP_CTRL)
+			&& (eth_hdr->eth_8023v.h_proto ==
+			htons(ETH_P_IP))) {
+			/* case 4: 802.3 LLC/SNAP vlan-tagged IP packet */
+			ip_hdr =
+				(struct iphdr *)
+				&pkt[sizeof(eth_hdr->eth_8023v)];
+			tos = ip_hdr->tos;
 #ifdef HDD_WMM_DEBUG
-				CDF_TRACE(CDF_MODULE_ID_HDD,
-					  WMM_TRACE_LEVEL_WARN,
-					  "%s: VLAN tagged Unhandled Protocol, using default tos",
-					  __func__);
+			CDF_TRACE(CDF_MODULE_ID_HDD,
+				WMM_TRACE_LEVEL_INFO_LOW,
+				"%s: 802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
+				__func__, tos);
 #endif /* HDD_WMM_DEBUG */
-				tos = 0;
-			}
 		} else {
 			/* default */
 #ifdef HDD_WMM_DEBUG
-			CDF_TRACE(CDF_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
-				  "%s: Unhandled Protocol, using default tos",
-				  __func__);
-#endif /* HDD_WMM_DEBUG */
-			/* Give the highest priority to 802.1x packet */
-			if (pHdr->eth_II.h_proto ==
-			    htons(HDD_ETHERTYPE_802_1_X)) {
-				tos = 0xC0;
-				*is_eapol = true;
-			} else
-				tos = 0;
-		}
-
-		dscp = (tos >> 2) & 0x3f;
-		userPri = pAdapter->hddWmmDscpToUpMap[dscp];
-
-#ifdef HDD_WMM_DEBUG
-		CDF_TRACE(CDF_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
-			  "%s: tos is %d, dscp is %d, up is %d",
-			  __func__, tos, dscp, userPri);
-#endif /* HDD_WMM_DEBUG */
-
-	} else if (HDD_WMM_CLASSIFICATION_802_1Q ==
-		   (WLAN_HDD_GET_CTX(pAdapter))->config->
-		   PktClassificationBasis) {
-		if (pHdr->eth_IIv.h_vlan_proto == htons(ETH_P_8021Q)) {
-			/* VLAN tagged */
-			userPri = (ntohs(pHdr->eth_IIv.h_vlan_TCI) >> 13) & 0x7;
-#ifdef HDD_WMM_DEBUG
-			CDF_TRACE(CDF_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
-				  "%s: Tagged frame, UP is %d",
-				  __func__, userPri);
-#endif /* HDD_WMM_DEBUG */
-		} else {
-			/* not VLAN tagged, use default */
-#ifdef HDD_WMM_DEBUG
-			CDF_TRACE(CDF_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
-				  "%s: Untagged frame, using default UP",
-				  __func__);
+			CDF_TRACE(CDF_MODULE_ID_HDD,
+				WMM_TRACE_LEVEL_WARN,
+				"%s: VLAN tagged Unhandled Protocol, using default tos",
+				__func__);
 #endif /* HDD_WMM_DEBUG */
-			/* Give the highest priority to 802.1x packet */
-			if (pHdr->eth_II.h_proto ==
-			    htons(HDD_ETHERTYPE_802_1_X)) {
-				userPri = SME_QOS_WMM_UP_VO;
-				*is_eapol = true;
-			} else
-				userPri = SME_QOS_WMM_UP_BE;
+			tos = 0;
 		}
 	} else {
 		/* default */
 #ifdef HDD_WMM_DEBUG
-		CDF_TRACE(CDF_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
-			  "%s: Unknown classification scheme, using default UP",
-			  __func__);
+		CDF_TRACE(CDF_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
+			"%s: Unhandled Protocol, using default tos",
+			__func__);
 #endif /* HDD_WMM_DEBUG */
-		userPri = SME_QOS_WMM_UP_BE;
+		/* Give the highest priority to 802.1x packet */
+		if (eth_hdr->eth_II.h_proto ==
+			htons(HDD_ETHERTYPE_802_1_X)) {
+			tos = 0xC0;
+			*is_eapol = true;
+		} else
+			tos = 0;
 	}
 
-	acType = hdd_wmm_up_to_ac_map[userPri];
+	dscp = (tos >> 2) & 0x3f;
+	*user_pri = adapter->hddWmmDscpToUpMap[dscp];
 
 #ifdef HDD_WMM_DEBUG
 	CDF_TRACE(CDF_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
-		  "%s: UP is %d, AC is %d", __func__, userPri, acType);
+		"%s: tos is %d, dscp is %d, up is %d",
+		__func__, tos, dscp, *user_pri);
 #endif /* HDD_WMM_DEBUG */
 
-	*pUserPri = userPri;
-	*pAcType = acType;
-
 	return;
 }
 
@@ -1780,25 +1739,21 @@ uint16_t hdd_hostapd_select_queue(struct net_device *dev, struct sk_buff *skb
 
 )
 {
-	sme_ac_enum_type ac;
 	sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
 	uint16_t queueIndex;
-	hdd_adapter_t *pAdapter = (hdd_adapter_t *) netdev_priv(dev);
-	hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+	hdd_adapter_t *adapter = (hdd_adapter_t *) netdev_priv(dev);
+	hdd_context_t *hddctx = WLAN_HDD_GET_CTX(adapter);
 	bool is_eapol = false;
 	int status = 0;
-	status = wlan_hdd_validate_context(pHddCtx);
+	status = wlan_hdd_validate_context(hddctx);
 
 	if (status != 0) {
 		skb->priority = SME_QOS_WMM_UP_BE;
 		return HDD_LINUX_AC_BE;
 	}
 
-	if (HDD_WMM_USER_MODE_NO_QOS != pHddCtx->config->WmmMode) {
-		/* Get the user priority from IP header & corresponding AC */
-		hdd_wmm_classify_pkt(pAdapter, skb, &ac, &up, &is_eapol);
-	}
-
+	/* Get the user priority from IP header */
+	hdd_wmm_classify_pkt(adapter, skb, &up, &is_eapol);
 	skb->priority = up;
 	queueIndex = hdd_get_queue_index(skb->priority, is_eapol);
 
@@ -1816,7 +1771,6 @@ uint16_t hdd_hostapd_select_queue(struct net_device *dev, struct sk_buff *skb
  */
 uint16_t hdd_wmm_select_queue(struct net_device *dev, struct sk_buff *skb)
 {
-	sme_ac_enum_type ac;
 	sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
 	uint16_t queueIndex;
 	hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
@@ -1830,15 +1784,11 @@ uint16_t hdd_wmm_select_queue(struct net_device *dev, struct sk_buff *skb)
 		return HDD_LINUX_AC_BE;
 	}
 
-	/* if we don't want QoS or the AP doesn't support Qos */
-	/* All traffic will get equal opportuniy to transmit data frames. */
-	if (hdd_wmm_is_active(pAdapter)) {
-		/* Get the user priority from IP header & corresponding AC */
-		hdd_wmm_classify_pkt(pAdapter, skb, &ac, &up, &is_eapol);
-	}
-
+	/* Get the user priority from IP header */
+	hdd_wmm_classify_pkt(pAdapter, skb, &up, &is_eapol);
 	skb->priority = up;
 	queueIndex = hdd_get_queue_index(skb->priority, is_eapol);
+
 	return queueIndex;
 }