On 16 February 2016 at 06:52, Bala Manoharan <[email protected]>
wrote:

> Hi,
>
> On 15 February 2016 at 20:52, Christophe Milard <
> [email protected]> wrote:
>
>>
>>
>> On 15 February 2016 at 15:12, Balasubramanian Manoharan <
>> [email protected]> wrote:
>>
>>> Adds user-guide documentation for classification module
>>>
>>> Signed-off-by: Balasubramanian Manoharan <[email protected]>
>>> ---
>>>  doc/users-guide/users-guide-cls.adoc | 220
>>> +++++++++++++++++++++++++++++++++++
>>>  1 file changed, 220 insertions(+)
>>>  create mode 100644 doc/users-guide/users-guide-cls.adoc
>>>
>>> diff --git a/doc/users-guide/users-guide-cls.adoc
>>> b/doc/users-guide/users-guide-cls.adoc
>>> new file mode 100644
>>> index 0000000..3089f86
>>> --- /dev/null
>>> +++ b/doc/users-guide/users-guide-cls.adoc
>>> @@ -0,0 +1,220 @@
>>> +== Classification \(CLS)
>>> +
>>> +ODP is a framework for software-based packet forwarding/filtering
>>> applications,
>>> +and the purpose of the Packet Classification API is to enable
>>> applications to
>>> +program the platform hardware or software implementation to assist in
>>> +prioritization, classification and scheduling of each packet, so that
>>> the
>>> +software application can run faster, scale better and adhere to QoS
>>> +requirements.
>>> +
>>> +The following API abstraction are not modelled after any existing
>>> product
>>> +implementation, but is instead defined in terms of what a typical
>>> data-plane
>>> +application may require from such a platform, without sacrificing
>>> simplicity and
>>> +avoiding ambiguity. Certain terms that are being used within the
>>> context of
>>> +existing products in relation to packet parsing and classification,
>>> such as
>>> +access lists are avoided such that not to suggest any relationship
>>> +between the abstraction used within this API and any particular manner
>>> in which
>>> +they may be implemented in hardware.
>>> +
>>> +=== Functional Description
>>> +
>>> +Following is the functionality that is required of the classification
>>> API, and
>>> +its underlying implementation. The details and order of the following
>>> paragraph
>>> +is informative, and is only intended to help convey the functional
>>> scope of a
>>> +classifier aznd provide context for the API. In reality,
>>> implementations may
>>>
>>
>> typo: "and", not aznd
>>
>
> Good catch :)
>
>>
>>
>>> +execute many of these steps concurrently, or in different order while
>>> +maintaining the evident dependencies:
>>> +
>>> +1. Apply a set of classification rules to the header of an incoming
>>> packet,
>>> +identify the header fields, e.g. ,ethertype, IP version, IP protocol,
>>> transport
>>> +layer port numbers, IP DiffServ, VLAN id, 802.1p priority.
>>> +
>>> +2. Store these fields as packet meta data for application use, and for
>>> the
>>> +remainder of parser operations. The odp_pktio is also stored as one of
>>> the meta
>>> +data fields for subsequent use.
>>> +
>>> +3. Compute an odp_cos (Class of Service) value from a subset of
>>> supported fields
>>> +from 1) above.
>>> +
>>> +4. Based on the odp_cos from 3) above, select the odp_queue through
>>> which the
>>> +packet is delivered to the application.
>>> +
>>> +5. Validate the packet data integrity (checksums, FCS)  and correctness
>>> (e.g.,
>>> +length fields) and store the validation result, along with optional
>>> error layer
>>> +and type indicator, in packet meta data. Optionally, if a packet fails
>>> +validation, override the odp_cos selection in step 3 to a class of
>>> service
>>> +designated for errored packets.
>>> +
>>> +6. Based on the odp_cos from 3) above, select the odp_buffer_pool that
>>> should be
>>> +used to acquire a buffer to store the packet data and meta data.
>>> +
>>> +7. Allocate a buffer from odp_buffer_pool selected in 6) above and
>>> logically[1]
>>> +store the packet data and meta data to the allocated buffer, or in
>>> accordance
>>> +with class-of-service drop policy and subject to pool buffer
>>> availability,
>>> +optionally discard the packet.
>>> +
>>> +8. Enqueue the buffer into the odp_queue selected in 4) above.
>>> +
>>> +The above is an abstract description of the classifier functionality,
>>> and may be
>>> +applied to a variety of applications in many different ways. The
>>> ultimate
>>> +meaning of how this functionality applies to an application also
>>> depends on
>>> +other ODP modules, so the above may not complete a full depiction. For
>>> instance,
>>> +the exact meaning of priority, which is a per-queue attribute is
>>> influenced by
>>> +the ODP scheduler semantics, and the system behavior under stress
>>> depends on the
>>> +ODP buffer pool module behavior.
>>> +
>>> +For the sole purpose of illustrating the above abstract functionality,
>>> here is
>>> +an example of a Layer-2 (IEEE 802.1D)  bridge application: Such a
>>> forwarding
>>> +application that also adheres to IEEE 802.1p/q priority, which has 8
>>> traffic
>>> +priority levels, might create 8 odp_buffer_pool instances, one for each
>>> PCP
>>> +priority level, and 8 odp_queue instances one per priority level.
>>> Incoming
>>> +packets will be inspected for a VLAN header; the PCP field will be
>>> extracted,
>>> +and used to select both the pool and the queue. Because each queue will
>>> be
>>> +assigned a priority value, the packets with highest PCP values will be
>>> scheduled
>>> +before any packet with a lower PCP value. Also, in a case of
>>> congestion, buffer
>>> +pools for lower priority packets will be depleted earlier than the pools
>>> +containing packets of the high priority, and hence the lower priority
>>> packets
>>> +will be dropped (assuming that is the only flow control method that is
>>> supported
>>> +in the platform) while higher priority packets will continue to be
>>> received into
>>> +buffers and processed.
>>> +
>>> +=== Class of Service Creation and Binding
>>> +
>>> +To program the classifier, a class-of-service instance must be created,
>>> which
>>> +will contain the packet filtering resources that it may require. All
>>> subsequent
>>> +calls refer to one or more of these resources.
>>> +
>>> +Each class of service instance must be associated with a single queue
>>> or queue
>>> +group, which will be the destination of all packets matching that
>>> particular
>>> +filter. The queue assignment is implemented as a separate function call
>>> such
>>> +that the queue may be modified at any time, without tearing down the
>>> filters
>>> +that define the class of service. In other words, it is possible to
>>> change the
>>> +destination queue for a class of service defined by its filters quickly
>>> and
>>> +dynamically.
>>> +
>>> +Optionally, on platforms that support multiple packet buffer pools,
>>> each class
>>> +of service may be assigned a different pool such that when buffers are
>>> exhausted
>>> +for one class of service, other classes are not negatively impacted and
>>> continue
>>> +to be processed.
>>> +
>>> +=== Default packet handling
>>> +
>>> +There SHOULD be one odp_cos assigned to each port with the
>>> odp_pktio_default_cos_set()
>>> +function,  which will function as the default class-of-service for all
>>> packets
>>> +received from an ingress port, that do not match any of the filters
>>> defined
>>> +subsequently. At minimum this default class-of-service MUST have a
>>> queue and a
>>> +buffer pool assigned to it on platforms that support multiple packet
>>> buffer
>>> +pools. Multiple odp_pktio instances (i.e., multiple ports) MAY each
>>> have their
>>> +own default odp_cos, or MAY share a odp_cos with other ports, based on
>>> +application requirements.
>>> +
>>> +Packet Classification
>>> +
>>> +For each odp_pktio port, the API allows the assignment of a
>>> class-of-service to
>>> +a packet using one of  three methods:
>>> +
>>> +1. The packet may be assigned a specific class-of-service based on its
>>> Layer-2
>>> +(802.1P/902.1Q VLAN tag) priority field. Since the standard field
>>> defines 8
>>> +discrete priority levels, the API allows to assign an odp_cos to each
>>> of these
>>> +priority levels with the odp_cos_with_l2_priority() function.
>>> +
>>> +2. Similarly, a class-of-service may be assigned using the Layer-3 (IP
>>> DiffServ)
>>> +header field. The application supplies an array of odp_cos values that
>>> covers
>>> +the entire range of the standard protocol header field, where array
>>> elements do
>>> +not need to contain unique values. There is also a need to specify if
>>> Layer-3
>>> +priority takes precedence over Layer-2 priority in a packet with both
>>> headers
>>> +present.
>>> +
>>> +3. Additionally, the application may also program a number of pattern
>>> matching
>>> +rules that assign a class-of-service for packets with header fields
>>> matching
>>> +specified values. The field-matching rules take precedence over the
>>> previously
>>> +described priority-based assignment of a class-of-service. Using these
>>> matching
>>> +rules the application should be able for example to identify all packets
>>> +containing VoIP traffic based on the protocol being UDP, and a specific
>>> +destination or source port numbers, and appropriately assign these
>>> packets an
>>> +class-of-service that maps to a higher priority queue, assuring voice
>>> packets a
>>> +lower and bound latency.
>>> +
>>> +Packet meta data Elements
>>> +
>>> +Here are the specific information elements that SHOULD be stored within
>>> the
>>> +packet meta data structure:
>>> +
>>> +* Protocol fields that are decoded and extracted by the parsing phase
>>> +
>>> +* The pool identifier that is selected for the packet
>>> +
>>> +* The ingress port identifier
>>> +
>>> +* The result of packet validation, including an indication of the type
>>> of error
>>> +* detected, if any
>>> +
>>> +The ODP packet API module SHALL provide accessors for retrieving the
>>> above meta
>>> +data fields from the container buffer in an implementation-independent
>>> manner.
>>>
>>
>> why SHOULD and SHALL? This is a user guide, not a ODP requirement spec:
>> shouldn't it be "ARE" (instead of should) and just "provides" (instead of
>> shall provide)?
>>
>
> Okay.
>
>>
>> +
>>> +===  Example configuration
>>> +
>>> +CoS configuration can be best illustrated by drawing a tree, where each
>>> CoS is
>>> +the vertex, and each link between any two vertices is a PMR. The root
>>> node for
>>> +the tree is the default CoS which is attached with the pktio
>>> interface.  All of
>>> +the CoS vertices can be final for some packets, if these packets do not
>>> match
>>> +any of the links.
>>> +
>>> +Let us consider the below configuration
>>> +
>>> +odp_pktio_default_cos_set(odp_pktio_t pktio, odp_cos_t default_cos);
>>> +
>>> +pmr1 = odp_cls_pmr_create(pmr_match1, default_cos,  cos1);
>>> +pmr2 = odp_cls_pmr_create(pmr_match2, default_cos,  cos2);
>>> +pmr3 = odp_cls_pmr_create(pmr_match3, default_cos,  cos3);
>>> +
>>> +pmr11 = odp_cls_pmr_create(pmr_match11, cos1,  cos11);
>>> +pmr12 = odp_cls_pmr_create(pmr_match12, cos1,  cos12);
>>> +
>>> +pmr21 = odp_cls_pmr_create(pmr_match11, cos2,  cos21);
>>> +pmr31 = odp_cls_pmr_create(pmr_match11, cos3,  cos31);
>>> +
>>> +The above configuration DOES imply order - a packet that matches
>>> pmr_match1 will
>>> +then be applied to pmr_match11 and pmr_match12, and as a result could
>>> terminate
>>> +with either cost1, cos11, cos12. In this case the packet was subjected
>>> to two
>>> +match attempts in total.
>>> +
>>> +The remaining two lines illustrate how a packet that matches
>>> pmr_match11 could
>>> +end up wth either cos11, cos21 or cos31, depending on wether it matches
>>>
>>
>> typos: "with" and "whether"
>>
>>
>>> +pmr_march1, pmr_march2 or pmr_match3.
>>>
>>
>> isn't it  " depending on whether it matches pmr_march1 only, pmr_march1
>> and pmr_march2, or pmr_march1 and pmr_match3" ?
>> I mean pmr_march2 and  pmr_march3 are only appliied if the packet matched
>> pmr_march1 first, right?
>>
>
> Actually No. pmr_match1, pmr_match2 and pmr_match3 are all applied on
> default_cos and hence all the three PMRs are in the same level and the
> classification API does not dictate any priority between PMRs on the same
> level. The order in which PMRs on the same level will be verified is
> implementation dependent. The responsibility lies in the application to
> make sure there is no ambiguity in classification configuration. I believe
> the example configuration below with practical configuration explains the
> use case in detail.
>
>  Also please note that the order of PMR matching can be implemented using
> PMR chaining i.e in the above example pmr_match11 will only be applied
> depending on whether the packet succeeded pmr_match1, pmr_match2 or
> pmr_match3.
>

