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