3 static BOOLEAN
MatchSrcIpv6Address(struct bcm_classifier_rule
*pstClassifierRule
,
4 struct bcm_ipv6_hdr
*pstIpv6Header
);
5 static BOOLEAN
MatchDestIpv6Address(struct bcm_classifier_rule
*pstClassifierRule
,
6 struct bcm_ipv6_hdr
*pstIpv6Header
);
7 static VOID
DumpIpv6Header(struct bcm_ipv6_hdr
*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 struct bcm_mini_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(struct bcm_ipv6_options_hdr
);
45 case IPV6HDR_TYPE_ROUTING
:
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
;
56 case IPV6HDR_TYPE_FRAGMENTATION
:
58 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV6_DBG
,
60 "\nIPv6 Fragmentation Header");
61 usNextHeaderOffset
+= sizeof(struct bcm_ipv6_fragment_hdr
);
65 case IPV6HDR_TYPE_DESTOPTS
:
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
,
71 "\nIPv6 DestOpts Header Header");
72 usNextHeaderOffset
+= sizeof(struct bcm_ipv6_dest_options_hdr
);
73 usNextHeaderOffset
+= nTotalOptions
* IPV6_DESTOPTS_HDR_OPTIONSIZE
;
77 case IPV6HDR_TYPE_AUTHENTICATION
:
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
,
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 struct bcm_mini_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 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
183 USHORT
IpVersion6(struct bcm_mini_adapter
*Adapter
, PVOID pcIpHeader
,
184 struct bcm_classifier_rule
*pstClassifierRule
)
186 USHORT ushDestPort
= 0;
187 USHORT ushSrcPort
= 0;
188 UCHAR ucNextProtocolAboveIP
= 0;
189 struct bcm_ipv6_hdr
*pstIpv6Header
= NULL
;
190 BOOLEAN bClassificationSucceed
= FALSE
;
192 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, IPV6_DBG
,
193 DBG_LVL_ALL
, "IpVersion6 ==========>\n");
195 pstIpv6Header
= (struct bcm_ipv6_hdr
*)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(struct bcm_ipv6_hdr
)),
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(struct bcm_classifier_rule
*pstClassifierRule
,
292 struct bcm_ipv6_hdr
*pstIpv6Header
)
294 UINT uiLoopIndex
= 0;
295 UINT uiIpv6AddIndex
= 0;
296 UINT uiIpv6AddrNoLongWords
= 4;
298 struct bcm_mini_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(struct bcm_classifier_rule
*pstClassifierRule
,
348 struct bcm_ipv6_hdr
*pstIpv6Header
)
350 UINT uiLoopIndex
= 0;
351 UINT uiIpv6AddIndex
= 0;
352 UINT uiIpv6AddrNoLongWords
= 4;
354 struct bcm_mini_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 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
]);
417 static VOID
DumpIpv6Header(struct bcm_ipv6_hdr
*pstIpv6Header
)
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
);
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---");