bogdanPricope replied on github web page:

include/odp/api/spec/packet.h
@@ -1140,6 +1179,82 @@ int odp_packet_move_data(odp_packet_t pkt, uint32_t 
dst_offset,
  */
 
 /**
+ * Packet parse parameters
+ */
+typedef struct odp_packet_parse_param_t {
+       /** Protocol header at parse starting point. Valid values for this
+        *  field are: ODP_PROTO_ETH, ODP_PROTO_IPV4, ODP_PROTO_IPV6. */
+       odp_proto_t proto;
+
+       /** Continue parsing until this layer. Must be the same or higher
+        *  layer than the layer of 'proto'. */
+       odp_proto_layer_t layer;
+
+       /** Flags to control payload data checks up to the selected parse
+        *  layer. Checksum checking status can be queried for each packet with
+        *  odp_packet_l3_chksum_status() and odp_packet_l4_chksum_status().
+        */
+       union {
+               struct {
+                       /** Check IPv4 header checksum */
+                       uint32_t ipv4_chksum   : 1;
+
+                       /** Check UDP checksum */
+                       uint32_t udp_chksum    : 1;
+
+                       /** Check TCP checksum */
+                       uint32_t tcp_chksum    : 1;
+
+               } check;
+
+               /** All check bits. This can be used to set/clear all flags. */
+               uint32_t all_check;
+       };
+
+} odp_packet_parse_param_t;
+
+/**
+ * Parse packet
+ *
+ * Parse protocol headers in packet data. Parsing starts at 'offset', which
+ * is the first header byte of protocol 'param.proto'. Parameter 'param.layer'
+ * defines the last layer application is interested about.
+ * Use ODP_PROTO_LAYER_ALL for all layers. The operation sets or resets packet
+ * metadata for all layers from the layer of 'param.proto' to the application
+ * defined last layer. Metadata of other layers have undefined values.
+ * When operation fails, metadata of all protocol layers have undefined values.


Comment:
Then: "When operation fails, metadata of all protocol layers remains 
unchanged." ?


> bogdanPricope wrote
> OK


>> bogdanPricope wrote
>> Processing of UDP/TCP (in OFP and BSD like) depends on IPv4/IPv6: there are 
>> different input functions for UDP/TCP processing for IPv4 and IPv6 
>> (https://github.com/OpenFastPath/ofp/blob/master/src/ofp_in_proto.c, 
>> https://github.com/OpenFastPath/ofp/blob/master/src/ofp_in6_proto.c)


>>> Petri Savolainen(psavol) wrote:
>>> Then I don't add it now. We can add param init also later if param struct 
>>> is extended with other things than check flags. Todays spec defines already 
>>> that all flags should be set to zero.
>>> 
>>>      @param param   Parse parameters. Proto and layer fields must be set. 
>>> Clear
>>>                   all check bits that are not used.


>>>> Petri Savolainen(psavol) wrote:
>>>> Fail means an operation error (bad param, internal error), not e.g. error 
>>>> in packet header formats.


>>>>> Petri Savolainen(psavol) wrote:
>>>>> Application calls parse because metadata is not valid to begin with. 
>>>>> There would not be much benefit for application to require that 
>>>>> implementation saves old metadata values before the operation and then 
>>>>> restores those after if e.g. an internal error occurred. Implementation 
>>>>> performance would be hurt by making a copy of the old metadata.
>>>>> 
>>>>> Since it's just (L2/L3/L4) metadata (not data) that may have changed, 
>>>>> application can continue processing the packet data also after a failed 
>>>>> parse. 


>>>>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>>>>> @psavol ok, agreed


>>>>>>> Petri Savolainen(psavol) wrote:
>>>>>>> This function is different from e.g. enqueue multi, where the 
>>>>>>> destination queue may be close to full and that's why only part of 
>>>>>>> events were enqueued. Here operation fails due to bad params or 
>>>>>>> internal error.
>>>>>>> 
>>>>>>> Anyway, I'll change it to return num processed. It's more flexible.


>>>>>>>> bogdanPricope wrote
>>>>>>>> What about: "When operation fails, metadata of checked layers 
>>>>>>>> indicates the error condition."?


>>>>>>>>> bogdanPricope wrote
>>>>>>>>> What about: "Metadata of other layers remains unmodified."? 


>>>>>>>>>> Petri Savolainen(psavol) wrote:
>>>>>>>>>> Layer is not enough information for the parser. It needs to know the 
>>>>>>>>>> first protocol (e.g. MPLS vs IP) to be able to start the parsing.


>>>>>>>>>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>>>>>>>>>> @psavol `_param_init` seems like an overkill in this case. From my 
>>>>>>>>>>> point of view, `param_init` are good for object creation params 
>>>>>>>>>>> (where we might not know platform-optimized defaults) but are an 
>>>>>>>>>>> overkill for operation functions (we do not have `param_init` for 
>>>>>>>>>>> ipsec, crypto, etc operational params).


>>>>>>>>>>>> Petri Savolainen(psavol) wrote:
>>>>>>>>>>>> No, other APIs order checksum checking the same way: per protocol. 
>>>>>>>>>>>> Application may be e.g. terminating only UDP and forwarding all 
>>>>>>>>>>>> others - so it would be waste to check e.g. TCP checksum.
>>>>>>>>>>>> 
>>>>>>>>>>>> typedef union odp_pktin_config_opt_t {
>>>>>>>>>>>>    /** Option flags */
>>>>>>>>>>>>    struct {
>>>>>>>>>>>>            /** Timestamp all packets on packet input */
>>>>>>>>>>>>            uint64_t ts_all        : 1;
>>>>>>>>>>>> 
>>>>>>>>>>>>            /** Timestamp (at least) IEEE1588 / PTP packets
>>>>>>>>>>>>              * on packet input */
>>>>>>>>>>>>            uint64_t ts_ptp        : 1;
>>>>>>>>>>>> 
>>>>>>>>>>>>            /** Check IPv4 header checksum on packet input */
>>>>>>>>>>>>            uint64_t ipv4_chksum   : 1;
>>>>>>>>>>>> 
>>>>>>>>>>>>            /** Check UDP checksum on packet input */
>>>>>>>>>>>>            uint64_t udp_chksum    : 1;
>>>>>>>>>>>> 
>>>>>>>>>>>>            /** Check TCP checksum on packet input */
>>>>>>>>>>>>            uint64_t tcp_chksum    : 1;


>>>>>>>>>>>>> Petri Savolainen(psavol) wrote:
>>>>>>>>>>>>> Param init on fast path is a bit overkill. However, application 
>>>>>>>>>>>>> could call it once and store the result. So, it could avoid extra 
>>>>>>>>>>>>> function call for every packet. So, I'll add it.


>>>>>>>>>>>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>>>>>>>>>>>>> `return i;` if we adopt the RC == number of successful packets 
>>>>>>>>>>>>>> parsed convention.


>>>>>>>>>>>>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>>>>>>>>>>>>>> For consistency with other `odp_xxx_multi()` APIs, the RC 
>>>>>>>>>>>>>>> should indicate the number of input packets that were 
>>>>>>>>>>>>>>> successfully processed. 


>>>>>>>>>>>>>>>> muvarov wrote
>>>>>>>>>>>>>>>> it looks like 2 enums are not needed here. odp_proto_layet_t  
>>>>>>>>>>>>>>>> layer_start; and  odp_proto_layet_t  layer_end;  and one enum 
>>>>>>>>>>>>>>>> for layers.


>>>>>>>>>>>>>>>>> muvarov wrote
>>>>>>>>>>>>>>>>> maybe return number of correctly parsed packets? And say that 
>>>>>>>>>>>>>>>>> parsing always starts from be beginning of array. 


>>>>>>>>>>>>>>>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>>>>>>>>>>>>>>>>> +1 since other checksum APIs refer to L3 and L4 rather than 
>>>>>>>>>>>>>>>>>> specific protocols. 


>>>>>>>>>>>>>>>>>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>>>>>>>>>>>>>>>>>> What about just `l3_chksum`, and `l4_chksum`? 


>>>>>>>>>>>>>>>>>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>>>>>>>>>>>>>>>>>>> Now that we have a `param` struct we should have an 
>>>>>>>>>>>>>>>>>>>> `odp_packet_parse_param_init()` API as well for 
>>>>>>>>>>>>>>>>>>>> completeness.


>>>>>>>>>>>>>>>>>>>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>>>>>>>>>>>>>>>>>>>> @Bill-Fischofer-Linaro Because it is a parsing error, if 
>>>>>>>>>>>>>>>>>>>>> lower layer provides us IP version that does not 
>>>>>>>>>>>>>>>>>>>>> correspond to the in-packet version. We should detect 
>>>>>>>>>>>>>>>>>>>>> that, rather than silently parsing this header.


>>>>>>>>>>>>>>>>>>>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>>>>>>>>>>>>>>>>>>>>> I'm not sure why an API named `odp_packet_parse()` needs 
>>>>>>>>>>>>>>>>>>>>>> help here. It's purpose, after all, is to parse packets 
>>>>>>>>>>>>>>>>>>>>>> and determining IPv4 vs IPv6 is part of that activity. 
>>>>>>>>>>>>>>>>>>>>>> Moreover, the only way an application can inspect the IP 
>>>>>>>>>>>>>>>>>>>>>> header is to access it via other ODP API calls, so I 
>>>>>>>>>>>>>>>>>>>>>> don't see how asking the application to do this is any 
>>>>>>>>>>>>>>>>>>>>>> better than having the `odp_packet_parse()` 
>>>>>>>>>>>>>>>>>>>>>> implementation do this itself. What's the purpose of 
>>>>>>>>>>>>>>>>>>>>>> having a parse API in that case since clearly the 
>>>>>>>>>>>>>>>>>>>>>> application could parse the entire packet "by hand" as 
>>>>>>>>>>>>>>>>>>>>>> well.


>>>>>>>>>>>>>>>>>>>>>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>>>>>>>>>>>>>>>>>>>>>> Failure needs to be defined in a more precise way (and 
>>>>>>>>>>>>>>>>>>>>>>> maybe for a single packet case). I assume that it means 
>>>>>>>>>>>>>>>>>>>>>>> internal ODP error, rather than just packet with wrong 
>>>>>>>>>>>>>>>>>>>>>>> headers. What happens in multi-packet case if failure 
>>>>>>>>>>>>>>>>>>>>>>> occurs in the middle of parsing?


>>>>>>>>>>>>>>>>>>>>>>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>>>>>>>>>>>>>>>>>>>>>>> @psavol Also for multi-packet parsing, we can change 
>>>>>>>>>>>>>>>>>>>>>>>> `proto` to be an array, allowing applications to 
>>>>>>>>>>>>>>>>>>>>>>>> easily intermix IPv4 and IPv6 packets.


>>>>>>>>>>>>>>>>>>>>>>>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>>>>>>>>>>>>>>>>>>>>>>>> @psavol yes. I just wanted to focus on cases, when 
>>>>>>>>>>>>>>>>>>>>>>>>> passing packet with wrong protocol is an error. E.g. 
>>>>>>>>>>>>>>>>>>>>>>>>> IPv6 packet inside IPsec packet with NH = 4. So it is 
>>>>>>>>>>>>>>>>>>>>>>>>> not a question of selecting proper L3 parser, but 
>>>>>>>>>>>>>>>>>>>>>>>>> rather a question of nailing down error/malicious 
>>>>>>>>>>>>>>>>>>>>>>>>> packets.


>>>>>>>>>>>>>>>>>>>>>>>>>> Petri Savolainen(psavol) wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>> It's there to enable application to call parsing in 
>>>>>>>>>>>>>>>>>>>>>>>>>> parts - e.g. first up to IP and then continue from 
>>>>>>>>>>>>>>>>>>>>>>>>>> L4. But since IP and transport protocols are tied 
>>>>>>>>>>>>>>>>>>>>>>>>>> together with pseudo headers, it's cleaner to remove 
>>>>>>>>>>>>>>>>>>>>>>>>>> L4 as a starting point. 


>>>>>>>>>>>>>>>>>>>>>>>>>>> Petri Savolainen(psavol) wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>> First bits of an IP header marks the version. So, 
>>>>>>>>>>>>>>>>>>>>>>>>>>> it would be trivial for both app and implementation 
>>>>>>>>>>>>>>>>>>>>>>>>>>> to read the version from the data. Common IP define 
>>>>>>>>>>>>>>>>>>>>>>>>>>> is easier for application when a burst of packets 
>>>>>>>>>>>>>>>>>>>>>>>>>>> may contain both v4 and v6 mixed. Application does 
>>>>>>>>>>>>>>>>>>>>>>>>>>> not need to sort  packets into two arrays (one for 
>>>>>>>>>>>>>>>>>>>>>>>>>>> v4 and other for v6) but just pass the entire array 
>>>>>>>>>>>>>>>>>>>>>>>>>>> for parsing.
>>>>>>>>>>>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>>>>>>>>>>> There are three ways to define the enumeration: IP, 
>>>>>>>>>>>>>>>>>>>>>>>>>>> IPv4+IPv6, IP+IPv4+IPv6. I'm OK with any of those. 
>>>>>>>>>>>>>>>>>>>>>>>>>>> IPv4+IPv6 would be a bit more robust since version 
>>>>>>>>>>>>>>>>>>>>>>>>>>> information comes from two sources.


>>>>>>>>>>>>>>>>>>>>>>>>>>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> I felt easier to reparse both L3 and L4 headers in 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> IPsec case, especially since transport mode ESP 
>>>>>>>>>>>>>>>>>>>>>>>>>>>> can en/decrypt some of L3 headers in IPv6 case. 


>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @Bill-Fischofer-Linaro In IPsec case Next Header 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> field will contain 4 for IPv4 and 41 for IPv6.


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> That might be overly complicated since until a 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> decrypted tunnel mode IPsec packet is parsed you 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> don't know whether it's IPv4 or IPv6. It's 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> parsing that makes that determination.


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @lumag IPsec operating in transport mode is, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I'd imagine, the main use case here.


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> What is the usecase for parsing a packet 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> starting from L4 header? Also there are 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> several (lots) of other L4 protocols. Do we 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> want to support them all here?


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Maybe it would be better to split this into 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> separate IPv4 and IPv6 packets. It would be 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> an error to pass IPv6 packet with ethtype (or 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IP tunnel type) being set to IPv4. 


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Petri Savolainen(psavol) wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> A vector of packets is CPU vector 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> instructions friendly.


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Petri Savolainen(psavol) wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The use case is mentioned in log message: 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> parse after decrypt/IP reassembly. 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Application has recreated an inner packet 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and needs to parse it before continue. This 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> is inherently SW parse which may be 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> accelerated with CPU vector instructions, 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> etc.


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Bill Fischofer(Bill-Fischofer-Linaro) 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> What's the use case for a multi() form of 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> this API? Might VPP use it? Perhaps Sachin 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> can comment?


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Bill Fischofer(Bill-Fischofer-Linaro) 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> We had considered an `odp_packet_parse()` 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> function some time back but it was 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rejected as something that would not fit 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> well with hardware parsers. What's 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> changed?


https://github.com/Linaro/odp/pull/273#discussion_r149945169
updated_at 2017-11-09 12:49:44

Reply via email to