Eric,
I am trying to make a change to my design to be able to do the steps described below but am running into problems. The example below is on a single core but of course I intend to extend the idea to multicore.
For IPv4 and UDP packets, I want the PA after matching on MAC address and then IP address and protocol type and ip type matching to be directed to a regular LUT2 port # matching, if it fails then I want it to be directed to a custom LUT2 entry with a arange of UDP ports. So for example UDP port 0x8000 could be the port # I am trying to match on using the pa_addPort command and then if it fails then I want to setup in the pa_addIp to have the nextrtFail set to use custom LUT2 with a range of UDP ports. I am trying to do this so that I can have the PA differentiate between say port 0x8000 and ports 0x8001-0x80FF and can then have the PA tag them with different swInfo words and also possible remove the ethernet and other headers for those packets received on port 0x8000.
Is what I am trying feasible? I cannot see any reason why it should not be the case but...
When I tried setting up by using the pa_addIp command with routeInfo set to {DEST_CONTINUE_LUT2, no custom type} and ntFailInfo set to {DEST_CONTINUE_LUT2, custom LUT2 type and custom Index = 1), the PA LLD returned error -10 which is errconfig. Looking through the pa LLD code for pa_addIp it points to only two cases when this happens:
1. if the ipInfo fields spi, greProto, sctpPort are non-zero which is not the case for my ipInfo structure.
2. if the iptype is not IPV4 or IPv6 which is again not the case for me.
Thanks, Aamir
Hi, Aamir:
Unfortunatly, I am not sure your intended use case is feasible. When a LUT1 entry is added, the caller can specify a routeInfo which will be invoked when match occurs and a nextFail routeInfo which will be invoked only if the packet is delivered to the next stage and no matched occurs. Please note that we can not deliver the packet back to the previous stage or perform another match at the current stage.Therefore, the only option for the nextFail route is to discard the packet or deliver it to host queue.
The error is caused by unsupported nextFail Route configuration.
Please click the "verify answer" button if I answer your question.
Best reagrds,
Eric
Thanks for your reply. Okay so I cannot setup the nextRtFail to be anything other than discard or send to host.
What happens if two entries in a stage match a packet i.e. Can one enter two entries on particular stage that will result in a packet matching both of them? If that is allowed, what is the behaviour of the PA?
I have a case of four LUT1 entries (checking for IP type and protocols) linked to the same MAC entry so I would think a packet that matches on the MAC entry would then go the level 1 match and check the first IP entry if it matches, then onto the custom LUT2 entry linked to it, otherwise it will try the second entry and so on, discarding the packet if it remains unmatched (Is this not performing another match at the current stage?). So using the same idea, should I not be able to have two LUT2 entries linked to the IPv4 and UDP LUT1 entry and when it matches on the particular port # on the first entry, it sends to the host with a swInfo word. If it fails it then try to match on the second entry which is on a range of ports and if it matches it sends to the host too but with a different swInfo word. The packet with UDP port # 0x8000 matches on the first so will not make it through to subsequent entries but those with ports 0x8001 to ox80ff make it through to the custom LUT2 rule that matches on the range of ports.
Is their any way I might be able to do what I am requesting within the confines of the PA currently? What about in the future with changes to the PA (so long as it is within software changes and does not require any hardware change to the PA)? Of course, I could handle the packets differently on the corePac when they are received but having the PA do this would provide a very elegant design as well as a performance and memory boost if I could strip of the headers in the headers in the PA for those packets that match on the single port # as I am not interested in all of those headers for traffic on that port #. I have another thread on this subject and David Brown has replied that I cannot do so. I have a reply to that and a query on the use of the option pa_CMD_REMOVE_HEADER within the pa_configCmdSet function.
Have you checked the PA version?I believe that you are using an old version of PA LLD. Please consider to upgrade.
What happens if two entries in a stage match a packet?[Eric] No, the PASS will only match the first entry only. That is why we need to enter the more general entry to PASS berfore the more specific entry is added.
[Eric] No, that is not how it works. PASS will perform a single lookup at each stage, if there is a match, the packet will be delivered to the next stage or the host queue based on the routing information, if there is no match, the packet will be discarded or follow the nextFail route of the previous match.
Is their any way I might be able to do what I am requesting within the confines of the PA currently?[Eric] No, PASS is not designed to do what you ask for.
I am not going to answer the other thread since I have already provided the answer here.
Best regards,
thanks for your reply. Okay I am resigned to the fact that the PA is not able to do what I am suggesting.
P.s: what is the use of the config CmdSet generally speaking and what is the use case of the pa_CMD_REMOVE_HEADER? What is the parsed header that it is talking about?
Please refer to pa.h or the PA doxygen for the general usage of tx commands and rx commad set operations!The pa_CMD_REMOVE_HEADER and pa_CMD_REMOVE_TAIL can be used to remove the current protocol header and other protocol tails so that only the protocol payload is delivered to the host queue. For example:
AfterLUT1 stage 1: MAC payload (including CRC)LUT1 stage 2: IP payloadLUT2 stage 1: UDP/TCP payload
I have had a look through the pa.h and the PA doxygen to get a sense of how the command actually operates and I feel that the documentation is inadequate in my opinion to address how to effectively use the PA and all of its features to do what I want in particular with the command set operation. It really could to with more examples that will specify when and how you call the function through examples. If as you say the pa_CMD_REMOVE_HEADER can be used to remove headers then it begs the question that I should then be able to at least strip off all of the headers in the packets before sending them to the host for the case of UDP IPv4 packets.
Can you provide some guidance on how I could go about calling the function and the settings etc? Can I setup the PA such that it only strips of the headers for certain matches i.e. those tied to UDP and IPv4. In other words can I configure the cmd set operation and then reset it back to normal for other entries.
My PASS_setup works as follows for core 0 for IPv4 UDP packets as shown below. I have added more calls at step 2, 3 and 4 below for ICMP, IPv6 UDP and ICMP v6
1. It adds the mac address for stage 1 through a call to ADD_MACAddress()
2. It then adds the IPV4 UDP rule entry to LUT1 by calling Add_IPAddress() which calls the pa_addIp with ipLink=0, cusIndex=0
3. It then configures the UDP port range for the cores by calling a function Config_PortRange that calls the pa_setCustomLUT2() and pushes command to PA and waits for response. The pa_setCustomLUT2 call uses custIndex=0, byteOffset={2, 3, 4, 5} and byteMask={0x7, 0, 0, 0}
The step below is done for all cores.
4. It then setups the LUT2 custom entry by calling the function Add_Portrange() which calls the pa_addCustomLUT2() and pushes the command and waits for the response. The pa_addCustomLUT2 call uses custIndex=0 and ipLink=0 linking this to the ip entry setup previously. Also match= {coreNum, 0, 0, 0}
If I call the pa_configCmdSet with index=0, nCmd=1 as I just have one command pa_CMD_REMOVE_HEADER and the command array is specified in tCmdSet which is
paCmdInfo_t tCmdSet[] = {
pa_CMD_REMOVE_HEADER
{
the fields ctrbbitfield,dest,pkttype,flowid,queue,swInfo0,swInfo1,multiroute? - not sure of the settings here?
}
Also where do I call the function that calls the pa_configCmdSet() and pushes to PA and awaits response. Before the Add_mac or after all of the steps or before the Add_PortRange? Note the queues used are 900 for core 0, 901 for core 1 etc and the flowIds are obtained by the getFlowId
Can you provide some guidance here.
THanks, Aamir
Just an update on what I tried to do. I setup a function Config_StripHeader() which calls pa_configCmdSet as specified in my previous post with index=0, nCmds=1 and pa_CMD_REMOVE_HEADER with the rest of the fields all zero.
I then called this function prior to the Add_mac() call. In the Add_PortRange() function which calls the pa_addCustomLUT2 I added &t5CmdSetCmd to the routeInfo last field pCmd.
I specified the t5CmdSetCmd as paCmdInfo_t t5CmdSetCmd = { pa_CMD_CMDSET
{ 0 }
When I sent a packet to the shannon DSP, In the buffer I see that the Ethernet and IP headers have been striped but the UDP header is still there and after my data pachet which is 4 bytes long I get some extra bytes there. Can you shed some light on what is happening?
I am glad that you figure out the right way to invoke the cmdSet feature. You might have found some (not perfect) examples at PA unit tests.Unfortunately the "Remove Header" command will not solve your problem completely since you are using customLUT1 and customLUT2 operation so that the PASS does not know the custom header size and the end of payload. Therefore this operation does not remove the UDP header. The extra 4 bytes at the end of packet is CRC. If you do normal protocol parsing operation then you can invoke "Remove Tail" command to remove the CRC bytes.
Hi Eric,
I had figured out today how to remove the extra bytes at the end by making use of the "remove tail" operation. It is frustrating that I am so close to getting what I want but cannot get that last little bit solved.However it does not seem like it was a CRC as that is what I was suspecting. The reason why I say that is I tried keeping the data bytes over words or shorts to be the same. So I tried two packets one with data 0xfdfdfdfd00000000 and the other with data 0x00000000fdfdfdfd and they both resulted in different 4 bytes at the end so I concluded it could not be a CRC.
I basically have IPV4 UDP packets addressed to a single port which is the start of the port range with ethernet and IP headers removed and all other ports in the port range I do not have the headers removed. I did that through calling the pa_addCustomLUT2 for each port and matching on the 2nd LSByte in the UDP dest port #. Also I have IPv6 and ICMP, ICMPv6 packets pass through without stripping headers like I want. Anyways I think this may just do. I have to think a little bit more about it.
Thanks for your help.
Aamir
I am not sure about your test environment and all the configurations. All the ingress packerts from the CPSW will contain the 4-byte MAC CRC and so internal end packet offset will point to the end of packet. This pointer will be set to end of the protocol payload offset if a known L3/L4 protocol header such as IP and/or UDP/TCP has been processed so that you will be able to use "Remove Tail" command to get rid of them.
We have enhanced the "Patch command" to be able to remove specific number of bytes in the packet. This feature is available at BIOS-MCSDK 2.0.7.
I take it the 4 bytes are supposed to represent the frame check sequence after the ethernet payload in an ethernet frame. I take it by default when not making use of the set command, the tail (these 4 bytes CRC) is removed prior to sending the packet data from the PA as it obviously does not show up in the buffers in the host. Is it when the routeInfo field pCmd is set to NULL, the start packet offset is set to the start of the ethernet header and the end packet offset is set to the start of the CRC so the CRC is not sent. When one uses pCmd to be set to something other than NULL, the start packet offset is roving and so as we are parsing the packet in the various LUT stages, and so it is being set to the start of the data but the end packet offset is being set to end of the data including tail i.e. CRC because of the use of the custom LUT2 rule. So if I had not used custom LUT2 and used pCmd and removed the header, once it removed the parsed UDP header it would also remove the tail i.e. CRC. Am I making sense?
I take it from your reply that I can use the "patch" command that is provided in BIOS_MCSDK 2.0.7 to strip of the remaining UDP header even though it is making use of custom LUT2. When is 2.0.7 available?
I just wanted to give you a flavour of why stripping this off really helps us. Basically we use the start of the IPv4 UDP port range i.e. port 0 and 1 in a range of 256 ports say to mimic command traffic to our application and so want to distinguish it from regular RTP traffic which is encapsulated within UDP and IPv4. For IPv6 we only have RTP traffic. Our command traffic packet is UDP data with a proprietary header at the start of the command packet so stripping off the Ethernet, IP and UDP headers make the first thing you see in a buffer linked to a descriptor as the proprietary header. For RTP data I envision creating holes in the buffer to place the proprietary header so that when the DSP core looks at any particular packet sent to the core for further processing, the common thing it sees is the proprietary header keeping it consistent with our current product implementation. In our current implementation the proprietary header is added by FPGAs in our hardware.
So my current implementation of the PA etc results in the following in the 256 byte long buffers to store incoming packets
IPv4 UDP port base+0/1: UDP header, then UDP data
IPV4 UDP other ports base + 2-255 say: Ethernet, IP, UDP headers followed by UDP data.
IPv6 UDP: same as above
ICMP and ICMPv6: same as above except inset ICMP in place of UDP.
[Eric] No, it does not make any sense. The PASS protocol parsing opertaion has nothing to do with the routing rule of the matched traffic. As I explained before, the endOffset will point to the end of IP or UDP payload (i.e. excluding L2 CRC) only if the normal IP or UDP pasring is done respectively. In that case, the L2 CRC can be removed by the "REMOVE_TAIL" command.
[Eric] Yes. BIOS-MCSDK 2.0.7 is available at http://software-dl.ti.com/sdoemb/sdoemb_public_sw/bios_mcsdk/latest/index_FDS.html. Please refer to the releaseNotes to find out all feature enhancements, bug fixes and API changes since the current release used.
Thanks for the clarification. I incorrectly though the L2 CRC was not included in the packets received by the host. I just was not paying attention to the bytes at the end of the packet in my earlier testing but only realized the CRC bytes being included when some of the headers were removed so yes my questioning does not make any sense now. I have got the PA stripping of headers and tails for IPv4 UDP on a specific port and removing tails otherwise. I will try mcsdk 2.0.7.
I was unable to post this last week as I was having problems posting on teh Ti website due to some firewall setting changes. Anyways here is my email that I ahd composed for posting last week.
I upgraded my MCSDK to use 2.0.7 and my CCS to 5.1.1, I was able to compile and run my multicore code. However, I ran into two issues.
First problem was not happening for me when I was using the older MCSDK and PDK. I would call my function Add_portRange () which calls the pa_addCustomLUT2 with the match[0] = coreNum and match[1] going from i=0 to 127 where i=0 corresponds to UDP port 0/1 pair, i=1 corresponds to port 2/3 pair etc. This would then basically create 128 lut2 entries for custom index 0 linked to lut1 index 0 for ip filtering for matching UDP IPv4 packets. However, after upgrading I am unable to run my loop to 128 times as it aborts on the i=124 run with pa_addCustomLUT2 returning error -11 which is insufficient command size which does not make sense as it should not work then for any i. My Pa_addCustomLUT2 call in the function Add_portRange() looks like the following with custIndex=0 and ipLink=0
retVal = Pa_addCustomLUT2 (gPAInstHnd, custIndex, match, gPaL3Handles [ipLink], FALSE, pa_PARAMS_NOT_SPECIFIED, &routeInfo, gPaL4Handles[custIndex], (paCmd_t) pHostDesc->buffPtr, &cmdSize, &cmdReplyInfo, &cmdDest);
Second issue is the use of the patch data command. This is what I did and it did not seem to work in getting rid of the UDP header. I had the remove header before this command and the remove tail after this command and called the pa_configCmdSet with index=0 and nCmds=3 as they are 3 commands now. Am I using the command incorrectly as I do not really have an example to go by.
/* Command 1: Remove UDP header by */ { pa_CMD_PATCH_DATA, { { pa_PATCH_OP_DELETE, /* ctrlBitfield */ 8, /* nPatchBytes */ 0, /* totalPatchSize */ 0, /* offset */ NULL, /* *patchData */ } } },
where the configCmdSet call is as follows and the headerAndTailCmdSet is an array of 3 commands, remove header; patch data and remove tail.
retVal = Pa_configCmdSet (gPAInstHnd, index, nCmd, ((index == 0) ? headerAndTailCmdSet : tailCmdSet), (paCmd_t) pHostDesc->buffPtr, &cmdSize, &cmdReplyInfo, &cmdDest);
Could you please start a new thread for any new issue?! It is so confused with the unrelated message title.If you just want to ping me, you could send a short response to the existing chain and just points to the new post.
For question #1, there seems to be an uninitialized variable issue. How do you set the variable cmdSize? You can set a break point and examine the value prior to API pa_addCustomLUT2 call.
For question #2, there seems to be an issue with the current implementation. Can you send me the expected packet and the actual packet received?!