Loading...
1#include "headers.h"
2
3static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header);
4static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header);
5static VOID DumpIpv6Header(IPV6Header *pstIpv6Header);
6
7static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader,BOOLEAN *bParseDone,USHORT *pusPayloadLength)
8{
9 UCHAR *pucRetHeaderPtr = NULL;
10 UCHAR *pucPayloadPtr = NULL;
11 USHORT usNextHeaderOffset = 0 ;
12 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
13
14 if((NULL == ppucPayload) || (*pusPayloadLength == 0) || (*bParseDone))
15 {
16 *bParseDone = TRUE;
17 return NULL;
18
19 }
20
21 pucRetHeaderPtr = *ppucPayload;
22 pucPayloadPtr = *ppucPayload;
23
24 if(!pucRetHeaderPtr || !pucPayloadPtr)
25 {
26 *bParseDone = TRUE;
27 return NULL;
28 }
29
30 //Get the Nextt Header Type
31 *bParseDone = FALSE;
32
33
34
35 switch(*pucNextHeader)
36 {
37 case IPV6HDR_TYPE_HOPBYHOP:
38 {
39
40 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 HopByHop Header");
41 usNextHeaderOffset+=sizeof(IPV6HopByHopOptionsHeader);
42 }
43 break;
44
45 case IPV6HDR_TYPE_ROUTING:
46 {
47 IPV6RoutingHeader *pstIpv6RoutingHeader;
48 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Routing Header");
49 pstIpv6RoutingHeader = (IPV6RoutingHeader *)pucPayloadPtr;
50 usNextHeaderOffset += sizeof(IPV6RoutingHeader);
51 usNextHeaderOffset += pstIpv6RoutingHeader->ucNumAddresses * IPV6_ADDRESS_SIZEINBYTES;
52
53 }
54 break;
55 case IPV6HDR_TYPE_FRAGMENTATION:
56 {
57 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Fragmentation Header");
58 usNextHeaderOffset+= sizeof(IPV6FragmentHeader);
59
60 }
61 break;
62 case IPV6HDR_TYPE_DESTOPTS:
63 {
64 IPV6DestOptionsHeader *pstIpv6DestOptsHdr = (IPV6DestOptionsHeader *)pucPayloadPtr;
65 int nTotalOptions = pstIpv6DestOptsHdr->ucHdrExtLen;
66 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 DestOpts Header Header");
67 usNextHeaderOffset+= sizeof(IPV6DestOptionsHeader);
68 usNextHeaderOffset+= nTotalOptions * IPV6_DESTOPTS_HDR_OPTIONSIZE ;
69
70 }
71 break;
72 case IPV6HDR_TYPE_AUTHENTICATION:
73 {
74 IPV6AuthenticationHeader *pstIpv6AuthHdr = (IPV6AuthenticationHeader *)pucPayloadPtr;
75 int nHdrLen = pstIpv6AuthHdr->ucLength;
76 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Authentication Header");
77 usNextHeaderOffset+= nHdrLen * 4;
78 }
79 break;
80 case IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD:
81 {
82 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Encrypted Security Payload Header");
83 *bParseDone = TRUE;
84
85 }
86 break;
87 case IPV6_ICMP_HDR_TYPE:
88 {
89 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " ICMP Header");
90 *bParseDone = TRUE;
91 }
92 break;
93 case TCP_HEADER_TYPE:
94 {
95 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nTCP Header");
96 *bParseDone = TRUE;
97 }
98 break;
99 case UDP_HEADER_TYPE:
100 {
101 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nUDP Header");
102 *bParseDone = TRUE;
103 }
104 break;
105 default :
106 {
107 *bParseDone = TRUE;
108
109 }
110 break;
111
112
113 }
114
115 if(*bParseDone == FALSE)
116 {
117 if(*pusPayloadLength <= usNextHeaderOffset)
118 {
119 *bParseDone = TRUE;
120 }
121 else
122 {
123 *pucNextHeader = *pucPayloadPtr;
124 pucPayloadPtr+=usNextHeaderOffset;
125 (*pusPayloadLength)-=usNextHeaderOffset;
126 }
127
128 }
129
130
131
132 *ppucPayload = pucPayloadPtr;
133 return pucRetHeaderPtr;
134}
135
136
137static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload,USHORT *pusSrcPort,USHORT *pusDestPort,USHORT usPayloadLength,UCHAR ucNextHeader)
138{
139 UCHAR *pIpv6HdrScanContext = pucPayload;
140 BOOLEAN bDone = FALSE;
141 UCHAR ucHeaderType =0;
142 UCHAR *pucNextHeader = NULL;
143 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
144
145 if( !pucPayload || (usPayloadLength == 0))
146 {
147 return 0;
148 }
149
150 *pusSrcPort = *pusDestPort = 0;
151 ucHeaderType = ucNextHeader;
152 while(!bDone)
153 {
154 pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext,&ucHeaderType,&bDone,&usPayloadLength);
155 if(bDone)
156 {
157 if((ucHeaderType==TCP_HEADER_TYPE) || (ucHeaderType == UDP_HEADER_TYPE))
158 {
159 *pusSrcPort=*((PUSHORT)(pucNextHeader));
160 *pusDestPort=*((PUSHORT)(pucNextHeader+2));
161 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nProtocol Ports - Src Port :0x%x Dest Port : 0x%x",ntohs(*pusSrcPort),ntohs(*pusDestPort));
162 }
163 break;
164
165 }
166 }
167 return ucHeaderType;
168}
169
170
171
172USHORT IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */
173 PVOID pcIpHeader, /**<Pointer to the IP Hdr of the packet*/
174 S_CLASSIFIER_RULE *pstClassifierRule )
175{
176 USHORT ushDestPort = 0;
177 USHORT ushSrcPort = 0;
178 UCHAR ucNextProtocolAboveIP =0;
179 IPV6Header *pstIpv6Header = NULL;
180 BOOLEAN bClassificationSucceed = FALSE;
181
182 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "IpVersion6 ==========>\n");
183
184 pstIpv6Header = (IPV6Header *)pcIpHeader;
185
186 DumpIpv6Header(pstIpv6Header);
187
188 //Try to get the next higher layer protocol and the Ports Nos if TCP or UDP
189 ucNextProtocolAboveIP = GetIpv6ProtocolPorts((UCHAR *)(pcIpHeader + sizeof(IPV6Header)),
190 &ushSrcPort,
191 &ushDestPort,
192 pstIpv6Header->usPayloadLength,
193 pstIpv6Header->ucNextHeader);
194
195 do
196 {
197 if(0 == pstClassifierRule->ucDirection)
198 {
199 //cannot be processed for classification.
200 // it is a down link connection
201 break;
202 }
203
204 if(!pstClassifierRule->bIpv6Protocol)
205 {
206 //We are looking for Ipv6 Classifiers . Lets ignore this classifier and try the next one.
207 break;
208 }
209
210 bClassificationSucceed=MatchSrcIpv6Address(pstClassifierRule,pstIpv6Header);
211 if(!bClassificationSucceed)
212 break;
213
214 bClassificationSucceed=MatchDestIpv6Address(pstClassifierRule,pstIpv6Header);
215 if(!bClassificationSucceed)
216 break;
217
218 //Match the protocol type.For IPv6 the next protocol at end of Chain of IPv6 prot headers
219 bClassificationSucceed=MatchProtocol(pstClassifierRule,ucNextProtocolAboveIP);
220 if(!bClassificationSucceed)
221 break;
222 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Protocol Matched");
223
224 if((ucNextProtocolAboveIP == TCP_HEADER_TYPE) || (ucNextProtocolAboveIP == UDP_HEADER_TYPE))
225 {
226 //Match Src Port
227 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Source Port:%x\n",ntohs(ushSrcPort));
228 bClassificationSucceed=MatchSrcPort(pstClassifierRule,ntohs(ushSrcPort));
229 if(!bClassificationSucceed)
230 break;
231
232 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Src Port Matched");
233
234 //Match Dest Port
235 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Destination Port:%x\n",ntohs(ushDestPort));
236 bClassificationSucceed=MatchDestPort(pstClassifierRule,ntohs(ushDestPort));
237 if(!bClassificationSucceed)
238 break;
239 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Dest Port Matched");
240 }
241 }while(0);
242
243 if(TRUE==bClassificationSucceed)
244 {
245 INT iMatchedSFQueueIndex = 0;
246 iMatchedSFQueueIndex = SearchSfid(Adapter,pstClassifierRule->ulSFID);
247 if(iMatchedSFQueueIndex >= NO_OF_QUEUES)
248 {
249 bClassificationSucceed = FALSE;
250 }
251 else
252 {
253 if(FALSE == Adapter->PackInfo[iMatchedSFQueueIndex].bActive)
254 {
255 bClassificationSucceed = FALSE;
256 }
257 }
258 }
259
260 return bClassificationSucceed;
261}
262
263
264static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header)
265{
266 UINT uiLoopIndex=0;
267 UINT uiIpv6AddIndex=0;
268 UINT uiIpv6AddrNoLongWords = 4;
269 ULONG aulSrcIP[4];
270 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
271 /*
272 //This is the no. of Src Addresses ie Range of IP Addresses contained
273 //in the classifier rule for which we need to match
274 */
275 UINT uiCountIPSrcAddresses = (UINT)pstClassifierRule->ucIPSourceAddressLength;
276
277
278 if(0 == uiCountIPSrcAddresses)
279 return TRUE;
280
281
282 //First Convert the Ip Address in the packet to Host Endian order
283 for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++)
284 {
285 aulSrcIP[uiIpv6AddIndex]=ntohl(pstIpv6Header->ulSrcIpAddress[uiIpv6AddIndex]);
286 }
287
288 for(uiLoopIndex=0;uiLoopIndex<uiCountIPSrcAddresses;uiLoopIndex+=uiIpv6AddrNoLongWords)
289 {
290 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Address In Received Packet : \n ");
291 DumpIpv6Address(aulSrcIP);
292 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Mask In Classifier Rule: \n");
293 DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex]);
294 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Address In Classifier Rule : \n");
295 DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex]);
296
297 for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++)
298 {
299 if((pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulSrcIP[uiIpv6AddIndex])
300 != pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex])
301 {
302 //Match failed for current Ipv6 Address.Try next Ipv6 Address
303 break;
304 }
305
306 if(uiIpv6AddIndex == uiIpv6AddrNoLongWords-1)
307 {
308 //Match Found
309 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Src Ip Address Matched\n");
310 return TRUE;
311 }
312 }
313 }
314 return FALSE;
315}
316
317static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header)
318{
319 UINT uiLoopIndex=0;
320 UINT uiIpv6AddIndex=0;
321 UINT uiIpv6AddrNoLongWords = 4;
322 ULONG aulDestIP[4];
323 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
324 /*
325 //This is the no. of Destination Addresses ie Range of IP Addresses contained
326 //in the classifier rule for which we need to match
327 */
328 UINT uiCountIPDestinationAddresses = (UINT)pstClassifierRule->ucIPDestinationAddressLength;
329
330
331 if(0 == uiCountIPDestinationAddresses)
332 return TRUE;
333
334
335 //First Convert the Ip Address in the packet to Host Endian order
336 for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++)
337 {
338 aulDestIP[uiIpv6AddIndex]=ntohl(pstIpv6Header->ulDestIpAddress[uiIpv6AddIndex]);
339 }
340
341 for(uiLoopIndex=0;uiLoopIndex<uiCountIPDestinationAddresses;uiLoopIndex+=uiIpv6AddrNoLongWords)
342 {
343 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Received Packet : \n ");
344 DumpIpv6Address(aulDestIP);
345 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Mask In Classifier Rule: \n");
346 DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex]);
347 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Classifier Rule : \n");
348 DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex]);
349
350 for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++)
351 {
352 if((pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulDestIP[uiIpv6AddIndex])
353 != pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex])
354 {
355 //Match failed for current Ipv6 Address.Try next Ipv6 Address
356 break;
357 }
358
359 if(uiIpv6AddIndex == uiIpv6AddrNoLongWords-1)
360 {
361 //Match Found
362 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Destination Ip Address Matched\n");
363 return TRUE;
364 }
365 }
366 }
367 return FALSE;
368
369}
370
371VOID DumpIpv6Address(ULONG *puIpv6Address)
372{
373 UINT uiIpv6AddrNoLongWords = 4;
374 UINT uiIpv6AddIndex=0;
375 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
376 for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++)
377 {
378 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, ":%lx",puIpv6Address[uiIpv6AddIndex]);
379 }
380
381}
382
383static VOID DumpIpv6Header(IPV6Header *pstIpv6Header)
384{
385 UCHAR ucVersion;
386 UCHAR ucPrio ;
387 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
388 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header---");
389 ucVersion = pstIpv6Header->ucVersionPrio & 0xf0;
390 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Version : %x \n",ucVersion);
391 ucPrio = pstIpv6Header->ucVersionPrio & 0x0f;
392 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Priority : %x \n",ucPrio);
393 //BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Flow Label : %x \n",(pstIpv6Header->ucVersionPrio &0xf0);
394 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Payload Length : %x \n",ntohs(pstIpv6Header->usPayloadLength));
395 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Next Header : %x \n",pstIpv6Header->ucNextHeader);
396 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Hop Limit : %x \n",pstIpv6Header->ucHopLimit);
397 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Src Address :\n");
398 DumpIpv6Address(pstIpv6Header->ulSrcIpAddress);
399 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Dest Address :\n");
400 DumpIpv6Address(pstIpv6Header->ulDestIpAddress);
401 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header End---");
402
403
404}
1#include "headers.h"
2
3static bool MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
4 struct bcm_ipv6_hdr *pstIpv6Header);
5static bool MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
6 struct bcm_ipv6_hdr *pstIpv6Header);
7static VOID DumpIpv6Header(struct bcm_ipv6_hdr *pstIpv6Header);
8
9static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload,
10 UCHAR *pucNextHeader, bool *bParseDone, USHORT *pusPayloadLength)
11{
12 UCHAR *pucRetHeaderPtr = NULL;
13 UCHAR *pucPayloadPtr = NULL;
14 USHORT usNextHeaderOffset = 0 ;
15 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
16
17 if ((ppucPayload == NULL) || (*pusPayloadLength == 0) ||
18 (*bParseDone)) {
19 *bParseDone = TRUE;
20 return NULL;
21 }
22
23 pucRetHeaderPtr = *ppucPayload;
24 pucPayloadPtr = *ppucPayload;
25
26 if (!pucRetHeaderPtr || !pucPayloadPtr) {
27 *bParseDone = TRUE;
28 return NULL;
29 }
30
31 /* Get the Nextt Header Type */
32 *bParseDone = false;
33
34
35 switch (*pucNextHeader) {
36 case IPV6HDR_TYPE_HOPBYHOP:
37 {
38
39 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
40 DBG_LVL_ALL, "\nIPv6 HopByHop Header");
41 usNextHeaderOffset += sizeof(struct bcm_ipv6_options_hdr);
42 }
43 break;
44
45 case IPV6HDR_TYPE_ROUTING:
46 {
47 struct bcm_ipv6_routing_hdr *pstIpv6RoutingHeader;
48 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
49 DBG_LVL_ALL, "\nIPv6 Routing Header");
50 pstIpv6RoutingHeader = (struct bcm_ipv6_routing_hdr *)pucPayloadPtr;
51 usNextHeaderOffset += sizeof(struct bcm_ipv6_routing_hdr);
52 usNextHeaderOffset += pstIpv6RoutingHeader->ucNumAddresses * IPV6_ADDRESS_SIZEINBYTES;
53
54 }
55 break;
56 case IPV6HDR_TYPE_FRAGMENTATION:
57 {
58 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
59 DBG_LVL_ALL,
60 "\nIPv6 Fragmentation Header");
61 usNextHeaderOffset += sizeof(struct bcm_ipv6_fragment_hdr);
62
63 }
64 break;
65 case IPV6HDR_TYPE_DESTOPTS:
66 {
67 struct bcm_ipv6_dest_options_hdr *pstIpv6DestOptsHdr = (struct bcm_ipv6_dest_options_hdr *)pucPayloadPtr;
68 int nTotalOptions = pstIpv6DestOptsHdr->ucHdrExtLen;
69 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
70 DBG_LVL_ALL,
71 "\nIPv6 DestOpts Header Header");
72 usNextHeaderOffset += sizeof(struct bcm_ipv6_dest_options_hdr);
73 usNextHeaderOffset += nTotalOptions * IPV6_DESTOPTS_HDR_OPTIONSIZE ;
74
75 }
76 break;
77 case IPV6HDR_TYPE_AUTHENTICATION:
78 {
79 struct bcm_ipv6_authentication_hdr *pstIpv6AuthHdr = (struct bcm_ipv6_authentication_hdr *)pucPayloadPtr;
80 int nHdrLen = pstIpv6AuthHdr->ucLength;
81 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
82 DBG_LVL_ALL,
83 "\nIPv6 Authentication Header");
84 usNextHeaderOffset += nHdrLen * 4;
85 }
86 break;
87 case IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD:
88 {
89 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
90 DBG_LVL_ALL,
91 "\nIPv6 Encrypted Security Payload Header");
92 *bParseDone = TRUE;
93
94 }
95 break;
96 case IPV6_ICMP_HDR_TYPE:
97 {
98 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
99 DBG_LVL_ALL, "\nICMP Header");
100 *bParseDone = TRUE;
101 }
102 break;
103 case TCP_HEADER_TYPE:
104 {
105 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
106 DBG_LVL_ALL, "\nTCP Header");
107 *bParseDone = TRUE;
108 }
109 break;
110 case UDP_HEADER_TYPE:
111 {
112 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
113 DBG_LVL_ALL, "\nUDP Header");
114 *bParseDone = TRUE;
115 }
116 break;
117 default:
118 {
119 *bParseDone = TRUE;
120
121 }
122 break;
123
124
125 }
126
127 if (*bParseDone == false) {
128 if (*pusPayloadLength <= usNextHeaderOffset) {
129 *bParseDone = TRUE;
130 } else {
131 *pucNextHeader = *pucPayloadPtr;
132 pucPayloadPtr += usNextHeaderOffset;
133 (*pusPayloadLength) -= usNextHeaderOffset;
134 }
135
136 }
137
138 *ppucPayload = pucPayloadPtr;
139 return pucRetHeaderPtr;
140}
141
142
143static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort,
144 USHORT *pusDestPort, USHORT usPayloadLength, UCHAR ucNextHeader)
145{
146 UCHAR *pIpv6HdrScanContext = pucPayload;
147 bool bDone = false;
148 UCHAR ucHeaderType = 0;
149 UCHAR *pucNextHeader = NULL;
150 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
151
152 if (!pucPayload || (usPayloadLength == 0))
153 return 0;
154
155 *pusSrcPort = *pusDestPort = 0;
156 ucHeaderType = ucNextHeader;
157 while (!bDone) {
158 pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext,
159 &ucHeaderType, &bDone, &usPayloadLength);
160 if (bDone) {
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,
166 DBG_LVL_ALL,
167 "\nProtocol Ports - Src Port :0x%x Dest Port : 0x%x",
168 ntohs(*pusSrcPort),
169 ntohs(*pusDestPort));
170 }
171 break;
172
173 }
174 }
175 return ucHeaderType;
176}
177
178
179/*
180 * Arg 1 struct bcm_mini_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
182 */
183USHORT IpVersion6(struct bcm_mini_adapter *Adapter, PVOID pcIpHeader,
184 struct bcm_classifier_rule *pstClassifierRule)
185{
186 USHORT ushDestPort = 0;
187 USHORT ushSrcPort = 0;
188 UCHAR ucNextProtocolAboveIP = 0;
189 struct bcm_ipv6_hdr *pstIpv6Header = NULL;
190 bool bClassificationSucceed = false;
191
192 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
193 DBG_LVL_ALL, "IpVersion6 ==========>\n");
194
195 pstIpv6Header = pcIpHeader;
196
197 DumpIpv6Header(pstIpv6Header);
198
199 /*
200 * Try to get the next higher layer protocol
201 * and the Ports Nos if TCP or UDP
202 */
203 ucNextProtocolAboveIP = GetIpv6ProtocolPorts((UCHAR *)(pcIpHeader + sizeof(struct bcm_ipv6_hdr)),
204 &ushSrcPort,
205 &ushDestPort,
206 pstIpv6Header->usPayloadLength,
207 pstIpv6Header->ucNextHeader);
208
209 do {
210 if (pstClassifierRule->ucDirection == 0) {
211 /*
212 * cannot be processed for classification.
213 * it is a down link connection
214 */
215 break;
216 }
217
218 if (!pstClassifierRule->bIpv6Protocol) {
219 /*
220 * We are looking for Ipv6 Classifiers
221 * Lets ignore this classifier and try the next one
222 */
223 break;
224 }
225
226 bClassificationSucceed = MatchSrcIpv6Address(pstClassifierRule,
227 pstIpv6Header);
228 if (!bClassificationSucceed)
229 break;
230
231 bClassificationSucceed = MatchDestIpv6Address(pstClassifierRule,
232 pstIpv6Header);
233 if (!bClassificationSucceed)
234 break;
235
236 /*
237 * Match the protocol type.
238 * For IPv6 the next protocol at end of
239 * Chain of IPv6 prot headers
240 */
241 bClassificationSucceed = MatchProtocol(pstClassifierRule,
242 ucNextProtocolAboveIP);
243 if (!bClassificationSucceed)
244 break;
245
246 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
247 DBG_LVL_ALL, "\nIPv6 Protocol Matched");
248
249 if ((ucNextProtocolAboveIP == TCP_HEADER_TYPE) ||
250 (ucNextProtocolAboveIP == UDP_HEADER_TYPE)) {
251 /* Match Src Port */
252 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
253 DBG_LVL_ALL, "\nIPv6 Source Port:%x\n",
254 ntohs(ushSrcPort));
255 bClassificationSucceed = MatchSrcPort(pstClassifierRule,
256 ntohs(ushSrcPort));
257 if (!bClassificationSucceed)
258 break;
259
260 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
261 DBG_LVL_ALL, "\nIPv6 Src Port Matched");
262
263 /* Match Dest Port */
264 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
265 DBG_LVL_ALL, "\nIPv6 Destination Port:%x\n",
266 ntohs(ushDestPort));
267 bClassificationSucceed = MatchDestPort(pstClassifierRule,
268 ntohs(ushDestPort));
269 if (!bClassificationSucceed)
270 break;
271 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
272 DBG_LVL_ALL, "\nIPv6 Dest Port Matched");
273 }
274 } while (0);
275
276 if (bClassificationSucceed == TRUE) {
277 INT iMatchedSFQueueIndex = 0;
278 iMatchedSFQueueIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID);
279 if (iMatchedSFQueueIndex >= NO_OF_QUEUES) {
280 bClassificationSucceed = false;
281 } else {
282 if (Adapter->PackInfo[iMatchedSFQueueIndex].bActive == false)
283 bClassificationSucceed = false;
284 }
285 }
286
287 return bClassificationSucceed;
288}
289
290
291static bool MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
292 struct bcm_ipv6_hdr *pstIpv6Header)
293{
294 UINT uiLoopIndex = 0;
295 UINT uiIpv6AddIndex = 0;
296 UINT uiIpv6AddrNoLongWords = 4;
297 ULONG aulSrcIP[4];
298 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
299 /*
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
302 */
303 UINT uiCountIPSrcAddresses = (UINT)pstClassifierRule->ucIPSourceAddressLength;
304
305
306 if (uiCountIPSrcAddresses == 0)
307 return TRUE;
308
309
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]);
313
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]);
324
325 for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) {
326 if ((pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulSrcIP[uiIpv6AddIndex])
327 != pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) {
328 /*
329 * Match failed for current Ipv6 Address
330 * Try next Ipv6 Address
331 */
332 break;
333 }
334
335 if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) {
336 /* Match Found */
337 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
338 DBG_LVL_ALL,
339 "Ipv6 Src Ip Address Matched\n");
340 return TRUE;
341 }
342 }
343 }
344 return false;
345}
346
347static bool MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
348 struct bcm_ipv6_hdr *pstIpv6Header)
349{
350 UINT uiLoopIndex = 0;
351 UINT uiIpv6AddIndex = 0;
352 UINT uiIpv6AddrNoLongWords = 4;
353 ULONG aulDestIP[4];
354 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
355 /*
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
359 */
360 UINT uiCountIPDestinationAddresses = (UINT)pstClassifierRule->ucIPDestinationAddressLength;
361
362
363 if (uiCountIPDestinationAddresses == 0)
364 return TRUE;
365
366
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]);
370
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]);
381
382 for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) {
383 if ((pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulDestIP[uiIpv6AddIndex])
384 != pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) {
385 /*
386 * Match failed for current Ipv6 Address.
387 * Try next Ipv6 Address
388 */
389 break;
390 }
391
392 if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) {
393 /* Match Found */
394 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
395 DBG_LVL_ALL,
396 "Ipv6 Destination Ip Address Matched\n");
397 return TRUE;
398 }
399 }
400 }
401 return false;
402
403}
404
405VOID DumpIpv6Address(ULONG *puIpv6Address)
406{
407 UINT uiIpv6AddrNoLongWords = 4;
408 UINT uiIpv6AddIndex = 0;
409 struct bcm_mini_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]);
413 }
414
415}
416
417static VOID DumpIpv6Header(struct bcm_ipv6_hdr *pstIpv6Header)
418{
419 UCHAR ucVersion;
420 UCHAR ucPrio;
421 struct bcm_mini_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);
430 /*
431 * BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
432 * "Flow Label : %x\n",(pstIpv6Header->ucVersionPrio &0xf0);
433 */
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,
442 "Src Address :\n");
443 DumpIpv6Address(pstIpv6Header->ulSrcIpAddress);
444 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
445 "Dest Address :\n");
446 DumpIpv6Address(pstIpv6Header->ulDestIpAddress);
447 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
448 "----Ipv6 Header End---");
449
450
451}