Ok. Actually your answer make more sense than my comment! :-). Many thanks
for the clarifications.
I would not mind a code example in this doc, but I guess that can come
later.
cheers,

Christophe

>
>> +
>>> +Here is a practical example:
>>> +
>>> +Let's look at DNS packets, these are identified by using UDP port 53,
>>> but each
>>> +UDP packet may run atop of IPv4 or IPv6, and in turn an IP packet might
>>> be
>>> +received as either multicast or unicast,
>>> +
>>> +Very simply, we can create these PMRs:
>>> +
>>> +PMR-L2 = match all multicast/broadcast packets based on DMAC address
>>> PMR_L3_IP4
>>> += match all IPv4 packets PMR_L3_IP6 = match all IPv6 packets PMR_L4_UDP
>>> = match
>>> +all UDP packets PMR_L4_53 = match all packets with dest port = 53.
>>> +
>>> +odp_cls_pmr_create(PMR_L2, port_cos, port_cos_mc);
>>> +odp_cls_pmr_create(PMR_L3_IP4, port_cos, port_cos_ip4_uc);
>>> +odp_cls_pmr_create(PMR_L3_IP6, port_cos, port_cos_ip6_uc);
>>> +
>>> +odp_cls_pmr_create(PMR_L3_IP4, port_cos_mc, port_cos_ip4_mc);
>>> +odp_cls_pmr_create(PMR_L3_IP6, port_cos_mc, port_cos_ip6_mc);
>>> +odp_cls_pmr_create(PMR_L4_UDP, port_cos_ip4_uc, cos_udp4_uc);
>>> +odp_cls_pmr_create(PMR_L4_UDP, port_cos_ip4_mc, cos_udp4_mc);
>>> +odp_cls_pmr_create(PMR_L4_UDP, port_cos_ip6_uc, cos_udp6_uc);
>>> +odp_cls_pmr_create(PMR_L4_UDP, port_cos_ip6_mc, cos_udp6_mc);
>>> +
>>> +odp_cls_pmr_create(PMR_L4_53, cos_udp4_uc, dns4_uc);
>>> +odp_cls_pmr_create(PMR_L4_53, cos_udp4_mc, dns4_mc);
>>> +odp_cls_pmr_create(PMR_L4_53, cos_udp6_uc, dns6_uc);
>>> +odp_cls_pmr_create(PMR_L4_53, cos_udp6_mc, dns6_mc);
>>>
>>
>> In the previous section, the root of the tree seemed to be "default_cos".
>> now it seems to be "default_cos". what is port_cos here?
>>
>
> Yes. port_cos and default_cos are the same. I will change everything to
> "default_cos" since I believe it is more easier to understand.
>
> Regards,
> Bala
>
>>
>> Thanks,
>> Christophe.
>>
>>> +
>>> +In this case, a packet may change CoS between 0 and 5 times, meaning
>>> that up to
>>> +5 PMRs may be applied in series, and the order
>>> +
>>> +Another interesting point is that an implementation will probably
>>> impose on a
>>> +limit of how many PMRs can be applied to a packet in series, so in the
>>> above
>>> +example, if an implementation limit on the number of consecutive
>>> classification
>>> +steps is 4, then all the DNS packets may only reach cos_udp?_?c set of
>>> vertices.
>>> --
>>> 1.9.1
>>>
>>> _______________________________________________
>>> lng-odp mailing list
>>> [email protected]
>>> https://lists.linaro.org/mailman/listinfo/lng-odp
>>>
>>
>>
>
_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to