3 static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,
4 IPV6Header *pstIpv6Header);
5 static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,
6 IPV6Header *pstIpv6Header);
7 static VOID DumpIpv6Header(IPV6Header *pstIpv6Header);
9 static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload,
10 UCHAR *pucNextHeader, BOOLEAN *bParseDone, USHORT *pusPayloadLength)
12 UCHAR *pucRetHeaderPtr = NULL;
13 UCHAR *pucPayloadPtr = NULL;
14 USHORT usNextHeaderOffset = 0 ;
15 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
17 if ((ppucPayload == NULL) || (*pusPayloadLength == 0) ||
23 pucRetHeaderPtr = *ppucPayload;
24 pucPayloadPtr = *ppucPayload;
26 if (!pucRetHeaderPtr || !pucPayloadPtr) {
31 /* Get the Nextt Header Type */
35 switch (*pucNextHeader) {
36 case IPV6HDR_TYPE_HOPBYHOP:
39 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
40 DBG_LVL_ALL, "\nIPv6 HopByHop Header");
41 usNextHeaderOffset += sizeof(IPV6HopByHopOptionsHeader);
45 case IPV6HDR_TYPE_ROUTING:
47 IPV6RoutingHeader *pstIpv6RoutingHeader;
48 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
49 DBG_LVL_ALL, "\nIPv6 Routing Header");
50 pstIpv6RoutingHeader = (IPV6RoutingHeader *)pucPayloadPtr;
51 usNextHeaderOffset += sizeof(IPV6RoutingHeader);
52 usNextHeaderOffset += pstIpv6RoutingHeader->ucNumAddresses * IPV6_ADDRESS_SIZEINBYTES;
56 case IPV6HDR_TYPE_FRAGMENTATION:
58 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
60 "\nIPv6 Fragmentation Header");
61 usNextHeaderOffset += sizeof(IPV6FragmentHeader);
65 case IPV6HDR_TYPE_DESTOPTS:
67 IPV6DestOptionsHeader *pstIpv6DestOptsHdr = (IPV6DestOptionsHeader *)pucPayloadPtr;
68 int nTotalOptions = pstIpv6DestOptsHdr->ucHdrExtLen;
69 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
71 "\nIPv6 DestOpts Header Header");
72 usNextHeaderOffset += sizeof(IPV6DestOptionsHeader);
73 usNextHeaderOffset += nTotalOptions * IPV6_DESTOPTS_HDR_OPTIONSIZE ;
77 case IPV6HDR_TYPE_AUTHENTICATION:
79 IPV6AuthenticationHeader *pstIpv6AuthHdr = (IPV6AuthenticationHeader *)pucPayloadPtr;
80 int nHdrLen = pstIpv6AuthHdr->ucLength;
81 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
83 "\nIPv6 Authentication Header");
84 usNextHeaderOffset += nHdrLen * 4;
87 case IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD:
89 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
91 "\nIPv6 Encrypted Security Payload Header");
96 case IPV6_ICMP_HDR_TYPE:
98 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
99 DBG_LVL_ALL, "\nICMP Header");
103 case TCP_HEADER_TYPE:
105 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
106 DBG_LVL_ALL, "\nTCP Header");
110 case UDP_HEADER_TYPE:
112 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
113 DBG_LVL_ALL, "\nUDP Header");
127 if (*bParseDone == FALSE) {
128 if (*pusPayloadLength <= usNextHeaderOffset) {
131 *pucNextHeader = *pucPayloadPtr;
132 pucPayloadPtr += usNextHeaderOffset;
133 (*pusPayloadLength) -= usNextHeaderOffset;
138 *ppucPayload = pucPayloadPtr;
139 return pucRetHeaderPtr;
143 static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort,
144 USHORT *pusDestPort, USHORT usPayloadLength, UCHAR ucNextHeader)
146 UCHAR *pIpv6HdrScanContext = pucPayload;
147 BOOLEAN bDone = FALSE;
148 UCHAR ucHeaderType = 0;
149 UCHAR *pucNextHeader = NULL;
150 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
152 if (!pucPayload || (usPayloadLength == 0))
155 *pusSrcPort = *pusDestPort = 0;
156 ucHeaderType = ucNextHeader;
158 pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext,
159 &ucHeaderType, &bDone, &usPayloadLength);
161 if ((ucHeaderType == TCP_HEADER_TYPE) ||
162 (ucHeaderType == UDP_HEADER_TYPE)) {
163 *pusSrcPort = *((PUSHORT)(pucNextHeader));
164 *pusDestPort = *((PUSHORT)(pucNextHeader+2));
165 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
167 "\nProtocol Ports - Src Port :0x%x Dest Port : 0x%x",
169 ntohs(*pusDestPort));
180 * Arg 1 PMINI_ADAPTER Adapter is a pointer ot the driver contorl structure
181 * Arg 2 PVOID pcIpHeader is a pointer to the IP header of the packet
183 USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader,
184 S_CLASSIFIER_RULE *pstClassifierRule)
186 USHORT ushDestPort = 0;
187 USHORT ushSrcPort = 0;
188 UCHAR ucNextProtocolAboveIP = 0;
189 IPV6Header *pstIpv6Header = NULL;
190 BOOLEAN bClassificationSucceed = FALSE;
192 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
193 DBG_LVL_ALL, "IpVersion6 ==========>\n");
195 pstIpv6Header = (IPV6Header *)pcIpHeader;
197 DumpIpv6Header(pstIpv6Header);
200 * Try to get the next higher layer protocol
201 * and the Ports Nos if TCP or UDP
203 ucNextProtocolAboveIP = GetIpv6ProtocolPorts((UCHAR *)(pcIpHeader + sizeof(IPV6Header)),
206 pstIpv6Header->usPayloadLength,
207 pstIpv6Header->ucNextHeader);
210 if (pstClassifierRule->ucDirection == 0) {
212 * cannot be processed for classification.
213 * it is a down link connection
218 if (!pstClassifierRule->bIpv6Protocol) {
220 * We are looking for Ipv6 Classifiers
221 * Lets ignore this classifier and try the next one
226 bClassificationSucceed = MatchSrcIpv6Address(pstClassifierRule,
228 if (!bClassificationSucceed)
231 bClassificationSucceed = MatchDestIpv6Address(pstClassifierRule,
233 if (!bClassificationSucceed)
237 * Match the protocol type.
238 * For IPv6 the next protocol at end of
239 * Chain of IPv6 prot headers
241 bClassificationSucceed = MatchProtocol(pstClassifierRule,
242 ucNextProtocolAboveIP);
243 if (!bClassificationSucceed)
246 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
247 DBG_LVL_ALL, "\nIPv6 Protocol Matched");
249 if ((ucNextProtocolAboveIP == TCP_HEADER_TYPE) ||
250 (ucNextProtocolAboveIP == UDP_HEADER_TYPE)) {
252 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
253 DBG_LVL_ALL, "\nIPv6 Source Port:%x\n",
255 bClassificationSucceed = MatchSrcPort(pstClassifierRule,
257 if (!bClassificationSucceed)
260 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
261 DBG_LVL_ALL, "\nIPv6 Src Port Matched");
263 /* Match Dest Port */
264 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
265 DBG_LVL_ALL, "\nIPv6 Destination Port:%x\n",
267 bClassificationSucceed = MatchDestPort(pstClassifierRule,
269 if (!bClassificationSucceed)
271 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
272 DBG_LVL_ALL, "\nIPv6 Dest Port Matched");
276 if (bClassificationSucceed == TRUE) {
277 INT iMatchedSFQueueIndex = 0;
278 iMatchedSFQueueIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID);
279 if (iMatchedSFQueueIndex >= NO_OF_QUEUES) {
280 bClassificationSucceed = FALSE;
282 if (Adapter->PackInfo[iMatchedSFQueueIndex].bActive == FALSE)
283 bClassificationSucceed = FALSE;
287 return bClassificationSucceed;
291 static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,
292 IPV6Header *pstIpv6Header)
294 UINT uiLoopIndex = 0;
295 UINT uiIpv6AddIndex = 0;
296 UINT uiIpv6AddrNoLongWords = 4;
298 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
300 * This is the no. of Src Addresses ie Range of IP Addresses contained
301 * in the classifier rule for which we need to match
303 UINT uiCountIPSrcAddresses = (UINT)pstClassifierRule->ucIPSourceAddressLength;
306 if (uiCountIPSrcAddresses == 0)
310 /* First Convert the Ip Address in the packet to Host Endian order */
311 for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++)
312 aulSrcIP[uiIpv6AddIndex] = ntohl(pstIpv6Header->ulSrcIpAddress[uiIpv6AddIndex]);
314 for (uiLoopIndex = 0; uiLoopIndex < uiCountIPSrcAddresses; uiLoopIndex += uiIpv6AddrNoLongWords) {
315 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
316 "\n Src Ipv6 Address In Received Packet :\n ");
317 DumpIpv6Address(aulSrcIP);
318 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
319 "\n Src Ipv6 Mask In Classifier Rule:\n");
320 DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex]);
321 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
322 "\n Src Ipv6 Address In Classifier Rule :\n");
323 DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex]);
325 for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) {
326 if ((pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulSrcIP[uiIpv6AddIndex])
327 != pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) {
329 * Match failed for current Ipv6 Address
330 * Try next Ipv6 Address
335 if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) {
337 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
339 "Ipv6 Src Ip Address Matched\n");
347 static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,
348 IPV6Header *pstIpv6Header)
350 UINT uiLoopIndex = 0;
351 UINT uiIpv6AddIndex = 0;
352 UINT uiIpv6AddrNoLongWords = 4;
354 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
356 * This is the no. of Destination Addresses
357 * ie Range of IP Addresses contained in the classifier rule
358 * for which we need to match
360 UINT uiCountIPDestinationAddresses = (UINT)pstClassifierRule->ucIPDestinationAddressLength;
363 if (uiCountIPDestinationAddresses == 0)
367 /* First Convert the Ip Address in the packet to Host Endian order */
368 for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++)
369 aulDestIP[uiIpv6AddIndex] = ntohl(pstIpv6Header->ulDestIpAddress[uiIpv6AddIndex]);
371 for (uiLoopIndex = 0; uiLoopIndex < uiCountIPDestinationAddresses; uiLoopIndex += uiIpv6AddrNoLongWords) {
372 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
373 "\n Destination Ipv6 Address In Received Packet :\n ");
374 DumpIpv6Address(aulDestIP);
375 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
376 "\n Destination Ipv6 Mask In Classifier Rule :\n");
377 DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex]);
378 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
379 "\n Destination Ipv6 Address In Classifier Rule :\n");
380 DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex]);
382 for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) {
383 if ((pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulDestIP[uiIpv6AddIndex])
384 != pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) {
386 * Match failed for current Ipv6 Address.
387 * Try next Ipv6 Address
392 if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) {
394 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
396 "Ipv6 Destination Ip Address Matched\n");
405 VOID DumpIpv6Address(ULONG *puIpv6Address)
407 UINT uiIpv6AddrNoLongWords = 4;
408 UINT uiIpv6AddIndex = 0;
409 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
410 for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) {
411 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
412 ":%lx", puIpv6Address[uiIpv6AddIndex]);
417 static VOID DumpIpv6Header(IPV6Header *pstIpv6Header)
421 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
422 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
423 "----Ipv6 Header---");
424 ucVersion = pstIpv6Header->ucVersionPrio & 0xf0;
425 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
426 "Version : %x\n", ucVersion);
427 ucPrio = pstIpv6Header->ucVersionPrio & 0x0f;
428 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
429 "Priority : %x\n", ucPrio);
431 * BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
432 * "Flow Label : %x\n",(pstIpv6Header->ucVersionPrio &0xf0);
434 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
435 "Payload Length : %x\n",
436 ntohs(pstIpv6Header->usPayloadLength));
437 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
438 "Next Header : %x\n", pstIpv6Header->ucNextHeader);
439 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
440 "Hop Limit : %x\n", pstIpv6Header->ucHopLimit);
441 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
443 DumpIpv6Address(pstIpv6Header->ulSrcIpAddress);
444 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
446 DumpIpv6Address(pstIpv6Header->ulDestIpAddress);
447 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
448 "----Ipv6 Header End---");