DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH v1 0/3] TAP RSS eBPF cover letter
@ 2017-12-17 12:21 Ophir Munk
  2017-12-17 12:21 ` [dpdk-dev] [PATCH v1 1/3] net/tap: add BPF sections for TAP device Ophir Munk
                   ` (3 more replies)
  0 siblings, 4 replies; 42+ messages in thread
From: Ophir Munk @ 2017-12-17 12:21 UTC (permalink / raw)
  To: Pascal Mazon; +Cc: Ophir Munk, dev, Thomas Monjalon, Olga Shern

The patches of TAP RSS eBPF follow the RFC on this issue
https://dpdk.org/dev/patchwork/patch/31781/

Pascal Mazon (1):
  net/tap: add BPF sections for TAP device
  ========================================
  This commit introduces BPF program (tap_bpf_program.c)
  with different sections which should be loaded to the kernel in BPF
  architecture format.
  BPF code compilation is not part of dpdk compilation.
  This commit also adds a skeleton for the RAP RSS implementation

Ophir Munk (2):
  net/tap: add eBPF instructions
  ==============================
  This commit adds eBPF machine instructions as part of dkdk compilation
  in the format of C arrays. This approach is currently under review with
  regard to:
  - licensing
  - Ability to update a BPF program and download new machine code

  net/tap: add eBPF classifiers map and actions
  =============================================
  This commit builds and sends netlink messages to the kernel that include BPF
  classifiers and actions.

  When using BPF system call to load code to the kernel a license name
  must be specified. The license name is currently set to "Dual BSD/GPL".
  Please note licensing in general is under review and is not adderessed in
  this patch.

 doc/guides/prog_guide/rte_flow_tap.rst |  962 ++++++
 drivers/net/tap/Makefile               |    7 +-
 drivers/net/tap/rte_eth_tap.h          |    9 +-
 drivers/net/tap/tap_bpf_insns.c        | 5460 ++++++++++++++++++++++++++++++++
 drivers/net/tap/tap_bpf_program.c      |  321 ++
 drivers/net/tap/tap_bpf_shared.h       |   56 +
 drivers/net/tap/tap_flow.c             |  613 +++-
 7 files changed, 7323 insertions(+), 105 deletions(-)
 create mode 100644 doc/guides/prog_guide/rte_flow_tap.rst
 create mode 100644 drivers/net/tap/tap_bpf_insns.c
 create mode 100644 drivers/net/tap/tap_bpf_program.c
 create mode 100644 drivers/net/tap/tap_bpf_shared.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v1 1/3] net/tap: add BPF sections for TAP device
  2017-12-17 12:21 [dpdk-dev] [PATCH v1 0/3] TAP RSS eBPF cover letter Ophir Munk
@ 2017-12-17 12:21 ` Ophir Munk
  2017-12-17 12:21 ` [dpdk-dev] [PATCH v1 2/3] net/tap: add eBPF instructions Ophir Munk
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2017-12-17 12:21 UTC (permalink / raw)
  To: Pascal Mazon; +Cc: Ophir Munk, dev, Thomas Monjalon, Olga Shern

From: Pascal Mazon <pascal.mazon@6wind.com>

The DPDK traffic classifier is the rte_flow API and the tap PMD must
support it including RSS queue mapping.  An example usage for this
requirement is failsafe transparent switching from a PCI device to TAP
device while keep redirecting packets to the same RSS queues on both
devices.

This commit uses eBPF classification and actions in order to support TAP
RSS.

eBPF requires Linux version 3.19. eBPF is effective only when running with
an appropriate kernel version.  In case kernel headers do not include eBPF
definitions a warning will be issued during compilation time and TAP RSS
will not be supported.

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 doc/guides/prog_guide/rte_flow_tap.rst | 962 +++++++++++++++++++++++++++++++++
 drivers/net/tap/Makefile               |   6 +-
 drivers/net/tap/rte_eth_tap.h          |   7 +-
 drivers/net/tap/tap_flow.c             | 336 ++++++++----
 4 files changed, 1207 insertions(+), 104 deletions(-)
 create mode 100644 doc/guides/prog_guide/rte_flow_tap.rst

diff --git a/doc/guides/prog_guide/rte_flow_tap.rst b/doc/guides/prog_guide/rte_flow_tap.rst
new file mode 100644
index 0000000..04ddda6
--- /dev/null
+++ b/doc/guides/prog_guide/rte_flow_tap.rst
@@ -0,0 +1,962 @@
+=====================================
+Flow API support in TAP PMD, using TC
+=====================================
+
+.. contents::
+.. sectnum::
+
+.. footer::
+
+   v0.8 - page ###Page###
+
+.. raw:: pdf
+
+  PageBreak
+
+Rationale
+=========
+
+For this project, the tap PMD has to receive selected traffic from a different
+netdevice (refer to *VM migration with Microsoft Hyper-V and Mellanox
+ConnectX-3* document) and only cover the same set of rules as supported by the
+mlx4 PMD.
+
+The DPDK traffic classifier is the rte_flow API, and the tap PMD must therefore
+implement it. For that, TC was chosen for several reasons:
+
+- it happens very early in the kernel stack for ingress (faster than netfilter).
+- it supports dropping packets given a specific flow.
+- it supports redirecting packets to a different netdevice.
+- it has a "flower" classifier type that meets mostly the pattern items in
+  rte_flow.
+- it can be configured through a netlink socket, without an external tool.
+
+Modes of operation
+==================
+
+There should be two modes of operation for the tap PMD regarding rte_flow:
+*local* and *remote*. Only one mode can be in use at a time for a specific tap
+interface.
+
+The *local* mode would be the default one, if no specific parameter is specified
+in the command line. To start the application with tap in *remote* mode, set the
+``remote`` tap parameter to the interface you want to redirect packets from,
+e.g.::
+
+   testpmd -n 4 -c 0xf -m 1024 --vdev=net_tap,iface=tap0,remote=eth3 -- \
+     -i --burst=64 --coremask=0x2
+
+*Local* mode
+------------
+
+In *local* mode, flow rules would be applied as-is, on the tap netdevice itself
+(e.g.: ``tap0``).
+
+The typical use-case is having a linux program (e.g. a webserver) communicating
+with the DPDK app through the tap netdevice::
+
+   +-------------------------+
+   |    DPDK application     |
+   +-------------------------+
+     |                     ^
+     | rte_flow   rte_flow |
+     v egress      ingress |
+   +-------------------------+
+   |        Tap PMD          |
+   +-------------------------+
+     |                     ^
+     | TC               TC |
+     v ingress      egress |
+   +-------------------------+              +-------------------------+
+   |                         |<-------------|                         |
+   |   Tap netdevice (tap0)  |              |  Linux app (webserver)  |
+   |                         |------------->|                         |
+   +-------------------------+              +-------------------------+
+
+.. raw:: pdf
+
+  PageBreak
+
+*Remote* mode
+-------------
+
+In *remote* mode, flow rules would be applied on the tap netdevice (e.g.:
+``tap0``), and use a similar match to redirect specific packets from another
+netdevice (e.g.: ``eth3``, a NetVSC netdevice in our project scenario)::
+
+   +-------------------------+
+   |    DPDK application     |
+   +-------------------------+
+     |                     ^
+     | rte_flow   rte_flow |
+     v egress      ingress |
+   +-------------------------+
+   |        Tap PMD          |
+   +-------------------------+
+     |                     ^
+     | TC               TC |
+     v ingress      egress |
+   +-------------------------+              +-------------------------+
+   |                         |<------------------redirection-------\  |
+   |   Tap netdevice (tap0)  |              |                       | |
+   |                         |------------->|-\       eth3          | |
+   +-------------------------+              +--|--------------------|-+
+                                               | TC              TC ^
+                                               | egress     ingress |
+                                               v                    |
+
+.. raw:: pdf
+
+  PageBreak
+
+rte_flow rules conversion
+=========================
+
+Netlink
+-------
+
+The only way to create TC rules in the kernel is through netlink messages.
+Two possibilities arise for managing TC rules:
+
+- Using native netlink API calls in the tap PMD
+- Calling the ``tc`` command from iproute2 inside our PMD, via ``system()``.
+
+The former will be done, as library calls are faster than changing context and
+executing an external program from within the tap PMD. Moreover, the kernel TC
+API might propose features not yet implemented in iproute2. Furthermore, a
+custom implementation enables finer tuning and better control.
+
+..
+   Some implementations for TC configuration through Netlink exist already. It's a
+   good source of inspiration on how to do it:
+
+   - iproute2's tc `source code`__
+   - ovs's tc implementation__ (not yet upstream)
+
+   __ https://github.com/shemminger/iproute2/tree/master/tc
+   __ https://mail.openvswitch.org/pipermail/ovs-dev/2016-November/324693.html
+
+Conversion examples
+-------------------
+
+Here are a few examples of rules and how they can be translated from rte_flow
+rules to TC rules. rte_flow rules will be expressed using testpmd's ``flow``
+command syntax, while TC rules will use iproute2 ``tc`` command syntax.
+
+**Notes**:
+   - rte_flow ``ingress`` direction can be translated into a TC ``egress`` rule,
+     and vice versa, when it applies to a tap interface, as TC considers the
+     kernel netdevice standpoint.
+   - in TC, redirecting a packet works by taking a packet from ``ingress`` and
+     sending to another device's ``egress``.
+
+*Local* mode
+~~~~~~~~~~~~
+
+#. Flow rule to give packets coming on the ``tap0`` interface to RX queue 0:
+
+   Using rte_flow::
+
+      flow validate 0 ingress pattern port index is 0 / end \
+        actions queue index 0 / end
+
+   Using ``tc``::
+
+      tc filter add dev tap0 parent 1: flower indev tap0 \
+        action skbedit queue_mapping 0
+
+#. Flow rule to get packets with source mac ``de:ad:ca:fe:00:02`` on RX queue 2:
+
+   Using rte_flow::
+
+      flow create 0 ingress pattern eth src is de:ad:ca:fe:00:02 / end \
+        actions queue 2 / end
+
+   Using ``tc``::
+
+      tc filter add dev tap0 parent 1: flower src_mac de:ad:ca:fe:00:02 \
+        action skbedit queue_mapping 2
+
+#. Flow rule to drop packets matching specific 5-tuple info:
+
+   Using rte_flow::
+
+      flow create 0 ingress pattern eth dst is 3a:80:ce:61:36:54 \
+        src is 52:43:7b:fd:ac:f3 / ipv4 src is 1.1.1.1 dst is 2.2.2.2 \
+        / udp src is 4444 dst is 5555 / end actions drop / end
+
+   Using ``tc``::
+
+      tc filter add dev tap0 parent 1: flower dst_mac 3a:80:ce:61:36:54 \
+        src_mac 52:43:7b:fd:ac:f3 eth_type ip src_ip 1.1.1.1 dst_ip 2.2.2.2 \
+        ip_proto udp src_port 4444 dst_port 5555 action drop
+
+*Remote* mode
+~~~~~~~~~~~~~
+
+In *remote* mode, an additional rule for redirecting packet is systematically
+required. The examples are similar to the previous section (the rte_flow rule
+will thus be omitted).
+
+#. TC rules to give packets coming on the ``eth3`` interface to ``tap0`` RX
+   queue 0::
+
+      # redirection rule
+      tc filter add dev eth3 parent ffff: flower indev eth3 \
+        action mirred egress redirect dev tap0
+      # actual tap rule
+      tc filter add dev tap0 parent 1: flower indev tap0 \
+        action skbedit queue_mapping 0
+
+#. TC rules to get packets with source mac ``de:ad:ca:fe:00:02`` on RX queue 2::
+
+      # redirection rule
+      tc filter add dev eth3 parent ffff: flower src_mac de:ad:ca:fe:00:02 \
+        action mirred egress redirect dev tap0
+      # actual tap rule
+      tc filter add dev tap0 parent 1: flower src_mac de:ad:ca:fe:00:02 \
+        action skbedit queue_mapping 2
+
+#. TC rules to drop packets matching specific 5-tuple info::
+
+      # redirection rule
+      tc filter add dev eth3 parent ffff:  flower dst_mac 3a:80:ce:61:36:54 \
+        src_mac 52:43:7b:fd:ac:f3 eth_type ip src_ip 1.1.1.1 dst_ip 2.2.2.2 \
+        ip_proto udp src_port 4444 dst_port 5555 \
+        action mirred egress redirect dev tap0
+      # actual tap rule
+      tc filter add dev tap0 parent 1: flower dst_mac 3a:80:ce:61:36:54 \
+        src_mac 52:43:7b:fd:ac:f3 eth_type ip src_ip 1.1.1.1 dst_ip 2.2.2.2 \
+        ip_proto udp src_port 4444 dst_port 5555 action drop
+
+One last thing, to redirect packets the other way around (from ``tap0`` to
+``eth3``), we would use a similar rule, exchanging interfaces and using an
+appropriate match, e.g.::
+
+   tc filter add dev tap0 parent ffff: flower indev tap0 \
+     action mirred egress redirect dev eth3
+
+..
+   **Note:** ``parent ffff:`` is for TC ``ingress`` while ``parent 1:`` is for TC
+    ``egress``.
+
+Broadcast and promiscuous support
++++++++++++++++++++++++++++++++++
+
+*Remote* mode requirements:
+
+#. When turning the tap netdevice promiscuous, the remote netdevice should
+   implicitly be turned promiscuous too, to get as many packets as possible.
+
+#. Packets matching the destination MAC configured in the tap PMD should be
+   redirected from the remote without being processed by the stack there in the
+   kernel.
+
+#. In promiscuous mode, an incoming packet should be duplicated to be processed
+   both by the tap PMD and the remote netdevice itself.
+
+#. Incoming packets with broadcast destination MAC (i.e.: ``ff:ff:ff:ff:ff:ff``)
+   should be duplicated to be processed both by the tap PMD and the remote
+   netdevice itself.
+
+#. Incoming packets with IPv6 multicast destination MAC (i.e.:
+   ``33:33:00:00:00:00/33:33:00:00:00:00``) should be duplicated to be processed
+   both by the tap PMD and the remote netdevice itself.
+
+#. Incoming packets with broadcast/multicast bit set in the destination MAC
+   (i.e.: ``01:00:00:00:00:00/01:00:00:00:00:00``) should be duplicated to be
+   processed both by the tap PMD and the remote netdevice itself.
+
+Each of these requirements (except the first one) can be directly translated
+into a TC rule, e.g.::
+
+   # local mac (notice the REDIRECT for mirred action):
+   tc filter add dev eth3 parent ffff: prio 1 flower dst_mac de:ad:be:ef:01:02 \
+     action mirred egress redirect dev tap0
+
+   # tap promisc:
+   tc filter add dev eth3 parent ffff: prio 2 basic \
+     action mirred egress mirror dev tap0
+
+   # broadcast:
+   tc filter add dev eth3 parent ffff: prio 3 flower dst_mac ff:ff:ff:ff:ff:ff \
+     action mirred egress mirror dev tap0
+
+   # broadcast v6 (can't express mac_mask with tc, but it works via netlink):
+   tc filter add dev eth3 parent ffff: prio 4 flower dst_mac 33:33:00:00:00:00 \
+     action mirred egress mirror dev tap0
+
+   # all_multi (can't express mac_mask with tc, but it works via netlink):
+   tc filter add dev eth3 parent ffff: prio 5 flower dst_mac 01:00:00:00:00:00 \
+     action mirred egress mirror dev tap0
+
+When promiscuous mode is switched off or on, the first TC rule will be modified
+to have respectively an empty action (``continue``) or the ``mirror`` action.
+
+The first 5 priorities are always reserved, and can only be used for these
+filters.
+
+On top of that, the tap PMD can configure explicit rte_flow rules, translated as
+TC rules on both the remote netdevice and the tap netdevice. On the remote,
+those would need to be processed after the default rules handling promiscuous
+mode, broadcast and all_multi packets.
+
+When using the ``mirror`` action, the packet is duplicated and sent to the tap
+netdevice, while the original packet gets directly processed by the kernel
+without going through later TC rules for the remote. On the tap netdevice, the
+duplicated packet will go through tap TC rules and be classified depending on
+those rules.
+
+**Note:** It is possible to combine a ``mirror`` action and a ``continue``
+action for a single TC rule. Then the original packet would undergo remaining TC
+rules on the remote netdevice side.
+
+When using the ``redirect`` action, the behavior is similar on the tap side, but
+the packet is not duplicated, no further kernel processing is done for the
+remote side.
+
+The following diagram sums it up. A packet that match a TC rule follows the
+associated action (the number in the diamond represents the rule prio as set in
+the above TC rules)::
+
+
+                        Incoming packet |
+                       on remote (eth3) |
+                                        | Going through
+                                        | TC ingress rules
+                                        v
+                                       / \
+                                      / 5 \
+                                     /     \    yes
+                                    /  mac  \____________________> tap0
+                                    \ match?/    duplicated pkt
+                                     \     /
+                                      \   /
+                                       \ /
+                                        V no, then continue
+                                        | with TC rules
+                                        |
+                                        v
+                                       / \
+                                      / 2 \
+         eth3                  yes   /     \    yes
+       kernel <____________________ /promisc\____________________> tap0
+        stack      original pkt     \ match?/    duplicated pkt
+                                     \     /
+                                      \   /
+                                       \ /
+                                        V no, then continue
+                                        | with TC rules
+                                        |
+                                        v
+                                       / \
+                                      / 3 \
+         eth3                  yes   /     \    yes
+       kernel <____________________ / bcast \____________________> tap0
+        stack      original pkt     \ match?/    duplicated pkt
+                                     \     /
+                                      \   /
+                                       \ /
+                                        V no, then continue
+                                        | with TC rules
+                                        |
+                                        v
+                                       / \
+                                      / 4 \
+         eth3                  yes   /     \    yes
+       kernel <____________________ / bcast6\____________________> tap0
+        stack      original pkt     \ match?/    duplicated pkt
+                                     \     /
+                                      \   /
+                                       \ /
+                                        V no, then continue
+                                        | with TC rules
+                                        |
+                                        v
+                                       / \
+                                      / 5 \
+         eth3                  yes   / all \    yes
+       kernel <____________________ / multi \____________________> tap0
+        stack      original pkt     \ match?/    duplicated pkt
+                                     \     /
+                                      \   /
+                                       \ /
+                                        V no, then continue
+                                        | with TC rules
+                                        |
+                                        v
+                                        |
+                                        . remaining TC rules
+                                        .
+         eth3                           |
+       kernel <________________________/
+        stack      original pkt
+
+.. raw:: pdf
+
+  PageBreak
+
+Associating an rte_flow rule with a TC one
+==========================================
+
+A TC rule is identified by a ``priority`` (16-bit value) and a ``handle``
+(32-bit value). To delete a rule, the priority must be specified, and if several
+rules have the same priority, the handle is needed to select the correct one.
+
+..
+   Specifying an empty priority and handle when requesting a TC rule creation will
+   let the kernel automatically decide what values to set. In fact, the kernel will
+   start with a high priority (i.e. 49152) and subsequent rules will get decreasing
+   priorities (lower priorites get evaluated first).
+
+To avoid further requests to the kernel to identify what priority/handle has
+been automatically allocated, the tap PMD can set priorities and handles
+systematically when creating a rule.
+
+In *local* mode, an rte_flow rule should be translated into a single TC flow
+identified by priority+handle.
+
+In *remote* mode, an rte_flow rule requires two TC rules, one on the tap
+netdevice itself (for the correct action) and another one on the other netdevice
+where packets are redirected from. Both TC rules' priorities+handles must be
+stored for a specific rte_flow rule, and associated with the device they are
+applied on.
+
+.. raw:: pdf
+
+  PageBreak
+
+Considerations regarding Flow API support
+=========================================
+
+Flow rule attributes
+--------------------
+
+Groups and priorities:
+   There is no native support of groups in TC. Instead, the priority field
+   (which is part of the netlink TC msg header) can be adapted. The four MSB
+   would be used to define the group (allowing for 16 groups), while the 12 LSB
+   would be left to define the actual priority (up to 4096).
+
+   Rules with lower priorities are evaluated first. For rules with identical
+   priorities, the one with the highest handle value gets evaluated first.
+
+Direction:
+   Both ingress and egress filtering can be supported.
+
+Meta item types
+---------------
+
+Most applications will use: ``(END | VOID)``
+
+END, VOID:
+   Supported without problem.
+
+INVERT:
+   There is no easy way to support that in TC. It won't be supported
+
+   **mlx4 will not support it either.**
+
+PF, VF, PORT:
+   Not applicable to a tap netdevice.
+
+Data matching item types
+------------------------
+
+Most applications will use:
+``ETH / (IPV4 | IPV6 | END) / (TCP | UDP | END) / END``
+
+ANY:
+   Should be supported.
+
+   **mlx4 will partially support it.**
+
+RAW:
+   It is not planned to support it for now. Matching Raw packets would require
+   using a different classifier than "flower", which is the most simple and
+   applicable for otherwise most other cases. With TC, it's not possible to
+   support in the same rule both "flower" and raw packets.
+
+   **mlx4 will not support it either**.
+
+VLAN:
+   Matching VLAN ID and prio supported.
+   **Note: linux v4.9 required for VLAN support.**
+
+ETH, IPV4, IPV6, UDP, TCP:
+   Matching source/destination MAC/IP/port is supported, with masks.
+
+   **mlx4 does not support partial bit-masks (full or zeroed only).**
+
+ICMP:
+   By specifying the appropriate ether type, ICMP packets can be matched.
+   However, there is no support for ICMP type or code.
+
+   **mlx4 will not support it, however.**
+
+SCTP:
+   By specifying the appropriate IP protocol, SCTP packets can be matched.
+   However, no specific SCTP fields can be matched.
+
+   **mlx4 will not support it, however.**
+
+VXLAN:
+   VXLAN is not recognized by the "flower" classifier. Kernel-managed VXLAN
+   traffic would come through an additional netdevice, which falls outside
+   the scope of this project. VXLAN traffic should occur outside VMs anyway.
+
+Action types
+------------
+
+Most applications will use: ``(VOID | END | QUEUE | DROP) / END``
+
+By default, multiple actions are possible for TC flow rules. However, they are
+ordered in the kernel. The implementation will need to handle actions in a way
+that orders them intelligently when creating them.
+
+VOID, END:
+   Supported.
+
+PASSTHRU:
+   The generic "continue" action can be used.
+
+   **mlx4 will not support it, however**.
+
+MARK / FLAG:
+   The mark is a field inside an skbuff. However, the tap reads messages (mostly
+   packet data), without that info. As an alternative, it may be possible to
+   create a specific queue to pass packets with a specific mark. Further testing
+   are needed to ensure it is feasable.
+
+QUEUE:
+   The ``skbedit`` action with the ``queue_mapping`` option enables directing
+   packets to specific queues.
+
+   Like rte_flow, specifying several ``skbedit queue_mapping`` actions in TC
+   only considers the last one.
+
+DROP:
+   The generic "drop" action can be used. Packets will effectively be dropped,
+   and not left for the kernel to process.
+
+COUNT: Stats are automatically stored in the kernel. The COUNT action will thus
+   be ignored when creating the rule. ``rte_flow_query()`` can be implemented
+   to request a rule's stats from the kernel.
+
+DUP:
+   Duplicating packets is not supported.
+
+RSS:
+   There's no built-in mechanism for RSS in TC.
+
+   By default, incoming packets go to the tap PMD queue 0. To support RSS in
+   software, several additional queues must be set up. Packets coming in on
+   queue 0 can be considered as requiring RSS, and the PMD will apply software
+   rss (using something like ``rte_softrss()``) to select a queue for the
+   packet.
+
+PF, VF:
+   Not applicable to a tap netdevice.
+
+.. raw:: pdf
+
+  PageBreak
+
+TC limitations for flow collision
+=================================
+
+From TC standpoint, filter rules with identical priorities do not collide, if
+they do specify values (at least one different) for the same fields in the TC
+message, with identical fields masks.
+
+Unfortunately, some flows that obviously are not colliding can be considered
+otherwise by the kernel when parsing the TC messages, and thus their creation
+would be rejected.
+
+Here is a table for matching TC fields with their flow API equivalent:
+
++------------------------------+-----------------------------------+-----------+
+|    TC message field          |      rte_flow API                 | maskable? |
++==============================+===================================+===========+
+| TCA_FLOWER_KEY_ETH_DST       | eth dst                           | yes       |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_ETH_SRC       | eth src                           | yes       |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_ETH_TYPE      | eth type is 0xZZZZ ||             | no        |
+|                              | eth / {ipv4|ipv6}                 |           |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_IP_PROTO      | eth / {ipv4|ipv6} / {tcp|udp}     | no        |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_IPV4_SRC      | eth / ipv4 src                    | yes       |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_IPV4_DST      | eth / ipv4 dst                    | yes       |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_IPV6_SRC      | eth / ipv6 src                    | yes       |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_IPV6_DST      | eth / ipv6 dst                    | yes       |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_L4_SRC        | eth / {ipv4|ipv6} / {tcp|udp} dst | no        |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_L4_DST        | eth / {ipv4|ipv6} / {tcp|udp} src | no        |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_VLAN_ID       | eth / vlan vid                    | no        |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_VLAN_PRIO     | eth / vlan pcp                    | no        |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_VLAN_ETH_TYPE | eth / vlan tpid                   | no        |
++------------------------------+-----------------------------------+-----------+
+
+When creating rules with identical priorities, one must make sure that they
+would be translated in TC using the same fields as shown in the above table.
+
+The following flow rules can share the same priority, as they use the same
+fields with identical masks under the hood::
+
+   > flow create 0 ingress priority 0 pattern eth / ipv4 / end
+          actions drop / end
+   Flow rule #0 created
+   > flow create 0 ingress priority 0 pattern eth type is 0x86dd / end
+          actions drop / end
+   Flow rule #1 created
+
+**Note:** Both rules use ETH_TYPE (mask 0xffff) in their TC form.
+
+Sadly, the following flow rules cannot share the same priority, since fields for
+matching IPv4 and IPv6 src/dst addresses are different::
+
+   > flow create 0 ingress priority 1 pattern eth / ipv4 src is 1.1.1.1 / end
+          actions drop / end
+   Flow rule #0 created
+   > flow create 0 ingress priority 1 pattern eth / ipv6 src is ::1 / end
+          actions drop / end
+   PMD: Kernel refused TC filter rule creation (22): Invalid argument
+   Caught error type 2 (flow rule (handle)): overlapping rules
+
+**Note:** First rule uses ETH_TYPE and IPV4_SRC, while the second uses ETH_TYPE
+and IPV6_SRC.
+
+It is however possible to match different IPvX addresses with the same
+priority::
+
+   > flow create 0 ingress priority 2 pattern eth / ipv4 src is 1.1.1.1 / end
+          actions drop / end
+   Flow rule #0 created
+   > flow create 0 ingress priority 2 pattern eth / ipv4 src is 2.2.2.2 / end
+          actions drop / end
+   Flow rule #1 created
+
+If the first rule specifies both destination and source addresses, then the
+other rule with the same priority must too (with identical masks)::
+
+   > flow create 0 ingress priority 3 pattern eth / ipv4 src is 1.1.1.1
+          dst is 1.1.1.2 / end actions drop / end
+   Flow rule #0 created
+   > flow create 0 ingress priority 3 pattern eth / ipv4 src is 2.2.2.2 / end
+          actions drop / end
+   PMD: Kernel refused TC filter rule creation (22): Invalid argument
+   Caught error type 2 (flow rule (handle)): overlapping rules
+   > flow create 0 ingress priority 3 pattern eth / ipv4 src is 2.2.2.2
+          dst spec 2.2.2.3 dst mask 255.255.255.0 / end actions drop / end
+   PMD: Kernel refused TC filter rule creation (22): Invalid argument
+   Caught error type 2 (flow rule (handle)): overlapping rules
+   > flow create 0 ingress priority 3 pattern eth / ipv4 src is 2.2.2.2
+          dst is 2.2.2.3 / end actions drop / end
+   Flow rule #1 created
+
+**Note:** First rule uses ETH_TYPE, IPV4_SRC and IPV4_DST (with full masks). The
+two others must also use those to share the same priority.
+
+It is possible to match TCP/UDP packets with different ports whatever the
+underlying L3, if the same fields are used (thus no l3 addresses specification).
+For instance::
+
+   > flow create 0 ingress priority 4 pattern eth / ipv4 / tcp dst is 3333 / end
+          actions drop / end
+   Flow rule #0 created
+   > flow create 0 ingress priority 4 pattern eth / ipv6 / udp dst is 4444 / end
+          actions drop / end
+   Flow rule #1 created
+   > flow create 0 ingress priority 4 pattern eth / ipv6 / udp src is 5555 / end
+          actions drop / end
+   PMD: Kernel refused TC filter rule creation (22): Invalid argument
+   Caught error type 2 (flow rule (handle)): overlapping rules
+
+**Note:** First 2 rules use ETH_TYPE, IP_PROTO and L4_DST with different values
+but identical masks, so they're OK. Last rule used L4_SRC instead of L4_DST.
+
+.. raw:: pdf
+
+  PageBreak
+
+RSS implementation for tap
+==========================
+
+There are several areas of research for a tap RSS implementation:
+
+#. userland implementation in tap PMD
+#. userland implementation in DPDK (generic)
+#. userland implementation using combination of TC rules and BPF filters/actions
+#. kernel-side implementation in tap driver
+#. kernel-side implementation as a BPF classifier/action
+#. kernel-side implementation as a separate TC action
+
++--------------+------------------------------+------------------------------+
+|              | Pros                         | Cons                         |
++==============+==============================+==============================+
+| tap PMD      | - no kernel upstreaming      | - tap PMD is supposed to be  |
+|              |                              |   simple, and would no longer|
+|              |                              |   be.                        |
+|              |                              |                              |
+|              |                              | - complex rework, with many  |
+|              |                              |   rings for enqueuing packets|
+|              |                              |   to the right queue         |
+|              |                              |                              |
+|              |                              | - slower                     |
+|              |                              |                              |
+|              |                              | - won't be accepted as it    |
+|              |                              |   doesn't make sense to redo |
+|              |                              |   what the kernel did        |
+|              |                              |   previously                 |
++--------------+------------------------------+------------------------------+
+| generic DPDK | - would be useful to others  | - design must be compatible  |
+|              |                              |   with most PMDs             |
+|              |                              |                              |
+|              |                              | - probably the longest to    |
+|              |                              |   develop                    |
+|              |                              |                              |
+|              |                              | - requires DPDK community    |
+|              |                              |   approval                   |
+|              |                              |                              |
+|              |                              | - requires heavy changes in  |
+|              |                              |   tap PMD itself anyway      |
++--------------+------------------------------+------------------------------+
+| TC rules     | - no kernel upstreaming      | - BPF is complicated to learn|
+| combination  |                              |                              |
+|              | - fast                       | - Runtime BPF compilation /  |
+|              |                              |   or bytecode change, would  |
+|              | - per-flow RSS               |   be tricky                  |
+|              |                              |                              |
+|              | - no change in tap PMD       | - much rework in the tap PMD |
+|              |   datapath                   |   to handle lots of new      |
+|              |                              |   netlink messages / actions |
++--------------+------------------------------+------------------------------+
+| tap driver   | - pretty fast as it          | - might not be accepted by   |
+|              |   intervenes early in packet |   the kernel community as    |
+|              |   RX                         |   they may cling to their    |
+|              |                              |   jhash2 hashing function for|
+|              |                              |   RX.                        |
+|              |                              |                              |
+|              |                              | - only a single RSS context  |
++--------------+------------------------------+------------------------------+
+| BPF          | - fast                       | - BPF is complicated to learn|
+| classifier - |                              |                              |
+| action       | - per-flow RSS               | - would require changing the |
+|              |                              |   kernel API to support      |
+|              |                              |   editing queue_mapping in an|
+|              |                              |   skb                        |
+|              |                              |                              |
+|              |                              | - hashing would be performed |
+|              |                              |   for each queue of a        |
+|              |                              |   specific RSS context       |
+|              |                              |                              |
+|              |                              | - probably difficult to gain |
+|              |                              |   community acceptance       |
++--------------+------------------------------+------------------------------+
+| TC action    | - much more flexibility, with| - needs to be in sync with   |
+|              |   per-flow RSS, multiple     |   iproute2's tc program      |
+|              |   keys, multiple packet      |                              |
+|              |   fields for the hash...     | - kernel upstreaming is not  |
+|              |                              |   necessarily easy           |
+|              | - it's a separate kernel     |                              |
+|              |   module that can be         | - rework in tap PMD to       |
+|              |   maintained out-of-tree and |   support new RSS action and |
+|              |   optionally upstreamed      |   configuration              |
+|              |   anytime                    |                              |
+|              |                              |                              |
+|              | - most logical to be handled |                              |
+|              |   in kernel as RSS is        |                              |
+|              |   supposed to be computed in |                              |
+|              |   the "NIC" exactly once.    |                              |
+|              |                              |                              |
+|              | - fastest                    |                              |
+|              |                              |                              |
+|              | - no change in tap PMD       |                              |
+|              |   datapath                   |                              |
++--------------+------------------------------+------------------------------+
+
+TC rules using BPF from tap PMD
+-------------------------------
+
+The third solution is the best for userland-based solutions.
+It does the job well, fast (datapath running in kernel), is logically happening
+in the kernel in runtime, supports flow-based RSS, has the best potential to
+be accepted by the community.
+
+Advantages with this solution:
+- hash can be recorded in the packet data and read in tap PMD
+- no kernel customization, everything in DPDK
+- packet gets in tap PMD on the correct queue directly
+
+Drawbacks:
+- complicates tap PMD a lot:
+  - 3 BPF programs
+  - new implicit rules
+  - new action and filter support
+  - packet stripping
+- numerous TC rules required (in proportion with the number of queues)
+- fast (kernel + JIT BPF), but several TC rules must be crossed
+
+BPF programs controlled from tap PMD will be used to match packets, compute a
+hash given the configured key, and send packets to tap using the desired queue.
+
+Design
+~~~~~~
+
+BPF has a limited set of functions for editing the skb in TC. They are listed
+in ``linux/net/core/filter.c:tc_cls_act_func_proto()``:
+
+- skb_store_bytes
+- skb_load_bytes
+- skb_pull_data
+- csum_diff
+- csum_update
+- l3_csum_replace
+- l4_csum_replace
+- clone_redirect
+- get_cgroup_classid
+- skb_vlan_push
+- skb_vlan_pop
+- skb_change_proto
+- skb_change_type
+- skb_change_tail
+- skb_get_tunnel_key
+- skb_set_tunnel_key
+- skb_get_tunnel_opt
+- skb_set_tunnel_opt
+- redirect
+- get_route_realm
+- get_hash_recalc
+- set_hash_invalid
+- perf_event_output
+- get_smp_processor_id
+- skb_under_cgroup
+
+In a BPF program, it is typically not possible to edit the queue_mapping field
+to direct the packet in the correct queue. That part would be done by chaining a
+``skbedit queue_mapping`` action.
+
+It is not possible either to directly prepend data to a packet (appending works,
+though).
+
+A packet would go through these rules (on the local side of the tap netdevice):
+
++-----+---------------------------+----------------------------------+----------+
+|PRIO |           Match           |              Action 1            | Action 2 |
++=====+===========================+==================================+==========+
+|  1  | marked?                   | skbedit queue 'mark' --> DPDK    |          |
++-----+---------------------------+----------------------------------+----------+
+|  2  | marked?                   | skbedit queue 'mark' --> DPDK    |          |
++-----+---------------------------+----------------------------------+----------+
+| ... |                           |                                  |          |
++-----+---------------------------+----------------------------------+----------+
+|  x  | ANY                       | BPF: append NULL 32bits for hash |          |
+|     |                           |                                  |          |
++-----+---------------------------+----------------------------------+----------+
+|x + 1| ACTUAL FLOW RULE 1 MATCH  | ...                              |          |
+|     |                           |                                  |          |
++-----+---------------------------+----------------------------------+----------+
+|x + 2| ACTUAL FLOW RULE 2 MATCH  | ...                              |          |
+|     |                           |                                  |          |
++-----+---------------------------+----------------------------------+----------+
+| ... |                           |                                  |          |
++-----+---------------------------+----------------------------------+----------+
+|  y  | FLOW RULE RSS 1 MATCH     | BPF compute hash into packet     |reclassify|
+|     |                           | tailroom && set queue in skb->cb |          |
++-----+---------------------------+----------------------------------+----------+
+|y + 1| FLOW RULE RSS 2 MATCH     | BPF compute hash into packet     |reclassify|
+|     |                           | tailroom && set queue in skb->cb |          |
++-----+---------------------------+----------------------------------+----------+
+| ... |                           |                                  |          |
++-----+---------------------------+----------------------------------+----------+
+|  z  | ANY (default RSS)         | BPF compute hash into packet     |reclassify|
+|     |                           | tailroom && set queue in skb->cb |          |
++-----+---------------------------+----------------------------------+----------+
+|  z  | ANY (isolate mode)        | DROP                             |          |
++-----+---------------------------+----------------------------------+----------+
+
+
+
+TC kernel action
+----------------
+
+The latest solution (implementing a TC action) would probably be the most simple
+to implement. It is also very flexible, opening more possibilities for filtering
+and RSS combined.
+
+For this solution, the following parameters could be used to configure RSS in a
+TC netlink message:
+
+``queues`` (u16 \*):
+  list of queues to spread incoming traffic on. That's actually the reta.
+  **Note:** the queue in an ``skb`` is on 16-bits, hence the type here.
+
+``key`` (u8 \*):
+  key to use for the Toeplitz-hash in this flow.
+
+``hash_fields`` (bitfield):
+  similar to what's in DPDK, the bitfield should determine what fields in the
+  packet header to use for hashing. It is likely another means of configuring
+  which fields to pick would be used actually.
+
+``algo`` (unsigned):
+  an enum value from the kernel act_rss header can be used to determine which
+  algorithm (implemented in the kernel) to use. Possible algos could be
+  toeplitz, xor, symmetric hash...
+
+**Note:** The number of queues to use is automatically deduced from the
+``queues`` netlink attribute length. The ``key`` length can be similarly
+obtained.
+
+.. raw:: pdf
+
+  PageBreak
+
+Appendix: TC netlink message
+============================
+
+**Note:** For deterministic behavior, TC queueing disciplines (QDISC), filters
+and classes must be flushed before starting to apply TC rules. There is a little
+bit of boilerplate (with specific netlink messages) to ensure TC rules can be
+applied. Typically, the TC ``ingress`` QDISC must be created first.
+
+For information, netlink messages regarding TC will look like this::
+
+      0          8         16         24         32
+      +----------+----------+----------+----------+  ---
+    0 |                  Length                   |     \
+      +---------------------+---------------------+      \
+    4 |         Type        |        Flags        |      |
+      +----------- ---------+---------------------+       >--  struct
+    8 |              Sequence number              |      |     nlmsghdr
+      +-------------------------------------------+      /
+   12 |           Process Port ID (PID)           |     /
+      +==========+==========+==========+==========+  ---
+   16 |  Family  |  Rsvd1   |      Reserved2      |     \
+      +----------+----------+---------------------+      \
+   20 |              Interface index              |      |
+      +-------------------------------------------+      |
+   24 |                  Handle                   |      |
+      +-------------------------------------------+       >--  struct
+   28 |               Parent handle               |      |     tcmsg
+      |        MAJOR        +        MINOR        |      |
+      +-------------------------------------------+      |
+   32 |                 TCM info                  |      /
+      |       priority      +      protocol       |     /
+      +===========================================+  ---
+      |                                           |
+      |                  Payload                  |
+      |                                           |
+        ........................................
+      |                                           |
+      |                                           |
+      +-------------------------------------------+
diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index 405b49e..9afae5e 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -39,6 +39,9 @@ EXPORT_MAP := rte_pmd_tap_version.map
 
 LIBABIVER := 1
 
+# TAP_MAX_QUEUES must be a power of 2 as it will be used for masking */
+TAP_MAX_QUEUES = 16
+
 CFLAGS += -O3
 CFLAGS += -I$(SRCDIR)
 CFLAGS += -I.
@@ -47,6 +50,8 @@ LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
 LDLIBS += -lrte_bus_vdev
 
+CFLAGS += -DTAP_MAX_QUEUES=$(TAP_MAX_QUEUES)
+
 #
 # all source are stored in SRCS-y
 #
@@ -89,7 +94,6 @@ tap_autoconf.h: tap_autoconf.h.new
 		mv '$<' '$@'
 
 $(SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP):.c=.o): tap_autoconf.h
-
 clean_tap: FORCE
 	$Q rm -f -- tap_autoconf.h tap_autoconf.h.new
 
diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
index 829f32f..01ac153 100644
--- a/drivers/net/tap/rte_eth_tap.h
+++ b/drivers/net/tap/rte_eth_tap.h
@@ -45,7 +45,7 @@
 #include <rte_ether.h>
 
 #ifdef IFF_MULTI_QUEUE
-#define RTE_PMD_TAP_MAX_QUEUES	16
+#define RTE_PMD_TAP_MAX_QUEUES	TAP_MAX_QUEUES
 #else
 #define RTE_PMD_TAP_MAX_QUEUES	1
 #endif
@@ -90,6 +90,11 @@ struct pmd_internals {
 	int ioctl_sock;                   /* socket for ioctl calls */
 	int nlsk_fd;                      /* Netlink socket fd */
 	int flow_isolate;                 /* 1 if flow isolation is enabled */
+	int flower_support;               /* 1 if kernel supports, else 0 */
+	int flower_vlan_support;          /* 1 if kernel supports, else 0 */
+	int rss_enabled;                  /* 1 if RSS is enabled, else 0 */
+	/* implicit rules set when RSS is enabled */
+	LIST_HEAD(tap_rss_flows, rte_flow) rss_flows;
 	LIST_HEAD(tap_flows, rte_flow) flows;        /* rte_flow rules */
 	/* implicit rte_flow rules set when a remote device is active */
 	LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows;
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index ffc0b85..43bab7d 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -43,6 +43,9 @@
 #include <tap_autoconf.h>
 #include <tap_tcmsgs.h>
 
+#include <linux/bpf.h>
+#include <linux/tc_act/tc_bpf.h>
+
 #ifndef HAVE_TC_FLOWER
 /*
  * For kernels < 4.2, this enum is not defined. Runtime checks will be made to
@@ -104,6 +107,23 @@ struct remote_rule {
 	int mirred;
 };
 
+struct action_data {
+	char id[16];
+
+	union {
+		struct tc_gact gact;
+		struct tc_mirred mirred;
+		struct skbedit {
+			struct tc_skbedit skbedit;
+			uint16_t queue;
+		} skbedit;
+		struct bpf {
+			int bpf_fd;
+			char *annotation;
+		} bpf;
+	};
+};
+
 static int tap_flow_create_eth(const struct rte_flow_item *item, void *data);
 static int tap_flow_create_vlan(const struct rte_flow_item *item, void *data);
 static int tap_flow_create_ipv4(const struct rte_flow_item *item, void *data);
@@ -134,6 +154,8 @@ tap_flow_isolate(struct rte_eth_dev *dev,
 		 int set,
 		 struct rte_flow_error *error);
 
+static int rss_enable(struct pmd_internals *pmd);
+
 static const struct rte_flow_ops tap_flow_ops = {
 	.validate = tap_flow_validate,
 	.create = tap_flow_create,
@@ -816,111 +838,64 @@ tap_flow_item_validate(const struct rte_flow_item *item,
 }
 
 /**
- * Transform a DROP/PASSTHRU action item in the provided flow for TC.
- *
- * @param[in, out] flow
- *   Flow to be filled.
- * @param[in] action
- *   Appropriate action to be set in the TCA_GACT_PARMS structure.
- *
- * @return
- *   0 if checks are alright, -1 otherwise.
+ * FIXME
  */
 static int
-add_action_gact(struct rte_flow *flow, int action)
+add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
 {
 	struct nlmsg *msg = &flow->msg;
-	size_t act_index = 1;
-	struct tc_gact p = {
-		.action = action
-	};
 
-	if (nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
-		return -1;
-	if (nlattr_nested_start(msg, act_index++) < 0)
+	if (nlattr_nested_start(msg, ++(*act_index)) < 0)
 		return -1;
-	nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("gact"), "gact");
-	if (nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
-		return -1;
-	nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(p), &p);
-	nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
-	nlattr_nested_finish(msg); /* nested act_index */
-	nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
-	return 0;
-}
-
-/**
- * Transform a MIRRED action item in the provided flow for TC.
- *
- * @param[in, out] flow
- *   Flow to be filled.
- * @param[in] ifindex
- *   Netdevice ifindex, where to mirror/redirect packet to.
- * @param[in] action_type
- *   Either TCA_EGRESS_REDIR for redirection or TCA_EGRESS_MIRROR for mirroring.
- *
- * @return
- *   0 if checks are alright, -1 otherwise.
- */
-static int
-add_action_mirred(struct rte_flow *flow, uint16_t ifindex, uint16_t action_type)
-{
-	struct nlmsg *msg = &flow->msg;
-	size_t act_index = 1;
-	struct tc_mirred p = {
-		.eaction = action_type,
-		.ifindex = ifindex,
-	};
 
-	if (nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
-		return -1;
-	if (nlattr_nested_start(msg, act_index++) < 0)
-		return -1;
-	nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("mirred"), "mirred");
+	nlattr_add(&msg->nh, TCA_ACT_KIND, strlen(adata->id), adata->id);
 	if (nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
 		return -1;
-	if (action_type == TCA_EGRESS_MIRROR)
-		p.action = TC_ACT_PIPE;
-	else /* REDIRECT */
-		p.action = TC_ACT_STOLEN;
-	nlattr_add(&msg->nh, TCA_MIRRED_PARMS, sizeof(p), &p);
+	if (strcmp("gact", adata->id) == 0) {
+		nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(adata->gact),
+			   &adata->gact);
+	} else if (strcmp("mirred", adata->id) == 0) {
+		if (adata->mirred.eaction == TCA_EGRESS_MIRROR)
+			adata->mirred.action = TC_ACT_PIPE;
+		else /* REDIRECT */
+			adata->mirred.action = TC_ACT_STOLEN;
+		nlattr_add(&msg->nh, TCA_MIRRED_PARMS, sizeof(adata->mirred),
+			   &adata->mirred);
+	} else if (strcmp("skbedit", adata->id) == 0) {
+		nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS,
+			   sizeof(adata->skbedit.skbedit),
+			   &adata->skbedit.skbedit);
+		nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING,
+			     adata->skbedit.queue);
+	} else if (strcmp("bpf", adata->id) == 0) {
+		nlattr_add32(&msg->nh, TCA_ACT_BPF_FD, adata->bpf.bpf_fd);
+		nlattr_add(&msg->nh, TCA_ACT_BPF_NAME,
+			   strlen(adata->bpf.annotation),
+			   adata->bpf.annotation);
+	} else {
+		return -1;
+	}
 	nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
 	nlattr_nested_finish(msg); /* nested act_index */
-	nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
 	return 0;
 }
 
 /**
- * Transform a QUEUE action item in the provided flow for TC.
- *
- * @param[in, out] flow
- *   Flow to be filled.
- * @param[in] queue
- *   Queue id to use.
- *
- * @return
- *   0 if checks are alright, -1 otherwise.
+ * FIXME
  */
 static int
-add_action_skbedit(struct rte_flow *flow, uint16_t queue)
+add_actions(struct rte_flow *flow, int nb_actions, struct action_data *data,
+	    int classifier_action)
 {
 	struct nlmsg *msg = &flow->msg;
-	size_t act_index = 1;
-	struct tc_skbedit p = {
-		.action = TC_ACT_PIPE
-	};
+	size_t act_index = 0;
+	int i;
 
-	if (nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
-		return -1;
-	if (nlattr_nested_start(msg, act_index++) < 0)
+	if (nlattr_nested_start(msg, classifier_action) < 0)
 		return -1;
-	nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("skbedit"), "skbedit");
-	if (nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
-		return -1;
-	nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS, sizeof(p), &p);
-	nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING, queue);
-	nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
-	nlattr_nested_finish(msg); /* nested act_index */
+	for (i = 0; i < nb_actions; i++)
+		if (add_action(flow, &act_index, data + i) < 0)
+			return -1;
 	nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
 	return 0;
 }
@@ -1053,7 +1028,12 @@ priv_flow_process(struct pmd_internals *pmd,
 		}
 	}
 	if (mirred && flow) {
-		uint16_t if_index = pmd->if_index;
+		struct action_data adata = {
+			.id = "mirred",
+			.mirred = {
+				.eaction = mirred,
+			},
+		};
 
 		/*
 		 * If attr->egress && mirred, then this is a special
@@ -1061,9 +1041,13 @@ priv_flow_process(struct pmd_internals *pmd,
 		 * redirect packets coming from the DPDK App, out
 		 * through the remote netdevice.
 		 */
-		if (attr->egress)
-			if_index = pmd->remote_if_index;
-		if (add_action_mirred(flow, if_index, mirred) < 0)
+		adata.mirred.ifindex = attr->ingress ? pmd->if_index :
+			pmd->remote_if_index;
+		if (mirred == TCA_EGRESS_MIRROR)
+			adata.mirred.action = TC_ACT_PIPE;
+		else
+			adata.mirred.action = TC_ACT_STOLEN;
+		if (add_actions(flow, 1, &adata, TCA_FLOWER_ACT) < 0)
 			goto exit_action_not_supported;
 		else
 			goto end;
@@ -1077,14 +1061,33 @@ priv_flow_process(struct pmd_internals *pmd,
 			if (action)
 				goto exit_action_not_supported;
 			action = 1;
-			if (flow)
-				err = add_action_gact(flow, TC_ACT_SHOT);
+			if (flow) {
+				struct action_data adata = {
+					.id = "gact",
+					.gact = {
+						.action = TC_ACT_SHOT,
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+						  TCA_FLOWER_ACT);
+			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_PASSTHRU) {
 			if (action)
 				goto exit_action_not_supported;
 			action = 1;
-			if (flow)
-				err = add_action_gact(flow, TC_ACT_UNSPEC);
+			if (flow) {
+				struct action_data adata = {
+					.id = "gact",
+					.gact = {
+						/* continue */
+						.action = TC_ACT_UNSPEC,
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+						  TCA_FLOWER_ACT);
+			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
 			const struct rte_flow_action_queue *queue =
 				(const struct rte_flow_action_queue *)
@@ -1096,22 +1099,30 @@ priv_flow_process(struct pmd_internals *pmd,
 			if (!queue ||
 			    (queue->index > pmd->dev->data->nb_rx_queues - 1))
 				goto exit_action_not_supported;
-			if (flow)
-				err = add_action_skbedit(flow, queue->index);
+			if (flow) {
+				struct action_data adata = {
+					.id = "skbedit",
+					.skbedit = {
+						.skbedit = {
+							.action = TC_ACT_PIPE,
+						},
+						.queue = queue->index,
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+					TCA_FLOWER_ACT);
+			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
-			/* Fake RSS support. */
 			const struct rte_flow_action_rss *rss =
 				(const struct rte_flow_action_rss *)
 				actions->conf;
 
-			if (action)
-				goto exit_action_not_supported;
-			action = 1;
-			if (!rss || rss->num < 1 ||
-			    (rss->queue[0] > pmd->dev->data->nb_rx_queues - 1))
+			if (action++)
 				goto exit_action_not_supported;
-			if (flow)
-				err = add_action_skbedit(flow, rss->queue[0]);
+			if (!pmd->rss_enabled)
+				err = rss_enable(pmd);
+			(void)rss;
 		} else {
 			goto exit_action_not_supported;
 		}
@@ -1632,6 +1643,127 @@ tap_flow_implicit_flush(struct pmd_internals *pmd, struct rte_flow_error *error)
 	return 0;
 }
 
+#define BPF_PROGRAM "tap_bpf_program.o"
+
+/**
+ * Enable RSS on tap: create leading TC rules for queuing.
+ */
+static int rss_enable(struct pmd_internals *pmd)
+{
+	struct rte_flow *rss_flow = NULL;
+	char section[64];
+	struct nlmsg *msg = NULL;
+	/* 4096 is the maximum number of instructions for a BPF program */
+	char annotation[256];
+	int bpf_fd;
+	int i;
+
+	/*
+	 * Add a rule per queue to match reclassified packets and direct them to
+	 * the correct queue.
+	 */
+	for (i = 0; i < pmd->dev->data->nb_rx_queues; i++) {
+		struct action_data adata = {
+			.id = "skbedit",
+			.skbedit = {
+				.skbedit = {
+					.action = TC_ACT_PIPE,
+				},
+				.queue = i,
+			},
+		};
+
+		bpf_fd = 0;
+
+		rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
+		if (!rss_flow) {
+			RTE_LOG(ERR, PMD,
+				"Cannot allocate memory for rte_flow");
+			return -1;
+		}
+		msg = &rss_flow->msg;
+		tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER, NLM_F_REQUEST |
+			    NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE);
+		msg->t.tcm_info = TC_H_MAKE((i + PRIORITY_OFFSET) << 16,
+					    htons(ETH_P_ALL));
+		msg->t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
+		tap_flow_set_handle(rss_flow);
+		nlattr_add(&msg->nh, TCA_KIND, sizeof("bpf"), "bpf");
+		if (nlattr_nested_start(msg, TCA_OPTIONS) < 0)
+			return -1;
+		nlattr_add32(&msg->nh, TCA_BPF_FD, bpf_fd);
+		snprintf(annotation, sizeof(annotation), "%s:[%s]",
+			 BPF_PROGRAM, section);
+		nlattr_add(&msg->nh, TCA_BPF_NAME, strlen(annotation),
+			   annotation);
+
+		if (add_actions(rss_flow, 1, &adata, TCA_BPF_ACT) < 0)
+			return -1;
+		nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
+		/* Netlink message is now ready to be sent */
+		if (nl_send(pmd->nlsk_fd, &msg->nh) < 0)
+			return -1;
+		if (nl_recv_ack(pmd->nlsk_fd) < 0)
+			return -1;
+		LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
+	}
+
+	snprintf(annotation, sizeof(annotation), "%s:[%s]", BPF_PROGRAM,
+		 section);
+	rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
+	if (!rss_flow) {
+		RTE_LOG(ERR, PMD,
+			"Cannot allocate memory for rte_flow");
+		return -1;
+	}
+	msg = &rss_flow->msg;
+	tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER,
+		    NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE);
+	msg->t.tcm_info =
+		TC_H_MAKE((RTE_PMD_TAP_MAX_QUEUES + PRIORITY_OFFSET) << 16,
+			  htons(ETH_P_ALL));
+	msg->t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
+	tap_flow_set_handle(rss_flow);
+	nlattr_add(&msg->nh, TCA_KIND, sizeof("flower"), "flower");
+	if (nlattr_nested_start(msg, TCA_OPTIONS) < 0)
+		return -1;
+
+	/* no fields for matching: all packets must match */
+	{
+		/* Actions */
+		struct action_data data[2] = {
+			[0] = {
+				.id = "bpf",
+				.bpf = {
+					.bpf_fd = bpf_fd,
+					.annotation = annotation,
+				},
+			},
+			[1] = {
+				.id = "gact",
+				.gact = {
+					/* continue */
+					.action = TC_ACT_UNSPEC,
+				},
+			},
+		};
+
+		if (add_actions(rss_flow, 2, data, TCA_FLOWER_ACT) < 0)
+			return -1;
+	}
+	nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
+	nlattr_nested_finish(msg); /* nested TCA_OPTIONS */
+	/* Netlink message is now ready to be sent */
+	if (nl_send(pmd->nlsk_fd, &msg->nh) < 0)
+		return -1;
+	if (nl_recv_ack(pmd->nlsk_fd) < 0)
+		return -1;
+	LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
+
+	pmd->rss_enabled = 1;
+	return 0;
+}
+
 /**
  * Manage filter operations.
  *
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v1 2/3] net/tap: add eBPF instructions
  2017-12-17 12:21 [dpdk-dev] [PATCH v1 0/3] TAP RSS eBPF cover letter Ophir Munk
  2017-12-17 12:21 ` [dpdk-dev] [PATCH v1 1/3] net/tap: add BPF sections for TAP device Ophir Munk
@ 2017-12-17 12:21 ` Ophir Munk
  2017-12-17 12:21 ` [dpdk-dev] [PATCH v1 3/3] net/tap: add eBPF classifiers map and actions Ophir Munk
  2017-12-28 10:09 ` [dpdk-dev] [PATCH v2 0/2] TAP RSS eBPF cover letter Ophir Munk
  3 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2017-12-17 12:21 UTC (permalink / raw)
  To: Pascal Mazon; +Cc: Ophir Munk, dev, Thomas Monjalon, Olga Shern

The C source file (tap_bpf_insns.c) includes eBPF "assembly
instructions" in the format of an array of struct bpf_insns.
This array is passed to the kernel for execution in BPF system call.
The C language source file (tap_bpf_program.c) from which the
"assembly instructions" were generated is included in TAP source tree,
however it does not take part in dpdk compilation.
TAP documentation details the process of eBPF "assembly instructions"
generation.

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 drivers/net/tap/Makefile          |    1 +
 drivers/net/tap/tap_bpf_insns.c   | 5427 +++++++++++++++++++++++++++++++++++++
 drivers/net/tap/tap_bpf_program.c |  321 +++
 drivers/net/tap/tap_bpf_shared.h  |   40 +
 drivers/net/tap/tap_flow.c        |   11 +-
 5 files changed, 5799 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/tap/tap_bpf_insns.c
 create mode 100644 drivers/net/tap/tap_bpf_program.c
 create mode 100644 drivers/net/tap/tap_bpf_shared.h

diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index 9afae5e..c334d90 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -59,6 +59,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += rte_eth_tap.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_flow.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_netlink.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_tcmsgs.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_bpf_insns.c
 
 include $(RTE_SDK)/mk/rte.lib.mk
 
diff --git a/drivers/net/tap/tap_bpf_insns.c b/drivers/net/tap/tap_bpf_insns.c
new file mode 100644
index 0000000..951d037
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_insns.c
@@ -0,0 +1,5427 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright 2017 6WIND S.A.
+ *   Copyright 2017 Mellanox.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND S.A. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <asm/types.h>
+#include <unistd.h>
+#include <string.h>
+#include <linux/in.h>
+#include <linux/if.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/if_tunnel.h>
+#include <linux/filter.h>
+#include <linux/bpf.h>
+
+#include "tap_bpf_shared.h"
+
+#define ERROR                   0
+
+/*
+ * The queue number is offset by 1, to distinguish packets that have
+ * gone through this rule (skb->cb[1] != 0) from others.
+ */
+#define QUEUE_OFFSET 1
+
+#define INV_KEY_IDX 0xdeadbeef
+
+/*
+ *
+ * __section("maps")
+ * struct bpf_elf_map map_keys = {
+ *	.type           =       BPF_MAP_TYPE_HASH,
+ *	.id             =       BPF_MAP_ID_KEY,
+ *	.size_key       =       sizeof(__u32),
+ *	.size_value     =       sizeof(struct rss_key),
+ *	.max_elem       =       256,
+ *	.pinning        =       PIN_GLOBAL_NS,
+ * };
+ */
+
+/*
+ * struct bpf_insn {
+ *	__u8    code;           opcode
+ *	__u8    dst_reg:4;      dest register
+ *	__u8    src_reg:4;      source register
+ *	__s16   off;            signed offset
+ *	__s32   imm;            signed immediate constant
+ * };
+ */
+
+/*
+ * The next bpf_insn array matches cls_q section
+ * see tap_bpf_program.c file
+ *
+ * __section("cls_q") int
+ * match_q (struct __sk_buff *skb)
+ * {
+ *	__u32 queue = skb->cb[1];
+ *	volatile __u32 q = INV_KEY_IDX;
+ *	__u32 match_queue = QUEUE_OFFSET + q;
+ *
+ *	if (queue != match_queue)
+ *		return TC_ACT_OK;
+ *	return TC_ACT_UNSPEC;
+ *
+ * }
+ */
+
+static struct bpf_insn cls_q_insns[] = {
+	{0x61,  1,  1,  52, 0x00000000},
+	{0x18,  2,  0,   0, 0xdeadbeef},
+	{0x00,  0,  0,   0, 0x00000000},
+	{0x63, 10,  2,  -4, 0x00000000},
+	{0x61,  2, 10,  -4, 0x00000000},
+	{0x07,  2,  0,   0, 0x00000001},
+	{0x67,  2,  0,   0, 0x00000020},
+	{0x77,  2,  0,   0, 0x00000020},
+	{0xb7,  0,  0,   0, 0xffffffff},
+	{0x1d,  1,  2,   1, 0x00000000},
+	{0xb7,  0,  0,   0, 0x00000000},
+	{0x95,  0,  0,   0, 0x00000000},
+};
+
+#define CLS_Q_INSNS_CNT \
+	(sizeof(cls_q_insns) / sizeof(cls_q_insns[0]))
+
+/**
+ * Load BPF program (section cls_q) into the kernel and return a bpf fd
+ *
+ * @param queue_idx
+ *   Queue index matching packet cb
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int bpf_load_cls_q_insns(__u32 queue_idx)
+{
+	cls_q_insns[1].imm = queue_idx;
+
+	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+		(struct bpf_insn *)cls_q_insns,
+		CLS_Q_INSNS_CNT,
+		"GPL", 0);
+}
+
+/*
+ * The next bpf_insn array matches tailing section
+ * see tap_bpf_program.c file
+ *
+ * __section("tailing") int
+ * tail(struct __sk_buff *skb)
+ * {
+ *	skb_change_tail(skb, skb->len + sizeof(__u32), 0);
+ *
+ * return TC_ACT_UNSPEC;
+ * }
+ */
+
+static struct bpf_insn tailing_insns[] = {
+	{0x61,  2,  1,   0, 0x00000000},
+	{0x07,  2,  0,   0, 0x00000004},
+	{0xb7,  3,  0,   0, 0x00000000},
+	{0x85,  0,  0,   0, 0x00000026},
+	{0x18,  0,  0,   0, 0xffffffff},
+	{0x00,  0,  0,   0, 0x00000000},
+	{0x95,  0,  0,   0, 0x00000000},
+};
+
+#define TAILING_INSNS_CNT \
+	(sizeof(tailing_insns) / sizeof(tailing_insns[0]))
+
+/**
+ * Load BPF program (section tailing) into the kernel and return a bpf fd.
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int bpf_load_tailing_insns(void)
+{
+	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+		(struct bpf_insn *)tailing_insns,
+		TAILING_INSNS_CNT,
+		"GPL", 0);
+}
+
+/*
+ * The next bpf_insn array matches hash_pending section
+ * see tap_bpf_program.c file
+ *
+ * __section("hash_appending") int
+ * append_hash(struct __sk_buff *skb)
+ * {
+ *	__u32 hash = skb->cb[0];
+ *
+ *	skb_store_bytes(skb, skb->len - sizeof(hash), &hash, sizeof(hash), 0);
+ *
+ *	return TC_ACT_PIPE;
+ * }
+ */
+
+static struct bpf_insn hash_appending_insns[] = {
+	{0x61,  2,  1,  48, 0x00000000},
+	{0x63, 10,  2,  -4, 0x00000000},
+	{0x61,  2,  1,   0, 0x00000000},
+	{0x07,  2,  0,   0, 0xfffffffc},
+	{0xbf,  3, 10,   0, 0x00000000},
+	{0x07,  3,  0,   0, 0xfffffffc},
+	{0xb7,  4,  0,   0, 0x00000004},
+	{0xb7,  5,  0,   0, 0x00000000},
+	{0x85,  0,  0,   0, 0x00000009},
+	{0xb7,  0,  0,   0, 0x00000003},
+	{0x95,  0,  0,   0, 0x00000000},
+};
+
+#define HASH_APPENDING_INSNS_CNT \
+	(sizeof(hash_appending_insns) / sizeof(hash_appending_insns[0]))
+
+/**
+ * Load BPF program into the kernel and return a bpf fd.
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int bpf_load_hash_appending_insns(void)
+{
+	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+		(struct bpf_insn *)hash_appending_insns,
+		HASH_APPENDING_INSNS_CNT,
+		"GPL", 0);
+}
+
+/*
+ * The next bpf_insn array matches queue_setting section
+ * see tap_bpf_program.c file
+ *
+ * static void __attribute__((always_inline))
+ * __section("queue_setting") int
+ * set_queue(struct __sk_buff *skb)
+ * {
+ *	__u32 key_idx = INV_KEY_IDX;
+ *	__u64 hash = skb->cb[0];
+ *	 struct rss_key *rsskey;
+ *	 __u32 queue = 0;
+ *
+ *	rsskey = map_lookup_elem(&map_keys, &key_idx);
+ *	if (rsskey && rsskey->nb_queues <= TAP_MAX_QUEUES)
+ *		queue = rsskey->queues[(hash % rsskey->nb_queues) &
+ *				       (TAP_MAX_QUEUES - 1)];
+ *
+ *	skb->cb[1] = QUEUE_OFFSET + queue;
+ *
+ *	return TC_ACT_RECLASSIFY;
+ * }
+ */
+
+static struct bpf_insn queue_setting_insns[] = {
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0x18,  1,  0,   0, 0xdeadbeef},
+	{0x00,  0,  0,   0, 0x00000000},
+	{0x63, 10,  1,  -4, 0x00000000},
+	{0x61,  7,  6,  48, 0x00000000},
+	{0xbf,  2, 10,   0, 0x00000000},
+	{0x07,  2,  0,   0, 0xfffffffc},
+	{0x18,  1,  1,   0, 0xffffffff},
+	{0x00,  0,  0,   0, 0x00000000},
+	{0x85,  0,  0,   0, 0x00000001},
+	{0xb7,  1,  0,   0, 0x00000001},
+	{0x15,  0,  0,  13, 0x00000000},
+	{0x61,  2,  0, 200, 0x00000000},
+	{0x25,  2,  0,  11, 0x00000010},
+	{0x67,  7,  0,   0, 0x00000020},
+	{0x77,  7,  0,   0, 0x00000020},
+	{0xbf,  1,  7,   0, 0x00000000},
+	{0x3f,  1,  2,   0, 0x00000000},
+	{0x2f,  1,  2,   0, 0x00000000},
+	{0x1f,  7,  1,   0, 0x00000000},
+	{0x57,  7,  0,   0, 0x0000000f},
+	{0x67,  7,  0,   0, 0x00000002},
+	{0x0f,  0,  7,   0, 0x00000000},
+	{0x61,  1,  0, 136, 0x00000000},
+	{0x07,  1,  0,   0, 0x00000001},
+	{0x63,  6,  1,  52, 0x00000000},
+	{0xb7,  0,  0,   0, 0x00000001},
+	{0x95,  0,  0,   0, 0x00000000},
+};
+
+#define QUEUE_SETTING_INSNS_CNT \
+	(sizeof(queue_setting_insns) / sizeof(queue_setting_insns[0]))
+
+/**
+ * Load BPF program (section queue_setting) into the kernel and return a bpf fd
+ *
+ * @param queue_idx
+ *   Queue index matching packet cb
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int bpf_load_queue_setting_insns(__u32 queue_idx)
+{
+	queue_setting_insns[1].imm = queue_idx;
+
+	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+		(struct bpf_insn *)queue_setting_insns,
+		QUEUE_SETTING_INSNS_CNT,
+		"GPL", 0);
+}
+
+/*
+ * The next bpf_insn array matches l2_src_hash section
+ * see tap_bpf_program.c file
+ *
+ * #define HASH(L)						\
+ *	__section(#L) int				\
+ *		L ## _hash(struct __sk_buff *skb)	\
+ *	{						\
+ *		return hash(skb, HASH_FIELD_ ## L);	\
+ *	}
+ *
+ * HASH(L2_SRC)
+ */
+
+
+static struct bpf_insn l2_src_hash_insns[] = {
+	{0xbf,  7,  1,   0, 0x00000000},
+	{0x61,  6,  7,  16, 0x00000000},
+	{0x61,  9,  7,  76, 0x00000000},
+	{0x61,  8,  7,  80, 0x00000000},
+	{0x18,  1,  0,   0, 0xdeadbeef},
+	{0x00,  0,  0,   0, 0x00000000},
+	{0x63, 10,  1,  -4, 0x00000000},
+	{0x61,  1,  7,  48, 0x00000000},
+	{0x7b, 10,  1, -56, 0x00000000},
+	{0xbf,  2, 10,   0, 0x00000000},
+	{0x07,  2,  0,   0, 0xfffffffc},
+	{0x18,  1,  1,   0, 0xffffffff},
+	{0x00,  0,  0,   0, 0x00000000},
+	{0x85,  0,  0,   0, 0x00000001},
+	{0x55,  0,  0,  21, 0x00000000},
+	{0xb7,  1,  0,   0, 0x00000a64},
+	{0x6b, 10,  1, -16, 0x00000000},
+	{0x18,  1,  0,   0, 0x69666e6f},
+	{0x00,  0,  0,   0, 0x65727567},
+	{0x7b, 10,  1, -24, 0x00000000},
+	{0x18,  1,  0,   0, 0x6e207369},
+	{0x00,  0,  0,   0, 0x6320746f},
+	{0x7b, 10,  1, -32, 0x00000000},
+	{0x18,  1,  0,   0, 0x20737372},
+	{0x00,  0,  0,   0, 0x2079656b},
+	{0x7b, 10,  1, -40, 0x00000000},
+	{0x18,  1,  0,   0, 0x68736168},
+	{0x00,  0,  0,   0, 0x203a2928},
+	{0x7b, 10,  1, -48, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0x73, 10,  7, -14, 0x00000000},
+	{0xbf,  1, 10,   0, 0x00000000},
+	{0x07,  1,  0,   0, 0xffffffd0},
+	{0xb7,  2,  0,   0, 0x00000023},
+	{0x85,  0,  0,   0, 0x00000006},
+	{0x05,  0,  0, 543, 0x00000000},
+	{0xb7,  1,  0,   0, 0x0000000e},
+	{0x61,  2,  7,  20, 0x00000000},
+	{0x15,  2,  0,  10, 0x00000000},
+	{0x61,  2,  7,  28, 0x00000000},
+	{0x55,  2,  0,   8, 0x0000a888},
+	{0xbf,  2,  7,   0, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0xbf,  1,  9,   0, 0x00000000},
+	{0x07,  1,  0,   0, 0x00000012},
+	{0x2d,  1,  8, 533, 0x00000000},
+	{0xb7,  1,  0,   0, 0x00000012},
+	{0x69,  6,  9,  16, 0x00000000},
+	{0xbf,  7,  2,   0, 0x00000000},
+	{0x61,  2,  0, 128, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0xb7,  4,  0,   0, 0x00000000},
+	{0x1d,  3,  4,   1, 0x00000000},
+	{0x07,  0,  0,   0, 0x00000006},
+	{0x57,  2,  0,   0, 0x00000002},
+	{0x15,  2,  0, 508, 0x00000000},
+	{0x7b, 10,  7, -64, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0xbf,  1,  9,   0, 0x00000000},
+	{0x07,  1,  0,   0, 0x0000000c},
+	{0x2d,  1,  8, 517, 0x00000000},
+	{0x71,  1,  0,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000018},
+	{0x71,  6,  0,   1, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000010},
+	{0x4f,  6,  1,   0, 0x00000000},
+	{0x71,  1,  0,   2, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000008},
+	{0x4f,  6,  1,   0, 0x00000000},
+	{0x71,  1,  0,   3, 0x00000000},
+	{0x4f,  6,  1,   0, 0x00000000},
+	{0x71,  5,  9,   6, 0x00000000},
+	{0x67,  5,  0,   0, 0x00000038},
+	{0xc7,  5,  0,   0, 0x00000038},
+	{0xb7,  2,  0,   0, 0x00000000},
+	{0xb7,  3,  0,   0, 0xffffffff},
+	{0xb7,  4,  0,   0, 0x00000000},
+	{0x6d,  5,  3,   1, 0x00000000},
+	{0xbf,  4,  6,   0, 0x00000000},
+	{0x79,  1, 10, -56, 0x00000000},
+	{0xaf,  4,  1,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000001},
+	{0x71,  7,  0,   4, 0x00000000},
+	{0xbf,  1,  7,   0, 0x00000000},
+	{0x77,  1,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  5,  0,   0, 0x0000003f},
+	{0xc7,  5,  0,   0, 0x0000003f},
+	{0x5f,  5,  1,   0, 0x00000000},
+	{0xaf,  4,  5,   0, 0x00000000},
+	{0x57,  7,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  7,   0, 0x00000000},
+	{0x71,  5,  9,   7, 0x00000000},
+	{0x67,  5,  0,   0, 0x00000038},
+	{0xc7,  5,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  5,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  7,  0,   5, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  5,  0,   0, 0x0000003f},
+	{0xc7,  5,  0,   0, 0x0000003f},
+	{0x5f,  5,  1,   0, 0x00000000},
+	{0xaf,  4,  5,   0, 0x00000000},
+	{0x57,  7,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  7,   0, 0x00000000},
+	{0x71,  5,  9,   8, 0x00000000},
+	{0x67,  5,  0,   0, 0x00000038},
+	{0xc7,  5,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  5,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  7,  0,   6, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  5,  0,   0, 0x0000003f},
+	{0xc7,  5,  0,   0, 0x0000003f},
+	{0x5f,  5,  1,   0, 0x00000000},
+	{0xaf,  4,  5,   0, 0x00000000},
+	{0x57,  7,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  7,   0, 0x00000000},
+	{0x71,  5,  9,   9, 0x00000000},
+	{0x67,  5,  0,   0, 0x00000038},
+	{0xc7,  5,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  5,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  7,  0,   7, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  5,  0,   0, 0x0000003f},
+	{0xc7,  5,  0,   0, 0x0000003f},
+	{0x5f,  5,  1,   0, 0x00000000},
+	{0xaf,  4,  5,   0, 0x00000000},
+	{0x57,  7,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  7,   0, 0x00000000},
+	{0x71,  5,  9,  10, 0x00000000},
+	{0x67,  5,  0,   0, 0x00000038},
+	{0xc7,  5,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  5,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  7,  0,   8, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  5,  0,   0, 0x0000003f},
+	{0xc7,  5,  0,   0, 0x0000003f},
+	{0x5f,  5,  1,   0, 0x00000000},
+	{0xaf,  4,  5,   0, 0x00000000},
+	{0x57,  7,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  7,   0, 0x00000000},
+	{0x71,  5,  9,  11, 0x00000000},
+	{0x67,  5,  0,   0, 0x00000038},
+	{0xc7,  5,  0,   0, 0x00000038},
+	{0x6d,  5,  3,   1, 0x00000000},
+	{0xbf,  2,  1,   0, 0x00000000},
+	{0xaf,  4,  2,   0, 0x00000000},
+	{0x71,  2,  0,   9, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000007},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  5,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x00000039},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000006},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  5,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003a},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000005},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  5,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003b},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000004},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  5,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003c},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000003},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  5,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003d},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000002},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  5,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003e},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0x77,  2,  0,   0, 0x00000001},
+	{0x57,  2,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  2,   0, 0x00000000},
+	{0x67,  5,  0,   0, 0x0000003f},
+	{0xc7,  5,  0,   0, 0x0000003f},
+	{0x5f,  5,  1,   0, 0x00000000},
+	{0xaf,  4,  5,   0, 0x00000000},
+	{0x79,  1, 10, -64, 0x00000000},
+	{0x63,  1,  4,  48, 0x00000000},
+	{0x18,  1,  0,   0, 0x25203d20},
+	{0x00,  0,  0,   0, 0x000a2964},
+	{0x7b, 10,  1, -24, 0x00000000},
+	{0x18,  1,  0,   0, 0x20782520},
+	{0x00,  0,  0,   0, 0x66666f28},
+	{0x7b, 10,  1, -32, 0x00000000},
+	{0x18,  1,  0,   0, 0x6168203a},
+	{0x00,  0,  0,   0, 0x3d206873},
+	{0x7b, 10,  1, -40, 0x00000000},
+	{0x18,  1,  0,   0, 0x68736168},
+	{0x00,  0,  0,   0, 0x29642528},
+	{0x7b, 10,  1, -48, 0x00000000},
+	{0xbf,  1, 10,   0, 0x00000000},
+	{0x07,  1,  0,   0, 0xffffffd0},
+	{0xb7,  2,  0,   0, 0x00000020},
+	{0xb7,  3,  0,   0, 0x00000001},
+	{0xb7,  5,  0,   0, 0x00000006},
+	{0x85,  0,  0,   0, 0x00000006},
+	{0x05,  0,  0,  13, 0x00000000},
+	{0x57,  6,  0,   0, 0x0000ffff},
+	{0x15,  6,  0,   7, 0x0000dd86},
+	{0xb7,  7,  0,   0, 0x00000003},
+	{0x55,  6,  0,  10, 0x00000008},
+	{0x0f,  9,  1,   0, 0x00000000},
+	{0x07,  9,  0,   0, 0x00000014},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0x2d,  9,  8,   6, 0x00000000},
+	{0x05,  0,  0,   4, 0x00000000},
+	{0x0f,  9,  1,   0, 0x00000000},
+	{0x07,  9,  0,   0, 0x00000028},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0x2d,  9,  8,   1, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000003},
+	{0xbf,  0,  7,   0, 0x00000000},
+	{0x95,  0,  0,   0, 0x00000000},
+};
+
+#define L2_SRC_HASH_INSNS_CNT \
+	(sizeof(l2_src_hash_insns) / sizeof(l2_src_hash_insns[0]))
+
+/**
+ * Load BPF program (section l2_src_hash) into the kernel and return a bpf fd.
+ *
+ * @param key_idx
+ *   RSS MAP key index
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int bpf_load_l2_src_hash_insns(__u32 key_idx)
+{
+	l2_src_hash_insns[4].imm = key_idx;
+
+	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+		(struct bpf_insn *)l2_src_hash_insns,
+		L2_SRC_HASH_INSNS_CNT,
+		"GPL", 0);
+}
+
+/*
+ * The next bpf_insn array matches l2_dst_hash section
+ * see tap_bpf_program.c file
+ *
+ * HASH(L2_DST)
+ */
+
+static struct bpf_insn l2_dst_hash_insns[] = {
+	{0xbf,  7,  1,   0, 0x00000000},
+	{0x61,  6,  7,  16, 0x00000000},
+	{0x61,  9,  7,  76, 0x00000000},
+	{0x61,  8,  7,  80, 0x00000000},
+	{0x18,  1,  0,   0, 0xdeadbeef},
+	{0x00,  0,  0,   0, 0x00000000},
+	{0x63, 10,  1,  -4, 0x00000000},
+	{0x61,  1,  7,  48, 0x00000000},
+	{0x7b, 10,  1, -56, 0x00000000},
+	{0xbf,  2, 10,   0, 0x00000000},
+	{0x07,  2,  0,   0, 0xfffffffc},
+	{0x18,  1,  1,   0, 0xffffffff},
+	{0x00,  0,  0,   0, 0x00000000},
+	{0x85,  0,  0,   0, 0x00000001},
+	{0x55,  0,  0,  21, 0x00000000},
+	{0xb7,  1,  0,   0, 0x00000a64},
+	{0x6b, 10,  1, -16, 0x00000000},
+	{0x18,  1,  0,   0, 0x69666e6f},
+	{0x00,  0,  0,   0, 0x65727567},
+	{0x7b, 10,  1, -24, 0x00000000},
+	{0x18,  1,  0,   0, 0x6e207369},
+	{0x00,  0,  0,   0, 0x6320746f},
+	{0x7b, 10,  1, -32, 0x00000000},
+	{0x18,  1,  0,   0, 0x20737372},
+	{0x00,  0,  0,   0, 0x2079656b},
+	{0x7b, 10,  1, -40, 0x00000000},
+	{0x18,  1,  0,   0, 0x68736168},
+	{0x00,  0,  0,   0, 0x203a2928},
+	{0x7b, 10,  1, -48, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0x73, 10,  7, -14, 0x00000000},
+	{0xbf,  1, 10,   0, 0x00000000},
+	{0x07,  1,  0,   0, 0xffffffd0},
+	{0xb7,  2,  0,   0, 0x00000023},
+	{0x85,  0,  0,   0, 0x00000006},
+	{0x05,  0,  0, 538, 0x00000000},
+	{0xb7,  1,  0,   0, 0x0000000e},
+	{0x61,  2,  7,  20, 0x00000000},
+	{0x15,  2,  0,  10, 0x00000000},
+	{0x61,  2,  7,  28, 0x00000000},
+	{0x55,  2,  0,   8, 0x0000a888},
+	{0xbf,  2,  7,   0, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0xbf,  1,  9,   0, 0x00000000},
+	{0x07,  1,  0,   0, 0x00000012},
+	{0x2d,  1,  8, 528, 0x00000000},
+	{0xb7,  1,  0,   0, 0x00000012},
+	{0x69,  6,  9,  16, 0x00000000},
+	{0xbf,  7,  2,   0, 0x00000000},
+	{0x71,  2,  0, 128, 0x00000000},
+	{0x57,  2,  0,   0, 0x00000001},
+	{0x15,  2,  0, 508, 0x00000000},
+	{0xbf,  5,  7,   0, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0xbf,  1,  9,   0, 0x00000000},
+	{0x07,  1,  0,   0, 0x00000006},
+	{0x2d,  1,  8, 517, 0x00000000},
+	{0x71,  1,  0,   1, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000010},
+	{0x71,  6,  0,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000018},
+	{0x4f,  6,  1,   0, 0x00000000},
+	{0x71,  1,  0,   2, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000008},
+	{0x4f,  6,  1,   0, 0x00000000},
+	{0x71,  1,  0,   3, 0x00000000},
+	{0x4f,  6,  1,   0, 0x00000000},
+	{0x71,  3,  9,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x00000038},
+	{0xc7,  3,  0,   0, 0x00000038},
+	{0xb7,  2,  0,   0, 0xffffffff},
+	{0xb7,  4,  0,   0, 0x00000000},
+	{0xbf,  7,  5,   0, 0x00000000},
+	{0x6d,  3,  2,   1, 0x00000000},
+	{0xbf,  4,  6,   0, 0x00000000},
+	{0x79,  1, 10, -56, 0x00000000},
+	{0xaf,  4,  1,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000001},
+	{0x71,  5,  0,   4, 0x00000000},
+	{0xbf,  1,  5,   0, 0x00000000},
+	{0x77,  1,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003f},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0x57,  5,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  5,   0, 0x00000000},
+	{0x71,  3,  9,   1, 0x00000000},
+	{0x67,  3,  0,   0, 0x00000038},
+	{0xc7,  3,  0,   0, 0x00000038},
+	{0xb7,  5,  0,   0, 0x00000000},
+	{0x6d,  3,  2,   1, 0x00000000},
+	{0xbf,  5,  1,   0, 0x00000000},
+	{0xaf,  4,  5,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  5,  0,   5, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003f},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0x57,  5,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  5,   0, 0x00000000},
+	{0x71,  3,  9,   2, 0x00000000},
+	{0x67,  3,  0,   0, 0x00000038},
+	{0xc7,  3,  0,   0, 0x00000038},
+	{0xb7,  5,  0,   0, 0x00000000},
+	{0x6d,  3,  2,   1, 0x00000000},
+	{0xbf,  5,  1,   0, 0x00000000},
+	{0xaf,  4,  5,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  5,  0,   6, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003f},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0x57,  5,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  5,   0, 0x00000000},
+	{0x71,  3,  9,   3, 0x00000000},
+	{0x67,  3,  0,   0, 0x00000038},
+	{0xc7,  3,  0,   0, 0x00000038},
+	{0xb7,  5,  0,   0, 0x00000000},
+	{0x6d,  3,  2,   1, 0x00000000},
+	{0xbf,  5,  1,   0, 0x00000000},
+	{0xaf,  4,  5,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  5,  0,   7, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003f},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0x57,  5,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  5,   0, 0x00000000},
+	{0x71,  3,  9,   4, 0x00000000},
+	{0x67,  3,  0,   0, 0x00000038},
+	{0xc7,  3,  0,   0, 0x00000038},
+	{0xb7,  5,  0,   0, 0x00000000},
+	{0x6d,  3,  2,   1, 0x00000000},
+	{0xbf,  5,  1,   0, 0x00000000},
+	{0xaf,  4,  5,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  5,  0,   8, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  3,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  5,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003f},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0x57,  5,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  5,   0, 0x00000000},
+	{0x71,  3,  9,   5, 0x00000000},
+	{0x67,  3,  0,   0, 0x00000038},
+	{0xc7,  3,  0,   0, 0x00000038},
+	{0xb7,  5,  0,   0, 0x00000000},
+	{0x6d,  3,  2,   1, 0x00000000},
+	{0xbf,  5,  1,   0, 0x00000000},
+	{0xaf,  4,  5,   0, 0x00000000},
+	{0x71,  2,  0,   9, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0xbf,  5,  2,   0, 0x00000000},
+	{0x77,  5,  0,   0, 0x00000007},
+	{0x4f,  1,  5,   0, 0x00000000},
+	{0xbf,  5,  3,   0, 0x00000000},
+	{0x67,  5,  0,   0, 0x00000039},
+	{0xc7,  5,  0,   0, 0x0000003f},
+	{0x5f,  5,  1,   0, 0x00000000},
+	{0xaf,  4,  5,   0, 0x00000000},
+	{0xbf,  5,  2,   0, 0x00000000},
+	{0x77,  5,  0,   0, 0x00000006},
+	{0x57,  5,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  5,   0, 0x00000000},
+	{0xbf,  5,  3,   0, 0x00000000},
+	{0x67,  5,  0,   0, 0x0000003a},
+	{0xc7,  5,  0,   0, 0x0000003f},
+	{0x5f,  5,  1,   0, 0x00000000},
+	{0xaf,  4,  5,   0, 0x00000000},
+	{0xbf,  5,  2,   0, 0x00000000},
+	{0x77,  5,  0,   0, 0x00000005},
+	{0x57,  5,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  5,   0, 0x00000000},
+	{0xbf,  5,  3,   0, 0x00000000},
+	{0x67,  5,  0,   0, 0x0000003b},
+	{0xc7,  5,  0,   0, 0x0000003f},
+	{0x5f,  5,  1,   0, 0x00000000},
+	{0xaf,  4,  5,   0, 0x00000000},
+	{0xbf,  5,  2,   0, 0x00000000},
+	{0x77,  5,  0,   0, 0x00000004},
+	{0x57,  5,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  5,   0, 0x00000000},
+	{0xbf,  5,  3,   0, 0x00000000},
+	{0x67,  5,  0,   0, 0x0000003c},
+	{0xc7,  5,  0,   0, 0x0000003f},
+	{0x5f,  5,  1,   0, 0x00000000},
+	{0xaf,  4,  5,   0, 0x00000000},
+	{0xbf,  5,  2,   0, 0x00000000},
+	{0x77,  5,  0,   0, 0x00000003},
+	{0x57,  5,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  5,   0, 0x00000000},
+	{0xbf,  5,  3,   0, 0x00000000},
+	{0x67,  5,  0,   0, 0x0000003d},
+	{0xc7,  5,  0,   0, 0x0000003f},
+	{0x5f,  5,  1,   0, 0x00000000},
+	{0xaf,  4,  5,   0, 0x00000000},
+	{0xbf,  5,  2,   0, 0x00000000},
+	{0x77,  5,  0,   0, 0x00000002},
+	{0x57,  5,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  5,   0, 0x00000000},
+	{0xbf,  5,  3,   0, 0x00000000},
+	{0x67,  5,  0,   0, 0x0000003e},
+	{0xc7,  5,  0,   0, 0x0000003f},
+	{0x5f,  5,  1,   0, 0x00000000},
+	{0xaf,  4,  5,   0, 0x00000000},
+	{0x77,  2,  0,   0, 0x00000001},
+	{0x57,  2,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  2,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003f},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0x63,  7,  4,  48, 0x00000000},
+	{0x18,  1,  0,   0, 0x25203d20},
+	{0x00,  0,  0,   0, 0x000a2964},
+	{0x7b, 10,  1, -24, 0x00000000},
+	{0x18,  1,  0,   0, 0x20782520},
+	{0x00,  0,  0,   0, 0x66666f28},
+	{0x7b, 10,  1, -32, 0x00000000},
+	{0x18,  1,  0,   0, 0x6168203a},
+	{0x00,  0,  0,   0, 0x3d206873},
+	{0x7b, 10,  1, -40, 0x00000000},
+	{0x18,  1,  0,   0, 0x68736168},
+	{0x00,  0,  0,   0, 0x29642528},
+	{0x7b, 10,  1, -48, 0x00000000},
+	{0xbf,  1, 10,   0, 0x00000000},
+	{0x07,  1,  0,   0, 0xffffffd0},
+	{0xb7,  2,  0,   0, 0x00000020},
+	{0xb7,  3,  0,   0, 0x00000000},
+	{0xb7,  5,  0,   0, 0x00000000},
+	{0x85,  0,  0,   0, 0x00000006},
+	{0x05,  0,  0,  13, 0x00000000},
+	{0x57,  6,  0,   0, 0x0000ffff},
+	{0x15,  6,  0,   7, 0x0000dd86},
+	{0xb7,  7,  0,   0, 0x00000003},
+	{0x55,  6,  0,  10, 0x00000008},
+	{0x0f,  9,  1,   0, 0x00000000},
+	{0x07,  9,  0,   0, 0x00000014},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0x2d,  9,  8,   6, 0x00000000},
+	{0x05,  0,  0,   4, 0x00000000},
+	{0x0f,  9,  1,   0, 0x00000000},
+	{0x07,  9,  0,   0, 0x00000028},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0x2d,  9,  8,   1, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000003},
+	{0xbf,  0,  7,   0, 0x00000000},
+	{0x95,  0,  0,   0, 0x00000000},
+};
+#define L2_DST_HASH_INSNS_CNT \
+	(sizeof(l2_dst_hash_insns) / sizeof(l2_dst_hash_insns[0]))
+
+/**
+ * Load BPF program (section l2_dst_hash) into the kernel and return a bpf fd.
+ *
+ * @param key_idx
+ *   RSS MAP key index
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int bpf_load_l2_dst_hash_insns(__u32 key_idx)
+{
+	l2_dst_hash_insns[4].imm = key_idx;
+
+	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+		(struct bpf_insn *)l2_dst_hash_insns,
+		L2_DST_HASH_INSNS_CNT,
+		"GPL", 0);
+}
+
+/*
+ * The next bpf_insn array matches l3_dst_hash section
+ * see tap_bpf_program.c file
+ *
+ *  HASH(L3_DST)
+ */
+
+
+static struct bpf_insn l3_dst_hash_insns[] = {
+	{0xbf,  7,  1,   0, 0x00000000},
+	{0x61,  6,  7,  16, 0x00000000},
+	{0x61,  9,  7,  76, 0x00000000},
+	{0x61,  8,  7,  80, 0x00000000},
+	{0x18,  1,  0,   0, 0xdeadbeef},
+	{0x00,  0,  0,   0, 0x00000000},
+	{0x63, 10,  1,  -4, 0x00000000},
+	{0x61,  1,  7,  48, 0x00000000},
+	{0x7b, 10,  1, -56, 0x00000000},
+	{0xbf,  2, 10,   0, 0x00000000},
+	{0x07,  2,  0,   0, 0xfffffffc},
+	{0x18,  1,  1,   0, 0xffffffff},
+	{0x00,  0,  0,   0, 0x00000000},
+	{0x85,  0,  0,   0, 0x00000001},
+	{0x55,  0,  0,  21, 0x00000000},
+	{0xb7,  1,  0,   0, 0x00000a64},
+	{0x6b, 10,  1, -16, 0x00000000},
+	{0x18,  1,  0,   0, 0x69666e6f},
+	{0x00,  0,  0,   0, 0x65727567},
+	{0x7b, 10,  1, -24, 0x00000000},
+	{0x18,  1,  0,   0, 0x6e207369},
+	{0x00,  0,  0,   0, 0x6320746f},
+	{0x7b, 10,  1, -32, 0x00000000},
+	{0x18,  1,  0,   0, 0x20737372},
+	{0x00,  0,  0,   0, 0x2079656b},
+	{0x7b, 10,  1, -40, 0x00000000},
+	{0x18,  1,  0,   0, 0x68736168},
+	{0x00,  0,  0,   0, 0x203a2928},
+	{0x7b, 10,  1, -48, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0x73, 10,  7, -14, 0x00000000},
+	{0xbf,  1, 10,   0, 0x00000000},
+	{0x07,  1,  0,   0, 0xffffffd0},
+	{0xb7,  2,  0,   0, 0x00000023},
+	{0x85,  0,  0,   0, 0x00000006},
+	{0x05,  0,  0, 1689, 0x00000000},
+	{0xb7,  5,  0,   0, 0x0000000e},
+	{0x61,  1,  7,  20, 0x00000000},
+	{0x15,  1,  0,  10, 0x00000000},
+	{0x61,  1,  7,  28, 0x00000000},
+	{0x55,  1,  0,   8, 0x0000a888},
+	{0xbf,  2,  7,   0, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0xbf,  1,  9,   0, 0x00000000},
+	{0x07,  1,  0,   0, 0x00000012},
+	{0x2d,  1,  8, 1679, 0x00000000},
+	{0xb7,  5,  0,   0, 0x00000012},
+	{0x69,  6,  9,  16, 0x00000000},
+	{0xbf,  7,  2,   0, 0x00000000},
+	{0x61,  1,  0, 128, 0x00000000},
+	{0xbf,  3,  1,   0, 0x00000000},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0xb7,  2,  0,   0, 0x00000000},
+	{0x1d,  3,  2,   1, 0x00000000},
+	{0x07,  0,  0,   0, 0x00000006},
+	{0x7b, 10,  7, -64, 0x00000000},
+	{0xbf,  3,  1,   0, 0x00000000},
+	{0x57,  3,  0,   0, 0x00000002},
+	{0x1d,  3,  2,   1, 0x00000000},
+	{0x07,  0,  0,   0, 0x00000006},
+	{0xb7,  7,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x0000ffff},
+	{0x15,  6,  0, 355, 0x0000dd86},
+	{0x55,  6,  0, 1661, 0x00000008},
+	{0x0f,  9,  5,   0, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0xbf,  2,  9,   0, 0x00000000},
+	{0x07,  2,  0,   0, 0x00000014},
+	{0x2d,  2,  8, 1656, 0x00000000},
+	{0xbf,  2,  1,   0, 0x00000000},
+	{0x57,  2,  0,   0, 0x00000004},
+	{0xb7,  3,  0,   0, 0x00000000},
+	{0x1d,  2,  3,   1, 0x00000000},
+	{0x07,  0,  0,   0, 0x00000004},
+	{0x57,  1,  0,   0, 0x00000008},
+	{0xb7,  7,  0,   0, 0x00000003},
+	{0x15,  1,  0, 1648, 0x00000000},
+	{0x71,  1,  0,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000018},
+	{0x71,  6,  0,   1, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000010},
+	{0x4f,  6,  1,   0, 0x00000000},
+	{0x71,  1,  0,   2, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000008},
+	{0x4f,  6,  1,   0, 0x00000000},
+	{0x71,  1,  0,   3, 0x00000000},
+	{0x4f,  6,  1,   0, 0x00000000},
+	{0xbf,  8,  9,   0, 0x00000000},
+	{0x71,  7,  8,  16, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  2,  0,   0, 0x00000000},
+	{0xb7,  3,  0,   0, 0xffffffff},
+	{0xb7,  4,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  4,  6,   0, 0x00000000},
+	{0x79,  1, 10, -56, 0x00000000},
+	{0xaf,  4,  1,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000001},
+	{0x71,  9,  0,   4, 0x00000000},
+	{0xbf,  1,  9,   0, 0x00000000},
+	{0x77,  1,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  17, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,   5, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  18, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,   6, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  19, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  2,  1,   0, 0x00000000},
+	{0xaf,  4,  2,   0, 0x00000000},
+	{0x71,  2,  0,   7, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000007},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x00000039},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000006},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003a},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000005},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003b},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000004},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003c},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000003},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003d},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000002},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003e},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0x77,  2,  0,   0, 0x00000001},
+	{0x57,  2,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  2,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x79,  1, 10, -64, 0x00000000},
+	{0x63,  1,  4,  48, 0x00000000},
+	{0x18,  1,  0,   0, 0x25203d20},
+	{0x00,  0,  0,   0, 0x000a2964},
+	{0x7b, 10,  1, -24, 0x00000000},
+	{0x18,  1,  0,   0, 0x20782520},
+	{0x00,  0,  0,   0, 0x66666f28},
+	{0x7b, 10,  1, -32, 0x00000000},
+	{0x18,  1,  0,   0, 0x6168203a},
+	{0x00,  0,  0,   0, 0x3d206873},
+	{0x7b, 10,  1, -40, 0x00000000},
+	{0x18,  1,  0,   0, 0x68736168},
+	{0x00,  0,  0,   0, 0x29642528},
+	{0x7b, 10,  1, -48, 0x00000000},
+	{0x07,  5,  0,   0, 0x00000010},
+	{0x05,  0,  0, 1301, 0x00000000},
+	{0x0f,  9,  5,   0, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0xbf,  2,  9,   0, 0x00000000},
+	{0x07,  2,  0,   0, 0x00000028},
+	{0x2d,  2,  8, 1302, 0x00000000},
+	{0xbf,  2,  1,   0, 0x00000000},
+	{0x57,  2,  0,   0, 0x00000004},
+	{0xb7,  3,  0,   0, 0x00000000},
+	{0x1d,  2,  3,   1, 0x00000000},
+	{0x07,  0,  0,   0, 0x00000010},
+	{0x57,  1,  0,   0, 0x00000008},
+	{0xb7,  7,  0,   0, 0x00000003},
+	{0x15,  1,  0, 1294, 0x00000000},
+	{0x71,  1,  0,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000018},
+	{0x71,  6,  0,   1, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000010},
+	{0x4f,  6,  1,   0, 0x00000000},
+	{0x71,  1,  0,   2, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000008},
+	{0x4f,  6,  1,   0, 0x00000000},
+	{0x71,  1,  0,   3, 0x00000000},
+	{0x4f,  6,  1,   0, 0x00000000},
+	{0xbf,  8,  9,   0, 0x00000000},
+	{0x71,  7,  8,  24, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  2,  0,   0, 0x00000000},
+	{0xb7,  3,  0,   0, 0xffffffff},
+	{0xb7,  4,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  4,  6,   0, 0x00000000},
+	{0x79,  1, 10, -56, 0x00000000},
+	{0xaf,  4,  1,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000001},
+	{0x71,  9,  0,   4, 0x00000000},
+	{0xbf,  1,  9,   0, 0x00000000},
+	{0x77,  1,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  25, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,   5, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  26, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,   6, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  27, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,   7, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  28, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,   8, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  29, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,   9, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  30, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,  10, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  31, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,  11, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  32, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,  12, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  33, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,  13, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  34, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,  14, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  35, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,  15, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  36, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,  16, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  37, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,  17, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  38, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,  18, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  39, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  2,  1,   0, 0x00000000},
+	{0xaf,  4,  2,   0, 0x00000000},
+	{0x71,  2,  0,  19, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000007},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x00000039},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000006},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003a},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000005},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003b},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000004},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003c},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000003},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003d},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000002},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003e},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0x77,  2,  0,   0, 0x00000001},
+	{0x57,  2,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  2,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x79,  1, 10, -64, 0x00000000},
+	{0x63,  1,  4,  48, 0x00000000},
+	{0x18,  1,  0,   0, 0x25203d20},
+	{0x00,  0,  0,   0, 0x000a2964},
+	{0x7b, 10,  1, -24, 0x00000000},
+	{0x18,  1,  0,   0, 0x20782520},
+	{0x00,  0,  0,   0, 0x66666f28},
+	{0x7b, 10,  1, -32, 0x00000000},
+	{0x18,  1,  0,   0, 0x6168203a},
+	{0x00,  0,  0,   0, 0x3d206873},
+	{0x7b, 10,  1, -40, 0x00000000},
+	{0x18,  1,  0,   0, 0x68736168},
+	{0x00,  0,  0,   0, 0x29642528},
+	{0x7b, 10,  1, -48, 0x00000000},
+	{0x07,  5,  0,   0, 0x00000018},
+	{0xbf,  1, 10,   0, 0x00000000},
+	{0x07,  1,  0,   0, 0xffffffd0},
+	{0xb7,  7,  0,   0, 0x00000003},
+	{0xb7,  2,  0,   0, 0x00000020},
+	{0xb7,  3,  0,   0, 0x00000003},
+	{0x85,  0,  0,   0, 0x00000006},
+	{0xbf,  0,  7,   0, 0x00000000},
+	{0x95,  0,  0,   0, 0x00000000},
+};
+
+#define L3_DST_HASH_INSNS_CNT \
+	(sizeof(l3_dst_hash_insns) / sizeof(l3_dst_hash_insns[0]))
+
+/**
+ * Load BPF program (section l3_dst_hash) into the kernel and return a bpf fd.
+ *
+ * @param queue_idx
+ *   RSS MAP key index
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int bpf_load_l3_dst_hash_insns(__u32 key_idx)
+{
+	l3_dst_hash_insns[4].imm = key_idx;
+
+	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+		(struct bpf_insn *)l3_dst_hash_insns,
+		L3_DST_HASH_INSNS_CNT,
+		"GPL", 0);
+}
+
+/*
+ * The next bpf_insn array matches l3_src_hash section
+ * see tap_bpf_program.c file
+ *
+ * HASH(L3_SRC)
+ */
+
+static struct bpf_insn l3_src_hash_insns[] = {
+	{0xbf,  7,  1,   0, 0x00000000},
+	{0x61,  6,  7,  16, 0x00000000},
+	{0x61,  9,  7,  76, 0x00000000},
+	{0x61,  8,  7,  80, 0x00000000},
+	{0x18,  1,  0,   0, 0xdeadbeef},
+	{0x00,  0,  0,   0, 0x00000000},
+	{0x63, 10,  1,  -4, 0x00000000},
+	{0x61,  1,  7,  48, 0x00000000},
+	{0x7b, 10,  1, -56, 0x00000000},
+	{0xbf,  2, 10,   0, 0x00000000},
+	{0x07,  2,  0,   0, 0xfffffffc},
+	{0x18,  1,  1,   0, 0xffffffff},
+	{0x00,  0,  0,   0, 0x00000000},
+	{0x85,  0,  0,   0, 0x00000001},
+	{0x55,  0,  0,  21, 0x00000000},
+	{0xb7,  1,  0,   0, 0x00000a64},
+	{0x6b, 10,  1, -16, 0x00000000},
+	{0x18,  1,  0,   0, 0x69666e6f},
+	{0x00,  0,  0,   0, 0x65727567},
+	{0x7b, 10,  1, -24, 0x00000000},
+	{0x18,  1,  0,   0, 0x6e207369},
+	{0x00,  0,  0,   0, 0x6320746f},
+	{0x7b, 10,  1, -32, 0x00000000},
+	{0x18,  1,  0,   0, 0x20737372},
+	{0x00,  0,  0,   0, 0x2079656b},
+	{0x7b, 10,  1, -40, 0x00000000},
+	{0x18,  1,  0,   0, 0x68736168},
+	{0x00,  0,  0,   0, 0x203a2928},
+	{0x7b, 10,  1, -48, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0x73, 10,  7, -14, 0x00000000},
+	{0xbf,  1, 10,   0, 0x00000000},
+	{0x07,  1,  0,   0, 0xffffffd0},
+	{0xb7,  2,  0,   0, 0x00000023},
+	{0x85,  0,  0,   0, 0x00000006},
+	{0x05,  0,  0, 1679, 0x00000000},
+	{0xb7,  5,  0,   0, 0x0000000e},
+	{0x61,  1,  7,  20, 0x00000000},
+	{0x15,  1,  0,  10, 0x00000000},
+	{0x61,  1,  7,  28, 0x00000000},
+	{0x55,  1,  0,   8, 0x0000a888},
+	{0xbf,  2,  7,   0, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0xbf,  1,  9,   0, 0x00000000},
+	{0x07,  1,  0,   0, 0x00000012},
+	{0x2d,  1,  8, 1669, 0x00000000},
+	{0xb7,  5,  0,   0, 0x00000012},
+	{0x69,  6,  9,  16, 0x00000000},
+	{0xbf,  7,  2,   0, 0x00000000},
+	{0x61,  1,  0, 128, 0x00000000},
+	{0xbf,  3,  1,   0, 0x00000000},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0xb7,  2,  0,   0, 0x00000000},
+	{0x1d,  3,  2,   1, 0x00000000},
+	{0x07,  0,  0,   0, 0x00000006},
+	{0xbf,  3,  1,   0, 0x00000000},
+	{0x57,  3,  0,   0, 0x00000002},
+	{0x1d,  3,  2,   1, 0x00000000},
+	{0x07,  0,  0,   0, 0x00000006},
+	{0x7b, 10,  7, -64, 0x00000000},
+	{0x57,  6,  0,   0, 0x0000ffff},
+	{0x15,  6,  0, 351, 0x0000dd86},
+	{0xb7,  7,  0,   0, 0x00000003},
+	{0x55,  6,  0, 1651, 0x00000008},
+	{0x0f,  9,  5,   0, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0xbf,  2,  9,   0, 0x00000000},
+	{0x07,  2,  0,   0, 0x00000014},
+	{0x2d,  2,  8, 1646, 0x00000000},
+	{0x57,  1,  0,   0, 0x00000004},
+	{0xb7,  7,  0,   0, 0x00000003},
+	{0x15,  1,  0, 1643, 0x00000000},
+	{0x71,  1,  0,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000018},
+	{0x71,  6,  0,   1, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000010},
+	{0x4f,  6,  1,   0, 0x00000000},
+	{0x71,  1,  0,   2, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000008},
+	{0x4f,  6,  1,   0, 0x00000000},
+	{0x71,  1,  0,   3, 0x00000000},
+	{0x4f,  6,  1,   0, 0x00000000},
+	{0xbf,  8,  9,   0, 0x00000000},
+	{0x71,  7,  8,  12, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  2,  0,   0, 0x00000000},
+	{0xb7,  3,  0,   0, 0xffffffff},
+	{0xb7,  4,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  4,  6,   0, 0x00000000},
+	{0x79,  1, 10, -56, 0x00000000},
+	{0xaf,  4,  1,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000001},
+	{0x71,  9,  0,   4, 0x00000000},
+	{0xbf,  1,  9,   0, 0x00000000},
+	{0x77,  1,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  13, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,   5, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  14, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,   6, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  15, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  2,  1,   0, 0x00000000},
+	{0xaf,  4,  2,   0, 0x00000000},
+	{0x71,  2,  0,   7, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000007},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x00000039},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000006},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003a},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000005},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003b},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000004},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003c},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000003},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003d},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000002},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003e},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0x77,  2,  0,   0, 0x00000001},
+	{0x57,  2,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  2,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x79,  1, 10, -64, 0x00000000},
+	{0x63,  1,  4,  48, 0x00000000},
+	{0x18,  1,  0,   0, 0x25203d20},
+	{0x00,  0,  0,   0, 0x000a2964},
+	{0x7b, 10,  1, -24, 0x00000000},
+	{0x18,  1,  0,   0, 0x20782520},
+	{0x00,  0,  0,   0, 0x66666f28},
+	{0x7b, 10,  1, -32, 0x00000000},
+	{0x18,  1,  0,   0, 0x6168203a},
+	{0x00,  0,  0,   0, 0x3d206873},
+	{0x7b, 10,  1, -40, 0x00000000},
+	{0x18,  1,  0,   0, 0x68736168},
+	{0x00,  0,  0,   0, 0x29642528},
+	{0x7b, 10,  1, -48, 0x00000000},
+	{0x07,  5,  0,   0, 0x0000000c},
+	{0x05,  0,  0, 1296, 0x00000000},
+	{0x0f,  9,  5,   0, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0xbf,  2,  9,   0, 0x00000000},
+	{0x07,  2,  0,   0, 0x00000028},
+	{0x2d,  2,  8, 1297, 0x00000000},
+	{0x57,  1,  0,   0, 0x00000004},
+	{0xb7,  7,  0,   0, 0x00000003},
+	{0x15,  1,  0, 1294, 0x00000000},
+	{0x71,  1,  0,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000018},
+	{0x71,  6,  0,   1, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000010},
+	{0x4f,  6,  1,   0, 0x00000000},
+	{0x71,  1,  0,   2, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000008},
+	{0x4f,  6,  1,   0, 0x00000000},
+	{0x71,  1,  0,   3, 0x00000000},
+	{0x4f,  6,  1,   0, 0x00000000},
+	{0xbf,  8,  9,   0, 0x00000000},
+	{0x71,  7,  8,   8, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  2,  0,   0, 0x00000000},
+	{0xb7,  3,  0,   0, 0xffffffff},
+	{0xb7,  4,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  4,  6,   0, 0x00000000},
+	{0x79,  1, 10, -56, 0x00000000},
+	{0xaf,  4,  1,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000001},
+	{0x71,  9,  0,   4, 0x00000000},
+	{0xbf,  1,  9,   0, 0x00000000},
+	{0x77,  1,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,   9, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,   5, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  10, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,   6, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  11, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,   7, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  12, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,   8, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  13, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,   9, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  14, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,  10, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  15, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,  11, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  16, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,  12, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  17, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,  13, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  18, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,  14, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  19, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,  15, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  20, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,  16, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  21, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,  17, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  22, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  6,  0,   0, 0x00000000},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x71,  9,  0,  18, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000007},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x00000039},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000006},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003a},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000005},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003b},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000004},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003c},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000003},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003d},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000002},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0xbf,  6,  7,   0, 0x00000000},
+	{0x67,  6,  0,   0, 0x0000003e},
+	{0xc7,  6,  0,   0, 0x0000003f},
+	{0x5f,  6,  1,   0, 0x00000000},
+	{0xaf,  4,  6,   0, 0x00000000},
+	{0xbf,  6,  9,   0, 0x00000000},
+	{0x77,  6,  0,   0, 0x00000001},
+	{0x57,  6,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  6,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  8,  23, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  2,  1,   0, 0x00000000},
+	{0xaf,  4,  2,   0, 0x00000000},
+	{0x71,  2,  0,  19, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000007},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x00000039},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000006},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003a},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000005},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003b},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000004},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003c},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000003},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003d},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000002},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003e},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0x77,  2,  0,   0, 0x00000001},
+	{0x57,  2,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  2,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x79,  1, 10, -64, 0x00000000},
+	{0x63,  1,  4,  48, 0x00000000},
+	{0x18,  1,  0,   0, 0x25203d20},
+	{0x00,  0,  0,   0, 0x000a2964},
+	{0x7b, 10,  1, -24, 0x00000000},
+	{0x18,  1,  0,   0, 0x20782520},
+	{0x00,  0,  0,   0, 0x66666f28},
+	{0x7b, 10,  1, -32, 0x00000000},
+	{0x18,  1,  0,   0, 0x6168203a},
+	{0x00,  0,  0,   0, 0x3d206873},
+	{0x7b, 10,  1, -40, 0x00000000},
+	{0x18,  1,  0,   0, 0x68736168},
+	{0x00,  0,  0,   0, 0x29642528},
+	{0x7b, 10,  1, -48, 0x00000000},
+	{0x07,  5,  0,   0, 0x00000008},
+	{0xbf,  1, 10,   0, 0x00000000},
+	{0x07,  1,  0,   0, 0xffffffd0},
+	{0xb7,  2,  0,   0, 0x00000020},
+	{0xb7,  3,  0,   0, 0x00000002},
+	{0x85,  0,  0,   0, 0x00000006},
+	{0xb7,  7,  0,   0, 0x00000003},
+	{0xbf,  0,  7,   0, 0x00000000},
+	{0x95,  0,  0,   0, 0x00000000},
+};
+
+#define L3_SRC_HASH_INSNS_CNT \
+	(sizeof(l3_src_hash_insns) / sizeof(l3_src_hash_insns[0]))
+
+/**
+ * Load BPF program (section l3_src_hash) into the kernel and return a bpf fd.
+ *
+ * @param queue_idx
+ *   RSS MAP key index
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int bpf_load_l3_src_hash_insns(__u32 key_idx)
+{
+	l3_src_hash_insns[4].imm = key_idx;
+
+	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+		(struct bpf_insn *)l3_src_hash_insns,
+		L3_SRC_HASH_INSNS_CNT,
+		"GPL", 0);
+}
+
+/*
+ * The next bpf_insn array matches l4_src_hash section
+ * see tap_bpf_program.c file
+ *
+ * HASH(L4_SRC)
+ */
+
+static struct bpf_insn l4_src_hash_insns[] = {
+	{0xbf,  6,  1,   0, 0x00000000},
+	{0x61,  8,  6,  16, 0x00000000},
+	{0x61,  9,  6,  76, 0x00000000},
+	{0x61,  1,  6,  80, 0x00000000},
+	{0x7b, 10,  1, -56, 0x00000000},
+	{0x18,  1,  0,   0, 0xdeadbeef},
+	{0x00,  0,  0,   0, 0x00000000},
+	{0x63, 10,  1,  -4, 0x00000000},
+	{0x61,  7,  6,  48, 0x00000000},
+	{0xbf,  2, 10,   0, 0x00000000},
+	{0x07,  2,  0,   0, 0xfffffffc},
+	{0x18,  1,  1,   0, 0xffffffff},
+	{0x00,  0,  0,   0, 0x00000000},
+	{0x85,  0,  0,   0, 0x00000001},
+	{0x55,  0,  0,  21, 0x00000000},
+	{0xb7,  1,  0,   0, 0x00000a64},
+	{0x6b, 10,  1, -16, 0x00000000},
+	{0x18,  1,  0,   0, 0x69666e6f},
+	{0x00,  0,  0,   0, 0x65727567},
+	{0x7b, 10,  1, -24, 0x00000000},
+	{0x18,  1,  0,   0, 0x6e207369},
+	{0x00,  0,  0,   0, 0x6320746f},
+	{0x7b, 10,  1, -32, 0x00000000},
+	{0x18,  1,  0,   0, 0x20737372},
+	{0x00,  0,  0,   0, 0x2079656b},
+	{0x7b, 10,  1, -40, 0x00000000},
+	{0x18,  1,  0,   0, 0x68736168},
+	{0x00,  0,  0,   0, 0x203a2928},
+	{0x7b, 10,  1, -48, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0x73, 10,  7, -14, 0x00000000},
+	{0xbf,  1, 10,   0, 0x00000000},
+	{0x07,  1,  0,   0, 0xffffffd0},
+	{0xb7,  2,  0,   0, 0x00000023},
+	{0x85,  0,  0,   0, 0x00000006},
+	{0x05,  0,  0, 272, 0x00000000},
+	{0xb7,  4,  0,   0, 0x0000000e},
+	{0x61,  1,  6,  20, 0x00000000},
+	{0x15,  1,  0,  11, 0x00000000},
+	{0x61,  1,  6,  28, 0x00000000},
+	{0x55,  1,  0,   9, 0x0000a888},
+	{0xbf,  2,  7,   0, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0xbf,  1,  9,   0, 0x00000000},
+	{0x07,  1,  0,   0, 0x00000012},
+	{0x79,  3, 10, -56, 0x00000000},
+	{0x2d,  1,  3, 261, 0x00000000},
+	{0xb7,  4,  0,   0, 0x00000012},
+	{0x69,  8,  9,  16, 0x00000000},
+	{0xbf,  7,  2,   0, 0x00000000},
+	{0x61,  1,  0, 128, 0x00000000},
+	{0xbf,  3,  1,   0, 0x00000000},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0xb7,  2,  0,   0, 0x00000000},
+	{0x1d,  3,  2,   1, 0x00000000},
+	{0x07,  0,  0,   0, 0x00000006},
+	{0xbf,  3,  1,   0, 0x00000000},
+	{0x57,  3,  0,   0, 0x00000002},
+	{0x1d,  3,  2,   1, 0x00000000},
+	{0x07,  0,  0,   0, 0x00000006},
+	{0x57,  8,  0,   0, 0x0000ffff},
+	{0x15,  8,  0,  24, 0x0000dd86},
+	{0xbf,  5,  7,   0, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000003},
+	{0x55,  8,  0, 243, 0x00000008},
+	{0xbf,  2,  9,   0, 0x00000000},
+	{0x0f,  2,  4,   0, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x07,  3,  0,   0, 0x00000014},
+	{0x79,  8, 10, -56, 0x00000000},
+	{0x2d,  3,  8, 236, 0x00000000},
+	{0xbf,  7,  4,   0, 0x00000000},
+	{0xbf,  4,  1,   0, 0x00000000},
+	{0x57,  4,  0,   0, 0x00000004},
+	{0xb7,  3,  0,   0, 0x00000000},
+	{0x1d,  4,  3,   1, 0x00000000},
+	{0x07,  0,  0,   0, 0x00000004},
+	{0xbf,  4,  1,   0, 0x00000000},
+	{0x57,  4,  0,   0, 0x00000008},
+	{0x1d,  4,  3,   1, 0x00000000},
+	{0x07,  0,  0,   0, 0x00000004},
+	{0xbf,  4,  7,   0, 0x00000000},
+	{0x07,  4,  0,   0, 0x00000014},
+	{0x07,  2,  0,   0, 0x00000009},
+	{0x05,  0,  0,  21, 0x00000000},
+	{0xbf,  5,  7,   0, 0x00000000},
+	{0xbf,  2,  9,   0, 0x00000000},
+	{0x0f,  2,  4,   0, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x07,  3,  0,   0, 0x00000028},
+	{0x79,  8, 10, -56, 0x00000000},
+	{0x2d,  3,  8, 214, 0x00000000},
+	{0xbf,  7,  4,   0, 0x00000000},
+	{0xbf,  4,  1,   0, 0x00000000},
+	{0x57,  4,  0,   0, 0x00000004},
+	{0xb7,  3,  0,   0, 0x00000000},
+	{0x1d,  4,  3,   1, 0x00000000},
+	{0x07,  0,  0,   0, 0x00000010},
+	{0xbf,  4,  1,   0, 0x00000000},
+	{0x57,  4,  0,   0, 0x00000008},
+	{0x1d,  4,  3,   1, 0x00000000},
+	{0x07,  0,  0,   0, 0x00000010},
+	{0xbf,  4,  7,   0, 0x00000000},
+	{0x07,  4,  0,   0, 0x00000028},
+	{0x07,  2,  0,   0, 0x00000006},
+	{0x71,  2,  2,   0, 0x00000000},
+	{0x15,  2,  0,   2, 0x00000011},
+	{0xb7,  7,  0,   0, 0x00000003},
+	{0x55,  2,  0, 197, 0x00000006},
+	{0x57,  1,  0,   0, 0x00000010},
+	{0xb7,  7,  0,   0, 0x00000003},
+	{0x15,  1,  0, 194, 0x00000000},
+	{0xbf,  3,  9,   0, 0x00000000},
+	{0x0f,  3,  4,   0, 0x00000000},
+	{0xb7,  7,  0,   0, 0x00000000},
+	{0xbf,  1,  3,   0, 0x00000000},
+	{0x07,  1,  0,   0, 0x00000002},
+	{0x79,  2, 10, -56, 0x00000000},
+	{0x2d,  1,  2, 187, 0x00000000},
+	{0x7b, 10,  4, -56, 0x00000000},
+	{0x71,  1,  0,   1, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000010},
+	{0x71,  8,  0,   0, 0x00000000},
+	{0x67,  8,  0,   0, 0x00000018},
+	{0x4f,  8,  1,   0, 0x00000000},
+	{0x71,  1,  0,   2, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000008},
+	{0x4f,  8,  1,   0, 0x00000000},
+	{0x71,  1,  0,   3, 0x00000000},
+	{0x4f,  8,  1,   0, 0x00000000},
+	{0x71,  7,  3,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  2,  0,   0, 0x00000000},
+	{0xb7,  1,  0,   0, 0xffffffff},
+	{0xb7,  4,  0,   0, 0x00000000},
+	{0x6d,  7,  1,   1, 0x00000000},
+	{0xbf,  4,  8,   0, 0x00000000},
+	{0xaf,  4,  5,   0, 0x00000000},
+	{0x67,  8,  0,   0, 0x00000001},
+	{0x71,  9,  0,   4, 0x00000000},
+	{0xbf,  1,  9,   0, 0x00000000},
+	{0x77,  1,  0,   0, 0x00000007},
+	{0x4f,  1,  8,   0, 0x00000000},
+	{0xbf,  8,  7,   0, 0x00000000},
+	{0x67,  8,  0,   0, 0x00000039},
+	{0xc7,  8,  0,   0, 0x0000003f},
+	{0x5f,  8,  1,   0, 0x00000000},
+	{0xaf,  4,  8,   0, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0xbf,  8,  9,   0, 0x00000000},
+	{0x77,  8,  0,   0, 0x00000006},
+	{0x57,  8,  0,   0, 0x00000001},
+	{0x4f,  1,  8,   0, 0x00000000},
+	{0xbf,  8,  7,   0, 0x00000000},
+	{0x67,  8,  0,   0, 0x0000003a},
+	{0xc7,  8,  0,   0, 0x0000003f},
+	{0x5f,  8,  1,   0, 0x00000000},
+	{0xaf,  4,  8,   0, 0x00000000},
+	{0xbf,  8,  9,   0, 0x00000000},
+	{0x77,  8,  0,   0, 0x00000005},
+	{0x57,  8,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  8,   0, 0x00000000},
+	{0xbf,  8,  7,   0, 0x00000000},
+	{0x67,  8,  0,   0, 0x0000003b},
+	{0xc7,  8,  0,   0, 0x0000003f},
+	{0x5f,  8,  1,   0, 0x00000000},
+	{0xaf,  4,  8,   0, 0x00000000},
+	{0xbf,  8,  9,   0, 0x00000000},
+	{0x77,  8,  0,   0, 0x00000004},
+	{0x57,  8,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  8,   0, 0x00000000},
+	{0xbf,  8,  7,   0, 0x00000000},
+	{0x67,  8,  0,   0, 0x0000003c},
+	{0xc7,  8,  0,   0, 0x0000003f},
+	{0x5f,  8,  1,   0, 0x00000000},
+	{0xaf,  4,  8,   0, 0x00000000},
+	{0xbf,  8,  9,   0, 0x00000000},
+	{0x77,  8,  0,   0, 0x00000003},
+	{0x57,  8,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  8,   0, 0x00000000},
+	{0xbf,  8,  7,   0, 0x00000000},
+	{0x67,  8,  0,   0, 0x0000003d},
+	{0xc7,  8,  0,   0, 0x0000003f},
+	{0x5f,  8,  1,   0, 0x00000000},
+	{0xaf,  4,  8,   0, 0x00000000},
+	{0xbf,  8,  9,   0, 0x00000000},
+	{0x77,  8,  0,   0, 0x00000002},
+	{0x57,  8,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  8,   0, 0x00000000},
+	{0xbf,  8,  7,   0, 0x00000000},
+	{0x67,  8,  0,   0, 0x0000003e},
+	{0xc7,  8,  0,   0, 0x0000003f},
+	{0x5f,  8,  1,   0, 0x00000000},
+	{0xaf,  4,  8,   0, 0x00000000},
+	{0xbf,  8,  9,   0, 0x00000000},
+	{0x77,  8,  0,   0, 0x00000001},
+	{0x57,  8,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  8,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x57,  9,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  9,   0, 0x00000000},
+	{0x71,  7,  3,   1, 0x00000000},
+	{0x67,  7,  0,   0, 0x00000038},
+	{0xc7,  7,  0,   0, 0x00000038},
+	{0xb7,  3,  0,   0, 0xffffffff},
+	{0x6d,  7,  3,   1, 0x00000000},
+	{0xbf,  2,  1,   0, 0x00000000},
+	{0xaf,  4,  2,   0, 0x00000000},
+	{0x71,  2,  0,   5, 0x00000000},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000007},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x00000039},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000006},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003a},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000005},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003b},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000004},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003c},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000003},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003d},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0xbf,  3,  2,   0, 0x00000000},
+	{0x77,  3,  0,   0, 0x00000002},
+	{0x57,  3,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  3,   0, 0x00000000},
+	{0xbf,  3,  7,   0, 0x00000000},
+	{0x67,  3,  0,   0, 0x0000003e},
+	{0xc7,  3,  0,   0, 0x0000003f},
+	{0x5f,  3,  1,   0, 0x00000000},
+	{0xaf,  4,  3,   0, 0x00000000},
+	{0x77,  2,  0,   0, 0x00000001},
+	{0x57,  2,  0,   0, 0x00000001},
+	{0x67,  1,  0,   0, 0x00000001},
+	{0x4f,  1,  2,   0, 0x00000000},
+	{0x67,  7,  0,   0, 0x0000003f},
+	{0xc7,  7,  0,   0, 0x0000003f},
+	{0x5f,  7,  1,   0, 0x00000000},
+	{0xaf,  4,  7,   0, 0x00000000},
+	{0x63,  6,  4,  48, 0x00000000},
+	{0x18,  1,  0,   0, 0x25203d20},
+	{0x00,  0,  0,   0, 0x000a2964},
+	{0x7b, 10,  1, -24, 0x00000000},
+	{0x18,  1,  0,   0, 0x20782520},
+	{0x00,  0,  0,   0, 0x66666f28},
+	{0x7b, 10,  1, -32, 0x00000000},
+	{0x18,  1,  0,   0, 0x6168203a},
+	{0x00,  0,  0,   0, 0x3d206873},
+	{0x7b, 10,  1, -40, 0x00000000},
+	{0x18,  1,  0,   0, 0x68736168},
+	{0x00,  0,  0,   0, 0x29642528},
+	{0x7b, 10,  1, -48, 0x00000000},
+	{0xbf,  1, 10,   0, 0x00000000},
+	{0x07,  1,  0,   0, 0xffffffd0},
+	{0xb7,  2,  0,   0, 0x00000020},
+	{0xb7,  3,  0,   0, 0x00000004},
+	{0x79,  5, 10, -56, 0x00000000},
+	{0x85,  0,  0,   0, 0x00000006},
+	{0xb7,  7,  0,   0, 0x00000003},
+	{0xbf,  0,  7,   0, 0x00000000},
+	{0x95,  0,  0,   0, 0x00000000},
+};
+
+#define L4_SRC_HASH_INSNS_CNT \
+	(sizeof(l4_src_hash_insns) / sizeof(l4_src_hash_insns[0]))
+
+/**
+ * Load BPF program (section l4_src_hash) into the kernel and return a bpf fd.
+ *
+ * @param queue_idx
+ *   RSS MAP key index
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int bpf_load_l4_src_hash_insns(__u32 key_idx)
+{
+	l4_src_hash_insns[4].imm = key_idx;
+
+	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+		(struct bpf_insn *)l4_src_hash_insns,
+		L4_SRC_HASH_INSNS_CNT,
+		"GPL", 0);
+}
+
+#ifndef __NR_bpf
+# if defined(__i386__)
+#  define __NR_bpf 357
+# elif defined(__x86_64__)
+#  define __NR_bpf 321
+# elif defined(__aarch64__)
+#  define __NR_bpf 280
+# elif defined(__sparc__)
+#  define __NR_bpf 349
+# elif defined(__s390__)
+#  define __NR_bpf 351
+# else
+#  error __NR_bpf not defined. libbpf does not support your arch.
+# endif
+#endif
+
+static inline __u64 ptr_to_u64(const void *ptr)
+{
+	return (__u64)(unsigned long)ptr;
+}
+
+static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
+			unsigned int size)
+{
+	return syscall(__NR_bpf, cmd, attr, size);
+}
+
+int bpf_load(enum bpf_prog_type type,
+		  const struct bpf_insn *insns,
+		  size_t insns_cnt,
+		  const char *license,
+		  __u32 kern_version)
+{
+	union bpf_attr attr;
+
+	bzero(&attr, sizeof(attr));
+	attr.prog_type = type;
+	attr.insn_cnt = (__u32)insns_cnt;
+	attr.insns = ptr_to_u64(insns);
+	attr.license = ptr_to_u64(license);
+	attr.log_buf = ptr_to_u64(NULL);
+	attr.log_level = 0;
+	attr.kern_version = kern_version;
+
+	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
+}
diff --git a/drivers/net/tap/tap_bpf_program.c b/drivers/net/tap/tap_bpf_program.c
new file mode 100644
index 0000000..e1ae0c5
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_program.c
@@ -0,0 +1,321 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright 2017 6WIND S.A.
+ *   Copyright 2017 Mellanox.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND S.A. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <asm/types.h>
+#include <linux/in.h>
+#include <linux/if.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/if_tunnel.h>
+#include <linux/filter.h>
+#include <linux/bpf.h>
+
+/* BPF helper functions for our example. */
+#include "tap_bpf_api.h"
+#include "tap_bpf_shared.h"
+
+#define ERROR                   0
+
+/*
+ * The queue number is offset by 1, to distinguish packets that have
+ * gone through this rule (skb->cb[1] != 0) from others.
+ */
+#define QUEUE_OFFSET 1
+
+#define INV_KEY_IDX 0xdeadbeef
+
+struct vlan_hdr {
+	__be16 proto;
+	__be16 tci;
+};
+
+__section("maps")
+struct bpf_elf_map map_keys = {
+	.type           =       BPF_MAP_TYPE_HASH,
+	.id             =       BPF_MAP_ID_KEY,
+	.size_key       =       sizeof(__u32),
+	.size_value     =       sizeof(struct rss_key),
+	.max_elem       =       256,
+	.pinning        =       PIN_GLOBAL_NS,
+};
+
+__section("cls_q") int
+match_q(struct __sk_buff *skb)
+{
+	__u32 queue = skb->cb[1];
+	volatile __u32 q = INV_KEY_IDX;
+	__u32 match_queue = QUEUE_OFFSET + q;
+
+	/* printt("match_q$i() queue = %d\n", queue); */
+
+	if (queue != match_queue)
+		return TC_ACT_OK;
+	return TC_ACT_UNSPEC;
+}
+
+__section("tailing") int
+tail(struct __sk_buff *skb)
+{
+	skb_change_tail(skb, skb->len + sizeof(__u32), 0);
+
+	return TC_ACT_UNSPEC;
+}
+
+static void __attribute__((always_inline))
+toeplitz_hash(__u32 *hash, __u8 *key, __u32 *v, __u8 *data, __u8 data_len)
+{
+	u_int i, b;
+
+#pragma unroll
+	for (i = 0; i < data_len; i++) {
+#pragma unroll
+		for (b = 0; b < 8; b++) {
+			if (data[i] & (1 << (7 - b)))
+				*hash ^= *v;
+			*v <<= 1;
+			if (key[i + 4] & (1 << (7 - b)))
+				*v |= 1;
+		}
+	}
+}
+
+static int __attribute__((always_inline))
+hash(struct __sk_buff *skb, enum hash_field f)
+{
+	void *data_end = (void *)(long)skb->data_end;
+	void *data = (void *)(long)skb->data;
+	__u16 proto = (__u16)skb->protocol;
+	__u32 key_idx = INV_KEY_IDX;
+	__u32 hash = skb->cb[0];
+	struct rss_key *rsskey;
+	__u64 off = ETH_HLEN;
+	__u8 ip_proto = 0;
+	__u8 *key = 0;
+	__u32 v, len;
+
+	rsskey = map_lookup_elem(&map_keys, &key_idx);
+	if (!rsskey) {
+		printt("hash(): rss key is not configured\n");
+		return TC_ACT_OK;
+	}
+	key = (__u8 *)rsskey->key;
+
+	/* Get correct proto for 802.1ad */
+	if (skb->vlan_present && skb->vlan_proto == htons(ETH_P_8021AD)) {
+		if (data + ETH_ALEN * 2 + sizeof(struct vlan_hdr) +
+		    sizeof(proto) > data_end)
+			return TC_ACT_OK;
+		proto = *(__u16 *)(data + ETH_ALEN * 2 +
+				   sizeof(struct vlan_hdr));
+		off += sizeof(struct vlan_hdr);
+	}
+
+	if (rsskey->hash_fields & (1 << HASH_FIELD_L2_DST)) {
+		if (f == HASH_FIELD_L2_DST) {
+			v = (key[0] << 24) + (key[1] << 16) + (key[2] << 8) + key[3];
+			if (data + ETH_ALEN > data_end)
+				return TC_ACT_OK;
+			toeplitz_hash(&hash, key, &v, data, ETH_ALEN);
+			skb->cb[0] = hash;
+			printt("hash(%d): hash = %x (off = %d)\n",
+			       f, skb->cb[0], 0);
+			return TC_ACT_PIPE;
+		}
+		key += ETH_ALEN;
+	}
+	if (rsskey->hash_fields & (1 << HASH_FIELD_L2_SRC)) {
+		if (f == HASH_FIELD_L2_SRC) {
+			v = (key[0] << 24) + (key[1] << 16) + (key[2] << 8) + key[3];
+			if (data + ETH_ALEN * 2 > data_end)
+				return TC_ACT_OK;
+			toeplitz_hash(&hash, key, &v, data + ETH_ALEN, ETH_ALEN);
+			skb->cb[0] = hash;
+			printt("hash(%d): hash = %x (off = %d)\n",
+			       f, skb->cb[0], ETH_ALEN);
+			return TC_ACT_PIPE;
+		}
+		key += ETH_ALEN;
+	}
+
+	if (proto == htons(ETH_P_IP)) {
+		struct iphdr *ip;
+
+		if (data + off + sizeof(struct iphdr) > data_end)
+			return TC_ACT_OK;
+		ip = data + off;
+		ip_proto = ip->protocol;
+
+		if (rsskey->hash_fields & (1 << HASH_FIELD_L3_SRC)) {
+			if (f == HASH_FIELD_L3_SRC) {
+				v = (key[0] << 24) + (key[1] << 16) +
+					(key[2] << 8) + key[3];
+				toeplitz_hash(&hash, key, &v, data + off +
+					      offsetof(struct iphdr, saddr),
+					      sizeof(__u32));
+				skb->cb[0] = hash;
+				printt("hash(%d): hash = %x (off = %d)\n",
+				       f, skb->cb[0],
+				       off + offsetof(struct iphdr, saddr));
+				return TC_ACT_PIPE;
+			}
+			key += sizeof(__u32);
+		}
+		if (rsskey->hash_fields & (1 << HASH_FIELD_L3_DST)) {
+			if (f == HASH_FIELD_L3_DST) {
+				v = (key[0] << 24) + (key[1] << 16) +
+					(key[2] << 8) + key[3];
+				toeplitz_hash(&hash, key, &v, data + off +
+					      offsetof(struct iphdr, daddr),
+					      sizeof(__u32));
+				skb->cb[0] = hash;
+				printt("hash(%d): hash = %x (off = %d)\n",
+				       f, skb->cb[0],
+				       off + offsetof(struct iphdr, daddr));
+				return TC_ACT_PIPE;
+			}
+			key += sizeof(__u32);
+		}
+		off += sizeof(struct iphdr);
+	} else if (proto == htons(ETH_P_IPV6)) {
+		struct ipv6hdr *ip;
+
+		if (data + off + sizeof(struct ipv6hdr) > data_end)
+			return TC_ACT_OK;
+		ip = data + off;
+		ip_proto = ip->nexthdr;
+
+		if (rsskey->hash_fields & (1 << HASH_FIELD_L3_SRC)) {
+			if (f == HASH_FIELD_L3_SRC) {
+				v = (key[0] << 24) + (key[1] << 16) +
+					(key[2] << 8) + key[3];
+				toeplitz_hash(&hash, key, &v, data + off +
+					      offsetof(struct ipv6hdr, saddr),
+					      sizeof(struct in6_addr));
+				skb->cb[0] = hash;
+				printt("hash(%d): hash = %x (off = %d)\n",
+				       f, skb->cb[0],
+				       off + offsetof(struct ipv6hdr, saddr));
+				return TC_ACT_PIPE;
+			}
+			key += sizeof(struct in6_addr);
+		}
+		if (rsskey->hash_fields & (1 << HASH_FIELD_L3_DST)) {
+			if (f == HASH_FIELD_L3_DST) {
+				v = (key[0] << 24) + (key[1] << 16) +
+					(key[2] << 8) + key[3];
+				toeplitz_hash(&hash, key, &v, data + off +
+					      offsetof(struct ipv6hdr, daddr),
+					      sizeof(struct in6_addr));
+				skb->cb[0] = hash;
+				printt("hash(%d): hash = %x (off = %d)\n",
+				       f, skb->cb[0],
+				       off + offsetof(struct ipv6hdr, daddr));
+				return TC_ACT_PIPE;
+			}
+			key += sizeof(struct in6_addr);
+		}
+		off += sizeof(struct ipv6hdr);
+	} else {
+		/* Unknown protocol: stop hashing there */
+		return TC_ACT_PIPE;
+	}
+
+	/* Unknown ip_proto: stop hashing there */
+	if ((ip_proto == IPPROTO_TCP || ip_proto == IPPROTO_UDP) &&
+	    (rsskey->hash_fields & (1 << HASH_FIELD_L4_SRC)) &&
+	    (f == HASH_FIELD_L4_SRC)) {
+		v = (key[0] << 24) + (key[1] << 16) + (key[2] << 8) + key[3];
+		if (data + off + sizeof(__u16) > data_end)
+			return TC_ACT_OK;
+		toeplitz_hash(&hash, key, &v, data + off,
+			      sizeof(__u16));
+		skb->cb[0] = hash;
+		printt("hash(%d): hash = %x (off = %d)\n",
+		       f, skb->cb[0], off);
+		return TC_ACT_PIPE;
+	}
+
+	return TC_ACT_PIPE;
+}
+
+#define HASH(L)						\
+	__section(#L) int				\
+		L ## _hash(struct __sk_buff *skb)	\
+	{						\
+		return hash(skb, HASH_FIELD_ ## L);	\
+	}
+
+HASH(L2_DST)
+
+HASH(L2_SRC)
+
+HASH(L3_SRC)
+
+HASH(L3_DST)
+
+HASH(L4_SRC)
+
+__section("hash_appending") int
+append_hash(struct __sk_buff *skb)
+{
+	__u32 hash = skb->cb[0];
+
+	skb_store_bytes(skb, skb->len - sizeof(hash), &hash, sizeof(hash), 0);
+
+	return TC_ACT_PIPE;
+}
+
+__section("queue_setting") int
+set_queue(struct __sk_buff *skb)
+{
+	__u32 key_idx = INV_KEY_IDX;
+	__u64 hash = skb->cb[0];
+	 struct rss_key *rsskey;
+	 __u32 queue = 0;
+
+	rsskey = map_lookup_elem(&map_keys, &key_idx);
+	if (rsskey && rsskey->nb_queues <= TAP_MAX_QUEUES)
+		queue = rsskey->queues[(hash % rsskey->nb_queues) &
+				       (TAP_MAX_QUEUES - 1)];
+
+	skb->cb[1] = QUEUE_OFFSET + queue;
+
+	return TC_ACT_RECLASSIFY;
+}
+
+BPF_LICENSE("GPL");
diff --git a/drivers/net/tap/tap_bpf_shared.h b/drivers/net/tap/tap_bpf_shared.h
new file mode 100644
index 0000000..6895cf4
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_shared.h
@@ -0,0 +1,40 @@
+#ifndef __BPF_SHARED__
+#define __BPF_SHARED__
+
+#define TAP_MAX_QUEUES 16
+
+enum hash_field {
+	HASH_FIELD_L2_DST,
+	HASH_FIELD_L2_SRC,
+	HASH_FIELD_L3_SRC,
+	HASH_FIELD_L3_DST,
+	HASH_FIELD_L4_SRC,
+};
+
+enum {
+	BPF_MAP_ID_KEY,
+	BPF_MAP_ID_SIMPLE,
+};
+
+struct rss_key {
+	__u32 key[32];
+	__u32 hash_fields;
+	__u32 key_size;
+	__u32 queues[TAP_MAX_QUEUES];
+	__u32 nb_queues;
+};
+
+int bpf_load_cls_q_insns(__u32 queue_idx);
+int bpf_load_tailing_insns(void);
+int bpf_load_hash_appending_insns(void);
+int bpf_load_queue_setting_insns(__u32 queue_idx);
+int bpf_load_l2_src_hash_insns(__u32 key_idx);
+int bpf_load_l2_dst_hash_insns(__u32 key_idx);
+int bpf_load_l3_dst_hash_insns(__u32 key_idx);
+int bpf_load_l3_src_hash_insns(__u32 key_idx);
+int bpf_load_l4_src_hash_insns(__u32 key_idx);
+
+int bpf_load(enum bpf_prog_type type, const struct bpf_insn *insns,
+		size_t insns_cnt, const char *license, __u32 kern_version);
+
+#endif /* __BPF_SHARED__ */
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index 43bab7d..355f493 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -46,6 +46,8 @@
 #include <linux/bpf.h>
 #include <linux/tc_act/tc_bpf.h>
 
+#include <tap_bpf_shared.h>
+
 #ifndef HAVE_TC_FLOWER
 /*
  * For kernels < 4.2, this enum is not defined. Runtime checks will be made to
@@ -1673,7 +1675,9 @@ static int rss_enable(struct pmd_internals *pmd)
 			},
 		};
 
-		bpf_fd = 0;
+		bpf_fd = bpf_load_cls_q_insns(i);
+		if (bpf_fd == -1)
+			return -1;
 
 		rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
 		if (!rss_flow) {
@@ -1708,6 +1712,11 @@ static int rss_enable(struct pmd_internals *pmd)
 		LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
 	}
 
+	/* Add a rule that adds 4 bytes at packet's end to hold the hash */
+	bpf_fd = bpf_load_tailing_insns();
+	if (bpf_fd == -1)
+		return -1;
+
 	snprintf(annotation, sizeof(annotation), "%s:[%s]", BPF_PROGRAM,
 		 section);
 	rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v1 3/3] net/tap: add eBPF classifiers map and actions
  2017-12-17 12:21 [dpdk-dev] [PATCH v1 0/3] TAP RSS eBPF cover letter Ophir Munk
  2017-12-17 12:21 ` [dpdk-dev] [PATCH v1 1/3] net/tap: add BPF sections for TAP device Ophir Munk
  2017-12-17 12:21 ` [dpdk-dev] [PATCH v1 2/3] net/tap: add eBPF instructions Ophir Munk
@ 2017-12-17 12:21 ` Ophir Munk
  2017-12-28 10:09 ` [dpdk-dev] [PATCH v2 0/2] TAP RSS eBPF cover letter Ophir Munk
  3 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2017-12-17 12:21 UTC (permalink / raw)
  To: Pascal Mazon; +Cc: Ophir Munk, dev, Thomas Monjalon, Olga Shern

Add TC BPF classifier for each TAP queue. Based on this classifier packets
marked with RSS queues will be directed to the matched queue using
TC "skbedit" action. This step is done once at startup

Add RSS BPF map entry for each new RSS rule. The BPF map entry includes
the RSS queues

Add TC BPF actions for each new RSS rule
- Calculate RSS hash based on L2 src, L2 dest, L3 src, L3 dst and L4 src.
- Write the selected RSS queue into skb control block based on the RSS hash
  (i.e. marking the packet) and set the next step as reclassify.

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 drivers/net/tap/rte_eth_tap.h     |   2 +
 drivers/net/tap/tap_bpf_insns.c   |  55 ++++--
 drivers/net/tap/tap_bpf_program.c |  14 +-
 drivers/net/tap/tap_bpf_shared.h  |  18 +-
 drivers/net/tap/tap_flow.c        | 402 +++++++++++++++++++++++++++++++-------
 5 files changed, 404 insertions(+), 87 deletions(-)

diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
index 01ac153..c185473 100644
--- a/drivers/net/tap/rte_eth_tap.h
+++ b/drivers/net/tap/rte_eth_tap.h
@@ -94,6 +94,8 @@ struct pmd_internals {
 	int flower_vlan_support;          /* 1 if kernel supports, else 0 */
 	int rss_enabled;                  /* 1 if RSS is enabled, else 0 */
 	/* implicit rules set when RSS is enabled */
+	int map_fd;                       /* BPF RSS map fd */
+	int bpf_fd[RTE_PMD_TAP_MAX_QUEUES];/* List of bpf fds per queue */
 	LIST_HEAD(tap_rss_flows, rte_flow) rss_flows;
 	LIST_HEAD(tap_flows, rte_flow) flows;        /* rte_flow rules */
 	/* implicit rte_flow rules set when a remote device is active */
diff --git a/drivers/net/tap/tap_bpf_insns.c b/drivers/net/tap/tap_bpf_insns.c
index 951d037..707dce8 100644
--- a/drivers/net/tap/tap_bpf_insns.c
+++ b/drivers/net/tap/tap_bpf_insns.c
@@ -134,7 +134,7 @@ int bpf_load_cls_q_insns(__u32 queue_idx)
 	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
 		(struct bpf_insn *)cls_q_insns,
 		CLS_Q_INSNS_CNT,
-		"GPL", 0);
+		"Dual BSD/GPL", 0);
 }
 
 /*
@@ -174,7 +174,7 @@ int bpf_load_tailing_insns(void)
 	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
 		(struct bpf_insn *)tailing_insns,
 		TAILING_INSNS_CNT,
-		"GPL", 0);
+		"Dual BSD/GPL", 0);
 }
 
 /*
@@ -220,7 +220,7 @@ int bpf_load_hash_appending_insns(void)
 	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
 		(struct bpf_insn *)hash_appending_insns,
 		HASH_APPENDING_INSNS_CNT,
-		"GPL", 0);
+		"Dual BSD/GPL", 0);
 }
 
 /*
@@ -290,14 +290,14 @@ static struct bpf_insn queue_setting_insns[] = {
  * @return
  *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
  */
-int bpf_load_queue_setting_insns(__u32 queue_idx)
+int bpf_load_queue_setting_insns(__u32 key_idx)
 {
-	queue_setting_insns[1].imm = queue_idx;
+	queue_setting_insns[1].imm = key_idx;
 
 	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
 		(struct bpf_insn *)queue_setting_insns,
 		QUEUE_SETTING_INSNS_CNT,
-		"GPL", 0);
+		"Dual BSD/GPL", 0);
 }
 
 /*
@@ -918,7 +918,7 @@ int bpf_load_l2_src_hash_insns(__u32 key_idx)
 	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
 		(struct bpf_insn *)l2_src_hash_insns,
 		L2_SRC_HASH_INSNS_CNT,
-		"GPL", 0);
+		"Dual BSD/GPL", 0);
 }
 
 /*
@@ -1525,7 +1525,7 @@ int bpf_load_l2_dst_hash_insns(__u32 key_idx)
 	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
 		(struct bpf_insn *)l2_dst_hash_insns,
 		L2_DST_HASH_INSNS_CNT,
-		"GPL", 0);
+		"Dual BSD/GPL", 0);
 }
 
 /*
@@ -3285,7 +3285,7 @@ int bpf_load_l3_dst_hash_insns(__u32 key_idx)
 	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
 		(struct bpf_insn *)l3_dst_hash_insns,
 		L3_DST_HASH_INSNS_CNT,
-		"GPL", 0);
+		"Dual BSD/GPL", 0);
 }
 
 /*
@@ -5034,7 +5034,7 @@ int bpf_load_l3_src_hash_insns(__u32 key_idx)
 	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
 		(struct bpf_insn *)l3_src_hash_insns,
 		L3_SRC_HASH_INSNS_CNT,
-		"GPL", 0);
+		"Dual BSD/GPL", 0);
 }
 
 /*
@@ -5376,7 +5376,7 @@ int bpf_load_l4_src_hash_insns(__u32 key_idx)
 	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
 		(struct bpf_insn *)l4_src_hash_insns,
 		L4_SRC_HASH_INSNS_CNT,
-		"GPL", 0);
+		"Dual BSD/GPL", 0);
 }
 
 #ifndef __NR_bpf
@@ -5425,3 +5425,36 @@ int bpf_load(enum bpf_prog_type type,
 
 	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
 }
+
+
+int bpf_map_create(enum bpf_map_type map_type,
+		unsigned int key_size,
+		unsigned int value_size,
+		unsigned int max_entries)
+{
+	union bpf_attr attr;
+
+	bzero(&attr, sizeof(attr));
+	attr.map_type    = map_type;
+	attr.key_size    = key_size;
+	attr.value_size  = value_size;
+	attr.max_entries = max_entries;
+
+	return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
+}
+
+int bpf_map_update_elem(enum bpf_map_type map_type,
+		int fd, void *key, void *value, __u64 flags)
+{
+	union bpf_attr attr;
+
+	bzero(&attr, sizeof(attr));
+
+	attr.map_type = map_type;
+	attr.map_fd = fd;
+	attr.key = ptr_to_u64(key);
+	attr.value = ptr_to_u64(value);
+	attr.flags = flags;
+
+	return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
+}
diff --git a/drivers/net/tap/tap_bpf_program.c b/drivers/net/tap/tap_bpf_program.c
index e1ae0c5..08370bb 100644
--- a/drivers/net/tap/tap_bpf_program.c
+++ b/drivers/net/tap/tap_bpf_program.c
@@ -57,15 +57,15 @@
  */
 #define QUEUE_OFFSET 1
 
-#define INV_KEY_IDX 0xdeadbeef
+#define KEY_IDX 0xdeadbeef
 
 struct vlan_hdr {
 	__be16 proto;
 	__be16 tci;
 };
 
-__section("maps")
-struct bpf_elf_map map_keys = {
+struct bpf_elf_map __section("maps")
+map_keys = {
 	.type           =       BPF_MAP_TYPE_HASH,
 	.id             =       BPF_MAP_ID_KEY,
 	.size_key       =       sizeof(__u32),
@@ -78,10 +78,10 @@ __section("cls_q") int
 match_q(struct __sk_buff *skb)
 {
 	__u32 queue = skb->cb[1];
-	volatile __u32 q = INV_KEY_IDX;
+	volatile __u32 q = KEY_IDX;
 	__u32 match_queue = QUEUE_OFFSET + q;
 
-	/* printt("match_q$i() queue = %d\n", queue); */
+	/* bpf_printk("match_q$i() queue = %d\n", queue); */
 
 	if (queue != match_queue)
 		return TC_ACT_OK;
@@ -120,7 +120,7 @@ hash(struct __sk_buff *skb, enum hash_field f)
 	void *data_end = (void *)(long)skb->data_end;
 	void *data = (void *)(long)skb->data;
 	__u16 proto = (__u16)skb->protocol;
-	__u32 key_idx = INV_KEY_IDX;
+	__u32 key_idx = KEY_IDX;
 	__u32 hash = skb->cb[0];
 	struct rss_key *rsskey;
 	__u64 off = ETH_HLEN;
@@ -303,7 +303,7 @@ append_hash(struct __sk_buff *skb)
 __section("queue_setting") int
 set_queue(struct __sk_buff *skb)
 {
-	__u32 key_idx = INV_KEY_IDX;
+	__u32 key_idx = KEY_IDX;
 	__u64 hash = skb->cb[0];
 	 struct rss_key *rsskey;
 	 __u32 queue = 0;
diff --git a/drivers/net/tap/tap_bpf_shared.h b/drivers/net/tap/tap_bpf_shared.h
index 6895cf4..e7d2ff4 100644
--- a/drivers/net/tap/tap_bpf_shared.h
+++ b/drivers/net/tap/tap_bpf_shared.h
@@ -11,6 +11,16 @@ enum hash_field {
 	HASH_FIELD_L4_SRC,
 };
 
+enum bpf_fd_index {
+	BPF_L2_DST = HASH_FIELD_L2_DST,
+	BPF_L2_SRC = HASH_FIELD_L2_SRC,
+	BPF_L3_SRC = HASH_FIELD_L3_SRC,
+	BPF_L3_DST = HASH_FIELD_L3_DST,
+	BPF_L4_SRC = HASH_FIELD_L4_SRC,
+	BPF_SET_Q,
+	BPF_MAX,
+};
+
 enum {
 	BPF_MAP_ID_KEY,
 	BPF_MAP_ID_SIMPLE,
@@ -27,7 +37,7 @@ struct rss_key {
 int bpf_load_cls_q_insns(__u32 queue_idx);
 int bpf_load_tailing_insns(void);
 int bpf_load_hash_appending_insns(void);
-int bpf_load_queue_setting_insns(__u32 queue_idx);
+int bpf_load_queue_setting_insns(__u32 key_idx);
 int bpf_load_l2_src_hash_insns(__u32 key_idx);
 int bpf_load_l2_dst_hash_insns(__u32 key_idx);
 int bpf_load_l3_dst_hash_insns(__u32 key_idx);
@@ -37,4 +47,10 @@ int bpf_load_l4_src_hash_insns(__u32 key_idx);
 int bpf_load(enum bpf_prog_type type, const struct bpf_insn *insns,
 		size_t insns_cnt, const char *license, __u32 kern_version);
 
+int bpf_map_create(enum bpf_map_type map_type, unsigned int key_size,
+		unsigned int value_size, unsigned int max_entries);
+
+int bpf_map_update_elem(enum bpf_map_type map_type, int fd, void *key,
+		void *value, __u64 flags);
+
 #endif /* __BPF_SHARED__ */
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index 355f493..ec6ae3c 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -34,6 +34,7 @@
 #include <errno.h>
 #include <string.h>
 #include <sys/queue.h>
+#include <sys/mount.h>
 
 #include <rte_byteorder.h>
 #include <rte_jhash.h>
@@ -87,11 +88,38 @@ enum {
 };
 #endif
 
+enum bpf_rss_key_e {
+	KEY_CMD_GET = 1,
+	KEY_CMD_RELEASE,
+	KEY_CMD_INIT,
+	KEY_CMD_DEINIT,
+};
+
+enum key_status_e {
+	KEY_STAT_UNSPEC,
+	KEY_STAT_USED,
+	KEY_STAT_AVAILABLE,
+};
+
 #define ISOLATE_HANDLE 1
 
+#define MAX_RSS_KEYS 256
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+#define SEC_NAME_CLS_Q "cls_q"
+const char *sec_name[BPF_MAX] = {
+	[BPF_L2_DST] = "L2_DST",
+	[BPF_L2_SRC] = "L2_SRC",
+	[BPF_L3_DST] = "L3_DST",
+	[BPF_L3_SRC] = "L3_SRC",
+	[BPF_L4_SRC] = "L4_SRC",
+	[BPF_SET_Q] = "queue_setting",
+};
+
 struct rte_flow {
 	LIST_ENTRY(rte_flow) next; /* Pointer to the next rte_flow structure */
 	struct rte_flow *remote_flow; /* associated remote flow */
+	int bpf_fd[BPF_MAX]; /* List of bfs fds */
 	struct nlmsg msg;
 };
 
@@ -120,8 +148,9 @@ struct action_data {
 			uint16_t queue;
 		} skbedit;
 		struct bpf {
+			struct tc_act_bpf bpf;
 			int bpf_fd;
-			char *annotation;
+			const char *annotation;
 		} bpf;
 	};
 };
@@ -157,6 +186,9 @@ tap_flow_isolate(struct rte_eth_dev *dev,
 		 struct rte_flow_error *error);
 
 static int rss_enable(struct pmd_internals *pmd);
+static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx);
+static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
+		const struct rte_flow_action_rss *rss);
 
 static const struct rte_flow_ops tap_flow_ops = {
 	.validate = tap_flow_validate,
@@ -874,6 +906,9 @@ add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
 		nlattr_add(&msg->nh, TCA_ACT_BPF_NAME,
 			   strlen(adata->bpf.annotation),
 			   adata->bpf.annotation);
+		nlattr_add(&msg->nh, TCA_ACT_BPF_PARMS,
+			   sizeof(adata->bpf.bpf),
+			   &adata->bpf.bpf);
 	} else {
 		return -1;
 	}
@@ -898,7 +933,7 @@ add_actions(struct rte_flow *flow, int nb_actions, struct action_data *data,
 	for (i = 0; i < nb_actions; i++)
 		if (add_action(flow, &act_index, data + i) < 0)
 			return -1;
-	nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
+	nlattr_nested_finish(msg); /* nested TCA_[FLOWER|BPF|...]_ACT */
 	return 0;
 }
 
@@ -1122,9 +1157,13 @@ priv_flow_process(struct pmd_internals *pmd,
 
 			if (action++)
 				goto exit_action_not_supported;
-			if (!pmd->rss_enabled)
+			if (!pmd->rss_enabled) {
 				err = rss_enable(pmd);
-			(void)rss;
+				if (err)
+					goto exit_action_not_supported;
+			}
+			if (rss)
+				err = rss_add_actions(flow, pmd, rss);
 		} else {
 			goto exit_action_not_supported;
 		}
@@ -1645,39 +1684,59 @@ tap_flow_implicit_flush(struct pmd_internals *pmd, struct rte_flow_error *error)
 	return 0;
 }
 
-#define BPF_PROGRAM "tap_bpf_program.o"
-
 /**
  * Enable RSS on tap: create leading TC rules for queuing.
+ *
+ * @param[in, out] pmd
+ *   Pointer to private structure.
+ *
+ * @return -1 if couldn't create map or add rules, 0 otherwise.
  */
 static int rss_enable(struct pmd_internals *pmd)
 {
 	struct rte_flow *rss_flow = NULL;
-	char section[64];
 	struct nlmsg *msg = NULL;
 	/* 4096 is the maximum number of instructions for a BPF program */
-	char annotation[256];
-	int bpf_fd;
+	char annotation[64];
 	int i;
+	int err = 0;
+
+	/*
+	 * At this point file system /sys/fs/bpf must be mounted
+	 * Check for it or mount it programatically
+	 */
+
+	/*
+	 *  Create RSS MAP
+	 */
+
+	err = bpf_rss_key(KEY_CMD_INIT, NULL);
+	if (err < 0) {
+		RTE_LOG(ERR, PMD, "Failed to initialize BPF RSS keys");
+		return -1;
+	}
+
+	pmd->map_fd = bpf_map_create(BPF_MAP_TYPE_HASH,
+				sizeof(__u32), /* key size */
+				sizeof(struct rss_key),
+				MAX_RSS_KEYS);
+	if (pmd->map_fd < 0) {
+		RTE_LOG(ERR, PMD, "Failed to create eBPF map");
+		return -1;
+	}
 
 	/*
 	 * Add a rule per queue to match reclassified packets and direct them to
 	 * the correct queue.
 	 */
 	for (i = 0; i < pmd->dev->data->nb_rx_queues; i++) {
-		struct action_data adata = {
-			.id = "skbedit",
-			.skbedit = {
-				.skbedit = {
-					.action = TC_ACT_PIPE,
-				},
-				.queue = i,
-			},
-		};
-
-		bpf_fd = bpf_load_cls_q_insns(i);
-		if (bpf_fd == -1)
+		pmd->bpf_fd[i] = bpf_load_cls_q_insns(i);
+		if (pmd->bpf_fd[i] < 0) {
+			RTE_LOG(ERR, PMD,
+				"Failed to load eBPF section %s for queue %d",
+				SEC_NAME_CLS_Q, i);
 			return -1;
+		}
 
 		rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
 		if (!rss_flow) {
@@ -1692,84 +1751,291 @@ static int rss_enable(struct pmd_internals *pmd)
 					    htons(ETH_P_ALL));
 		msg->t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
 		tap_flow_set_handle(rss_flow);
+
 		nlattr_add(&msg->nh, TCA_KIND, sizeof("bpf"), "bpf");
 		if (nlattr_nested_start(msg, TCA_OPTIONS) < 0)
 			return -1;
-		nlattr_add32(&msg->nh, TCA_BPF_FD, bpf_fd);
-		snprintf(annotation, sizeof(annotation), "%s:[%s]",
-			 BPF_PROGRAM, section);
+		nlattr_add32(&msg->nh, TCA_BPF_FD, pmd->bpf_fd[i]);
+		snprintf(annotation, sizeof(annotation), "[%s%d]",
+			SEC_NAME_CLS_Q, i);
 		nlattr_add(&msg->nh, TCA_BPF_NAME, strlen(annotation),
 			   annotation);
+		/* Actions */
+		{
+			struct action_data adata = {
+				.id = "skbedit",
+				.skbedit = {
+					.skbedit = {
+						.action = TC_ACT_PIPE,
+					},
+					.queue = i,
+				},
+			};
+			if (add_actions(rss_flow, 1, &adata, TCA_BPF_ACT) < 0)
+				return -1;
+		}
+		nlattr_nested_finish(msg); /* nested TCA_OPTIONS */
 
-		if (add_actions(rss_flow, 1, &adata, TCA_BPF_ACT) < 0)
-			return -1;
-		nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
 		/* Netlink message is now ready to be sent */
 		if (nl_send(pmd->nlsk_fd, &msg->nh) < 0)
 			return -1;
-		if (nl_recv_ack(pmd->nlsk_fd) < 0)
-			return -1;
+		err = nl_recv_ack(pmd->nlsk_fd);
+		if (err < 0) {
+			RTE_LOG(ERR, PMD,
+				"Kernel refused TC filter rule creation (%d): %s\n",
+				errno, strerror(errno));
+			return err;
+		}
 		LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
 	}
 
-	/* Add a rule that adds 4 bytes at packet's end to hold the hash */
-	bpf_fd = bpf_load_tailing_insns();
-	if (bpf_fd == -1)
+	pmd->rss_enabled = 1;
+	return err;
+}
+
+/**
+ * Manage bpf RSS keys repository with operations: init, get, release
+ *
+ * @param[in] cmd
+ *   Command on RSS keys: init, get, release
+ *
+ * @param[in, out] key_idx
+ *   Pointer to RSS Key index (out for get command, in for release command)
+ *
+ * @return -1 if couldn't get, release or init the RSS keys, 0 otherwise.
+ */
+static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx)
+{
+	__u32 i;
+	int err = -1;
+	static __u32 num_used_keys;
+	static __u32 rss_keys[MAX_RSS_KEYS] = {KEY_STAT_UNSPEC};
+	static __u32 rss_keys_initialized;
+
+	switch (cmd) {
+	case KEY_CMD_GET:
+		if (!rss_keys_initialized)
+			break;
+
+		if (num_used_keys == ARRAY_SIZE(rss_keys))
+			break;
+
+		*key_idx = num_used_keys % ARRAY_SIZE(rss_keys);
+		while (rss_keys[*key_idx] == KEY_STAT_USED)
+			*key_idx = (*key_idx + 1) % ARRAY_SIZE(rss_keys);
+		rss_keys[*key_idx] = KEY_STAT_USED;
+		num_used_keys++;
+		err = 0;
+	break;
+
+	case KEY_CMD_RELEASE:
+		if (!rss_keys_initialized)
+			break;
+
+		if (rss_keys[*key_idx] == KEY_STAT_USED) {
+			rss_keys[*key_idx] = KEY_STAT_AVAILABLE;
+			num_used_keys--;
+			err = 0;
+		}
+	break;
+
+	case KEY_CMD_INIT:
+		for (i = 0; i < ARRAY_SIZE(rss_keys); i++)
+			rss_keys[i] = KEY_STAT_AVAILABLE;
+		rss_keys_initialized = 1;
+		num_used_keys = 0;
+		err = 0;
+	break;
+
+	case KEY_CMD_DEINIT:
+		for (i = 0; i < ARRAY_SIZE(rss_keys); i++)
+			rss_keys[i] = KEY_STAT_UNSPEC;
+		rss_keys_initialized = 0;
+		num_used_keys = 0;
+		err = 0;
+	break;
+
+	default:
+		break;
+	}
+
+	return err;
+}
+
+/**
+ * Add RSS hash calculations and queue selection
+ *
+ * @param[in, out] pmd
+ *   Command on RSS keys: init, get, release
+ *
+ * @param[in] rss
+ *   Pointer to RSS flow actions
+ *
+ * @return -1 if couldn't add any action, 0 otherwise.
+ */
+static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
+			   const struct rte_flow_action_rss *rss)
+{
+	/* 4096 is the maximum number of instructions for a BPF program */
+	int i;
+	__u32 key_idx;
+	int err;
+
+	struct rss_key rss_entry = {
+		.key = {
+			0x98badcfe, 0x10325476, 0x98badcfe, 0x10325476,
+			0x98badcfe, 0x10325476, 0x98badcfe, 0x10325476,
+			0x98badcfe, 0x10325476, 0x98badcfe, 0x10325476,
+			0x98badcfe, 0x10325476, 0x98badcfe, 0x10325476,
+		},
+		.key_size = 16,
+		.hash_fields =
+		1 << HASH_FIELD_L2_SRC |
+		1 << HASH_FIELD_L2_DST |
+		1 << HASH_FIELD_L3_SRC |
+		1 << HASH_FIELD_L3_DST |
+		1 << HASH_FIELD_L4_SRC,
+		.queues = { 1, 2 },
+		.nb_queues = 2,
+	};
+	/* Get a new map key for a new RSS rule */
+	err = bpf_rss_key(KEY_CMD_GET, &key_idx);
+	if (err)
+		return -1;
+
+	/* Update RSS map entry with queues */
+	rss_entry.nb_queues = rss->num;
+	for (i = 0; i < rss->num; i++)
+		rss_entry.queues[i] = rss->queue[i];
+
+	/* Add this RSS entry to map */
+	err = bpf_map_update_elem(BPF_MAP_TYPE_HASH, pmd->map_fd,
+				&key_idx, &rss_entry, BPF_ANY);
+
+	if (err) {
+		fprintf(stderr, "RSS map entry #%u failed: %s\n", key_idx,
+			strerror(errno));
+		return -1;
+	}
+
+
+	/*
+	 * Load bpf rules to calculate hash for this key_idx
+	 */
+
+	// OMTODO - consider putting the repetitive pattern below within a macro
+	flow->bpf_fd[BPF_L2_DST] =  bpf_load_l2_dst_hash_insns(key_idx);
+	if (flow->bpf_fd[BPF_L2_DST] < 0) {
+		RTE_LOG(ERR, PMD,
+			"Failed to load eBPF section %s", sec_name[BPF_L2_DST]);
 		return -1;
+	}
 
-	snprintf(annotation, sizeof(annotation), "%s:[%s]", BPF_PROGRAM,
-		 section);
-	rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
-	if (!rss_flow) {
+	flow->bpf_fd[BPF_L2_SRC] = bpf_load_l2_src_hash_insns(key_idx);
+	if (flow->bpf_fd[BPF_L2_SRC] < 0) {
 		RTE_LOG(ERR, PMD,
-			"Cannot allocate memory for rte_flow");
+			"Failed to load eBPF section %s", sec_name[BPF_L2_SRC]);
 		return -1;
 	}
-	msg = &rss_flow->msg;
-	tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER,
-		    NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE);
-	msg->t.tcm_info =
-		TC_H_MAKE((RTE_PMD_TAP_MAX_QUEUES + PRIORITY_OFFSET) << 16,
-			  htons(ETH_P_ALL));
-	msg->t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
-	tap_flow_set_handle(rss_flow);
-	nlattr_add(&msg->nh, TCA_KIND, sizeof("flower"), "flower");
-	if (nlattr_nested_start(msg, TCA_OPTIONS) < 0)
+
+	flow->bpf_fd[BPF_L3_DST] = bpf_load_l3_dst_hash_insns(key_idx);
+	if (flow->bpf_fd[BPF_L3_DST] < 0) {
+		RTE_LOG(ERR, PMD,
+			"Failed to load eBPF section %s", sec_name[BPF_L3_DST]);
+		return -1;
+	}
+
+	flow->bpf_fd[BPF_L3_SRC] = bpf_load_l3_src_hash_insns(key_idx);
+	if (flow->bpf_fd[BPF_L3_SRC] < 0) {
+		RTE_LOG(ERR, PMD,
+			"Failed to load eBPF section %s", sec_name[BPF_L3_SRC]);
+		return -1;
+	}
+
+	flow->bpf_fd[BPF_L4_SRC] = bpf_load_l4_src_hash_insns(key_idx);
+	if (flow->bpf_fd[BPF_L4_SRC] < 0) {
+		RTE_LOG(ERR, PMD,
+			"Failed to load eBPF section %s", sec_name[BPF_L4_SRC]);
 		return -1;
+	}
 
-	/* no fields for matching: all packets must match */
+	flow->bpf_fd[BPF_SET_Q] = bpf_load_queue_setting_insns(key_idx);
+	if (flow->bpf_fd[BPF_SET_Q] < 0) {
+		RTE_LOG(ERR, PMD,
+			"Failed to load eBPF section %s", sec_name[BPF_SET_Q]);
+		return -1;
+	}
+
+	/* Actions */
 	{
-		/* Actions */
-		struct action_data data[2] = {
-			[0] = {
+		struct action_data adata[] = {
+			{
+				.id = "bpf",
+				.bpf = {
+					.bpf_fd = flow->bpf_fd[BPF_L2_DST],
+					.annotation = sec_name[BPF_L2_DST],
+					.bpf = {
+						.action = TC_ACT_PIPE,
+					},
+				},
+			},
+			{
+				.id = "bpf",
+				.bpf = {
+					.bpf_fd = flow->bpf_fd[BPF_L2_SRC],
+					.annotation = sec_name[BPF_L2_SRC],
+					.bpf = {
+						.action = TC_ACT_PIPE,
+					},
+				},
+			},
+			{
 				.id = "bpf",
 				.bpf = {
-					.bpf_fd = bpf_fd,
-					.annotation = annotation,
+					.bpf_fd = flow->bpf_fd[BPF_L3_SRC],
+					.annotation = sec_name[BPF_L3_SRC],
+					.bpf = {
+						.action = TC_ACT_PIPE,
+					},
 				},
 			},
-			[1] = {
-				.id = "gact",
-				.gact = {
-					/* continue */
-					.action = TC_ACT_UNSPEC,
+			{
+				.id = "bpf",
+				.bpf = {
+					.bpf_fd = flow->bpf_fd[BPF_L3_DST],
+					.annotation = sec_name[BPF_L3_DST],
+					.bpf = {
+						.action = TC_ACT_PIPE,
+					},
+				},
+			},
+			{
+				.id = "bpf",
+				.bpf = {
+					.bpf_fd = flow->bpf_fd[BPF_L4_SRC],
+					.annotation = sec_name[BPF_L4_SRC],
+					.bpf = {
+						.action = TC_ACT_PIPE,
+					},
+				},
+			},
+			{
+				.id = "bpf",
+				.bpf = {
+					.bpf_fd = flow->bpf_fd[BPF_SET_Q],
+					.annotation = sec_name[BPF_SET_Q],
+					.bpf = {
+						.action = TC_ACT_RECLASSIFY,
+					},
 				},
 			},
 		};
 
-		if (add_actions(rss_flow, 2, data, TCA_FLOWER_ACT) < 0)
+		if (add_actions(flow, ARRAY_SIZE(adata), adata,
+			TCA_FLOWER_ACT) < 0)
 			return -1;
 	}
-	nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
-	nlattr_nested_finish(msg); /* nested TCA_OPTIONS */
-	/* Netlink message is now ready to be sent */
-	if (nl_send(pmd->nlsk_fd, &msg->nh) < 0)
-		return -1;
-	if (nl_recv_ack(pmd->nlsk_fd) < 0)
-		return -1;
-	LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
 
-	pmd->rss_enabled = 1;
 	return 0;
 }
 
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v2  0/2] TAP RSS eBPF cover letter
  2017-12-17 12:21 [dpdk-dev] [PATCH v1 0/3] TAP RSS eBPF cover letter Ophir Munk
                   ` (2 preceding siblings ...)
  2017-12-17 12:21 ` [dpdk-dev] [PATCH v1 3/3] net/tap: add eBPF classifiers map and actions Ophir Munk
@ 2017-12-28 10:09 ` Ophir Munk
  2017-12-28 10:09   ` [dpdk-dev] [PATCH v2 1/2] net/tap: add eBPF instructions to TAP device Ophir Munk
                     ` (2 more replies)
  3 siblings, 3 replies; 42+ messages in thread
From: Ophir Munk @ 2017-12-28 10:09 UTC (permalink / raw)
  To: dev, Pascal Mazon, Ophir Munk; +Cc: Thomas Monjalon, Olga Shern

The patches of TAP RSS eBPF follow the RFC on this issue
https://dpdk.org/dev/patchwork/patch/31781/

v2 changes with respect to v1
=============================
* v2 has new commits organization (3 --> 2)
* BPF program was revised. It is successfully tested on
  IPv4 L3 L4 layers (compatible to mlx4 device)
* Licensing: no comments received for using "Dual BSD/GPL"
  string during BPF program loading to the kernel.
  (v1 and v2 are using the same license strings)
  Any comments are welcome.
* Compatibility to kernel versions:
  eBPF requires Linux version 4.2 configured with BPF. TAP PMD will
  successfully compile on systems with old or non-BPF configured kernels.
  During compilation time the required Linux headers are searched for.
  If they are not present missing definitions are locally added
  (tap_autoconf.h).
  If the kernel cannot support a BPF operation - at runtime it will
  gracefully reject the netlink message (with BPF) sent to it.

Commit #1:
net/tap: add eBPF instructions to TAP device
===========================================
  This commit introduces BPF program (tap_bpf_program.c)
  with a classifier and an action sections.
  The current implementation calculates RSS hash
  over L3 addresses (IPv4) and L4 ports.
  BPF program compilation is not part of dpdk compilation.
  This commit includes the eBPF machine instructions
  in the format of C arrays (tap_bpf_insns.c).

  The option to update the BPF program and download new machine
  instructions will be described in another commit.

Commit #2:
net/tap: implement RSS with eBPF classifier and action
======================================================
This commit builds and sends netlink messages to the kernel
that include BPF programs.
There is a single BPF classifier for each TAP queue. Packets
marked with an RSS queue will be directed to this queue using a traffic
control with "skbedit" action otherwise they will be pipelined to
the following rules.
There is a single BPF action for each RSS rule (may add more
to support IPv6).
The action is to calculate Toeplitz hash based on L3 addresses and L4 ports,
mark the packet with the RSS queue according the resulting hash,
then reclassify the packet.

Ophir Munk (2):
  net/tap: add eBPF instructions to TAP device
  net/tap: implement RSS with eBPF classifier and action

 drivers/net/tap/Makefile          |  31 ++
 drivers/net/tap/rte_eth_tap.h     |   9 +-
 drivers/net/tap/tap_bpf.h         |  92 +++++
 drivers/net/tap/tap_bpf_insns.c   | 759 ++++++++++++++++++++++++++++++++++++++
 drivers/net/tap/tap_bpf_program.c | 213 +++++++++++
 drivers/net/tap/tap_flow.c        | 625 ++++++++++++++++++++++++++-----
 drivers/net/tap/tap_flow.h        |  15 +
 drivers/net/tap/tap_tcmsgs.h      |   4 +
 8 files changed, 1652 insertions(+), 96 deletions(-)
 create mode 100644 drivers/net/tap/tap_bpf.h
 create mode 100644 drivers/net/tap/tap_bpf_insns.c
 create mode 100644 drivers/net/tap/tap_bpf_program.c

-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v2 1/2] net/tap: add eBPF instructions to TAP device
  2017-12-28 10:09 ` [dpdk-dev] [PATCH v2 0/2] TAP RSS eBPF cover letter Ophir Munk
@ 2017-12-28 10:09   ` Ophir Munk
  2017-12-28 10:09   ` [dpdk-dev] [PATCH v2 2/2] net/tap: implement RSS with eBPF classifier and action Ophir Munk
  2018-01-10  7:06   ` [dpdk-dev] [PATCH v3 0/2] TAP RSS eBPF cover letter Ophir Munk
  2 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2017-12-28 10:09 UTC (permalink / raw)
  To: dev, Pascal Mazon, Ophir Munk; +Cc: Thomas Monjalon, Olga Shern

TAP PMD is required to support RSS queue mapping based on rte_flow API. An
example usage for this requirement is failsafe transparent switching from a
PCI device to TAP device while keep redirecting packets to the same RSS
queues on both devices.

TAP RSS implementation is based on eBPF programs sent to Linux kernel
through BPF system calls and using netlink messages to reference the
programs as part of traffic control commands.

An eBPF program acts as a traffic control classifier or action. Each
program is written in C code under a different ELF section name. Clang 3.7
is used to compile the C code into eBPF-formatted object file. The ELF file
is parsed and its sections (programs) can be downloaded to the kernel using
BPF system call. The BPF system call parameters contain the array of eBPF
instructions. This commit includes BPF classifier and action programs
(tap_bpf_program.c) as reference and their corresponding arrays of eBPF
instructions (tap_bpf_insns.c). The reference file does not take part in
dpdk compilation. The details on how to generate new eBPF code will be
presented in another commit.

In a follow up commit TAP PMD will use the eBPF programs to implement RSS
flow rules.

eBPF requires Linux version 4.2 configured with BPF. TAP PMD will
successfully compile on systems with old or non-BPF configured kernels but
RSS rules creation on TAP devices will not be possible.

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 drivers/net/tap/Makefile          |  11 +
 drivers/net/tap/tap_bpf.h         |  92 +++++
 drivers/net/tap/tap_bpf_insns.c   | 699 ++++++++++++++++++++++++++++++++++++++
 drivers/net/tap/tap_bpf_program.c | 213 ++++++++++++
 drivers/net/tap/tap_flow.h        |   5 +
 5 files changed, 1020 insertions(+)
 create mode 100644 drivers/net/tap/tap_bpf.h
 create mode 100644 drivers/net/tap/tap_bpf_insns.c
 create mode 100644 drivers/net/tap/tap_bpf_program.c

diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index 405b49e..d7439b0 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -39,6 +39,9 @@ EXPORT_MAP := rte_pmd_tap_version.map
 
 LIBABIVER := 1
 
+# TAP_MAX_QUEUES must be a power of 2 as it will be used for masking */
+TAP_MAX_QUEUES = 16
+
 CFLAGS += -O3
 CFLAGS += -I$(SRCDIR)
 CFLAGS += -I.
@@ -47,6 +50,8 @@ LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
 LDLIBS += -lrte_bus_vdev
 
+CFLAGS += -DTAP_MAX_QUEUES=$(TAP_MAX_QUEUES)
+
 #
 # all source are stored in SRCS-y
 #
@@ -54,6 +59,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += rte_eth_tap.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_flow.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_netlink.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_tcmsgs.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_bpf_insns.c
 
 include $(RTE_SDK)/mk/rte.lib.mk
 
@@ -80,6 +86,11 @@ tap_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
 		linux/pkt_cls.h \
 		enum TCA_FLOWER_KEY_VLAN_PRIO \
 		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_BPF_PROG_LOAD \
+		linux/bpf.h \
+		enum BPF_PROG_LOAD \
+		$(AUTOCONF_OUTPUT)
 
 # Create tap_autoconf.h or update it in case it differs from the new one.
 
diff --git a/drivers/net/tap/tap_bpf.h b/drivers/net/tap/tap_bpf.h
new file mode 100644
index 0000000..075c005
--- /dev/null
+++ b/drivers/net/tap/tap_bpf.h
@@ -0,0 +1,92 @@
+#ifndef __TAP_BPF_H__
+#define __TAP_BPF_H__
+
+#include <tap_autoconf.h>
+
+#ifdef HAVE_BPF_PROG_LOAD
+#include <linux/bpf.h>
+#else
+/* BPF_MAP_UPDATE_ELEM command flags */
+#define	BPF_ANY	0 /* create a new element or update an existing */
+
+/* BPF architecture instruction struct */
+struct bpf_insn {
+	__u8	code;
+	__u8	dst_reg:4;
+	__u8	src_reg:4;
+	__s16	off;
+	__s32	imm; /* immediate value */
+};
+
+/* BPF program types */
+enum bpf_prog_type {
+	BPF_PROG_TYPE_UNSPEC,
+	BPF_PROG_TYPE_SOCKET_FILTER,
+	BPF_PROG_TYPE_KPROBE,
+	BPF_PROG_TYPE_SCHED_CLS,
+	BPF_PROG_TYPE_SCHED_ACT,
+};
+
+/* BPF commands types */
+enum bpf_cmd {
+	BPF_MAP_CREATE,
+	BPF_MAP_LOOKUP_ELEM,
+	BPF_MAP_UPDATE_ELEM,
+	BPF_MAP_DELETE_ELEM,
+	BPF_MAP_GET_NEXT_KEY,
+	BPF_PROG_LOAD,
+};
+
+/* BPF maps types */
+enum bpf_map_type {
+	BPF_MAP_TYPE_UNSPEC,
+	BPF_MAP_TYPE_HASH,
+};
+
+/* union of anonymous structs used with TAP BPF commands */
+union bpf_attr {
+	/* BPF_MAP_CREATE command */
+	struct {
+		__u32	map_type;
+		__u32	key_size;
+		__u32	value_size;
+		__u32	max_entries;
+		__u32	map_flags;
+		__u32	inner_map_fd;
+	};
+
+	/* BPF_MAP_UPDATE_ELEM, BPF_MAP_DELETE_ELEM commands */
+	struct {
+		__u32		map_fd;
+		__aligned_u64	key;
+		union {
+			__aligned_u64 value;
+			__aligned_u64 next_key;
+		};
+		__u64		flags;
+	};
+
+	/* BPF_PROG_LOAD command */
+	struct {
+		__u32		prog_type;
+		__u32		insn_cnt;
+		__aligned_u64	insns;
+		__aligned_u64	license;
+		__u32		log_level;
+		__u32		log_size;
+		__aligned_u64	log_buf;
+		__u32		kern_version;
+		__u32		prog_flags;
+	};
+} __attribute__((aligned(8)));
+#endif
+
+enum {
+	BPF_MAP_ID_KEY,
+	BPF_MAP_ID_SIMPLE,
+};
+
+static int bpf_load(enum bpf_prog_type type, const struct bpf_insn *insns,
+		size_t insns_cnt, const char *license);
+
+#endif /* __TAP_BPF_H__ */
diff --git a/drivers/net/tap/tap_bpf_insns.c b/drivers/net/tap/tap_bpf_insns.c
new file mode 100644
index 0000000..2db3fce
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_insns.c
@@ -0,0 +1,699 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright 2017 6WIND S.A.
+ *   Copyright 2017 Mellanox.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND S.A. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/queue.h>
+#include <sys/mount.h>
+
+#include <rte_byteorder.h>
+#include <rte_jhash.h>
+#include <rte_malloc.h>
+#include <rte_eth_tap.h>
+#include <tap_flow.h>
+#include <tap_autoconf.h>
+#include <tap_tcmsgs.h>
+#include <tap_bpf.h>
+
+#define ERROR                   0
+
+/*
+ * The queue number is offset by 1, to distinguish packets that have
+ * gone through this rule (skb->cb[1] != 0) from others.
+ */
+#define QUEUE_OFFSET 1
+
+/* bpf_insn array matching cls_q section. See tap_bpf_program.c file */
+static struct bpf_insn cls_q_insns[] = {
+	{0x61,  1,  1,  52, 0x00000000},
+	{0x18,  2,  0,   0, 0xdeadbeef},
+	{0x00,  0,  0,   0, 0x00000000},
+	{0x63, 10,  2,  -4, 0x00000000},
+	{0x61,  2, 10,  -4, 0x00000000},
+	{0x07,  2,  0,   0, 0x00000001},
+	{0x67,  2,  0,   0, 0x00000020},
+	{0x77,  2,  0,   0, 0x00000020},
+	{0xb7,  0,  0,   0, 0xffffffff},
+	{0x1d,  1,  2,   1, 0x00000000},
+	{0xb7,  0,  0,   0, 0x00000000},
+	{0x95,  0,  0,   0, 0x00000000},
+};
+
+/**
+ * Load BPF program (section cls_q) into the kernel and return a bpf fd
+ *
+ * @param queue_idx
+ *   Queue index matching packet cb
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int tap_flow_bpf_cls_q(__u32 queue_idx)
+{
+	cls_q_insns[1].imm = queue_idx;
+
+	return bpf_load(BPF_PROG_TYPE_SCHED_CLS,
+		(struct bpf_insn *)cls_q_insns,
+		ARRAY_SIZE(cls_q_insns),
+		"Dual BSD/GPL");
+}
+
+/* bpf_insn array matching l3_l4 section. see tap_bpf_program.c file */
+static struct bpf_insn l3_l4_hash_insns[] = {
+	{0xbf,    6,    1,        0, 0x00000000},
+	{0x61,    8,    6,       16, 0x00000000},
+	{0x61,    7,    6,       76, 0x00000000},
+	{0x61,    9,    6,       80, 0x00000000},
+	{0x18,    1,    0,        0, 0xdeadbeef},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0x63,   10,    1,       -4, 0x00000000},
+	{0xbf,    2,   10,        0, 0x00000000},
+	{0x07,    2,    0,        0, 0xfffffffc},
+	{0x18,    1,    1,        0, 0x00000005},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0x85,    0,    0,        0, 0x00000001},
+	{0x55,    0,    0,       21, 0x00000000},
+	{0xb7,    1,    0,        0, 0x00000a64},
+	{0x6b,   10,    1,      -16, 0x00000000},
+	{0x18,    1,    0,        0, 0x69666e6f},
+	{0x00,    0,    0,        0, 0x65727567},
+	{0x7b,   10,    1,      -24, 0x00000000},
+	{0x18,    1,    0,        0, 0x6e207369},
+	{0x00,    0,    0,        0, 0x6320746f},
+	{0x7b,   10,    1,      -32, 0x00000000},
+	{0x18,    1,    0,        0, 0x20737372},
+	{0x00,    0,    0,        0, 0x2079656b},
+	{0x7b,   10,    1,      -40, 0x00000000},
+	{0x18,    1,    0,        0, 0x68736168},
+	{0x00,    0,    0,        0, 0x203a2928},
+	{0x7b,   10,    1,      -48, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0x73,   10,    7,      -14, 0x00000000},
+	{0xbf,    1,   10,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0xffffffd0},
+	{0xb7,    2,    0,        0, 0x00000023},
+	{0x85,    0,    0,        0, 0x00000006},
+	{0x05,    0,    0,      457, 0x00000000},
+	{0xbf,    3,    7,        0, 0x00000000},
+	{0xb7,    1,    0,        0, 0x0000000e},
+	{0x61,    2,    6,       20, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    6,       28, 0x00000000},
+	{0x55,    2,    0,        6, 0x0000a888},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0xbf,    1,    3,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0x00000012},
+	{0x2d,    1,    9,      447, 0x00000000},
+	{0xb7,    1,    0,        0, 0x00000012},
+	{0x69,    8,    3,       16, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000003},
+	{0x57,    8,    0,        0, 0x0000ffff},
+	{0x55,    8,    0,      442, 0x00000008},
+	{0x0f,    3,    1,        0, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0xbf,    1,    3,        0, 0x00000000},
+	{0xbf,    2,    3,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0x00000018},
+	{0x2d,    1,    9,      436, 0x00000000},
+	{0xbf,    7,    2,        0, 0x00000000},
+	{0x71,    2,    7,       12, 0x00000000},
+	{0xbf,    3,    2,        0, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000038},
+	{0xc7,    3,    0,        0, 0x00000020},
+	{0x77,    3,    0,        0, 0x0000001f},
+	{0x57,    3,    0,        0, 0x2cc681d1},
+	{0x67,    2,    0,        0, 0x00000018},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x40000000},
+	{0xb7,    1,    0,        0, 0x00000000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x598d03a2},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x20000000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xb31a0745},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x10000000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x66340e8a},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x08000000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xcc681d15},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x04000000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x98d03a2b},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x02000000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x31a07456},
+	{0x57,    2,    0,        0, 0x01000000},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x6340e8ad},
+	{0x71,    2,    7,       13, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000010},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00800000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xc681d15b},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00400000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x8d03a2b7},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00200000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x1a07456f},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00100000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x340e8ade},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00080000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x681d15bd},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00040000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xd03a2b7b},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00020000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xa07456f6},
+	{0x57,    2,    0,        0, 0x00010000},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x40e8aded},
+	{0x71,    2,    7,       14, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000008},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00008000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x81d15bdb},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00004000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x03a2b7b7},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00002000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x07456f6f},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00001000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x0e8adedf},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000800},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x1d15bdbf},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000400},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x3a2b7b7e},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000200},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x7456f6fd},
+	{0x57,    2,    0,        0, 0x00000100},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xe8adedfa},
+	{0x71,    2,    7,       15, 0x00000000},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000080},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xd15bdbf4},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000040},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xa2b7b7e9},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000020},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x456f6fd3},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000010},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x8adedfa7},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000008},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x15bdbf4f},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000004},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x2b7b7e9e},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000002},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x56f6fd3d},
+	{0x57,    2,    0,        0, 0x00000001},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xadedfa7b},
+	{0x71,    4,    7,       16, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000038},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0xb7,    2,    0,        0, 0xffffffff},
+	{0x6d,    5,    2,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x5bdbf4f7},
+	{0x67,    4,    0,        0, 0x00000018},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xb7b7e9ef},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x6f6fd3df},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xdedfa7bf},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xbdbf4f7f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x7b7e9eff},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xf6fd3dff},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xedfa7bfe},
+	{0x71,    4,    7,       17, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000010},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xdbf4f7fc},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xb7e9eff9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x6fd3dff2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xdfa7bfe5},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xbf4f7fca},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x7e9eff94},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xfd3dff28},
+	{0x57,    4,    0,        0, 0x00010000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xfa7bfe51},
+	{0x71,    4,    7,       18, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000008},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xf4f7fca2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xe9eff945},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xd3dff28a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xa7bfe514},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x4f7fca28},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x9eff9450},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x3dff28a0},
+	{0x57,    4,    0,        0, 0x00000100},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x7bfe5141},
+	{0x71,    4,    7,       19, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xf7fca283},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xeff94506},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xdff28a0c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xbfe51418},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x7fca2831},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xff945063},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xff28a0c6},
+	{0x57,    4,    0,        0, 0x00000001},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xfe51418c},
+	{0x71,    4,    7,       20, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000008},
+	{0x71,    5,    7,       21, 0x00000000},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000030},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    2,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xfca28319},
+	{0x67,    4,    0,        0, 0x00000010},
+	{0xbf,    2,    4,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x40000000},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xf9450633},
+	{0xbf,    2,    4,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x20000000},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xf28a0c67},
+	{0xbf,    2,    4,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x10000000},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xe51418ce},
+	{0xbf,    2,    4,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x08000000},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xca28319d},
+	{0xbf,    2,    4,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x04000000},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x9450633b},
+	{0xbf,    2,    4,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x02000000},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x28a0c676},
+	{0xbf,    2,    4,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x01000000},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x51418ced},
+	{0xbf,    2,    4,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00800000},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xa28319db},
+	{0xbf,    2,    4,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00400000},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x450633b6},
+	{0xbf,    2,    4,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00200000},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x8a0c676c},
+	{0xbf,    2,    4,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00100000},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x1418ced8},
+	{0xbf,    2,    4,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00080000},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x28319db1},
+	{0xbf,    2,    4,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00040000},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x50633b63},
+	{0xbf,    2,    4,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00020000},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xa0c676c6},
+	{0x57,    4,    0,        0, 0x00010000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x418ced8d},
+	{0x71,    2,    7,       22, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000008},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00008000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x8319db1a},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00004000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x0633b634},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00002000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x0c676c68},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00001000},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x18ced8d1},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000800},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x319db1a3},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000400},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x633b6347},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000200},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xc676c68f},
+	{0x57,    2,    0,        0, 0x00000100},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x8ced8d1f},
+	{0x71,    2,    7,       23, 0x00000000},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000080},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x19db1a3e},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000040},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x33b6347d},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000020},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x676c68fa},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000010},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xced8d1f4},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000008},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x9db1a3e9},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000004},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x3b6347d2},
+	{0xbf,    4,    2,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000002},
+	{0x1d,    4,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x76c68fa5},
+	{0x57,    2,    0,        0, 0x00000001},
+	{0x1d,    2,    1,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0xed8d1f4a},
+	{0xbf,    2,    3,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000020},
+	{0x77,    2,    0,        0, 0x00000020},
+	{0x61,    4,    0,      200, 0x00000000},
+	{0xbf,    5,    2,        0, 0x00000000},
+	{0x3f,    5,    4,        0, 0x00000000},
+	{0x2f,    5,    4,        0, 0x00000000},
+	{0x1f,    2,    5,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x0000000f},
+	{0x67,    2,    0,        0, 0x00000002},
+	{0x0f,    0,    2,        0, 0x00000000},
+	{0x61,    4,    0,      136, 0x00000000},
+	{0xbf,    2,    4,        0, 0x00000000},
+	{0x07,    2,    0,        0, 0x00000001},
+	{0x63,    6,    2,       52, 0x00000000},
+	{0x73,   10,    1,      -12, 0x00000000},
+	{0xb7,    1,    0,        0, 0x0a75253d},
+	{0x63,   10,    1,      -16, 0x00000000},
+	{0x18,    1,    0,        0, 0x71207825},
+	{0x00,    0,    0,        0, 0x65756575},
+	{0x7b,   10,    1,      -24, 0x00000000},
+	{0x18,    1,    0,        0, 0x73616820},
+	{0x00,    0,    0,        0, 0x78303d68},
+	{0x7b,   10,    1,      -32, 0x00000000},
+	{0x18,    1,    0,        0, 0x6c5f3476},
+	{0x00,    0,    0,        0, 0x346c5f33},
+	{0x7b,   10,    1,      -40, 0x00000000},
+	{0x18,    1,    0,        0, 0x3e3e3e3e},
+	{0x00,    0,    0,        0, 0x7069203e},
+	{0x7b,   10,    1,      -48, 0x00000000},
+	{0xbf,    1,   10,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0xffffffd0},
+	{0xb7,    2,    0,        0, 0x00000025},
+	{0x85,    0,    0,        0, 0x00000006},
+	{0xb7,    7,    0,        0, 0x00000001},
+	{0xbf,    0,    7,        0, 0x00000000},
+	{0x95,    0,    0,        0, 0x00000000},
+};
+
+/**
+ * Load BPF program (section l3_l4) into the kernel and return a bpf fd.
+ *
+ * @param[in] key_idx
+ *   RSS MAP key index
+ *
+ * @param[in] map_fd
+ *   BPF RSS map file descriptor
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd)
+{
+	l3_l4_hash_insns[4].imm = key_idx;
+	l3_l4_hash_insns[9].imm = map_fd;
+
+	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+		(struct bpf_insn *)l3_l4_hash_insns,
+		ARRAY_SIZE(l3_l4_hash_insns),
+		"Dual BSD/GPL");
+}
+
+
+#ifndef __NR_bpf
+# if defined(__i386__)
+#  define __NR_bpf 357
+# elif defined(__x86_64__)
+#  define __NR_bpf 321
+# elif defined(__aarch64__)
+#  define __NR_bpf 280
+# elif defined(__sparc__)
+#  define __NR_bpf 349
+# elif defined(__s390__)
+#  define __NR_bpf 351
+# else
+#  error __NR_bpf not defined. libbpf does not support your arch.
+# endif
+#endif
+
+/**
+ * Helper function to convert a pointer to unsigned 64 bits
+ *
+ * @param[in] ptr
+ *   pointer to address
+ *
+ * @return
+ *   64 bit unsigned long type of pointer address
+ */
+static inline __u64 ptr_to_u64(const void *ptr)
+{
+	return (__u64)(unsigned long)ptr;
+}
+
+/**
+ * Call BPF system call
+ *
+ * @param[in] cmd
+ *   BPF command for program loading, map creation, map entry update, etc
+ *
+ * @param[in] attr
+ *   System call attributes relevant to system call command
+ *
+ * @param[in] size
+ *   size of attr parameter
+ *
+ * @return
+ *   -1 if BPF system call failed, 0 otherwise
+ */
+static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
+			unsigned int size)
+{
+	return syscall(__NR_bpf, cmd, attr, size);
+}
+
+/**
+ * Load BPF instructions to kernel
+ *
+ * @param[in] type
+ *   BPF program type: classifieir or action
+ *
+ * @param[in] insns
+ *   Array of BPF instructions (equivalent to BPF instructions)
+ *
+ * @param[in] insns_cnt
+ *   Number of BPF instructions (size of array)
+ *
+ * @param[in] lincense
+ *   License string that must be acknowledged by the kernel
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded, fd (file descriptor) otherwise
+ */
+static int bpf_load(enum bpf_prog_type type,
+		  const struct bpf_insn *insns,
+		  size_t insns_cnt,
+		  const char *license)
+{
+	union bpf_attr attr;
+
+	bzero(&attr, sizeof(attr));
+	attr.prog_type = type;
+	attr.insn_cnt = (__u32)insns_cnt;
+	attr.insns = ptr_to_u64(insns);
+	attr.license = ptr_to_u64(license);
+	attr.log_buf = ptr_to_u64(NULL);
+	attr.log_level = 0;
+	attr.kern_version = 0;
+
+	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
+}
diff --git a/drivers/net/tap/tap_bpf_program.c b/drivers/net/tap/tap_bpf_program.c
new file mode 100644
index 0000000..eea7669
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_program.c
@@ -0,0 +1,213 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright 2017 6WIND S.A.
+ *   Copyright 2017 Mellanox.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND S.A. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <asm/types.h>
+#include <linux/in.h>
+#include <linux/if.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/if_tunnel.h>
+#include <linux/filter.h>
+#include <linux/bpf.h>
+
+#include "tap_rss.h"
+
+/** Create IPv4 address */
+#define IPv4(a, b, c, d) ((__u32)(((a) & 0xff) << 24) | \
+		(((b) & 0xff) << 16) | \
+		(((c) & 0xff) << 8)  | \
+		((d) & 0xff))
+
+#define PORT(a, b) ((__u16)(((a) & 0xff) << 8) | \
+		((b) & 0xff))
+
+/*
+ * The queue number is offset by 1, to distinguish packets that have
+ * gone through this rule (skb->cb[1] != 0) from others.
+ */
+#define QUEUE_OFFSET 1
+
+#define KEY_IDX			0
+#define BPF_MAP_ID_KEY	1
+
+struct vlan_hdr {
+	__be16 proto;
+	__be16 tci;
+};
+
+struct bpf_elf_map __attribute__((section("maps"), used))
+map_keys = {
+	.type           =       BPF_MAP_TYPE_HASH,
+	.id             =       BPF_MAP_ID_KEY,
+	.size_key       =       sizeof(__u32),
+	.size_value     =       sizeof(struct rss_key),
+	.max_elem       =       256,
+	.pinning        =       PIN_GLOBAL_NS,
+};
+
+
+__section("cls_q") int
+match_q(struct __sk_buff *skb)
+{
+	__u32 queue = skb->cb[1];
+	volatile __u32 q = 0xdeadbeef;
+	__u32 match_queue = QUEUE_OFFSET + q;
+
+	/* printt("match_q$i() queue = %d\n", queue); */
+
+	if (queue != match_queue)
+		return TC_ACT_OK;
+	return TC_ACT_UNSPEC;
+}
+
+
+struct ipv4_l3_l4_tuple {
+	__u32    src_addr;
+	__u32    dst_addr;
+	__u16    dport;
+	__u16    sport;
+} __attribute__((packed));
+
+static const __u8 def_rss_key[] = {
+	0xd1, 0x81, 0xc6, 0x2c,
+	0xf7, 0xf4, 0xdb, 0x5b,
+	0x19, 0x83, 0xa2, 0xfc,
+	0x94, 0x3e, 0x1a, 0xdb,
+	0xd9, 0x38, 0x9e, 0x6b,
+	0xd1, 0x03, 0x9c, 0x2c,
+	0xa7, 0x44, 0x99, 0xad,
+	0x59, 0x3d, 0x56, 0xd9,
+	0xf3, 0x25, 0x3c, 0x06,
+	0x2a, 0xdc, 0x1f, 0xfc,
+};
+
+static __u32  __attribute__((always_inline))
+rte_softrss_be(const __u32 *input_tuple, __u32 input_len,
+		const uint8_t *rss_key)
+{
+	__u32 i, j, hash = 0;
+#pragma unroll
+	for (j = 0; j < 3; j++) {
+#pragma unroll
+		for (i = 0; i < 32; i++) {
+			if (input_tuple[j] & (1 << (31 - i))) {
+				hash ^= ((const __u32 *)def_rss_key)[j] << i |
+				(__u32)((uint64_t)
+				(((const __u32 *)def_rss_key)[j + 1])
+					>> (32 - i));
+			}
+		}
+	}
+	return hash;
+}
+
+static int __attribute__((always_inline))
+ipv4_l3_l4_rss(struct __sk_buff *skb)
+{
+	void *data_end = (void *)(long)skb->data_end;
+	void *data = (void *)(long)skb->data;
+	__u16 proto = (__u16)skb->protocol;
+	__u32 key_idx = 0xdeadbeef;
+	__u32 hash;
+	struct rss_key *rsskey;
+	__u64 off = ETH_HLEN;
+	__u8 *key = 0;
+	__u32 len;
+	__u32 queue = 0;
+
+	rsskey = map_lookup_elem(&map_keys, &key_idx);
+	if (!rsskey) {
+		printt("hash(): rss key is not configured\n");
+		return TC_ACT_OK;
+	}
+	key = (__u8 *)rsskey->key;
+
+	/* Get correct proto for 802.1ad */
+	if (skb->vlan_present && skb->vlan_proto == htons(ETH_P_8021AD)) {
+		if (data + ETH_ALEN * 2 + sizeof(struct vlan_hdr) +
+		    sizeof(proto) > data_end)
+			return TC_ACT_OK;
+		proto = *(__u16 *)(data + ETH_ALEN * 2 +
+				   sizeof(struct vlan_hdr));
+		off += sizeof(struct vlan_hdr);
+	}
+
+	if (proto == htons(ETH_P_IP)) {
+		if (data + off + sizeof(struct iphdr) + sizeof(__u32)
+			> data_end)
+			return TC_ACT_OK;
+
+		__u8 *src_dst_addr = data + off + offsetof(struct iphdr, saddr);
+		__u8 *src_dst_port = data + off + sizeof(struct iphdr);
+		struct ipv4_l3_l4_tuple tuple = {
+			.src_addr = IPv4(*(src_dst_addr + 0),
+					*(src_dst_addr + 1),
+					*(src_dst_addr + 2),
+					*(src_dst_addr + 3)),
+			.dst_addr = IPv4(*(src_dst_addr + 4),
+					*(src_dst_addr + 5),
+					*(src_dst_addr + 6),
+					*(src_dst_addr + 7)),
+			.sport = PORT(*(src_dst_port + 0),
+					*(src_dst_port + 1)),
+			.dport = PORT(*(src_dst_port + 2),
+					*(src_dst_port + 3)),
+		};
+		hash = rte_softrss_be((__u32 *)&tuple,
+			sizeof(tuple) / sizeof(__u32), key);
+	} else {
+		return TC_ACT_PIPE;
+	}
+
+	queue = rsskey->queues[(hash % rsskey->nb_queues) &
+				       (TAP_MAX_QUEUES - 1)];
+	skb->cb[1] = QUEUE_OFFSET + queue;
+
+	return TC_ACT_RECLASSIFY;
+}
+
+#define RSS(L)						\
+	__section(#L) int				\
+		L ## _hash(struct __sk_buff *skb)	\
+	{						\
+		return L ## _rss(skb);			\
+	}
+
+RSS(ipv4_l3_l4)
+
+BPF_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h
index 9e332b0..6cc01b4 100644
--- a/drivers/net/tap/tap_flow.h
+++ b/drivers/net/tap/tap_flow.h
@@ -50,6 +50,8 @@
 #define GROUP_SHIFT 12
 #define MAX_GROUP GROUP_MASK
 
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
 /**
  * These index are actually in reversed order: their priority is processed
  * by subtracting their value to the lowest priority (PRIORITY_MASK).
@@ -80,4 +82,7 @@ int tap_flow_implicit_destroy(struct pmd_internals *pmd,
 int tap_flow_implicit_flush(struct pmd_internals *pmd,
 			    struct rte_flow_error *error);
 
+int tap_flow_bpf_cls_q(__u32 queue_idx);
+int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd);
+
 #endif /* _TAP_FLOW_H_ */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v2 2/2] net/tap: implement RSS with eBPF classifier and action
  2017-12-28 10:09 ` [dpdk-dev] [PATCH v2 0/2] TAP RSS eBPF cover letter Ophir Munk
  2017-12-28 10:09   ` [dpdk-dev] [PATCH v2 1/2] net/tap: add eBPF instructions to TAP device Ophir Munk
@ 2017-12-28 10:09   ` Ophir Munk
  2018-01-10  7:06   ` [dpdk-dev] [PATCH v3 0/2] TAP RSS eBPF cover letter Ophir Munk
  2 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2017-12-28 10:09 UTC (permalink / raw)
  To: dev, Pascal Mazon, Ophir Munk; +Cc: Thomas Monjalon, Olga Shern

Add BPF classifier for each TAP queue. According to this classifier packets
marked with an RSS queue will be directed to this queue using a traffic
control with "skbedit" action.
The BPF classifier program is downloaded to the kernel once per TAP Rx
queue.

Add RSS BPF map entry for each new RSS rule. A BPF map entry contains the
RSS queues of that rule.

Add BPF action for each new RSS rule in which the Toeplitz RSS hash is
calculated based on L3 addresses and L4 ports. Mark the packet with the RSS
queue according the resulting RSS hash, then reclassify the packet.

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 drivers/net/tap/Makefile        |  20 ++
 drivers/net/tap/rte_eth_tap.h   |   9 +-
 drivers/net/tap/tap_bpf_insns.c |  60 ++++
 drivers/net/tap/tap_flow.c      | 625 ++++++++++++++++++++++++++++++++++------
 drivers/net/tap/tap_flow.h      |  10 +
 drivers/net/tap/tap_tcmsgs.h    |   4 +
 6 files changed, 632 insertions(+), 96 deletions(-)

diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index d7439b0..ffd8061 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -87,6 +87,26 @@ tap_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
 		enum TCA_FLOWER_KEY_VLAN_PRIO \
 		$(AUTOCONF_OUTPUT)
 	$Q sh -- '$<' '$@' \
+		HAVE_TC_BPF \
+		linux/pkt_cls.h \
+		enum TCA_BPF_UNSPEC \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_TC_BPF_FD \
+		linux/pkt_cls.h \
+		enum TCA_BPF_FD \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_TC_ACT_BPF \
+		linux/tc_act/tc_bpf.h \
+		enum TCA_ACT_BPF_UNSPEC \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_TC_ACT_BPF_FD \
+		linux/tc_act/tc_bpf.h \
+		enum TCA_ACT_BPF_FD \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
 		HAVE_BPF_PROG_LOAD \
 		linux/bpf.h \
 		enum BPF_PROG_LOAD \
diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
index 829f32f..c185473 100644
--- a/drivers/net/tap/rte_eth_tap.h
+++ b/drivers/net/tap/rte_eth_tap.h
@@ -45,7 +45,7 @@
 #include <rte_ether.h>
 
 #ifdef IFF_MULTI_QUEUE
-#define RTE_PMD_TAP_MAX_QUEUES	16
+#define RTE_PMD_TAP_MAX_QUEUES	TAP_MAX_QUEUES
 #else
 #define RTE_PMD_TAP_MAX_QUEUES	1
 #endif
@@ -90,6 +90,13 @@ struct pmd_internals {
 	int ioctl_sock;                   /* socket for ioctl calls */
 	int nlsk_fd;                      /* Netlink socket fd */
 	int flow_isolate;                 /* 1 if flow isolation is enabled */
+	int flower_support;               /* 1 if kernel supports, else 0 */
+	int flower_vlan_support;          /* 1 if kernel supports, else 0 */
+	int rss_enabled;                  /* 1 if RSS is enabled, else 0 */
+	/* implicit rules set when RSS is enabled */
+	int map_fd;                       /* BPF RSS map fd */
+	int bpf_fd[RTE_PMD_TAP_MAX_QUEUES];/* List of bpf fds per queue */
+	LIST_HEAD(tap_rss_flows, rte_flow) rss_flows;
 	LIST_HEAD(tap_flows, rte_flow) flows;        /* rte_flow rules */
 	/* implicit rte_flow rules set when a remote device is active */
 	LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows;
diff --git a/drivers/net/tap/tap_bpf_insns.c b/drivers/net/tap/tap_bpf_insns.c
index 2db3fce..409d688 100644
--- a/drivers/net/tap/tap_bpf_insns.c
+++ b/drivers/net/tap/tap_bpf_insns.c
@@ -697,3 +697,63 @@ static int bpf_load(enum bpf_prog_type type,
 
 	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
 }
+
+/**
+ * Create BPF map for RSS rules
+ *
+ * @param[in] key_size
+ *   map RSS key size
+ *
+ * @param[in] value_size
+ *   Map RSS value size
+ *
+ * @param[in] max_entries
+ *   Map max number of RSS entries (limit on max RSS rules)
+ *
+ * @return
+ *   -1 if BPF map couldn't be created, map fd otherwise
+ */
+int tap_flow_bpf_rss_map_create(unsigned int key_size,
+		unsigned int value_size,
+		unsigned int max_entries)
+{
+	union bpf_attr attr;
+
+	bzero(&attr, sizeof(attr));
+	attr.map_type    = BPF_MAP_TYPE_HASH;
+	attr.key_size    = key_size;
+	attr.value_size  = value_size;
+	attr.max_entries = max_entries;
+
+	return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
+}
+
+/**
+ * Update RSS entry in BPF map
+ *
+ * @param[in] fd
+ *   RSS map fd
+ *
+ * @param[in] key
+ *   Pointer to RSS key whose entry is updated
+ *
+ * @param[in] value
+ *   Pointer to RSS new updated value
+ *
+ * @return
+ *   -1 if RSS entry failed to be updated, 0 otherwise
+ */
+int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value)
+{
+	union bpf_attr attr;
+
+	bzero(&attr, sizeof(attr));
+
+	attr.map_type = BPF_MAP_TYPE_HASH;
+	attr.map_fd = fd;
+	attr.key = ptr_to_u64(key);
+	attr.value = ptr_to_u64(value);
+	attr.flags = BPF_ANY;
+
+	return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
+}
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index ffc0b85..8345c86 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -33,6 +33,7 @@
 
 #include <errno.h>
 #include <string.h>
+#include <unistd.h>
 #include <sys/queue.h>
 
 #include <rte_byteorder.h>
@@ -42,6 +43,7 @@
 #include <tap_flow.h>
 #include <tap_autoconf.h>
 #include <tap_tcmsgs.h>
+#include <tap_rss.h>
 
 #ifndef HAVE_TC_FLOWER
 /*
@@ -81,12 +83,78 @@ enum {
 	TCA_FLOWER_KEY_VLAN_ETH_TYPE,   /* be16 */
 };
 #endif
+/*
+ * For kernels < 4.2 BPF related enums may not be defined.
+ * Runtime checks will be carried out to gracefully report on TC messages that
+ * are rejected by the kernel. Rejection reasons may be due to:
+ * 1. enum is not defined
+ * 2. enum is defined but kerenl is not configured to support BPF system calls,
+ *    BPF classifications or BPF actions.
+ */
+#ifndef HAVE_TC_BPF
+enum {
+	TCA_BPF_UNSPEC,
+	TCA_BPF_ACT,
+	TCA_BPF_POLICE,
+	TCA_BPF_CLASSID,
+	TCA_BPF_OPS_LEN,
+	TCA_BPF_OPS,
+};
+#endif
+#ifndef HAVE_TC_BPF_FD
+enum {
+	TCA_BPF_FD = TCA_BPF_OPS + 1,
+	TCA_BPF_NAME,
+};
+#endif
+#ifndef HAVE_TC_ACT_BPF
+#define tc_gen \
+	__u32                 index; \
+	__u32                 capab; \
+	int                   action; \
+	int                   refcnt; \
+	int                   bindcnt
+
+struct tc_act_bpf {
+	tc_gen;
+};
+
+enum {
+	TCA_ACT_BPF_UNSPEC,
+	TCA_ACT_BPF_TM,
+	TCA_ACT_BPF_PARMS,
+	TCA_ACT_BPF_OPS_LEN,
+	TCA_ACT_BPF_OPS,
+};
+
+#endif
+#ifndef HAVE_TC_ACT_BPF_FD
+enum {
+	TCA_ACT_BPF_FD = TCA_ACT_BPF_OPS + 1,
+	TCA_ACT_BPF_NAME,
+};
+#endif
+
+/* RSS key management */
+enum bpf_rss_key_e {
+	KEY_CMD_GET = 1,
+	KEY_CMD_RELEASE,
+	KEY_CMD_INIT,
+	KEY_CMD_DEINIT,
+};
+
+enum key_status_e {
+	KEY_STAT_UNSPEC,
+	KEY_STAT_USED,
+	KEY_STAT_AVAILABLE,
+};
 
 #define ISOLATE_HANDLE 1
 
 struct rte_flow {
 	LIST_ENTRY(rte_flow) next; /* Pointer to the next rte_flow structure */
 	struct rte_flow *remote_flow; /* associated remote flow */
+	int bpf_fd[SEC_MAX]; /* list of bfs fds per ELF section */
 	struct nlmsg msg;
 };
 
@@ -104,6 +172,24 @@ struct remote_rule {
 	int mirred;
 };
 
+struct action_data {
+	char id[16];
+
+	union {
+		struct tc_gact gact;
+		struct tc_mirred mirred;
+		struct skbedit {
+			struct tc_skbedit skbedit;
+			uint16_t queue;
+		} skbedit;
+		struct bpf {
+			struct tc_act_bpf bpf;
+			int bpf_fd;
+			const char *annotation;
+		} bpf;
+	};
+};
+
 static int tap_flow_create_eth(const struct rte_flow_item *item, void *data);
 static int tap_flow_create_vlan(const struct rte_flow_item *item, void *data);
 static int tap_flow_create_ipv4(const struct rte_flow_item *item, void *data);
@@ -134,6 +220,14 @@ tap_flow_isolate(struct rte_eth_dev *dev,
 		 int set,
 		 struct rte_flow_error *error);
 
+static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx);
+static int rss_enable(struct pmd_internals *pmd,
+			const struct rte_flow_attr *attr,
+			struct rte_flow_error *error);
+static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
+			const struct rte_flow_action_rss *rss,
+			struct rte_flow_error *error);
+
 static const struct rte_flow_ops tap_flow_ops = {
 	.validate = tap_flow_validate,
 	.create = tap_flow_create,
@@ -816,111 +910,95 @@ tap_flow_item_validate(const struct rte_flow_item *item,
 }
 
 /**
- * Transform a DROP/PASSTHRU action item in the provided flow for TC.
+ * Configure the kernel with a TC action and its configured parameters
+ * Handled actions: "gact", "mirred", "skbedit", "bpf"
  *
- * @param[in, out] flow
- *   Flow to be filled.
- * @param[in] action
- *   Appropriate action to be set in the TCA_GACT_PARMS structure.
+ * @param[in] flow
+ *   Pointer to rte flow containing the netlink message
  *
- * @return
- *   0 if checks are alright, -1 otherwise.
- */
-static int
-add_action_gact(struct rte_flow *flow, int action)
-{
-	struct nlmsg *msg = &flow->msg;
-	size_t act_index = 1;
-	struct tc_gact p = {
-		.action = action
-	};
-
-	if (nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
-		return -1;
-	if (nlattr_nested_start(msg, act_index++) < 0)
-		return -1;
-	nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("gact"), "gact");
-	if (nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
-		return -1;
-	nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(p), &p);
-	nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
-	nlattr_nested_finish(msg); /* nested act_index */
-	nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
-	return 0;
-}
-
-/**
- * Transform a MIRRED action item in the provided flow for TC.
+ * @param[in, out] act_index
+ *   Pointer to action sequence number in the TC command
  *
- * @param[in, out] flow
- *   Flow to be filled.
- * @param[in] ifindex
- *   Netdevice ifindex, where to mirror/redirect packet to.
- * @param[in] action_type
- *   Either TCA_EGRESS_REDIR for redirection or TCA_EGRESS_MIRROR for mirroring.
+ * @param[in] adata
+ *  Pointer to struct holding the action parameters
  *
  * @return
- *   0 if checks are alright, -1 otherwise.
+ *   -1 on failure, 0 on success
  */
 static int
-add_action_mirred(struct rte_flow *flow, uint16_t ifindex, uint16_t action_type)
+add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
 {
 	struct nlmsg *msg = &flow->msg;
-	size_t act_index = 1;
-	struct tc_mirred p = {
-		.eaction = action_type,
-		.ifindex = ifindex,
-	};
 
-	if (nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
-		return -1;
-	if (nlattr_nested_start(msg, act_index++) < 0)
+	if (nlattr_nested_start(msg, (*act_index)++) < 0)
 		return -1;
-	nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("mirred"), "mirred");
+
+	nlattr_add(&msg->nh, TCA_ACT_KIND, strlen(adata->id) + 1, adata->id);
 	if (nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
 		return -1;
-	if (action_type == TCA_EGRESS_MIRROR)
-		p.action = TC_ACT_PIPE;
-	else /* REDIRECT */
-		p.action = TC_ACT_STOLEN;
-	nlattr_add(&msg->nh, TCA_MIRRED_PARMS, sizeof(p), &p);
+	if (strcmp("gact", adata->id) == 0) {
+		nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(adata->gact),
+			   &adata->gact);
+	} else if (strcmp("mirred", adata->id) == 0) {
+		if (adata->mirred.eaction == TCA_EGRESS_MIRROR)
+			adata->mirred.action = TC_ACT_PIPE;
+		else /* REDIRECT */
+			adata->mirred.action = TC_ACT_STOLEN;
+		nlattr_add(&msg->nh, TCA_MIRRED_PARMS, sizeof(adata->mirred),
+			   &adata->mirred);
+	} else if (strcmp("skbedit", adata->id) == 0) {
+		nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS,
+			   sizeof(adata->skbedit.skbedit),
+			   &adata->skbedit.skbedit);
+		nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING,
+			     adata->skbedit.queue);
+	} else if (strcmp("bpf", adata->id) == 0) {
+		nlattr_add32(&msg->nh, TCA_ACT_BPF_FD, adata->bpf.bpf_fd);
+		nlattr_add(&msg->nh, TCA_ACT_BPF_NAME,
+			   strlen(adata->bpf.annotation) + 1,
+			   adata->bpf.annotation);
+		nlattr_add(&msg->nh, TCA_ACT_BPF_PARMS,
+			   sizeof(adata->bpf.bpf),
+			   &adata->bpf.bpf);
+	} else {
+		return -1;
+	}
 	nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
 	nlattr_nested_finish(msg); /* nested act_index */
-	nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
 	return 0;
 }
 
 /**
- * Transform a QUEUE action item in the provided flow for TC.
+ * Helper function to send a serie of TC actions to the kernel
  *
- * @param[in, out] flow
- *   Flow to be filled.
- * @param[in] queue
- *   Queue id to use.
+ * @param[in] flow
+ *   Pointer to rte flow containing the netlink message
+ *
+ * @param[in] nb_actions
+ *   Number of actions in an array of action structs
+ *
+ * @param[in] data
+ *   Pointer to an array of action structs
+ *
+ * @param[in] classifier_actions
+ *   The classifier on behave of which the actions are configured
  *
  * @return
- *   0 if checks are alright, -1 otherwise.
+ *   -1 on failure, 0 on success
  */
 static int
-add_action_skbedit(struct rte_flow *flow, uint16_t queue)
+add_actions(struct rte_flow *flow, int nb_actions, struct action_data *data,
+	    int classifier_action)
 {
 	struct nlmsg *msg = &flow->msg;
 	size_t act_index = 1;
-	struct tc_skbedit p = {
-		.action = TC_ACT_PIPE
-	};
+	int i;
 
-	if (nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
-		return -1;
-	if (nlattr_nested_start(msg, act_index++) < 0)
+	if (nlattr_nested_start(msg, classifier_action) < 0)
 		return -1;
-	nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("skbedit"), "skbedit");
-	if (nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
-		return -1;
-	nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS, sizeof(p), &p);
-	nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING, queue);
-	nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
-	nlattr_nested_finish(msg); /* nested act_index */
+	for (i = 0; i < nb_actions; i++)
+		if (add_action(flow, &act_index, data + i) < 0)
+			return -1;
 	nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
 	return 0;
 }
@@ -984,7 +1062,8 @@ priv_flow_process(struct pmd_internals *pmd,
 		return -rte_errno;
 	} else if (flow) {
 		uint16_t group = attr->group << GROUP_SHIFT;
-		uint16_t prio = group | (attr->priority + PRIORITY_OFFSET);
+		uint16_t prio = group | (attr->priority +
+				RSS_PRIORITY_OFFSET + PRIORITY_OFFSET);
 		flow->msg.t.tcm_info = TC_H_MAKE(prio << 16,
 						 flow->msg.t.tcm_info);
 	}
@@ -1053,7 +1132,12 @@ priv_flow_process(struct pmd_internals *pmd,
 		}
 	}
 	if (mirred && flow) {
-		uint16_t if_index = pmd->if_index;
+		struct action_data adata = {
+			.id = "mirred",
+			.mirred = {
+				.eaction = mirred,
+			},
+		};
 
 		/*
 		 * If attr->egress && mirred, then this is a special
@@ -1061,9 +1145,13 @@ priv_flow_process(struct pmd_internals *pmd,
 		 * redirect packets coming from the DPDK App, out
 		 * through the remote netdevice.
 		 */
-		if (attr->egress)
-			if_index = pmd->remote_if_index;
-		if (add_action_mirred(flow, if_index, mirred) < 0)
+		adata.mirred.ifindex = attr->ingress ? pmd->if_index :
+			pmd->remote_if_index;
+		if (mirred == TCA_EGRESS_MIRROR)
+			adata.mirred.action = TC_ACT_PIPE;
+		else
+			adata.mirred.action = TC_ACT_STOLEN;
+		if (add_actions(flow, 1, &adata, TCA_FLOWER_ACT) < 0)
 			goto exit_action_not_supported;
 		else
 			goto end;
@@ -1077,14 +1165,33 @@ priv_flow_process(struct pmd_internals *pmd,
 			if (action)
 				goto exit_action_not_supported;
 			action = 1;
-			if (flow)
-				err = add_action_gact(flow, TC_ACT_SHOT);
+			if (flow) {
+				struct action_data adata = {
+					.id = "gact",
+					.gact = {
+						.action = TC_ACT_SHOT,
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+						  TCA_FLOWER_ACT);
+			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_PASSTHRU) {
 			if (action)
 				goto exit_action_not_supported;
 			action = 1;
-			if (flow)
-				err = add_action_gact(flow, TC_ACT_UNSPEC);
+			if (flow) {
+				struct action_data adata = {
+					.id = "gact",
+					.gact = {
+						/* continue */
+						.action = TC_ACT_UNSPEC,
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+						  TCA_FLOWER_ACT);
+			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
 			const struct rte_flow_action_queue *queue =
 				(const struct rte_flow_action_queue *)
@@ -1096,22 +1203,35 @@ priv_flow_process(struct pmd_internals *pmd,
 			if (!queue ||
 			    (queue->index > pmd->dev->data->nb_rx_queues - 1))
 				goto exit_action_not_supported;
-			if (flow)
-				err = add_action_skbedit(flow, queue->index);
+			if (flow) {
+				struct action_data adata = {
+					.id = "skbedit",
+					.skbedit = {
+						.skbedit = {
+							.action = TC_ACT_PIPE,
+						},
+						.queue = queue->index,
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+					TCA_FLOWER_ACT);
+			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
-			/* Fake RSS support. */
 			const struct rte_flow_action_rss *rss =
 				(const struct rte_flow_action_rss *)
 				actions->conf;
 
-			if (action)
-				goto exit_action_not_supported;
-			action = 1;
-			if (!rss || rss->num < 1 ||
-			    (rss->queue[0] > pmd->dev->data->nb_rx_queues - 1))
+			if (action++)
 				goto exit_action_not_supported;
-			if (flow)
-				err = add_action_skbedit(flow, rss->queue[0]);
+
+			if (!pmd->rss_enabled) {
+				err = rss_enable(pmd, attr, error);
+				if (err)
+					goto exit_action_not_supported;
+			}
+			if (rss)
+				err = rss_add_actions(flow, pmd, rss, error);
 		} else {
 			goto exit_action_not_supported;
 		}
@@ -1323,6 +1443,7 @@ tap_flow_destroy_pmd(struct pmd_internals *pmd,
 		     struct rte_flow_error *error)
 {
 	struct rte_flow *remote_flow = flow->remote_flow;
+	int i;
 	int ret = 0;
 
 	LIST_REMOVE(flow, next);
@@ -1348,6 +1469,13 @@ tap_flow_destroy_pmd(struct pmd_internals *pmd,
 			"couldn't receive kernel ack to our request");
 		goto end;
 	}
+	/* Close opened BPF file descriptors of this flow */
+	for (i = 0; i < SEC_MAX; i++)
+		if (flow->bpf_fd[i] != 0) {
+			close(flow->bpf_fd[i]);
+			flow->bpf_fd[i] = 0;
+		}
+
 	if (remote_flow) {
 		remote_flow->msg.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
 		remote_flow->msg.nh.nlmsg_type = RTM_DELTFILTER;
@@ -1632,6 +1760,313 @@ tap_flow_implicit_flush(struct pmd_internals *pmd, struct rte_flow_error *error)
 	return 0;
 }
 
+#define MAX_RSS_KEYS 256
+#define SEC_NAME_CLS_Q "cls_q"
+
+const char *sec_name[SEC_MAX] = {
+	[SEC_L3_L4] = "l3_l4",
+};
+
+/**
+ * Enable RSS on tap: create TC rules for queuing.
+ *
+ * @param[in, out] pmd
+ *   Pointer to private structure.
+ *
+ * @param[in] attr
+ *   Pointer to rte_flow to get flow group
+ *
+ * @param[out] error
+ *   Pointer to error reporting if not NULL.
+ *
+ * @return 0 on success, negative value on failure.
+ */
+static int rss_enable(struct pmd_internals *pmd,
+			const struct rte_flow_attr *attr,
+			struct rte_flow_error *error)
+{
+	struct rte_flow *rss_flow = NULL;
+	struct nlmsg *msg = NULL;
+	/* 4096 is the maximum number of instructions for a BPF program */
+	char annotation[64];
+	int i;
+	int err = 0;
+
+	 /* Get a new map key for a new RSS rule */
+	err = bpf_rss_key(KEY_CMD_INIT, NULL);
+	if (err < 0) {
+		rte_flow_error_set(
+			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Failed to initialize BPF RSS keys");
+
+		return -1;
+	}
+
+	/*
+	 *  Create BPF RSS MAP
+	 */
+	pmd->map_fd = tap_flow_bpf_rss_map_create(sizeof(__u32), /* key size */
+				sizeof(struct rss_key),
+				MAX_RSS_KEYS);
+	if (pmd->map_fd < 0) {
+		RTE_LOG(ERR, PMD,
+			"Failed to create BPF map (%d): %s\n",
+				errno, strerror(errno));
+		rte_flow_error_set(
+			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Kernel too old or not configured "
+			"to support BPF maps");
+
+		return -ENOTSUP;
+	}
+
+	/*
+	 * Add a rule per queue to match reclassified packets and direct them to
+	 * the correct queue.
+	 */
+	for (i = 0; i < pmd->dev->data->nb_rx_queues; i++) {
+		pmd->bpf_fd[i] = tap_flow_bpf_cls_q(i);
+		if (pmd->bpf_fd[i] < 0) {
+			RTE_LOG(ERR, PMD,
+				"Failed to load BPF section %s for queue %d",
+				SEC_NAME_CLS_Q, i);
+			rte_flow_error_set(
+				error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
+				NULL,
+				"Kernel too old or not configured "
+				"to support BPF programs loading");
+
+			return -ENOTSUP;
+		}
+
+		rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
+		if (!rss_flow) {
+			RTE_LOG(ERR, PMD,
+				"Cannot allocate memory for rte_flow");
+			return -1;
+		}
+		msg = &rss_flow->msg;
+		tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER, NLM_F_REQUEST |
+			    NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE);
+		msg->t.tcm_info = TC_H_MAKE(0, htons(ETH_P_ALL));
+		tap_flow_set_handle(rss_flow);
+		uint16_t group = attr->group << GROUP_SHIFT;
+		uint16_t prio = group | (i + PRIORITY_OFFSET);
+		msg->t.tcm_info = TC_H_MAKE(prio << 16, msg->t.tcm_info);
+		msg->t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
+
+		nlattr_add(&msg->nh, TCA_KIND, sizeof("bpf"), "bpf");
+		if (nlattr_nested_start(msg, TCA_OPTIONS) < 0)
+			return -1;
+		nlattr_add32(&msg->nh, TCA_BPF_FD, pmd->bpf_fd[i]);
+		snprintf(annotation, sizeof(annotation), "[%s%d]",
+			SEC_NAME_CLS_Q, i);
+		nlattr_add(&msg->nh, TCA_BPF_NAME, strlen(annotation) + 1,
+			   annotation);
+		/* Actions */
+		{
+			struct action_data adata = {
+				.id = "skbedit",
+				.skbedit = {
+					.skbedit = {
+						.action = TC_ACT_PIPE,
+					},
+					.queue = i,
+				},
+			};
+			if (add_actions(rss_flow, 1, &adata, TCA_BPF_ACT) < 0)
+				return -1;
+		}
+		nlattr_nested_finish(msg); /* nested TCA_OPTIONS */
+
+		/* Netlink message is now ready to be sent */
+		if (nl_send(pmd->nlsk_fd, &msg->nh) < 0)
+			return -1;
+		err = nl_recv_ack(pmd->nlsk_fd);
+		if (err < 0) {
+			RTE_LOG(ERR, PMD,
+				"Kernel refused TC filter rule creation (%d): %s\n",
+				errno, strerror(errno));
+			return err;
+		}
+		LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
+	}
+
+	pmd->rss_enabled = 1;
+	return err;
+}
+
+/**
+ * Manage bpf RSS keys repository with operations: init, get, release
+ *
+ * @param[in] cmd
+ *   Command on RSS keys: init, get, release
+ *
+ * @param[in, out] key_idx
+ *   Pointer to RSS Key index (out for get command, in for release command)
+ *
+ * @return -1 if couldn't get, release or init the RSS keys, 0 otherwise.
+ */
+static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx)
+{
+	__u32 i;
+	int err = -1;
+	static __u32 num_used_keys;
+	static __u32 rss_keys[MAX_RSS_KEYS] = {KEY_STAT_UNSPEC};
+	static __u32 rss_keys_initialized;
+
+	switch (cmd) {
+	case KEY_CMD_GET:
+		if (!rss_keys_initialized)
+			break;
+
+		if (num_used_keys == ARRAY_SIZE(rss_keys))
+			break;
+
+		*key_idx = num_used_keys % ARRAY_SIZE(rss_keys);
+		while (rss_keys[*key_idx] == KEY_STAT_USED)
+			*key_idx = (*key_idx + 1) % ARRAY_SIZE(rss_keys);
+
+		rss_keys[*key_idx] = KEY_STAT_USED;
+		num_used_keys++;
+		err = 0;
+	break;
+
+	case KEY_CMD_RELEASE:
+		if (!rss_keys_initialized)
+			break;
+
+		if (rss_keys[*key_idx] == KEY_STAT_USED) {
+			rss_keys[*key_idx] = KEY_STAT_AVAILABLE;
+			num_used_keys--;
+			err = 0;
+		}
+	break;
+
+	case KEY_CMD_INIT:
+		for (i = 0; i < ARRAY_SIZE(rss_keys); i++)
+			rss_keys[i] = KEY_STAT_AVAILABLE;
+
+		rss_keys_initialized = 1;
+		num_used_keys = 0;
+		err = 0;
+	break;
+
+	case KEY_CMD_DEINIT:
+		for (i = 0; i < ARRAY_SIZE(rss_keys); i++)
+			rss_keys[i] = KEY_STAT_UNSPEC;
+
+		rss_keys_initialized = 0;
+		num_used_keys = 0;
+		err = 0;
+	break;
+
+	default:
+		break;
+	}
+
+	return err;
+}
+
+/**
+ * Add RSS hash calculations and queue selection
+ *
+ * @param[in, out] pmd
+ *   Pointer to internal structure. Used to set/get RSS map fd
+ *
+ * @param[in] rss
+ *   Pointer to RSS flow actions
+ *
+ * @param[out] error
+ *   Pointer to error reporting if not NULL.
+ *
+ * @return 0 on success, negative value on failure
+ */
+static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
+			   const struct rte_flow_action_rss *rss,
+			   struct rte_flow_error *error)
+{
+	/* 4096 is the maximum number of instructions for a BPF program */
+	int i;
+	__u32 key_idx;
+	int err;
+	struct rss_key rss_entry = { .hash_fields = 0,
+				     .key_size = 0 };
+
+	/* Get a new map key for a new RSS rule */
+	err = bpf_rss_key(KEY_CMD_GET, &key_idx);
+	if (err < 0) {
+		rte_flow_error_set(
+			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Failed to get BPF RSS key");
+
+		return -1;
+	}
+
+	/* Update RSS map entry with queues */
+	rss_entry.nb_queues = rss->num;
+	for (i = 0; i < rss->num; i++)
+		rss_entry.queues[i] = rss->queue[i];
+	rss_entry.hash_fields =
+		(1 << HASH_FIELD_IPV4_L3_L4) | (1 << HASH_FIELD_IPV6_L3_L4);
+
+	/* Add this RSS entry to map */
+	err = tap_flow_bpf_update_rss_elem(pmd->map_fd, &key_idx, &rss_entry);
+
+	if (err) {
+		RTE_LOG(ERR, PMD,
+			"Failed to update BPF map entry #%u (%d): %s\n",
+			key_idx, errno, strerror(errno));
+		rte_flow_error_set(
+			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Kernel too old or not configured "
+			"to support BPF maps updates");
+
+		return -ENOTSUP;
+	}
+
+
+	/*
+	 * Load bpf rules to calculate hash for this key_idx
+	 */
+
+	flow->bpf_fd[SEC_L3_L4] =
+		tap_flow_bpf_calc_l3_l4_hash(key_idx, pmd->map_fd);
+	if (flow->bpf_fd[SEC_L3_L4] < 0) {
+		RTE_LOG(ERR, PMD,
+			"Failed to load BPF section %s (%d): %s\n",
+				sec_name[SEC_L3_L4], errno, strerror(errno));
+		rte_flow_error_set(
+			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Kernel too old or not configured "
+			"to support BPF program loading");
+
+		return -ENOTSUP;
+	}
+
+	/* Actions */
+	{
+		struct action_data adata[] = {
+			{
+				.id = "bpf",
+				.bpf = {
+					.bpf_fd = flow->bpf_fd[SEC_L3_L4],
+					.annotation = sec_name[SEC_L3_L4],
+					.bpf = {
+						.action = TC_ACT_PIPE,
+					},
+				},
+			},
+		};
+
+		if (add_actions(flow, ARRAY_SIZE(adata), adata,
+			TCA_FLOWER_ACT) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
 /**
  * Manage filter operations.
  *
diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h
index 6cc01b4..dbb7ff6 100644
--- a/drivers/net/tap/tap_flow.h
+++ b/drivers/net/tap/tap_flow.h
@@ -37,6 +37,7 @@
 #include <rte_flow.h>
 #include <rte_flow_driver.h>
 #include <rte_eth_tap.h>
+#include <tap_autoconf.h>
 
 /**
  * In TC, priority 0 means we require the kernel to allocate one for us.
@@ -49,6 +50,7 @@
 #define GROUP_MASK (0xf)
 #define GROUP_SHIFT 12
 #define MAX_GROUP GROUP_MASK
+#define RSS_PRIORITY_OFFSET 256
 
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 
@@ -69,6 +71,11 @@ enum implicit_rule_index {
 	TAP_REMOTE_MAX_IDX,
 };
 
+enum bpf_fd_idx {
+	SEC_L3_L4,
+	SEC_MAX,
+};
+
 int tap_dev_filter_ctrl(struct rte_eth_dev *dev,
 			enum rte_filter_type filter_type,
 			enum rte_filter_op filter_op,
@@ -84,5 +91,8 @@ int tap_flow_implicit_flush(struct pmd_internals *pmd,
 
 int tap_flow_bpf_cls_q(__u32 queue_idx);
 int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd);
+int tap_flow_bpf_rss_map_create(unsigned int key_size, unsigned int value_size,
+			unsigned int max_entries);
+int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value);
 
 #endif /* _TAP_FLOW_H_ */
diff --git a/drivers/net/tap/tap_tcmsgs.h b/drivers/net/tap/tap_tcmsgs.h
index 7895957..07c5074 100644
--- a/drivers/net/tap/tap_tcmsgs.h
+++ b/drivers/net/tap/tap_tcmsgs.h
@@ -34,6 +34,7 @@
 #ifndef _TAP_TCMSGS_H_
 #define _TAP_TCMSGS_H_
 
+#include <tap_autoconf.h>
 #include <linux/if_ether.h>
 #include <linux/rtnetlink.h>
 #include <linux/pkt_sched.h>
@@ -41,6 +42,9 @@
 #include <linux/tc_act/tc_mirred.h>
 #include <linux/tc_act/tc_gact.h>
 #include <linux/tc_act/tc_skbedit.h>
+#ifdef HAVE_TC_ACT_BPF
+#include <linux/tc_act/tc_bpf.h>
+#endif
 #include <inttypes.h>
 
 #include <rte_ether.h>
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v3 0/2] TAP RSS eBPF cover letter
  2017-12-28 10:09 ` [dpdk-dev] [PATCH v2 0/2] TAP RSS eBPF cover letter Ophir Munk
  2017-12-28 10:09   ` [dpdk-dev] [PATCH v2 1/2] net/tap: add eBPF instructions to TAP device Ophir Munk
  2017-12-28 10:09   ` [dpdk-dev] [PATCH v2 2/2] net/tap: implement RSS with eBPF classifier and action Ophir Munk
@ 2018-01-10  7:06   ` Ophir Munk
  2018-01-10  7:06     ` [dpdk-dev] [PATCH v3 1/2] net/tap: add eBPF instructions to TAP device Ophir Munk
                       ` (3 more replies)
  2 siblings, 4 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-10  7:06 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

The patches of TAP RSS eBPF follow the RFC on this issue
https://dpdk.org/dev/patchwork/patch/31781/

v3 changes with respect to v2
=============================
* Add support for IPv6 RSS in BPF program
* Bug fixes
* Updated compatibility to kernel versions:
  eBPF requires Linux version 4.9 configured with BPF
* New license header (SPDX) for newly added files

v2 changes with respect to v1
=============================
* v2 has new commits organization (3 --> 2)
* BPF program was revised. It is successfully tested on
  IPv4 L3 L4 layers (compatible to mlx4 device)
* Licensing: no comments received for using "Dual BSD/GPL"
  string during BPF program loading to the kernel.
  (v1 and v2 are using the same license strings)
  Any comments are welcome.
* Compatibility to kernel versions:
  eBPF requires Linux version 4.2 configured with BPF. TAP PMD will
  successfully compile on systems with old or non-BPF configured kernels.
  During compilation time the required Linux headers are searched for.
  If they are not present missing definitions are locally added
  (tap_autoconf.h).
  If the kernel cannot support a BPF operation - at runtime it will
  gracefully reject the netlink message (with BPF) sent to it.

Commit #1:
net/tap: add eBPF instructions to TAP device
===========================================
  This commit introduces BPF program (tap_bpf_program.c)
  with a classifier and an action sections.
  The current implementation calculates RSS hash
  over L3 addresses and L4 ports.
  BPF program compilation is not part of dpdk compilation.
  This commit includes the eBPF machine instructions
  in the format of C arrays (tap_bpf_insns.c).

  The option to update the BPF program and download new machine
  instructions will be described in another commit.

Commit #2:
net/tap: implement RSS with eBPF classifier and action
======================================================
This commit builds and sends netlink messages to the kernel
that include BPF programs.
There is a single BPF classifier for each TAP queue. Packets
marked with an RSS queue will be directed to this queue using a traffic
control with "skbedit" action otherwise they will be pipelined to
the following rules.
There is a single BPF action for each RSS rule (may add more
to support IPv6).
The action is to calculate Toeplitz hash based on L3 addresses and L4 ports,
mark the packet with the RSS queue according the resulting hash,
then reclassify the packet.
Ophir Munk (2):
  net/tap: add eBPF instructions to TAP device
  net/tap: implement RSS with eBPF classifier and action

 drivers/net/tap/Makefile          |   31 +
 drivers/net/tap/rte_eth_tap.h     |    9 +-
 drivers/net/tap/tap_bpf.h         |   92 ++
 drivers/net/tap/tap_bpf_insns.c   | 1905 +++++++++++++++++++++++++++++++++++++
 drivers/net/tap/tap_bpf_program.c |  221 +++++
 drivers/net/tap/tap_flow.c        |  635 +++++++++++--
 drivers/net/tap/tap_flow.h        |   15 +
 drivers/net/tap/tap_rss.h         |   32 +
 drivers/net/tap/tap_tcmsgs.h      |    4 +
 9 files changed, 2848 insertions(+), 96 deletions(-)
 create mode 100644 drivers/net/tap/tap_bpf.h
 create mode 100644 drivers/net/tap/tap_bpf_insns.c
 create mode 100644 drivers/net/tap/tap_bpf_program.c
 create mode 100644 drivers/net/tap/tap_rss.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v3 1/2] net/tap: add eBPF instructions to TAP device
  2018-01-10  7:06   ` [dpdk-dev] [PATCH v3 0/2] TAP RSS eBPF cover letter Ophir Munk
@ 2018-01-10  7:06     ` Ophir Munk
  2018-01-10  9:34       ` Pascal Mazon
  2018-01-10  7:06     ` [dpdk-dev] [PATCH v3 2/2] net/tap: implement RSS with eBPF classifier and action Ophir Munk
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 42+ messages in thread
From: Ophir Munk @ 2018-01-10  7:06 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

TAP PMD is required to support RSS queue mapping based on rte_flow API. An
example usage for this requirement is failsafe transparent switching from a
PCI device to TAP device while keep redirecting packets to the same RSS
queues on both devices.

TAP RSS implementation is based on eBPF programs sent to Linux kernel
through BPF system calls and using netlink messages to reference the
programs as part of traffic control commands.

An eBPF program acts as a traffic control classifier or action. Each
program is written in C code under a different ELF section name. Clang 3.7
is used to compile the C code into eBPF-formatted object file. The ELF file
is parsed and its sections (programs) can be downloaded to the kernel using
BPF system call. The BPF system call parameters contain the array of eBPF
instructions. This commit includes BPF classifier and action programs
(tap_bpf_program.c) as reference and their corresponding arrays of eBPF
instructions (tap_bpf_insns.c). The reference file does not take part in
dpdk compilation. The details on how to generate new eBPF code will be
presented in another commit.

In a follow up commit TAP PMD will use the eBPF programs to implement RSS
flow rules.

TAP eBPF requires Linux version 4.9 configured with BPF. TAP PMD will
successfully compile on systems with old or non-BPF configured kernels but
RSS rules creation on TAP devices will not be supported.

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 drivers/net/tap/Makefile          |   11 +
 drivers/net/tap/tap_bpf.h         |   96 ++
 drivers/net/tap/tap_bpf_insns.c   | 1845 +++++++++++++++++++++++++++++++++++++
 drivers/net/tap/tap_bpf_program.c |  221 +++++
 drivers/net/tap/tap_flow.h        |    5 +
 5 files changed, 2178 insertions(+)
 create mode 100644 drivers/net/tap/tap_bpf.h
 create mode 100644 drivers/net/tap/tap_bpf_insns.c
 create mode 100644 drivers/net/tap/tap_bpf_program.c

diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index fd4195f..feaa5b7 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -12,6 +12,9 @@ EXPORT_MAP := rte_pmd_tap_version.map
 
 LIBABIVER := 1
 
+# TAP_MAX_QUEUES must be a power of 2 as it will be used for masking */
+TAP_MAX_QUEUES = 16
+
 CFLAGS += -O3
 CFLAGS += -I$(SRCDIR)
 CFLAGS += -I.
@@ -20,6 +23,8 @@ LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
 LDLIBS += -lrte_bus_vdev
 
+CFLAGS += -DTAP_MAX_QUEUES=$(TAP_MAX_QUEUES)
+
 #
 # all source are stored in SRCS-y
 #
@@ -27,6 +32,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += rte_eth_tap.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_flow.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_netlink.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_tcmsgs.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_bpf_insns.c
 
 include $(RTE_SDK)/mk/rte.lib.mk
 
@@ -53,6 +59,11 @@ tap_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
 		linux/pkt_cls.h \
 		enum TCA_FLOWER_KEY_VLAN_PRIO \
 		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_BPF_PROG_LOAD \
+		linux/bpf.h \
+		enum BPF_PROG_LOAD \
+		$(AUTOCONF_OUTPUT)
 
 # Create tap_autoconf.h or update it in case it differs from the new one.
 
diff --git a/drivers/net/tap/tap_bpf.h b/drivers/net/tap/tap_bpf.h
new file mode 100644
index 0000000..82775b7
--- /dev/null
+++ b/drivers/net/tap/tap_bpf.h
@@ -0,0 +1,96 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#ifndef __TAP_BPF_H__
+#define __TAP_BPF_H__
+
+#include <tap_autoconf.h>
+
+#ifdef HAVE_BPF_PROG_LOAD
+#include <linux/bpf.h>
+#else
+/* BPF_MAP_UPDATE_ELEM command flags */
+#define	BPF_ANY	0 /* create a new element or update an existing */
+
+/* BPF architecture instruction struct */
+struct bpf_insn {
+	__u8	code;
+	__u8	dst_reg:4;
+	__u8	src_reg:4;
+	__s16	off;
+	__s32	imm; /* immediate value */
+};
+
+/* BPF program types */
+enum bpf_prog_type {
+	BPF_PROG_TYPE_UNSPEC,
+	BPF_PROG_TYPE_SOCKET_FILTER,
+	BPF_PROG_TYPE_KPROBE,
+	BPF_PROG_TYPE_SCHED_CLS,
+	BPF_PROG_TYPE_SCHED_ACT,
+};
+
+/* BPF commands types */
+enum bpf_cmd {
+	BPF_MAP_CREATE,
+	BPF_MAP_LOOKUP_ELEM,
+	BPF_MAP_UPDATE_ELEM,
+	BPF_MAP_DELETE_ELEM,
+	BPF_MAP_GET_NEXT_KEY,
+	BPF_PROG_LOAD,
+};
+
+/* BPF maps types */
+enum bpf_map_type {
+	BPF_MAP_TYPE_UNSPEC,
+	BPF_MAP_TYPE_HASH,
+};
+
+/* union of anonymous structs used with TAP BPF commands */
+union bpf_attr {
+	/* BPF_MAP_CREATE command */
+	struct {
+		__u32	map_type;
+		__u32	key_size;
+		__u32	value_size;
+		__u32	max_entries;
+		__u32	map_flags;
+		__u32	inner_map_fd;
+	};
+
+	/* BPF_MAP_UPDATE_ELEM, BPF_MAP_DELETE_ELEM commands */
+	struct {
+		__u32		map_fd;
+		__aligned_u64	key;
+		union {
+			__aligned_u64 value;
+			__aligned_u64 next_key;
+		};
+		__u64		flags;
+	};
+
+	/* BPF_PROG_LOAD command */
+	struct {
+		__u32		prog_type;
+		__u32		insn_cnt;
+		__aligned_u64	insns;
+		__aligned_u64	license;
+		__u32		log_level;
+		__u32		log_size;
+		__aligned_u64	log_buf;
+		__u32		kern_version;
+		__u32		prog_flags;
+	};
+} __attribute__((aligned(8)));
+#endif
+
+enum {
+	BPF_MAP_ID_KEY,
+	BPF_MAP_ID_SIMPLE,
+};
+
+static int bpf_load(enum bpf_prog_type type, const struct bpf_insn *insns,
+		size_t insns_cnt, const char *license);
+
+#endif /* __TAP_BPF_H__ */
diff --git a/drivers/net/tap/tap_bpf_insns.c b/drivers/net/tap/tap_bpf_insns.c
new file mode 100644
index 0000000..25aa82c
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_insns.c
@@ -0,0 +1,1845 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/queue.h>
+#include <sys/mount.h>
+
+#include <rte_byteorder.h>
+#include <rte_jhash.h>
+#include <rte_malloc.h>
+#include <rte_eth_tap.h>
+#include <tap_flow.h>
+#include <tap_autoconf.h>
+#include <tap_tcmsgs.h>
+#include <tap_bpf.h>
+
+#define ERROR                   0
+
+/*
+ * The queue number is offset by 1, to distinguish packets that have
+ * gone through this rule (skb->cb[1] != 0) from others.
+ */
+#define QUEUE_OFFSET 1
+
+/* bpf_insn array matching cls_q section. See tap_bpf_program.c file */
+static struct bpf_insn cls_q_insns[] = {
+	{0x61,    1,    1,       52, 0x00000000},
+	{0x18,    2,    0,        0, 0xdeadbeef},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0x63,   10,    2,       -4, 0x00000000},
+	{0x61,    2,   10,       -4, 0x00000000},
+	{0x07,    2,    0,        0, 0x00000001},
+	{0x67,    2,    0,        0, 0x00000020},
+	{0x77,    2,    0,        0, 0x00000020},
+	{0xb7,    0,    0,        0, 0xffffffff},
+	{0x1d,    1,    2,        1, 0x00000000},
+	{0xb7,    0,    0,        0, 0x00000000},
+	{0x95,    0,    0,        0, 0x00000000},
+};
+
+/**
+ * Load BPF program (section cls_q) into the kernel and return a bpf fd
+ *
+ * @param queue_idx
+ *   Queue index matching packet cb
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int tap_flow_bpf_cls_q(__u32 queue_idx)
+{
+	cls_q_insns[1].imm = queue_idx;
+
+	return bpf_load(BPF_PROG_TYPE_SCHED_CLS,
+		(struct bpf_insn *)cls_q_insns,
+		ARRAY_SIZE(cls_q_insns),
+		"Dual BSD/GPL");
+}
+
+/* bpf_insn array matching l3_l4 section. see tap_bpf_program.c file */
+static struct bpf_insn l3_l4_hash_insns[] = {
+	{0xbf,    7,    1,        0, 0x00000000},
+	{0x61,    8,    7,       16, 0x00000000},
+	{0x61,    6,    7,       76, 0x00000000},
+	{0x61,    9,    7,       80, 0x00000000},
+	{0x18,    1,    0,        0, 0xdeadbeef},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0x63,   10,    1,       -4, 0x00000000},
+	{0xbf,    2,   10,        0, 0x00000000},
+	{0x07,    2,    0,        0, 0xfffffffc},
+	{0x18,    1,    1,        0, 0x0000cafe},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0x85,    0,    0,        0, 0x00000001},
+	{0x55,    0,    0,       21, 0x00000000},
+	{0xb7,    1,    0,        0, 0x00000a64},
+	{0x6b,   10,    1,      -16, 0x00000000},
+	{0x18,    1,    0,        0, 0x69666e6f},
+	{0x00,    0,    0,        0, 0x65727567},
+	{0x7b,   10,    1,      -24, 0x00000000},
+	{0x18,    1,    0,        0, 0x6e207369},
+	{0x00,    0,    0,        0, 0x6320746f},
+	{0x7b,   10,    1,      -32, 0x00000000},
+	{0x18,    1,    0,        0, 0x20737372},
+	{0x00,    0,    0,        0, 0x2079656b},
+	{0x7b,   10,    1,      -40, 0x00000000},
+	{0x18,    1,    0,        0, 0x68736168},
+	{0x00,    0,    0,        0, 0x203a2928},
+	{0x7b,   10,    1,      -48, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0x73,   10,    7,      -14, 0x00000000},
+	{0xbf,    1,   10,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0xffffffd0},
+	{0xb7,    2,    0,        0, 0x00000023},
+	{0x85,    0,    0,        0, 0x00000006},
+	{0x05,    0,    0,     1632, 0x00000000},
+	{0xb7,    1,    0,        0, 0x0000000e},
+	{0x61,    2,    7,       20, 0x00000000},
+	{0x15,    2,    0,       10, 0x00000000},
+	{0x61,    2,    7,       28, 0x00000000},
+	{0x55,    2,    0,        8, 0x0000a888},
+	{0xbf,    2,    7,        0, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0xbf,    1,    6,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0x00000012},
+	{0x2d,    1,    9,     1622, 0x00000000},
+	{0xb7,    1,    0,        0, 0x00000012},
+	{0x69,    8,    6,       16, 0x00000000},
+	{0xbf,    7,    2,        0, 0x00000000},
+	{0x7b,   10,    7,      -56, 0x00000000},
+	{0x57,    8,    0,        0, 0x0000ffff},
+	{0x15,    8,    0,      409, 0x0000dd86},
+	{0xb7,    7,    0,        0, 0x00000003},
+	{0x55,    8,    0,     1614, 0x00000008},
+	{0x0f,    6,    1,        0, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0xbf,    1,    6,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0x00000018},
+	{0x2d,    1,    9,     1609, 0x00000000},
+	{0x71,    3,    6,       12, 0x00000000},
+	{0xbf,    1,    3,        0, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000038},
+	{0xc7,    1,    0,        0, 0x00000020},
+	{0x77,    1,    0,        0, 0x0000001f},
+	{0x57,    1,    0,        0, 0x2cc681d1},
+	{0x67,    3,    0,        0, 0x00000018},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x40000000},
+	{0xb7,    2,    0,        0, 0x00000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x598d03a2},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x20000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb31a0745},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x10000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x66340e8a},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x08000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcc681d15},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x04000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x98d03a2b},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x02000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x31a07456},
+	{0x57,    3,    0,        0, 0x01000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6340e8ad},
+	{0x71,    3,    6,       13, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000010},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00800000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc681d15b},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00400000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d03a2b7},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00200000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1a07456f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00100000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x340e8ade},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00080000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x681d15bd},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00040000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd03a2b7b},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00020000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa07456f6},
+	{0x57,    3,    0,        0, 0x00010000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x40e8aded},
+	{0x71,    3,    6,       14, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00008000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x81d15bdb},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00004000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x03a2b7b7},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00002000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x07456f6f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00001000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0e8adedf},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000800},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1d15bdbf},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000400},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3a2b7b7e},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000200},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7456f6fd},
+	{0x57,    3,    0,        0, 0x00000100},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe8adedfa},
+	{0x71,    3,    6,       15, 0x00000000},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000080},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd15bdbf4},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000040},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa2b7b7e9},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000020},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x456f6fd3},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000010},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8adedfa7},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000008},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x15bdbf4f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000004},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2b7b7e9e},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000002},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x56f6fd3d},
+	{0x57,    3,    0,        0, 0x00000001},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xadedfa7b},
+	{0x71,    4,    6,       16, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000038},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0xb7,    3,    0,        0, 0xffffffff},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5bdbf4f7},
+	{0x67,    4,    0,        0, 0x00000018},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb7b7e9ef},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6f6fd3df},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdedfa7bf},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbdbf4f7f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7b7e9eff},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf6fd3dff},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xedfa7bfe},
+	{0x71,    4,    6,       17, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000010},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdbf4f7fc},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb7e9eff9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6fd3dff2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdfa7bfe5},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbf4f7fca},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7e9eff94},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfd3dff28},
+	{0x57,    4,    0,        0, 0x00010000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfa7bfe51},
+	{0x71,    4,    6,       18, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000008},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf4f7fca2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe9eff945},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd3dff28a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa7bfe514},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4f7fca28},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9eff9450},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3dff28a0},
+	{0x57,    4,    0,        0, 0x00000100},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7bfe5141},
+	{0x71,    4,    6,       19, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf7fca283},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xeff94506},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdff28a0c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbfe51418},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7fca2831},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff945063},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff28a0c6},
+	{0x57,    4,    0,        0, 0x00000001},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfe51418c},
+	{0x71,    4,    6,       20, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000008},
+	{0x71,    5,    6,       21, 0x00000000},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000030},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfca28319},
+	{0x67,    4,    0,        0, 0x00000010},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x40000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf9450633},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x20000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf28a0c67},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x10000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe51418ce},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x08000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xca28319d},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x04000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9450633b},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x02000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28a0c676},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x01000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x51418ced},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00800000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa28319db},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00400000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x450633b6},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00200000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8a0c676c},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00100000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1418ced8},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00080000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28319db1},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00040000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x50633b63},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00020000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa0c676c6},
+	{0x57,    4,    0,        0, 0x00010000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x418ced8d},
+	{0x71,    3,    6,       22, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00008000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8319db1a},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00004000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0633b634},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00002000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0c676c68},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00001000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x18ced8d1},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000800},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x319db1a3},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000400},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x633b6347},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000200},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc676c68f},
+	{0x57,    3,    0,        0, 0x00000100},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8ced8d1f},
+	{0x71,    3,    6,       23, 0x00000000},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000080},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x19db1a3e},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000040},
+	{0x79,    5,   10,      -56, 0x00000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x33b6347d},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000020},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x676c68fa},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000010},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xced8d1f4},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000008},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9db1a3e9},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000004},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3b6347d2},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000002},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x76c68fa5},
+	{0x57,    3,    0,        0, 0x00000001},
+	{0x1d,    3,    2,     1177, 0x00000000},
+	{0xa7,    1,    0,        0, 0xed8d1f4a},
+	{0x05,    0,    0,     1175, 0x00000000},
+	{0x0f,    6,    1,        0, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0xbf,    1,    6,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0x0000002c},
+	{0x2d,    1,    9,     1202, 0x00000000},
+	{0x61,    4,    6,        8, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000038},
+	{0xc7,    1,    0,        0, 0x00000020},
+	{0x77,    1,    0,        0, 0x0000001f},
+	{0x57,    1,    0,        0, 0x2cc681d1},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000040},
+	{0xb7,    2,    0,        0, 0x00000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x598d03a2},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000020},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb31a0745},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000010},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x66340e8a},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000008},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcc681d15},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000004},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x98d03a2b},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000002},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x31a07456},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000001},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6340e8ad},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00008000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc681d15b},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00004000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d03a2b7},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00002000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1a07456f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00001000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x340e8ade},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000800},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x681d15bd},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000400},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd03a2b7b},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000200},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa07456f6},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000100},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x40e8aded},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00800000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x81d15bdb},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00400000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x03a2b7b7},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00200000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x07456f6f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00100000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0e8adedf},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00080000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1d15bdbf},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00040000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3a2b7b7e},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00020000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7456f6fd},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00010000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe8adedfa},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0xb7,    3,    0,        0, 0xffffffff},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd15bdbf4},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa2b7b7e9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x456f6fd3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8adedfa7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x15bdbf4f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2b7b7e9e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x56f6fd3d},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xadedfa7b},
+	{0x61,    4,    6,       12, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5bdbf4f7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb7b7e9ef},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6f6fd3df},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdedfa7bf},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbdbf4f7f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7b7e9eff},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf6fd3dff},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xedfa7bfe},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdbf4f7fc},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb7e9eff9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6fd3dff2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdfa7bfe5},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbf4f7fca},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7e9eff94},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfd3dff28},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfa7bfe51},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf4f7fca2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe9eff945},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd3dff28a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa7bfe514},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4f7fca28},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9eff9450},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3dff28a0},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7bfe5141},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf7fca283},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xeff94506},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdff28a0c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbfe51418},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7fca2831},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff945063},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff28a0c6},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfe51418c},
+	{0x61,    4,    6,       16, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfca28319},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf9450633},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf28a0c67},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe51418ce},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xca28319d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9450633b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28a0c676},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x51418ced},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa28319db},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x450633b6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8a0c676c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1418ced8},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28319db1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x50633b63},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa0c676c6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x418ced8d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8319db1a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0633b634},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0c676c68},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x18ced8d1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x319db1a3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x633b6347},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc676c68f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8ced8d1f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x19db1a3e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x33b6347d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x676c68fa},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xced8d1f4},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9db1a3e9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3b6347d2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x76c68fa5},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xed8d1f4a},
+	{0x61,    4,    6,       20, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdb1a3e94},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb6347d28},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6c68fa51},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd8d1f4a3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb1a3e946},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6347d28d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc68fa51a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d1f4a35},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1a3e946b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x347d28d7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x68fa51ae},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd1f4a35c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa3e946b9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x47d28d73},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8fa51ae7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1f4a35cf},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3e946b9e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7d28d73c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfa51ae78},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf4a35cf1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe946b9e3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd28d73c7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa51ae78e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4a35cf1c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x946b9e38},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28d73c71},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x51ae78e3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa35cf1c6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x46b9e38d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d73c71b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1ae78e36},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x35cf1c6c},
+	{0x61,    4,    6,       24, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6b9e38d9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd73c71b2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xae78e364},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5cf1c6c9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb9e38d92},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x73c71b25},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe78e364b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcf1c6c96},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9e38d92c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3c71b259},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x78e364b2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf1c6c964},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe38d92c9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc71b2593},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8e364b27},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1c6c964e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x38d92c9c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x71b25938},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe364b270},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc6c964e0},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d92c9c0},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1b259380},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x364b2700},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6c964e01},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd92c9c03},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb2593807},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x64b2700f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc964e01e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x92c9c03d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2593807a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4b2700f4},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x964e01e8},
+	{0x61,    4,    6,       28, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2c9c03d1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x593807a3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb2700f46},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x64e01e8d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc9c03d1a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x93807a35},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2700f46b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4e01e8d6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9c03d1ad},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3807a35b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x700f46b6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe01e8d6c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc03d1ad9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x807a35b3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x00f46b66},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x01e8d6cc},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x03d1ad99},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x07a35b32},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0f46b665},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1e8d6cca},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3d1ad994},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7a35b328},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf46b6651},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe8d6cca2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd1ad9944},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa35b3289},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x46b66512},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d6cca25},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1ad9944a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x35b32894},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6b665129},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd6cca253},
+	{0x61,    4,    6,       32, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xad9944a7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5b32894f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb665129f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6cca253e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd9944a7d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb32894fb},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x665129f6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcca253ec},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9944a7d9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x32894fb2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x65129f65},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xca253eca},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x944a7d95},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2894fb2a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5129f655},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa253ecab},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x44a7d956},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x894fb2ac},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x129f6558},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x253ecab1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4a7d9563},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x94fb2ac7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x29f6558f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x53ecab1e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa7d9563d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4fb2ac7a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9f6558f5},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3ecab1ea},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7d9563d5},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfb2ac7ab},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf6558f56},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xecab1eac},
+	{0x61,    4,    6,       36, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd9563d59},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb2ac7ab2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6558f564},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcab1eac8},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9563d590},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2ac7ab20},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x558f5641},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xab1eac83},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x563d5906},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xac7ab20c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x58f56418},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb1eac831},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x63d59063},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc7ab20c7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8f56418f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1eac831e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3d59063c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7ab20c78},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf56418f0},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xeac831e1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd59063c2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xab20c784},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x56418f09},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xac831e12},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x59063c25},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb20c784b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6418f097},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc831e12f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9063c25f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x20c784be},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x418f097c},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x831e12f9},
+	{0x71,    4,    6,       40, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000008},
+	{0x71,    5,    6,       41, 0x00000000},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000030},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x063c25f3},
+	{0x67,    4,    0,        0, 0x00000010},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x40000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0c784be7},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x20000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x18f097cf},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x10000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x31e12f9f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x08000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x63c25f3f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x04000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc784be7f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x02000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8f097cff},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x01000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1e12f9fe},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00800000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3c25f3fc},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00400000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x784be7f8},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00200000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf097cff0},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00100000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe12f9fe0},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00080000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc25f3fc1},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00040000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x84be7f83},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00020000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x097cff07},
+	{0x57,    4,    0,        0, 0x00010000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x12f9fe0f},
+	{0x71,    3,    6,       42, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00008000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x25f3fc1f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00004000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4be7f83f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00002000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x97cff07f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00001000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2f9fe0fe},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000800},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5f3fc1fd},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000400},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbe7f83fb},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000200},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7cff07f7},
+	{0x57,    3,    0,        0, 0x00000100},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf9fe0fee},
+	{0x71,    3,    6,       43, 0x00000000},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000080},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf3fc1fdc},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000040},
+	{0x79,    5,   10,      -56, 0x00000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe7f83fb8},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000020},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcff07f70},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000010},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9fe0fee1},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000008},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3fc1fdc2},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000004},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7f83fb85},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000002},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff07f70a},
+	{0x57,    3,    0,        0, 0x00000001},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfe0fee15},
+	{0x71,    2,    0,      201, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000008},
+	{0x71,    3,    0,      200, 0x00000000},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0x71,    3,    0,      203, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0x71,    4,    0,      202, 0x00000000},
+	{0x4f,    3,    4,        0, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000010},
+	{0x4f,    3,    2,        0, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000020},
+	{0x77,    1,    0,        0, 0x00000020},
+	{0xbf,    2,    1,        0, 0x00000000},
+	{0x3f,    2,    3,        0, 0x00000000},
+	{0x2f,    2,    3,        0, 0x00000000},
+	{0x1f,    1,    2,        0, 0x00000000},
+	{0x57,    1,    0,        0, 0x0000000f},
+	{0x67,    1,    0,        0, 0x00000002},
+	{0x0f,    0,    1,        0, 0x00000000},
+	{0x71,    1,    0,      137, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000008},
+	{0x71,    2,    0,      136, 0x00000000},
+	{0x4f,    1,    2,        0, 0x00000000},
+	{0x71,    2,    0,      138, 0x00000000},
+	{0x71,    3,    0,      139, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0x4f,    3,    2,        0, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000010},
+	{0x4f,    3,    1,        0, 0x00000000},
+	{0x07,    3,    0,        0, 0x00000001},
+	{0x63,    5,    3,       52, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000001},
+	{0xbf,    0,    7,        0, 0x00000000},
+	{0x95,    0,    0,        0, 0x00000000},
+};
+
+/**
+ * Load BPF program (section l3_l4) into the kernel and return a bpf fd.
+ *
+ * @param[in] key_idx
+ *   RSS MAP key index
+ *
+ * @param[in] map_fd
+ *   BPF RSS map file descriptor
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd)
+{
+	l3_l4_hash_insns[4].imm = key_idx;
+	l3_l4_hash_insns[9].imm = map_fd;
+
+	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+		(struct bpf_insn *)l3_l4_hash_insns,
+		ARRAY_SIZE(l3_l4_hash_insns),
+		"Dual BSD/GPL");
+}
+
+
+#ifndef __NR_bpf
+# if defined(__i386__)
+#  define __NR_bpf 357
+# elif defined(__x86_64__)
+#  define __NR_bpf 321
+# elif defined(__aarch64__)
+#  define __NR_bpf 280
+# elif defined(__sparc__)
+#  define __NR_bpf 349
+# elif defined(__s390__)
+#  define __NR_bpf 351
+# else
+#  error __NR_bpf not defined. libbpf does not support your arch.
+# endif
+#endif
+
+/**
+ * Helper function to convert a pointer to unsigned 64 bits
+ *
+ * @param[in] ptr
+ *   pointer to address
+ *
+ * @return
+ *   64 bit unsigned long type of pointer address
+ */
+static inline __u64 ptr_to_u64(const void *ptr)
+{
+	return (__u64)(unsigned long)ptr;
+}
+
+/**
+ * Call BPF system call
+ *
+ * @param[in] cmd
+ *   BPF command for program loading, map creation, map entry update, etc
+ *
+ * @param[in] attr
+ *   System call attributes relevant to system call command
+ *
+ * @param[in] size
+ *   size of attr parameter
+ *
+ * @return
+ *   -1 if BPF system call failed, 0 otherwise
+ */
+static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
+			unsigned int size)
+{
+	return syscall(__NR_bpf, cmd, attr, size);
+}
+
+/**
+ * Load BPF instructions to kernel
+ *
+ * @param[in] type
+ *   BPF program type: classifieir or action
+ *
+ * @param[in] insns
+ *   Array of BPF instructions (equivalent to BPF instructions)
+ *
+ * @param[in] insns_cnt
+ *   Number of BPF instructions (size of array)
+ *
+ * @param[in] lincense
+ *   License string that must be acknowledged by the kernel
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded, fd (file descriptor) otherwise
+ */
+static int bpf_load(enum bpf_prog_type type,
+		  const struct bpf_insn *insns,
+		  size_t insns_cnt,
+		  const char *license)
+{
+	union bpf_attr attr;
+
+	bzero(&attr, sizeof(attr));
+	attr.prog_type = type;
+	attr.insn_cnt = (__u32)insns_cnt;
+	attr.insns = ptr_to_u64(insns);
+	attr.license = ptr_to_u64(license);
+	attr.log_buf = ptr_to_u64(NULL);
+	attr.log_level = 0;
+	attr.kern_version = 0;
+
+	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
+}
diff --git a/drivers/net/tap/tap_bpf_program.c b/drivers/net/tap/tap_bpf_program.c
new file mode 100644
index 0000000..08bc881
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_program.c
@@ -0,0 +1,221 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <asm/types.h>
+#include <linux/in.h>
+#include <linux/if.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/if_tunnel.h>
+#include <linux/filter.h>
+#include <linux/bpf.h>
+
+#include "tap_rss.h"
+
+/** Create IPv4 address */
+#define IPv4(a, b, c, d) ((__u32)(((a) & 0xff) << 24) | \
+		(((b) & 0xff) << 16) | \
+		(((c) & 0xff) << 8)  | \
+		((d) & 0xff))
+
+#define PORT(a, b) ((__u16)(((a) & 0xff) << 8) | \
+		((b) & 0xff))
+
+/*
+ * The queue number is offset by 1, to distinguish packets that have
+ * gone through this rule (skb->cb[1] != 0) from others.
+ */
+#define QUEUE_OFFSET		1
+#define PIN_GLOBAL_NS		2
+
+#define KEY_IDX			0
+#define BPF_MAP_ID_KEY	1
+
+struct vlan_hdr {
+	__be16 proto;
+	__be16 tci;
+};
+
+struct bpf_elf_map __attribute__((section("maps"), used))
+map_keys = {
+	.type           =       BPF_MAP_TYPE_HASH,
+	.id             =       BPF_MAP_ID_KEY,
+	.size_key       =       sizeof(__u32),
+	.size_value     =       sizeof(struct rss_key),
+	.max_elem       =       256,
+	.pinning        =       PIN_GLOBAL_NS,
+};
+
+__section("cls_q") int
+match_q(struct __sk_buff *skb)
+{
+	__u32 queue = skb->cb[1];
+	volatile __u32 q = 0xdeadbeef;
+	__u32 match_queue = QUEUE_OFFSET + q;
+
+	/* printt("match_q$i() queue = %d\n", queue); */
+
+	if (queue != match_queue)
+		return TC_ACT_OK;
+	return TC_ACT_UNSPEC;
+}
+
+
+struct ipv4_l3_l4_tuple {
+	__u32    src_addr;
+	__u32    dst_addr;
+	__u16    dport;
+	__u16    sport;
+} __attribute__((packed));
+
+struct ipv6_l3_l4_tuple {
+	__u8        src_addr[16];
+	__u8        dst_addr[16];
+	__u16       dport;
+	__u16       sport;
+} __attribute__((packed));
+
+static const __u8 def_rss_key[] = {
+	0xd1, 0x81, 0xc6, 0x2c,
+	0xf7, 0xf4, 0xdb, 0x5b,
+	0x19, 0x83, 0xa2, 0xfc,
+	0x94, 0x3e, 0x1a, 0xdb,
+	0xd9, 0x38, 0x9e, 0x6b,
+	0xd1, 0x03, 0x9c, 0x2c,
+	0xa7, 0x44, 0x99, 0xad,
+	0x59, 0x3d, 0x56, 0xd9,
+	0xf3, 0x25, 0x3c, 0x06,
+	0x2a, 0xdc, 0x1f, 0xfc,
+};
+
+static __u32  __attribute__((always_inline))
+rte_softrss_be(const __u32 *input_tuple, const uint8_t *rss_key,
+		__u8 input_len)
+{
+	__u32 i, j, hash = 0;
+#pragma unroll
+	for (j = 0; j < input_len; j++) {
+#pragma unroll
+		for (i = 0; i < 32; i++) {
+			if (input_tuple[j] & (1 << (31 - i))) {
+				hash ^= ((const __u32 *)def_rss_key)[j] << i |
+				(__u32)((uint64_t)
+				(((const __u32 *)def_rss_key)[j + 1])
+					>> (32 - i));
+			}
+		}
+	}
+	return hash;
+}
+
+static int __attribute__((always_inline))
+rss_l3_l4(struct __sk_buff *skb)
+{
+	void *data_end = (void *)(long)skb->data_end;
+	void *data = (void *)(long)skb->data;
+	__u16 proto = (__u16)skb->protocol;
+	__u32 key_idx = 0xdeadbeef;
+	__u32 hash;
+	struct rss_key *rsskey;
+	__u64 off = ETH_HLEN;
+	int j;
+	__u8 *key = 0;
+	__u32 len;
+	__u32 queue = 0;
+
+	rsskey = map_lookup_elem(&map_keys, &key_idx);
+	if (!rsskey) {
+		printt("hash(): rss key is not configured\n");
+		return TC_ACT_OK;
+	}
+	key = (__u8 *)rsskey->key;
+
+	/* Get correct proto for 802.1ad */
+	if (skb->vlan_present && skb->vlan_proto == htons(ETH_P_8021AD)) {
+		if (data + ETH_ALEN * 2 + sizeof(struct vlan_hdr) +
+		    sizeof(proto) > data_end)
+			return TC_ACT_OK;
+		proto = *(__u16 *)(data + ETH_ALEN * 2 +
+				   sizeof(struct vlan_hdr));
+		off += sizeof(struct vlan_hdr);
+	}
+
+	if (proto == htons(ETH_P_IP)) {
+		if (data + off + sizeof(struct iphdr) + sizeof(__u32)
+			> data_end)
+			return TC_ACT_OK;
+
+		__u8 *src_dst_addr = data + off + offsetof(struct iphdr, saddr);
+		__u8 *src_dst_port = data + off + sizeof(struct iphdr);
+		struct ipv4_l3_l4_tuple v4_tuple = {
+			.src_addr = IPv4(*(src_dst_addr + 0),
+					*(src_dst_addr + 1),
+					*(src_dst_addr + 2),
+					*(src_dst_addr + 3)),
+			.dst_addr = IPv4(*(src_dst_addr + 4),
+					*(src_dst_addr + 5),
+					*(src_dst_addr + 6),
+					*(src_dst_addr + 7)),
+			.sport = PORT(*(src_dst_port + 0),
+					*(src_dst_port + 1)),
+			.dport = PORT(*(src_dst_port + 2),
+					*(src_dst_port + 3)),
+		};
+		__u8 input_len = sizeof(v4_tuple) / sizeof(__u32);
+		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV4_L3))
+			input_len--;
+		hash = rte_softrss_be((__u32 *)&v4_tuple, key, 3);
+	} else if (proto == htons(ETH_P_IPV6)) {
+		if (data + off + sizeof(struct ipv6hdr) +
+					sizeof(__u32) > data_end)
+			return TC_ACT_OK;
+		__u8 *src_dst_addr = data + off +
+					offsetof(struct ipv6hdr, saddr);
+		__u8 *src_dst_port = data + off +
+					sizeof(struct ipv6hdr);
+		struct ipv6_l3_l4_tuple v6_tuple;
+		for (j = 0; j < 4; j++)
+			*((uint32_t *)&v6_tuple.src_addr + j) =
+				__builtin_bswap32(*((uint32_t *)
+						src_dst_addr + j));
+		for (j = 0; j < 4; j++)
+			*((uint32_t *)&v6_tuple.dst_addr + j) =
+				__builtin_bswap32(*((uint32_t *)
+						src_dst_addr + 4 + j));
+		v6_tuple.sport = PORT(*(src_dst_port + 0),
+			      *(src_dst_port + 1));
+		v6_tuple.dport = PORT(*(src_dst_port + 2),
+			      *(src_dst_port + 3));
+
+		__u8 input_len = sizeof(v6_tuple) / sizeof(__u32);
+		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV6_L3))
+			input_len--;
+		hash = rte_softrss_be((__u32 *)&v6_tuple, key, 9);
+	} else {
+		return TC_ACT_PIPE;
+	}
+
+	queue = rsskey->queues[(hash % rsskey->nb_queues) &
+				       (TAP_MAX_QUEUES - 1)];
+	skb->cb[1] = QUEUE_OFFSET + queue;
+	/* printt(">>>>> rss_l3_l4 hash=0x%x queue=%u\n", hash, queue); */
+
+	return TC_ACT_RECLASSIFY;
+}
+
+#define RSS(L)						\
+	__section(#L) int				\
+		L ## _hash(struct __sk_buff *skb)	\
+	{						\
+		return rss_ ## L (skb);			\
+	}
+
+RSS(l3_l4)
+
+BPF_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h
index 9e332b0..6cc01b4 100644
--- a/drivers/net/tap/tap_flow.h
+++ b/drivers/net/tap/tap_flow.h
@@ -50,6 +50,8 @@
 #define GROUP_SHIFT 12
 #define MAX_GROUP GROUP_MASK
 
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
 /**
  * These index are actually in reversed order: their priority is processed
  * by subtracting their value to the lowest priority (PRIORITY_MASK).
@@ -80,4 +82,7 @@ int tap_flow_implicit_destroy(struct pmd_internals *pmd,
 int tap_flow_implicit_flush(struct pmd_internals *pmd,
 			    struct rte_flow_error *error);
 
+int tap_flow_bpf_cls_q(__u32 queue_idx);
+int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd);
+
 #endif /* _TAP_FLOW_H_ */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v3 2/2] net/tap: implement RSS with eBPF classifier and action
  2018-01-10  7:06   ` [dpdk-dev] [PATCH v3 0/2] TAP RSS eBPF cover letter Ophir Munk
  2018-01-10  7:06     ` [dpdk-dev] [PATCH v3 1/2] net/tap: add eBPF instructions to TAP device Ophir Munk
@ 2018-01-10  7:06     ` Ophir Munk
  2018-01-10 10:19       ` Pascal Mazon
  2018-01-10 10:10     ` [dpdk-dev] [PATCH v3 0/2] TAP RSS eBPF cover letter Jason Wang
  2018-01-11 17:45     ` [dpdk-dev] [PATCH v4 0/5] " Ophir Munk
  3 siblings, 1 reply; 42+ messages in thread
From: Ophir Munk @ 2018-01-10  7:06 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

Add BPF classifier for each TAP queue. According to this classifier packets
marked with an RSS queue will be directed to this queue using a traffic
control with "skbedit" action.
The BPF classifier program is downloaded to the kernel once per TAP Rx
queue.

Add RSS BPF map entry for each new RSS rule. A BPF map entry contains the
RSS queues of that rule.

Add BPF action for each new RSS rule in which the Toeplitz RSS hash is
calculated based on L3 addresses and L4 ports. Mark the packet with the RSS
queue according the resulting RSS hash, then reclassify the packet.

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 drivers/net/tap/Makefile        |  20 ++
 drivers/net/tap/rte_eth_tap.h   |   9 +-
 drivers/net/tap/tap_bpf_insns.c |  62 +++-
 drivers/net/tap/tap_flow.c      | 635 ++++++++++++++++++++++++++++++++++------
 drivers/net/tap/tap_flow.h      |  10 +
 drivers/net/tap/tap_rss.h       |  32 ++
 drivers/net/tap/tap_tcmsgs.h    |   4 +
 7 files changed, 675 insertions(+), 97 deletions(-)
 create mode 100644 drivers/net/tap/tap_rss.h

diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index feaa5b7..0e7c494 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -60,6 +60,26 @@ tap_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
 		enum TCA_FLOWER_KEY_VLAN_PRIO \
 		$(AUTOCONF_OUTPUT)
 	$Q sh -- '$<' '$@' \
+		HAVE_TC_BPF \
+		linux/pkt_cls.h \
+		enum TCA_BPF_UNSPEC \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_TC_BPF_FD \
+		linux/pkt_cls.h \
+		enum TCA_BPF_FD \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_TC_ACT_BPF \
+		linux/tc_act/tc_bpf.h \
+		enum TCA_ACT_BPF_UNSPEC \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_TC_ACT_BPF_FD \
+		linux/tc_act/tc_bpf.h \
+		enum TCA_ACT_BPF_FD \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
 		HAVE_BPF_PROG_LOAD \
 		linux/bpf.h \
 		enum BPF_PROG_LOAD \
diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
index 829f32f..c185473 100644
--- a/drivers/net/tap/rte_eth_tap.h
+++ b/drivers/net/tap/rte_eth_tap.h
@@ -45,7 +45,7 @@
 #include <rte_ether.h>
 
 #ifdef IFF_MULTI_QUEUE
-#define RTE_PMD_TAP_MAX_QUEUES	16
+#define RTE_PMD_TAP_MAX_QUEUES	TAP_MAX_QUEUES
 #else
 #define RTE_PMD_TAP_MAX_QUEUES	1
 #endif
@@ -90,6 +90,13 @@ struct pmd_internals {
 	int ioctl_sock;                   /* socket for ioctl calls */
 	int nlsk_fd;                      /* Netlink socket fd */
 	int flow_isolate;                 /* 1 if flow isolation is enabled */
+	int flower_support;               /* 1 if kernel supports, else 0 */
+	int flower_vlan_support;          /* 1 if kernel supports, else 0 */
+	int rss_enabled;                  /* 1 if RSS is enabled, else 0 */
+	/* implicit rules set when RSS is enabled */
+	int map_fd;                       /* BPF RSS map fd */
+	int bpf_fd[RTE_PMD_TAP_MAX_QUEUES];/* List of bpf fds per queue */
+	LIST_HEAD(tap_rss_flows, rte_flow) rss_flows;
 	LIST_HEAD(tap_flows, rte_flow) flows;        /* rte_flow rules */
 	/* implicit rte_flow rules set when a remote device is active */
 	LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows;
diff --git a/drivers/net/tap/tap_bpf_insns.c b/drivers/net/tap/tap_bpf_insns.c
index 25aa82c..bf95f2d 100644
--- a/drivers/net/tap/tap_bpf_insns.c
+++ b/drivers/net/tap/tap_bpf_insns.c
@@ -1830,7 +1830,7 @@ static int bpf_load(enum bpf_prog_type type,
 		  size_t insns_cnt,
 		  const char *license)
 {
-	union bpf_attr attr;
+	union bpf_attr attr = {};
 
 	bzero(&attr, sizeof(attr));
 	attr.prog_type = type;
@@ -1843,3 +1843,63 @@ static int bpf_load(enum bpf_prog_type type,
 
 	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
 }
+
+/**
+ * Create BPF map for RSS rules
+ *
+ * @param[in] key_size
+ *   map RSS key size
+ *
+ * @param[in] value_size
+ *   Map RSS value size
+ *
+ * @param[in] max_entries
+ *   Map max number of RSS entries (limit on max RSS rules)
+ *
+ * @return
+ *   -1 if BPF map couldn't be created, map fd otherwise
+ */
+int tap_flow_bpf_rss_map_create(unsigned int key_size,
+		unsigned int value_size,
+		unsigned int max_entries)
+{
+	union bpf_attr attr = {};
+
+	bzero(&attr, sizeof(attr));
+	attr.map_type    = BPF_MAP_TYPE_HASH;
+	attr.key_size    = key_size;
+	attr.value_size  = value_size;
+	attr.max_entries = max_entries;
+
+	return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
+}
+
+/**
+ * Update RSS entry in BPF map
+ *
+ * @param[in] fd
+ *   RSS map fd
+ *
+ * @param[in] key
+ *   Pointer to RSS key whose entry is updated
+ *
+ * @param[in] value
+ *   Pointer to RSS new updated value
+ *
+ * @return
+ *   -1 if RSS entry failed to be updated, 0 otherwise
+ */
+int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value)
+{
+	union bpf_attr attr = {};
+
+	bzero(&attr, sizeof(attr));
+
+	attr.map_type = BPF_MAP_TYPE_HASH;
+	attr.map_fd = fd;
+	attr.key = ptr_to_u64(key);
+	attr.value = ptr_to_u64(value);
+	attr.flags = BPF_ANY;
+
+	return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
+}
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index 90b2654..7c51614 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -33,7 +33,9 @@
 
 #include <errno.h>
 #include <string.h>
+#include <unistd.h>
 #include <sys/queue.h>
+#include <sys/resource.h>
 
 #include <rte_byteorder.h>
 #include <rte_jhash.h>
@@ -42,6 +44,7 @@
 #include <tap_flow.h>
 #include <tap_autoconf.h>
 #include <tap_tcmsgs.h>
+#include <tap_rss.h>
 
 #ifndef HAVE_TC_FLOWER
 /*
@@ -81,12 +84,78 @@ enum {
 	TCA_FLOWER_KEY_VLAN_ETH_TYPE,   /* be16 */
 };
 #endif
+/*
+ * For kernels < 4.2 BPF related enums may not be defined.
+ * Runtime checks will be carried out to gracefully report on TC messages that
+ * are rejected by the kernel. Rejection reasons may be due to:
+ * 1. enum is not defined
+ * 2. enum is defined but kerenl is not configured to support BPF system calls,
+ *    BPF classifications or BPF actions.
+ */
+#ifndef HAVE_TC_BPF
+enum {
+	TCA_BPF_UNSPEC,
+	TCA_BPF_ACT,
+	TCA_BPF_POLICE,
+	TCA_BPF_CLASSID,
+	TCA_BPF_OPS_LEN,
+	TCA_BPF_OPS,
+};
+#endif
+#ifndef HAVE_TC_BPF_FD
+enum {
+	TCA_BPF_FD = TCA_BPF_OPS + 1,
+	TCA_BPF_NAME,
+};
+#endif
+#ifndef HAVE_TC_ACT_BPF
+#define tc_gen \
+	__u32                 index; \
+	__u32                 capab; \
+	int                   action; \
+	int                   refcnt; \
+	int                   bindcnt
+
+struct tc_act_bpf {
+	tc_gen;
+};
+
+enum {
+	TCA_ACT_BPF_UNSPEC,
+	TCA_ACT_BPF_TM,
+	TCA_ACT_BPF_PARMS,
+	TCA_ACT_BPF_OPS_LEN,
+	TCA_ACT_BPF_OPS,
+};
+
+#endif
+#ifndef HAVE_TC_ACT_BPF_FD
+enum {
+	TCA_ACT_BPF_FD = TCA_ACT_BPF_OPS + 1,
+	TCA_ACT_BPF_NAME,
+};
+#endif
+
+/* RSS key management */
+enum bpf_rss_key_e {
+	KEY_CMD_GET = 1,
+	KEY_CMD_RELEASE,
+	KEY_CMD_INIT,
+	KEY_CMD_DEINIT,
+};
+
+enum key_status_e {
+	KEY_STAT_UNSPEC,
+	KEY_STAT_USED,
+	KEY_STAT_AVAILABLE,
+};
 
 #define ISOLATE_HANDLE 1
 
 struct rte_flow {
 	LIST_ENTRY(rte_flow) next; /* Pointer to the next rte_flow structure */
 	struct rte_flow *remote_flow; /* associated remote flow */
+	int bpf_fd[SEC_MAX]; /* list of bfs fds per ELF section */
 	struct nlmsg msg;
 };
 
@@ -104,6 +173,24 @@ struct remote_rule {
 	int mirred;
 };
 
+struct action_data {
+	char id[16];
+
+	union {
+		struct tc_gact gact;
+		struct tc_mirred mirred;
+		struct skbedit {
+			struct tc_skbedit skbedit;
+			uint16_t queue;
+		} skbedit;
+		struct bpf {
+			struct tc_act_bpf bpf;
+			int bpf_fd;
+			const char *annotation;
+		} bpf;
+	};
+};
+
 static int tap_flow_create_eth(const struct rte_flow_item *item, void *data);
 static int tap_flow_create_vlan(const struct rte_flow_item *item, void *data);
 static int tap_flow_create_ipv4(const struct rte_flow_item *item, void *data);
@@ -134,6 +221,14 @@ tap_flow_isolate(struct rte_eth_dev *dev,
 		 int set,
 		 struct rte_flow_error *error);
 
+static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx);
+static int rss_enable(struct pmd_internals *pmd,
+			const struct rte_flow_attr *attr,
+			struct rte_flow_error *error);
+static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
+			const struct rte_flow_action_rss *rss,
+			struct rte_flow_error *error);
+
 static const struct rte_flow_ops tap_flow_ops = {
 	.validate = tap_flow_validate,
 	.create = tap_flow_create,
@@ -819,111 +914,97 @@ tap_flow_item_validate(const struct rte_flow_item *item,
 }
 
 /**
- * Transform a DROP/PASSTHRU action item in the provided flow for TC.
+ * Configure the kernel with a TC action and its configured parameters
+ * Handled actions: "gact", "mirred", "skbedit", "bpf"
  *
- * @param[in, out] flow
- *   Flow to be filled.
- * @param[in] action
- *   Appropriate action to be set in the TCA_GACT_PARMS structure.
+ * @param[in] flow
+ *   Pointer to rte flow containing the netlink message
  *
- * @return
- *   0 if checks are alright, -1 otherwise.
- */
-static int
-add_action_gact(struct rte_flow *flow, int action)
-{
-	struct nlmsg *msg = &flow->msg;
-	size_t act_index = 1;
-	struct tc_gact p = {
-		.action = action
-	};
-
-	if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
-		return -1;
-	if (tap_nlattr_nested_start(msg, act_index++) < 0)
-		return -1;
-	tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("gact"), "gact");
-	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
-		return -1;
-	tap_nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(p), &p);
-	tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
-	tap_nlattr_nested_finish(msg); /* nested act_index */
-	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
-	return 0;
-}
-
-/**
- * Transform a MIRRED action item in the provided flow for TC.
+ * @param[in, out] act_index
+ *   Pointer to action sequence number in the TC command
  *
- * @param[in, out] flow
- *   Flow to be filled.
- * @param[in] ifindex
- *   Netdevice ifindex, where to mirror/redirect packet to.
- * @param[in] action_type
- *   Either TCA_EGRESS_REDIR for redirection or TCA_EGRESS_MIRROR for mirroring.
+ * @param[in] adata
+ *  Pointer to struct holding the action parameters
  *
  * @return
- *   0 if checks are alright, -1 otherwise.
+ *   -1 on failure, 0 on success
  */
 static int
-add_action_mirred(struct rte_flow *flow, uint16_t ifindex, uint16_t action_type)
+add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
 {
 	struct nlmsg *msg = &flow->msg;
-	size_t act_index = 1;
-	struct tc_mirred p = {
-		.eaction = action_type,
-		.ifindex = ifindex,
-	};
 
-	if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
-		return -1;
-	if (tap_nlattr_nested_start(msg, act_index++) < 0)
+	if (tap_nlattr_nested_start(msg, (*act_index)++) < 0)
 		return -1;
-	tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("mirred"), "mirred");
+
+	tap_nlattr_add(&msg->nh, TCA_ACT_KIND,
+				strlen(adata->id) + 1, adata->id);
 	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
 		return -1;
-	if (action_type == TCA_EGRESS_MIRROR)
-		p.action = TC_ACT_PIPE;
-	else /* REDIRECT */
-		p.action = TC_ACT_STOLEN;
-	tap_nlattr_add(&msg->nh, TCA_MIRRED_PARMS, sizeof(p), &p);
+	if (strcmp("gact", adata->id) == 0) {
+		tap_nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(adata->gact),
+			   &adata->gact);
+	} else if (strcmp("mirred", adata->id) == 0) {
+		if (adata->mirred.eaction == TCA_EGRESS_MIRROR)
+			adata->mirred.action = TC_ACT_PIPE;
+		else /* REDIRECT */
+			adata->mirred.action = TC_ACT_STOLEN;
+		tap_nlattr_add(&msg->nh, TCA_MIRRED_PARMS,
+			   sizeof(adata->mirred),
+			   &adata->mirred);
+	} else if (strcmp("skbedit", adata->id) == 0) {
+		tap_nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS,
+			   sizeof(adata->skbedit.skbedit),
+			   &adata->skbedit.skbedit);
+		tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING,
+			     adata->skbedit.queue);
+	} else if (strcmp("bpf", adata->id) == 0) {
+		tap_nlattr_add32(&msg->nh, TCA_ACT_BPF_FD, adata->bpf.bpf_fd);
+		tap_nlattr_add(&msg->nh, TCA_ACT_BPF_NAME,
+			   strlen(adata->bpf.annotation) + 1,
+			   adata->bpf.annotation);
+		tap_nlattr_add(&msg->nh, TCA_ACT_BPF_PARMS,
+			   sizeof(adata->bpf.bpf),
+			   &adata->bpf.bpf);
+	} else {
+		return -1;
+	}
 	tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
 	tap_nlattr_nested_finish(msg); /* nested act_index */
-	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
 	return 0;
 }
 
 /**
- * Transform a QUEUE action item in the provided flow for TC.
+ * Helper function to send a serie of TC actions to the kernel
  *
- * @param[in, out] flow
- *   Flow to be filled.
- * @param[in] queue
- *   Queue id to use.
+ * @param[in] flow
+ *   Pointer to rte flow containing the netlink message
+ *
+ * @param[in] nb_actions
+ *   Number of actions in an array of action structs
+ *
+ * @param[in] data
+ *   Pointer to an array of action structs
+ *
+ * @param[in] classifier_actions
+ *   The classifier on behave of which the actions are configured
  *
  * @return
- *   0 if checks are alright, -1 otherwise.
+ *   -1 on failure, 0 on success
  */
 static int
-add_action_skbedit(struct rte_flow *flow, uint16_t queue)
+add_actions(struct rte_flow *flow, int nb_actions, struct action_data *data,
+	    int classifier_action)
 {
 	struct nlmsg *msg = &flow->msg;
 	size_t act_index = 1;
-	struct tc_skbedit p = {
-		.action = TC_ACT_PIPE
-	};
+	int i;
 
-	if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
-		return -1;
-	if (tap_nlattr_nested_start(msg, act_index++) < 0)
+	if (tap_nlattr_nested_start(msg, classifier_action) < 0)
 		return -1;
-	tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("skbedit"), "skbedit");
-	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
-		return -1;
-	tap_nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS, sizeof(p), &p);
-	tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING, queue);
-	tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
-	tap_nlattr_nested_finish(msg); /* nested act_index */
+	for (i = 0; i < nb_actions; i++)
+		if (add_action(flow, &act_index, data + i) < 0)
+			return -1;
 	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
 	return 0;
 }
@@ -987,7 +1068,8 @@ priv_flow_process(struct pmd_internals *pmd,
 		return -rte_errno;
 	} else if (flow) {
 		uint16_t group = attr->group << GROUP_SHIFT;
-		uint16_t prio = group | (attr->priority + PRIORITY_OFFSET);
+		uint16_t prio = group | (attr->priority +
+				RSS_PRIORITY_OFFSET + PRIORITY_OFFSET);
 		flow->msg.t.tcm_info = TC_H_MAKE(prio << 16,
 						 flow->msg.t.tcm_info);
 	}
@@ -1056,7 +1138,12 @@ priv_flow_process(struct pmd_internals *pmd,
 		}
 	}
 	if (mirred && flow) {
-		uint16_t if_index = pmd->if_index;
+		struct action_data adata = {
+			.id = "mirred",
+			.mirred = {
+				.eaction = mirred,
+			},
+		};
 
 		/*
 		 * If attr->egress && mirred, then this is a special
@@ -1064,9 +1151,13 @@ priv_flow_process(struct pmd_internals *pmd,
 		 * redirect packets coming from the DPDK App, out
 		 * through the remote netdevice.
 		 */
-		if (attr->egress)
-			if_index = pmd->remote_if_index;
-		if (add_action_mirred(flow, if_index, mirred) < 0)
+		adata.mirred.ifindex = attr->ingress ? pmd->if_index :
+			pmd->remote_if_index;
+		if (mirred == TCA_EGRESS_MIRROR)
+			adata.mirred.action = TC_ACT_PIPE;
+		else
+			adata.mirred.action = TC_ACT_STOLEN;
+		if (add_actions(flow, 1, &adata, TCA_FLOWER_ACT) < 0)
 			goto exit_action_not_supported;
 		else
 			goto end;
@@ -1080,14 +1171,33 @@ priv_flow_process(struct pmd_internals *pmd,
 			if (action)
 				goto exit_action_not_supported;
 			action = 1;
-			if (flow)
-				err = add_action_gact(flow, TC_ACT_SHOT);
+			if (flow) {
+				struct action_data adata = {
+					.id = "gact",
+					.gact = {
+						.action = TC_ACT_SHOT,
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+						  TCA_FLOWER_ACT);
+			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_PASSTHRU) {
 			if (action)
 				goto exit_action_not_supported;
 			action = 1;
-			if (flow)
-				err = add_action_gact(flow, TC_ACT_UNSPEC);
+			if (flow) {
+				struct action_data adata = {
+					.id = "gact",
+					.gact = {
+						/* continue */
+						.action = TC_ACT_UNSPEC,
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+						  TCA_FLOWER_ACT);
+			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
 			const struct rte_flow_action_queue *queue =
 				(const struct rte_flow_action_queue *)
@@ -1099,22 +1209,35 @@ priv_flow_process(struct pmd_internals *pmd,
 			if (!queue ||
 			    (queue->index > pmd->dev->data->nb_rx_queues - 1))
 				goto exit_action_not_supported;
-			if (flow)
-				err = add_action_skbedit(flow, queue->index);
+			if (flow) {
+				struct action_data adata = {
+					.id = "skbedit",
+					.skbedit = {
+						.skbedit = {
+							.action = TC_ACT_PIPE,
+						},
+						.queue = queue->index,
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+					TCA_FLOWER_ACT);
+			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
-			/* Fake RSS support. */
 			const struct rte_flow_action_rss *rss =
 				(const struct rte_flow_action_rss *)
 				actions->conf;
 
-			if (action)
-				goto exit_action_not_supported;
-			action = 1;
-			if (!rss || rss->num < 1 ||
-			    (rss->queue[0] > pmd->dev->data->nb_rx_queues - 1))
+			if (action++)
 				goto exit_action_not_supported;
-			if (flow)
-				err = add_action_skbedit(flow, rss->queue[0]);
+
+			if (!pmd->rss_enabled) {
+				err = rss_enable(pmd, attr, error);
+				if (err)
+					goto exit_action_not_supported;
+			}
+			if (flow && rss)
+				err = rss_add_actions(flow, pmd, rss, error);
 		} else {
 			goto exit_action_not_supported;
 		}
@@ -1326,6 +1449,7 @@ tap_flow_destroy_pmd(struct pmd_internals *pmd,
 		     struct rte_flow_error *error)
 {
 	struct rte_flow *remote_flow = flow->remote_flow;
+	int i;
 	int ret = 0;
 
 	LIST_REMOVE(flow, next);
@@ -1351,6 +1475,13 @@ tap_flow_destroy_pmd(struct pmd_internals *pmd,
 			"couldn't receive kernel ack to our request");
 		goto end;
 	}
+	/* Close opened BPF file descriptors of this flow */
+	for (i = 0; i < SEC_MAX; i++)
+		if (flow->bpf_fd[i] != 0) {
+			close(flow->bpf_fd[i]);
+			flow->bpf_fd[i] = 0;
+		}
+
 	if (remote_flow) {
 		remote_flow->msg.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
 		remote_flow->msg.nh.nlmsg_type = RTM_DELTFILTER;
@@ -1635,6 +1766,320 @@ tap_flow_implicit_flush(struct pmd_internals *pmd, struct rte_flow_error *error)
 	return 0;
 }
 
+#define MAX_RSS_KEYS 256
+#define SEC_NAME_CLS_Q "cls_q"
+
+const char *sec_name[SEC_MAX] = {
+	[SEC_L3_L4] = "l3_l4",
+};
+
+/**
+ * Enable RSS on tap: create TC rules for queuing.
+ *
+ * @param[in, out] pmd
+ *   Pointer to private structure.
+ *
+ * @param[in] attr
+ *   Pointer to rte_flow to get flow group
+ *
+ * @param[out] error
+ *   Pointer to error reporting if not NULL.
+ *
+ * @return 0 on success, negative value on failure.
+ */
+static int rss_enable(struct pmd_internals *pmd,
+			const struct rte_flow_attr *attr,
+			struct rte_flow_error *error)
+{
+	struct rte_flow *rss_flow = NULL;
+	struct nlmsg *msg = NULL;
+	/* 4096 is the maximum number of instructions for a BPF program */
+	char annotation[64];
+	int i;
+	int err = 0;
+
+	/* unlimit locked memory */
+	struct rlimit limit = {
+		.rlim_cur = RLIM_INFINITY,
+		.rlim_max = RLIM_INFINITY,
+	};
+	setrlimit(RLIMIT_MEMLOCK, &limit);
+
+	 /* Get a new map key for a new RSS rule */
+	err = bpf_rss_key(KEY_CMD_INIT, NULL);
+	if (err < 0) {
+		rte_flow_error_set(
+			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Failed to initialize BPF RSS keys");
+
+		return -1;
+	}
+
+	/*
+	 *  Create BPF RSS MAP
+	 */
+	pmd->map_fd = tap_flow_bpf_rss_map_create(sizeof(__u32), /* key size */
+				sizeof(struct rss_key),
+				MAX_RSS_KEYS);
+	if (pmd->map_fd < 0) {
+		RTE_LOG(ERR, PMD,
+			"Failed to create BPF map (%d): %s\n",
+				errno, strerror(errno));
+		rte_flow_error_set(
+			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Kernel too old or not configured "
+			"to support BPF maps");
+
+		return -ENOTSUP;
+	}
+
+	/*
+	 * Add a rule per queue to match reclassified packets and direct them to
+	 * the correct queue.
+	 */
+	for (i = 0; i < pmd->dev->data->nb_rx_queues; i++) {
+		pmd->bpf_fd[i] = tap_flow_bpf_cls_q(i);
+		if (pmd->bpf_fd[i] < 0) {
+			RTE_LOG(ERR, PMD,
+				"Failed to load BPF section %s for queue %d",
+				SEC_NAME_CLS_Q, i);
+			rte_flow_error_set(
+				error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
+				NULL,
+				"Kernel too old or not configured "
+				"to support BPF programs loading");
+
+			return -ENOTSUP;
+		}
+
+		rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
+		if (!rss_flow) {
+			RTE_LOG(ERR, PMD,
+				"Cannot allocate memory for rte_flow");
+			return -1;
+		}
+		msg = &rss_flow->msg;
+		tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER, NLM_F_REQUEST |
+			    NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE);
+		msg->t.tcm_info = TC_H_MAKE(0, htons(ETH_P_ALL));
+		tap_flow_set_handle(rss_flow);
+		uint16_t group = attr->group << GROUP_SHIFT;
+		uint16_t prio = group | (i + PRIORITY_OFFSET);
+		msg->t.tcm_info = TC_H_MAKE(prio << 16, msg->t.tcm_info);
+		msg->t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
+
+		tap_nlattr_add(&msg->nh, TCA_KIND, sizeof("bpf"), "bpf");
+		if (tap_nlattr_nested_start(msg, TCA_OPTIONS) < 0)
+			return -1;
+		tap_nlattr_add32(&msg->nh, TCA_BPF_FD, pmd->bpf_fd[i]);
+		snprintf(annotation, sizeof(annotation), "[%s%d]",
+			SEC_NAME_CLS_Q, i);
+		tap_nlattr_add(&msg->nh, TCA_BPF_NAME, strlen(annotation) + 1,
+			   annotation);
+		/* Actions */
+		{
+			struct action_data adata = {
+				.id = "skbedit",
+				.skbedit = {
+					.skbedit = {
+						.action = TC_ACT_PIPE,
+					},
+					.queue = i,
+				},
+			};
+			if (add_actions(rss_flow, 1, &adata, TCA_BPF_ACT) < 0)
+				return -1;
+		}
+		tap_nlattr_nested_finish(msg); /* nested TCA_OPTIONS */
+
+		/* Netlink message is now ready to be sent */
+		if (tap_nl_send(pmd->nlsk_fd, &msg->nh) < 0)
+			return -1;
+		err = tap_nl_recv_ack(pmd->nlsk_fd);
+		if (err < 0) {
+			RTE_LOG(ERR, PMD,
+				"Kernel refused TC filter rule creation (%d): %s\n",
+				errno, strerror(errno));
+			return err;
+		}
+		LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
+	}
+
+	pmd->rss_enabled = 1;
+	return err;
+}
+
+/**
+ * Manage bpf RSS keys repository with operations: init, get, release
+ *
+ * @param[in] cmd
+ *   Command on RSS keys: init, get, release
+ *
+ * @param[in, out] key_idx
+ *   Pointer to RSS Key index (out for get command, in for release command)
+ *
+ * @return -1 if couldn't get, release or init the RSS keys, 0 otherwise.
+ */
+static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx)
+{
+	__u32 i;
+	int err = -1;
+	static __u32 num_used_keys;
+	static __u32 rss_keys[MAX_RSS_KEYS] = {KEY_STAT_UNSPEC};
+	static __u32 rss_keys_initialized;
+
+	switch (cmd) {
+	case KEY_CMD_GET:
+		if (!rss_keys_initialized)
+			break;
+
+		if (num_used_keys == ARRAY_SIZE(rss_keys))
+			break;
+
+		*key_idx = num_used_keys % ARRAY_SIZE(rss_keys);
+		while (rss_keys[*key_idx] == KEY_STAT_USED)
+			*key_idx = (*key_idx + 1) % ARRAY_SIZE(rss_keys);
+
+		rss_keys[*key_idx] = KEY_STAT_USED;
+		num_used_keys++;
+		err = 0;
+	break;
+
+	case KEY_CMD_RELEASE:
+		if (!rss_keys_initialized)
+			break;
+
+		if (rss_keys[*key_idx] == KEY_STAT_USED) {
+			rss_keys[*key_idx] = KEY_STAT_AVAILABLE;
+			num_used_keys--;
+			err = 0;
+		}
+	break;
+
+	case KEY_CMD_INIT:
+		for (i = 0; i < ARRAY_SIZE(rss_keys); i++)
+			rss_keys[i] = KEY_STAT_AVAILABLE;
+
+		rss_keys_initialized = 1;
+		num_used_keys = 0;
+		err = 0;
+	break;
+
+	case KEY_CMD_DEINIT:
+		for (i = 0; i < ARRAY_SIZE(rss_keys); i++)
+			rss_keys[i] = KEY_STAT_UNSPEC;
+
+		rss_keys_initialized = 0;
+		num_used_keys = 0;
+		err = 0;
+	break;
+
+	default:
+		break;
+	}
+
+	return err;
+}
+
+/**
+ * Add RSS hash calculations and queue selection
+ *
+ * @param[in, out] pmd
+ *   Pointer to internal structure. Used to set/get RSS map fd
+ *
+ * @param[in] rss
+ *   Pointer to RSS flow actions
+ *
+ * @param[out] error
+ *   Pointer to error reporting if not NULL.
+ *
+ * @return 0 on success, negative value on failure
+ */
+static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
+			   const struct rte_flow_action_rss *rss,
+			   struct rte_flow_error *error)
+{
+	/* 4096 is the maximum number of instructions for a BPF program */
+	int i;
+	__u32 key_idx;
+	int err;
+	struct rss_key rss_entry = { .hash_fields = 0,
+				     .key_size = 0 };
+
+	/* Get a new map key for a new RSS rule */
+	err = bpf_rss_key(KEY_CMD_GET, &key_idx);
+	if (err < 0) {
+		rte_flow_error_set(
+			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Failed to get BPF RSS key");
+
+		return -1;
+	}
+
+	/* Update RSS map entry with queues */
+	rss_entry.nb_queues = rss->num;
+	for (i = 0; i < rss->num; i++)
+		rss_entry.queues[i] = rss->queue[i];
+	rss_entry.hash_fields =
+		(1 << HASH_FIELD_IPV4_L3_L4) | (1 << HASH_FIELD_IPV6_L3_L4);
+
+	/* Add this RSS entry to map */
+	err = tap_flow_bpf_update_rss_elem(pmd->map_fd, &key_idx, &rss_entry);
+
+	if (err) {
+		RTE_LOG(ERR, PMD,
+			"Failed to update BPF map entry #%u (%d): %s\n",
+			key_idx, errno, strerror(errno));
+		rte_flow_error_set(
+			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Kernel too old or not configured "
+			"to support BPF maps updates");
+
+		return -ENOTSUP;
+	}
+
+
+	/*
+	 * Load bpf rules to calculate hash for this key_idx
+	 */
+
+	flow->bpf_fd[SEC_L3_L4] =
+		tap_flow_bpf_calc_l3_l4_hash(key_idx, pmd->map_fd);
+	if (flow->bpf_fd[SEC_L3_L4] < 0) {
+		RTE_LOG(ERR, PMD,
+			"Failed to load BPF section %s (%d): %s\n",
+				sec_name[SEC_L3_L4], errno, strerror(errno));
+		rte_flow_error_set(
+			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Kernel too old or not configured "
+			"to support BPF program loading");
+
+		return -ENOTSUP;
+	}
+
+	/* Actions */
+	{
+		struct action_data adata[] = {
+			{
+				.id = "bpf",
+				.bpf = {
+					.bpf_fd = flow->bpf_fd[SEC_L3_L4],
+					.annotation = sec_name[SEC_L3_L4],
+					.bpf = {
+						.action = TC_ACT_PIPE,
+					},
+				},
+			},
+		};
+
+		if (add_actions(flow, ARRAY_SIZE(adata), adata,
+			TCA_FLOWER_ACT) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
 /**
  * Manage filter operations.
  *
diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h
index 6cc01b4..dbb7ff6 100644
--- a/drivers/net/tap/tap_flow.h
+++ b/drivers/net/tap/tap_flow.h
@@ -37,6 +37,7 @@
 #include <rte_flow.h>
 #include <rte_flow_driver.h>
 #include <rte_eth_tap.h>
+#include <tap_autoconf.h>
 
 /**
  * In TC, priority 0 means we require the kernel to allocate one for us.
@@ -49,6 +50,7 @@
 #define GROUP_MASK (0xf)
 #define GROUP_SHIFT 12
 #define MAX_GROUP GROUP_MASK
+#define RSS_PRIORITY_OFFSET 256
 
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 
@@ -69,6 +71,11 @@ enum implicit_rule_index {
 	TAP_REMOTE_MAX_IDX,
 };
 
+enum bpf_fd_idx {
+	SEC_L3_L4,
+	SEC_MAX,
+};
+
 int tap_dev_filter_ctrl(struct rte_eth_dev *dev,
 			enum rte_filter_type filter_type,
 			enum rte_filter_op filter_op,
@@ -84,5 +91,8 @@ int tap_flow_implicit_flush(struct pmd_internals *pmd,
 
 int tap_flow_bpf_cls_q(__u32 queue_idx);
 int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd);
+int tap_flow_bpf_rss_map_create(unsigned int key_size, unsigned int value_size,
+			unsigned int max_entries);
+int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value);
 
 #endif /* _TAP_FLOW_H_ */
diff --git a/drivers/net/tap/tap_rss.h b/drivers/net/tap/tap_rss.h
new file mode 100644
index 0000000..5e12531
--- /dev/null
+++ b/drivers/net/tap/tap_rss.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#ifndef _TAP_RSS_H_
+#define _TAP_RSS_H_
+
+#define TAP_MAX_QUEUES 16
+
+/* hashed fields for RSS */
+enum hash_field {
+	HASH_FIELD_IPV4_L3,	/* IPv4 src/dst addr */
+	HASH_FIELD_IPV4_L3_L4,	/* IPv4 src/dst addr + L4 src/dst ports */
+	HASH_FIELD_IPV6_L3,	/* IPv6 src/dst addr */
+	HASH_FIELD_IPV6_L3_L4,	/* IPv6 src/dst addr + L4 src/dst ports */
+	HASH_FIELD_L2_SRC,	/* Ethernet src addr */
+	HASH_FIELD_L2_DST,	/* Ethernet dst addr */
+	HASH_FIELD_L3_SRC,	/* L3 src addr */
+	HASH_FIELD_L3_DST,	/* L3 dst addr */
+	HASH_FIELD_L4_SRC,	/* TCP/UDP src ports */
+	HASH_FIELD_L4_DST,	/* TCP/UDP dst ports */
+};
+
+struct rss_key {
+	 __u8 key[128];
+	__u32 hash_fields;
+	__u32 key_size;
+	__u32 queues[TAP_MAX_QUEUES];
+	__u32 nb_queues;
+} __attribute__((packed));
+
+#endif /* _TAP_RSS_H_ */
diff --git a/drivers/net/tap/tap_tcmsgs.h b/drivers/net/tap/tap_tcmsgs.h
index 7895957..07c5074 100644
--- a/drivers/net/tap/tap_tcmsgs.h
+++ b/drivers/net/tap/tap_tcmsgs.h
@@ -34,6 +34,7 @@
 #ifndef _TAP_TCMSGS_H_
 #define _TAP_TCMSGS_H_
 
+#include <tap_autoconf.h>
 #include <linux/if_ether.h>
 #include <linux/rtnetlink.h>
 #include <linux/pkt_sched.h>
@@ -41,6 +42,9 @@
 #include <linux/tc_act/tc_mirred.h>
 #include <linux/tc_act/tc_gact.h>
 #include <linux/tc_act/tc_skbedit.h>
+#ifdef HAVE_TC_ACT_BPF
+#include <linux/tc_act/tc_bpf.h>
+#endif
 #include <inttypes.h>
 
 #include <rte_ether.h>
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/2] net/tap: add eBPF instructions to TAP device
  2018-01-10  7:06     ` [dpdk-dev] [PATCH v3 1/2] net/tap: add eBPF instructions to TAP device Ophir Munk
@ 2018-01-10  9:34       ` Pascal Mazon
  2018-01-10 10:12         ` Ophir Munk
  0 siblings, 1 reply; 42+ messages in thread
From: Pascal Mazon @ 2018-01-10  9:34 UTC (permalink / raw)
  To: Ophir Munk, dev; +Cc: Thomas Monjalon, Olga Shern

Hi Ophir,

I have a few remarks.

- Why do you define ARRAY_SIZE in tap_flow.h while it's used only in
tap_bpf_insns.c?

- I really dislike having the BPF bytecode hardcoded in tap_bpf_insns.c.
  You don't provide the commands used to generate that bytecode.
  And you don't provide the way to translate bytecode into these insns[]
arrays.
  So we're just supposed to trust that these instructions are indeed
what they pretend to be.
  The process is not repeatable nor verifiable.
 

On 10/01/2018 08:06, Ophir Munk wrote:
> TAP PMD is required to support RSS queue mapping based on rte_flow API. An
> example usage for this requirement is failsafe transparent switching from a
> PCI device to TAP device while keep redirecting packets to the same RSS
> queues on both devices.
>
> TAP RSS implementation is based on eBPF programs sent to Linux kernel
> through BPF system calls and using netlink messages to reference the
> programs as part of traffic control commands.
>
> An eBPF program acts as a traffic control classifier or action. Each
> program is written in C code under a different ELF section name. Clang 3.7
> is used to compile the C code into eBPF-formatted object file. The ELF file
> is parsed and its sections (programs) can be downloaded to the kernel using
> BPF system call. The BPF system call parameters contain the array of eBPF
> instructions. This commit includes BPF classifier and action programs
> (tap_bpf_program.c) as reference and their corresponding arrays of eBPF
> instructions (tap_bpf_insns.c). The reference file does not take part in
> dpdk compilation. The details on how to generate new eBPF code will be
> presented in another commit.
>
> In a follow up commit TAP PMD will use the eBPF programs to implement RSS
> flow rules.
>
> TAP eBPF requires Linux version 4.9 configured with BPF. TAP PMD will
> successfully compile on systems with old or non-BPF configured kernels but
> RSS rules creation on TAP devices will not be supported.
>
> Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
> ---
>  drivers/net/tap/Makefile          |   11 +
>  drivers/net/tap/tap_bpf.h         |   96 ++
>  drivers/net/tap/tap_bpf_insns.c   | 1845 +++++++++++++++++++++++++++++++++++++
>  drivers/net/tap/tap_bpf_program.c |  221 +++++
>  drivers/net/tap/tap_flow.h        |    5 +
>  5 files changed, 2178 insertions(+)
>  create mode 100644 drivers/net/tap/tap_bpf.h
>  create mode 100644 drivers/net/tap/tap_bpf_insns.c
>  create mode 100644 drivers/net/tap/tap_bpf_program.c
>
> diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
> index fd4195f..feaa5b7 100644
> --- a/drivers/net/tap/Makefile
> +++ b/drivers/net/tap/Makefile
> @@ -12,6 +12,9 @@ EXPORT_MAP := rte_pmd_tap_version.map
>  
>  LIBABIVER := 1
>  
> +# TAP_MAX_QUEUES must be a power of 2 as it will be used for masking */
> +TAP_MAX_QUEUES = 16
> +
>  CFLAGS += -O3
>  CFLAGS += -I$(SRCDIR)
>  CFLAGS += -I.
> @@ -20,6 +23,8 @@ LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
>  LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
>  LDLIBS += -lrte_bus_vdev
>  
> +CFLAGS += -DTAP_MAX_QUEUES=$(TAP_MAX_QUEUES)
> +
>  #
>  # all source are stored in SRCS-y
>  #
> @@ -27,6 +32,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += rte_eth_tap.c
>  SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_flow.c
>  SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_netlink.c
>  SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_tcmsgs.c
> +SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_bpf_insns.c
>  
>  include $(RTE_SDK)/mk/rte.lib.mk
>  
> @@ -53,6 +59,11 @@ tap_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
>  		linux/pkt_cls.h \
>  		enum TCA_FLOWER_KEY_VLAN_PRIO \
>  		$(AUTOCONF_OUTPUT)
> +	$Q sh -- '$<' '$@' \
> +		HAVE_BPF_PROG_LOAD \
> +		linux/bpf.h \
> +		enum BPF_PROG_LOAD \
> +		$(AUTOCONF_OUTPUT)
>  
>  # Create tap_autoconf.h or update it in case it differs from the new one.
>  
> diff --git a/drivers/net/tap/tap_bpf.h b/drivers/net/tap/tap_bpf.h
> new file mode 100644
> index 0000000..82775b7
> --- /dev/null
> +++ b/drivers/net/tap/tap_bpf.h
> @@ -0,0 +1,96 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2017 Mellanox Technologies, Ltd.
> + */
> +
> +#ifndef __TAP_BPF_H__
> +#define __TAP_BPF_H__
> +
> +#include <tap_autoconf.h>
> +
> +#ifdef HAVE_BPF_PROG_LOAD
> +#include <linux/bpf.h>
> +#else
> +/* BPF_MAP_UPDATE_ELEM command flags */
> +#define	BPF_ANY	0 /* create a new element or update an existing */
> +
> +/* BPF architecture instruction struct */
> +struct bpf_insn {
> +	__u8	code;
> +	__u8	dst_reg:4;
> +	__u8	src_reg:4;
> +	__s16	off;
> +	__s32	imm; /* immediate value */
> +};
> +
> +/* BPF program types */
> +enum bpf_prog_type {
> +	BPF_PROG_TYPE_UNSPEC,
> +	BPF_PROG_TYPE_SOCKET_FILTER,
> +	BPF_PROG_TYPE_KPROBE,
> +	BPF_PROG_TYPE_SCHED_CLS,
> +	BPF_PROG_TYPE_SCHED_ACT,
> +};
> +
> +/* BPF commands types */
> +enum bpf_cmd {
> +	BPF_MAP_CREATE,
> +	BPF_MAP_LOOKUP_ELEM,
> +	BPF_MAP_UPDATE_ELEM,
> +	BPF_MAP_DELETE_ELEM,
> +	BPF_MAP_GET_NEXT_KEY,
> +	BPF_PROG_LOAD,
> +};
> +
> +/* BPF maps types */
> +enum bpf_map_type {
> +	BPF_MAP_TYPE_UNSPEC,
> +	BPF_MAP_TYPE_HASH,
> +};
> +
> +/* union of anonymous structs used with TAP BPF commands */
> +union bpf_attr {
> +	/* BPF_MAP_CREATE command */
> +	struct {
> +		__u32	map_type;
> +		__u32	key_size;
> +		__u32	value_size;
> +		__u32	max_entries;
> +		__u32	map_flags;
> +		__u32	inner_map_fd;
> +	};
> +
> +	/* BPF_MAP_UPDATE_ELEM, BPF_MAP_DELETE_ELEM commands */
> +	struct {
> +		__u32		map_fd;
> +		__aligned_u64	key;
> +		union {
> +			__aligned_u64 value;
> +			__aligned_u64 next_key;
> +		};
> +		__u64		flags;
> +	};
> +
> +	/* BPF_PROG_LOAD command */
> +	struct {
> +		__u32		prog_type;
> +		__u32		insn_cnt;
> +		__aligned_u64	insns;
> +		__aligned_u64	license;
> +		__u32		log_level;
> +		__u32		log_size;
> +		__aligned_u64	log_buf;
> +		__u32		kern_version;
> +		__u32		prog_flags;
> +	};
> +} __attribute__((aligned(8)));
> +#endif
> +
> +enum {
> +	BPF_MAP_ID_KEY,
> +	BPF_MAP_ID_SIMPLE,
> +};
> +
> +static int bpf_load(enum bpf_prog_type type, const struct bpf_insn *insns,
> +		size_t insns_cnt, const char *license);
> +
> +#endif /* __TAP_BPF_H__ */
> diff --git a/drivers/net/tap/tap_bpf_insns.c b/drivers/net/tap/tap_bpf_insns.c
> new file mode 100644
> index 0000000..25aa82c
> --- /dev/null
> +++ b/drivers/net/tap/tap_bpf_insns.c
> @@ -0,0 +1,1845 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2017 Mellanox Technologies, Ltd.
> + */
> +
> +#include <errno.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <sys/queue.h>
> +#include <sys/mount.h>
> +
> +#include <rte_byteorder.h>
> +#include <rte_jhash.h>
> +#include <rte_malloc.h>
> +#include <rte_eth_tap.h>
> +#include <tap_flow.h>
> +#include <tap_autoconf.h>
> +#include <tap_tcmsgs.h>
> +#include <tap_bpf.h>
> +
> +#define ERROR                   0
> +
> +/*
> + * The queue number is offset by 1, to distinguish packets that have
> + * gone through this rule (skb->cb[1] != 0) from others.
> + */
> +#define QUEUE_OFFSET 1
> +
> +/* bpf_insn array matching cls_q section. See tap_bpf_program.c file */
> +static struct bpf_insn cls_q_insns[] = {
> +	{0x61,    1,    1,       52, 0x00000000},
> +	{0x18,    2,    0,        0, 0xdeadbeef},
> +	{0x00,    0,    0,        0, 0x00000000},
> +	{0x63,   10,    2,       -4, 0x00000000},
> +	{0x61,    2,   10,       -4, 0x00000000},
> +	{0x07,    2,    0,        0, 0x00000001},
> +	{0x67,    2,    0,        0, 0x00000020},
> +	{0x77,    2,    0,        0, 0x00000020},
> +	{0xb7,    0,    0,        0, 0xffffffff},
> +	{0x1d,    1,    2,        1, 0x00000000},
> +	{0xb7,    0,    0,        0, 0x00000000},
> +	{0x95,    0,    0,        0, 0x00000000},
> +};
> +
> +/**
> + * Load BPF program (section cls_q) into the kernel and return a bpf fd
> + *
> + * @param queue_idx
> + *   Queue index matching packet cb
> + *
> + * @return
> + *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
> + */
> +int tap_flow_bpf_cls_q(__u32 queue_idx)
> +{
> +	cls_q_insns[1].imm = queue_idx;
> +
> +	return bpf_load(BPF_PROG_TYPE_SCHED_CLS,
> +		(struct bpf_insn *)cls_q_insns,
> +		ARRAY_SIZE(cls_q_insns),
> +		"Dual BSD/GPL");
> +}
> +
> +/* bpf_insn array matching l3_l4 section. see tap_bpf_program.c file */
> +static struct bpf_insn l3_l4_hash_insns[] = {
> +	{0xbf,    7,    1,        0, 0x00000000},
> +	{0x61,    8,    7,       16, 0x00000000},
> +	{0x61,    6,    7,       76, 0x00000000},
> +	{0x61,    9,    7,       80, 0x00000000},
> +	{0x18,    1,    0,        0, 0xdeadbeef},
> +	{0x00,    0,    0,        0, 0x00000000},
> +	{0x63,   10,    1,       -4, 0x00000000},
> +	{0xbf,    2,   10,        0, 0x00000000},
> +	{0x07,    2,    0,        0, 0xfffffffc},
> +	{0x18,    1,    1,        0, 0x0000cafe},
> +	{0x00,    0,    0,        0, 0x00000000},
> +	{0x85,    0,    0,        0, 0x00000001},
> +	{0x55,    0,    0,       21, 0x00000000},
> +	{0xb7,    1,    0,        0, 0x00000a64},
> +	{0x6b,   10,    1,      -16, 0x00000000},
> +	{0x18,    1,    0,        0, 0x69666e6f},
> +	{0x00,    0,    0,        0, 0x65727567},
> +	{0x7b,   10,    1,      -24, 0x00000000},
> +	{0x18,    1,    0,        0, 0x6e207369},
> +	{0x00,    0,    0,        0, 0x6320746f},
> +	{0x7b,   10,    1,      -32, 0x00000000},
> +	{0x18,    1,    0,        0, 0x20737372},
> +	{0x00,    0,    0,        0, 0x2079656b},
> +	{0x7b,   10,    1,      -40, 0x00000000},
> +	{0x18,    1,    0,        0, 0x68736168},
> +	{0x00,    0,    0,        0, 0x203a2928},
> +	{0x7b,   10,    1,      -48, 0x00000000},
> +	{0xb7,    7,    0,        0, 0x00000000},
> +	{0x73,   10,    7,      -14, 0x00000000},
> +	{0xbf,    1,   10,        0, 0x00000000},
> +	{0x07,    1,    0,        0, 0xffffffd0},
> +	{0xb7,    2,    0,        0, 0x00000023},
> +	{0x85,    0,    0,        0, 0x00000006},
> +	{0x05,    0,    0,     1632, 0x00000000},
> +	{0xb7,    1,    0,        0, 0x0000000e},
> +	{0x61,    2,    7,       20, 0x00000000},
> +	{0x15,    2,    0,       10, 0x00000000},
> +	{0x61,    2,    7,       28, 0x00000000},
> +	{0x55,    2,    0,        8, 0x0000a888},
> +	{0xbf,    2,    7,        0, 0x00000000},
> +	{0xb7,    7,    0,        0, 0x00000000},
> +	{0xbf,    1,    6,        0, 0x00000000},
> +	{0x07,    1,    0,        0, 0x00000012},
> +	{0x2d,    1,    9,     1622, 0x00000000},
> +	{0xb7,    1,    0,        0, 0x00000012},
> +	{0x69,    8,    6,       16, 0x00000000},
> +	{0xbf,    7,    2,        0, 0x00000000},
> +	{0x7b,   10,    7,      -56, 0x00000000},
> +	{0x57,    8,    0,        0, 0x0000ffff},
> +	{0x15,    8,    0,      409, 0x0000dd86},
> +	{0xb7,    7,    0,        0, 0x00000003},
> +	{0x55,    8,    0,     1614, 0x00000008},
> +	{0x0f,    6,    1,        0, 0x00000000},
> +	{0xb7,    7,    0,        0, 0x00000000},
> +	{0xbf,    1,    6,        0, 0x00000000},
> +	{0x07,    1,    0,        0, 0x00000018},
> +	{0x2d,    1,    9,     1609, 0x00000000},
> +	{0x71,    3,    6,       12, 0x00000000},
> +	{0xbf,    1,    3,        0, 0x00000000},
> +	{0x67,    1,    0,        0, 0x00000038},
> +	{0xc7,    1,    0,        0, 0x00000020},
> +	{0x77,    1,    0,        0, 0x0000001f},
> +	{0x57,    1,    0,        0, 0x2cc681d1},
> +	{0x67,    3,    0,        0, 0x00000018},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x40000000},
> +	{0xb7,    2,    0,        0, 0x00000000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x598d03a2},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x20000000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xb31a0745},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x10000000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x66340e8a},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x08000000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xcc681d15},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x04000000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x98d03a2b},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x02000000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x31a07456},
> +	{0x57,    3,    0,        0, 0x01000000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x6340e8ad},
> +	{0x71,    3,    6,       13, 0x00000000},
> +	{0x67,    3,    0,        0, 0x00000010},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00800000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xc681d15b},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00400000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x8d03a2b7},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00200000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x1a07456f},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00100000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x340e8ade},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00080000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x681d15bd},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00040000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xd03a2b7b},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00020000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xa07456f6},
> +	{0x57,    3,    0,        0, 0x00010000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x40e8aded},
> +	{0x71,    3,    6,       14, 0x00000000},
> +	{0x67,    3,    0,        0, 0x00000008},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00008000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x81d15bdb},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00004000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x03a2b7b7},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00002000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x07456f6f},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00001000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x0e8adedf},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000800},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x1d15bdbf},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000400},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x3a2b7b7e},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000200},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x7456f6fd},
> +	{0x57,    3,    0,        0, 0x00000100},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xe8adedfa},
> +	{0x71,    3,    6,       15, 0x00000000},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000080},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xd15bdbf4},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000040},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xa2b7b7e9},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000020},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x456f6fd3},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000010},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x8adedfa7},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000008},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x15bdbf4f},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000004},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x2b7b7e9e},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000002},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x56f6fd3d},
> +	{0x57,    3,    0,        0, 0x00000001},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xadedfa7b},
> +	{0x71,    4,    6,       16, 0x00000000},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x67,    5,    0,        0, 0x00000038},
> +	{0xc7,    5,    0,        0, 0x00000020},
> +	{0xb7,    3,    0,        0, 0xffffffff},
> +	{0x6d,    5,    3,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x5bdbf4f7},
> +	{0x67,    4,    0,        0, 0x00000018},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x40000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xb7b7e9ef},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x20000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x6f6fd3df},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x10000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xdedfa7bf},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x08000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xbdbf4f7f},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x04000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x7b7e9eff},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x02000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xf6fd3dff},
> +	{0x57,    4,    0,        0, 0x01000000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xedfa7bfe},
> +	{0x71,    4,    6,       17, 0x00000000},
> +	{0x67,    4,    0,        0, 0x00000010},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00800000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xdbf4f7fc},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00400000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xb7e9eff9},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00200000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x6fd3dff2},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00100000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xdfa7bfe5},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00080000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xbf4f7fca},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00040000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x7e9eff94},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00020000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xfd3dff28},
> +	{0x57,    4,    0,        0, 0x00010000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xfa7bfe51},
> +	{0x71,    4,    6,       18, 0x00000000},
> +	{0x67,    4,    0,        0, 0x00000008},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00008000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xf4f7fca2},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00004000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xe9eff945},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00002000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xd3dff28a},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00001000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xa7bfe514},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000800},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x4f7fca28},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000400},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x9eff9450},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000200},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x3dff28a0},
> +	{0x57,    4,    0,        0, 0x00000100},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x7bfe5141},
> +	{0x71,    4,    6,       19, 0x00000000},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000080},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xf7fca283},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000040},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xeff94506},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000020},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xdff28a0c},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000010},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xbfe51418},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000008},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x7fca2831},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000004},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xff945063},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000002},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xff28a0c6},
> +	{0x57,    4,    0,        0, 0x00000001},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xfe51418c},
> +	{0x71,    4,    6,       20, 0x00000000},
> +	{0x67,    4,    0,        0, 0x00000008},
> +	{0x71,    5,    6,       21, 0x00000000},
> +	{0x4f,    4,    5,        0, 0x00000000},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x67,    5,    0,        0, 0x00000030},
> +	{0xc7,    5,    0,        0, 0x00000020},
> +	{0x6d,    5,    3,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xfca28319},
> +	{0x67,    4,    0,        0, 0x00000010},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x40000000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xf9450633},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x20000000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xf28a0c67},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x10000000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xe51418ce},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x08000000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xca28319d},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x04000000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x9450633b},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x02000000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x28a0c676},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x01000000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x51418ced},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00800000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xa28319db},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00400000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x450633b6},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00200000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x8a0c676c},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00100000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x1418ced8},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00080000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x28319db1},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00040000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x50633b63},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00020000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xa0c676c6},
> +	{0x57,    4,    0,        0, 0x00010000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x418ced8d},
> +	{0x71,    3,    6,       22, 0x00000000},
> +	{0x67,    3,    0,        0, 0x00000008},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00008000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x8319db1a},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00004000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x0633b634},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00002000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x0c676c68},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00001000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x18ced8d1},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000800},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x319db1a3},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000400},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x633b6347},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000200},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xc676c68f},
> +	{0x57,    3,    0,        0, 0x00000100},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x8ced8d1f},
> +	{0x71,    3,    6,       23, 0x00000000},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000080},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x19db1a3e},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000040},
> +	{0x79,    5,   10,      -56, 0x00000000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x33b6347d},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000020},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x676c68fa},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000010},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xced8d1f4},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000008},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x9db1a3e9},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000004},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x3b6347d2},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000002},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x76c68fa5},
> +	{0x57,    3,    0,        0, 0x00000001},
> +	{0x1d,    3,    2,     1177, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xed8d1f4a},
> +	{0x05,    0,    0,     1175, 0x00000000},
> +	{0x0f,    6,    1,        0, 0x00000000},
> +	{0xb7,    7,    0,        0, 0x00000000},
> +	{0xbf,    1,    6,        0, 0x00000000},
> +	{0x07,    1,    0,        0, 0x0000002c},
> +	{0x2d,    1,    9,     1202, 0x00000000},
> +	{0x61,    4,    6,        8, 0x00000000},
> +	{0xbf,    1,    4,        0, 0x00000000},
> +	{0x67,    1,    0,        0, 0x00000038},
> +	{0xc7,    1,    0,        0, 0x00000020},
> +	{0x77,    1,    0,        0, 0x0000001f},
> +	{0x57,    1,    0,        0, 0x2cc681d1},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00000040},
> +	{0xb7,    2,    0,        0, 0x00000000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x598d03a2},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00000020},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xb31a0745},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00000010},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x66340e8a},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00000008},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xcc681d15},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00000004},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x98d03a2b},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00000002},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x31a07456},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00000001},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x6340e8ad},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00008000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xc681d15b},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00004000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x8d03a2b7},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00002000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x1a07456f},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00001000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x340e8ade},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00000800},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x681d15bd},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00000400},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xd03a2b7b},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00000200},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xa07456f6},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00000100},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x40e8aded},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00800000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x81d15bdb},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00400000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x03a2b7b7},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00200000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x07456f6f},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00100000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x0e8adedf},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00080000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x1d15bdbf},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00040000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x3a2b7b7e},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00020000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x7456f6fd},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00010000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xe8adedfa},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x67,    5,    0,        0, 0x00000020},
> +	{0xc7,    5,    0,        0, 0x00000020},
> +	{0xb7,    3,    0,        0, 0xffffffff},
> +	{0x6d,    5,    3,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xd15bdbf4},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x40000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xa2b7b7e9},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x20000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x456f6fd3},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x10000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x8adedfa7},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x08000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x15bdbf4f},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x04000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x2b7b7e9e},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x02000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x56f6fd3d},
> +	{0x57,    4,    0,        0, 0x01000000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xadedfa7b},
> +	{0x61,    4,    6,       12, 0x00000000},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000080},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x5bdbf4f7},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000040},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xb7b7e9ef},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000020},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x6f6fd3df},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000010},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xdedfa7bf},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000008},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xbdbf4f7f},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000004},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x7b7e9eff},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000002},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xf6fd3dff},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000001},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xedfa7bfe},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00008000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xdbf4f7fc},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00004000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xb7e9eff9},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00002000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x6fd3dff2},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00001000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xdfa7bfe5},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000800},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xbf4f7fca},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000400},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x7e9eff94},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000200},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xfd3dff28},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000100},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xfa7bfe51},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00800000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xf4f7fca2},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00400000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xe9eff945},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00200000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xd3dff28a},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00100000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xa7bfe514},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00080000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x4f7fca28},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00040000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x9eff9450},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00020000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x3dff28a0},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00010000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x7bfe5141},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x67,    5,    0,        0, 0x00000020},
> +	{0xc7,    5,    0,        0, 0x00000020},
> +	{0x6d,    5,    3,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xf7fca283},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x40000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xeff94506},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x20000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xdff28a0c},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x10000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xbfe51418},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x08000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x7fca2831},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x04000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xff945063},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x02000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xff28a0c6},
> +	{0x57,    4,    0,        0, 0x01000000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xfe51418c},
> +	{0x61,    4,    6,       16, 0x00000000},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000080},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xfca28319},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000040},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xf9450633},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000020},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xf28a0c67},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000010},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xe51418ce},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000008},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xca28319d},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000004},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x9450633b},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000002},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x28a0c676},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000001},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x51418ced},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00008000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xa28319db},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00004000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x450633b6},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00002000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x8a0c676c},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00001000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x1418ced8},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000800},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x28319db1},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000400},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x50633b63},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000200},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xa0c676c6},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000100},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x418ced8d},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00800000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x8319db1a},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00400000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x0633b634},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00200000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x0c676c68},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00100000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x18ced8d1},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00080000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x319db1a3},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00040000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x633b6347},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00020000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xc676c68f},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00010000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x8ced8d1f},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x67,    5,    0,        0, 0x00000020},
> +	{0xc7,    5,    0,        0, 0x00000020},
> +	{0x6d,    5,    3,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x19db1a3e},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x40000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x33b6347d},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x20000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x676c68fa},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x10000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xced8d1f4},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x08000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x9db1a3e9},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x04000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x3b6347d2},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x02000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x76c68fa5},
> +	{0x57,    4,    0,        0, 0x01000000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xed8d1f4a},
> +	{0x61,    4,    6,       20, 0x00000000},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000080},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xdb1a3e94},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000040},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xb6347d28},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000020},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x6c68fa51},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000010},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xd8d1f4a3},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000008},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xb1a3e946},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000004},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x6347d28d},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000002},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xc68fa51a},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000001},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x8d1f4a35},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00008000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x1a3e946b},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00004000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x347d28d7},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00002000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x68fa51ae},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00001000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xd1f4a35c},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000800},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xa3e946b9},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000400},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x47d28d73},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000200},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x8fa51ae7},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000100},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x1f4a35cf},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00800000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x3e946b9e},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00400000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x7d28d73c},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00200000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xfa51ae78},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00100000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xf4a35cf1},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00080000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xe946b9e3},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00040000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xd28d73c7},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00020000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xa51ae78e},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00010000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x4a35cf1c},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x67,    5,    0,        0, 0x00000020},
> +	{0xc7,    5,    0,        0, 0x00000020},
> +	{0x6d,    5,    3,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x946b9e38},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x40000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x28d73c71},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x20000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x51ae78e3},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x10000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xa35cf1c6},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x08000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x46b9e38d},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x04000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x8d73c71b},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x02000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x1ae78e36},
> +	{0x57,    4,    0,        0, 0x01000000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x35cf1c6c},
> +	{0x61,    4,    6,       24, 0x00000000},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000080},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x6b9e38d9},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000040},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xd73c71b2},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000020},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xae78e364},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000010},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x5cf1c6c9},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000008},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xb9e38d92},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000004},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x73c71b25},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000002},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xe78e364b},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000001},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xcf1c6c96},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00008000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x9e38d92c},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00004000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x3c71b259},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00002000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x78e364b2},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00001000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xf1c6c964},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000800},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xe38d92c9},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000400},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xc71b2593},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000200},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x8e364b27},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000100},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x1c6c964e},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00800000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x38d92c9c},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00400000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x71b25938},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00200000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xe364b270},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00100000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xc6c964e0},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00080000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x8d92c9c0},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00040000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x1b259380},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00020000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x364b2700},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00010000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x6c964e01},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x67,    5,    0,        0, 0x00000020},
> +	{0xc7,    5,    0,        0, 0x00000020},
> +	{0x6d,    5,    3,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xd92c9c03},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x40000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xb2593807},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x20000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x64b2700f},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x10000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xc964e01e},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x08000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x92c9c03d},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x04000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x2593807a},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x02000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x4b2700f4},
> +	{0x57,    4,    0,        0, 0x01000000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x964e01e8},
> +	{0x61,    4,    6,       28, 0x00000000},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000080},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x2c9c03d1},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000040},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x593807a3},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000020},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xb2700f46},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000010},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x64e01e8d},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000008},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xc9c03d1a},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000004},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x93807a35},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000002},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x2700f46b},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000001},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x4e01e8d6},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00008000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x9c03d1ad},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00004000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x3807a35b},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00002000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x700f46b6},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00001000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xe01e8d6c},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000800},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xc03d1ad9},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000400},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x807a35b3},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000200},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x00f46b66},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000100},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x01e8d6cc},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00800000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x03d1ad99},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00400000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x07a35b32},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00200000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x0f46b665},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00100000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x1e8d6cca},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00080000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x3d1ad994},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00040000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x7a35b328},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00020000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xf46b6651},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00010000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xe8d6cca2},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x67,    5,    0,        0, 0x00000020},
> +	{0xc7,    5,    0,        0, 0x00000020},
> +	{0x6d,    5,    3,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xd1ad9944},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x40000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xa35b3289},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x20000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x46b66512},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x10000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x8d6cca25},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x08000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x1ad9944a},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x04000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x35b32894},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x02000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x6b665129},
> +	{0x57,    4,    0,        0, 0x01000000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xd6cca253},
> +	{0x61,    4,    6,       32, 0x00000000},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000080},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xad9944a7},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000040},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x5b32894f},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000020},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xb665129f},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000010},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x6cca253e},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000008},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xd9944a7d},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000004},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xb32894fb},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000002},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x665129f6},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000001},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xcca253ec},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00008000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x9944a7d9},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00004000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x32894fb2},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00002000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x65129f65},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00001000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xca253eca},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000800},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x944a7d95},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000400},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x2894fb2a},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000200},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x5129f655},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000100},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xa253ecab},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00800000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x44a7d956},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00400000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x894fb2ac},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00200000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x129f6558},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00100000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x253ecab1},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00080000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x4a7d9563},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00040000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x94fb2ac7},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00020000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x29f6558f},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00010000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x53ecab1e},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x67,    5,    0,        0, 0x00000020},
> +	{0xc7,    5,    0,        0, 0x00000020},
> +	{0x6d,    5,    3,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xa7d9563d},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x40000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x4fb2ac7a},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x20000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x9f6558f5},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x10000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x3ecab1ea},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x08000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x7d9563d5},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x04000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xfb2ac7ab},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x02000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xf6558f56},
> +	{0x57,    4,    0,        0, 0x01000000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xecab1eac},
> +	{0x61,    4,    6,       36, 0x00000000},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000080},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xd9563d59},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000040},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xb2ac7ab2},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000020},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x6558f564},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000010},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xcab1eac8},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000008},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x9563d590},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000004},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x2ac7ab20},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000002},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x558f5641},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000001},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xab1eac83},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00008000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x563d5906},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00004000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xac7ab20c},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00002000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x58f56418},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00001000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xb1eac831},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000800},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x63d59063},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000400},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xc7ab20c7},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000200},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x8f56418f},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00000100},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x1eac831e},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00800000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x3d59063c},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00400000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x7ab20c78},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00200000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xf56418f0},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00100000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xeac831e1},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00080000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xd59063c2},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00040000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xab20c784},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00020000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x56418f09},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x00010000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xac831e12},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x67,    5,    0,        0, 0x00000020},
> +	{0xc7,    5,    0,        0, 0x00000020},
> +	{0x6d,    5,    3,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x59063c25},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x40000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xb20c784b},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x20000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x6418f097},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x10000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xc831e12f},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x08000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x9063c25f},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x04000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x20c784be},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x57,    5,    0,        0, 0x02000000},
> +	{0x1d,    5,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x418f097c},
> +	{0x57,    4,    0,        0, 0x01000000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x831e12f9},
> +	{0x71,    4,    6,       40, 0x00000000},
> +	{0x67,    4,    0,        0, 0x00000008},
> +	{0x71,    5,    6,       41, 0x00000000},
> +	{0x4f,    4,    5,        0, 0x00000000},
> +	{0xbf,    5,    4,        0, 0x00000000},
> +	{0x67,    5,    0,        0, 0x00000030},
> +	{0xc7,    5,    0,        0, 0x00000020},
> +	{0x6d,    5,    3,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x063c25f3},
> +	{0x67,    4,    0,        0, 0x00000010},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x40000000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x0c784be7},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x20000000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x18f097cf},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x10000000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x31e12f9f},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x08000000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x63c25f3f},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x04000000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xc784be7f},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x02000000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x8f097cff},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x01000000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x1e12f9fe},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00800000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x3c25f3fc},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00400000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x784be7f8},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00200000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xf097cff0},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00100000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xe12f9fe0},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00080000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xc25f3fc1},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00040000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x84be7f83},
> +	{0xbf,    3,    4,        0, 0x00000000},
> +	{0x57,    3,    0,        0, 0x00020000},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x097cff07},
> +	{0x57,    4,    0,        0, 0x00010000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x12f9fe0f},
> +	{0x71,    3,    6,       42, 0x00000000},
> +	{0x67,    3,    0,        0, 0x00000008},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00008000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x25f3fc1f},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00004000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x4be7f83f},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00002000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x97cff07f},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00001000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x2f9fe0fe},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000800},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x5f3fc1fd},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000400},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xbe7f83fb},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000200},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x7cff07f7},
> +	{0x57,    3,    0,        0, 0x00000100},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xf9fe0fee},
> +	{0x71,    3,    6,       43, 0x00000000},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000080},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xf3fc1fdc},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000040},
> +	{0x79,    5,   10,      -56, 0x00000000},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xe7f83fb8},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000020},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xcff07f70},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000010},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x9fe0fee1},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000008},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x3fc1fdc2},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000004},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0x7f83fb85},
> +	{0xbf,    4,    3,        0, 0x00000000},
> +	{0x57,    4,    0,        0, 0x00000002},
> +	{0x1d,    4,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xff07f70a},
> +	{0x57,    3,    0,        0, 0x00000001},
> +	{0x1d,    3,    2,        1, 0x00000000},
> +	{0xa7,    1,    0,        0, 0xfe0fee15},
> +	{0x71,    2,    0,      201, 0x00000000},
> +	{0x67,    2,    0,        0, 0x00000008},
> +	{0x71,    3,    0,      200, 0x00000000},
> +	{0x4f,    2,    3,        0, 0x00000000},
> +	{0x71,    3,    0,      203, 0x00000000},
> +	{0x67,    3,    0,        0, 0x00000008},
> +	{0x71,    4,    0,      202, 0x00000000},
> +	{0x4f,    3,    4,        0, 0x00000000},
> +	{0x67,    3,    0,        0, 0x00000010},
> +	{0x4f,    3,    2,        0, 0x00000000},
> +	{0x67,    1,    0,        0, 0x00000020},
> +	{0x77,    1,    0,        0, 0x00000020},
> +	{0xbf,    2,    1,        0, 0x00000000},
> +	{0x3f,    2,    3,        0, 0x00000000},
> +	{0x2f,    2,    3,        0, 0x00000000},
> +	{0x1f,    1,    2,        0, 0x00000000},
> +	{0x57,    1,    0,        0, 0x0000000f},
> +	{0x67,    1,    0,        0, 0x00000002},
> +	{0x0f,    0,    1,        0, 0x00000000},
> +	{0x71,    1,    0,      137, 0x00000000},
> +	{0x67,    1,    0,        0, 0x00000008},
> +	{0x71,    2,    0,      136, 0x00000000},
> +	{0x4f,    1,    2,        0, 0x00000000},
> +	{0x71,    2,    0,      138, 0x00000000},
> +	{0x71,    3,    0,      139, 0x00000000},
> +	{0x67,    3,    0,        0, 0x00000008},
> +	{0x4f,    3,    2,        0, 0x00000000},
> +	{0x67,    3,    0,        0, 0x00000010},
> +	{0x4f,    3,    1,        0, 0x00000000},
> +	{0x07,    3,    0,        0, 0x00000001},
> +	{0x63,    5,    3,       52, 0x00000000},
> +	{0xb7,    7,    0,        0, 0x00000001},
> +	{0xbf,    0,    7,        0, 0x00000000},
> +	{0x95,    0,    0,        0, 0x00000000},
> +};
> +
> +/**
> + * Load BPF program (section l3_l4) into the kernel and return a bpf fd.
> + *
> + * @param[in] key_idx
> + *   RSS MAP key index
> + *
> + * @param[in] map_fd
> + *   BPF RSS map file descriptor
> + *
> + * @return
> + *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
> + */
> +int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd)
> +{
> +	l3_l4_hash_insns[4].imm = key_idx;
> +	l3_l4_hash_insns[9].imm = map_fd;
> +
> +	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
> +		(struct bpf_insn *)l3_l4_hash_insns,
> +		ARRAY_SIZE(l3_l4_hash_insns),
> +		"Dual BSD/GPL");
> +}
> +
> +
> +#ifndef __NR_bpf
> +# if defined(__i386__)
> +#  define __NR_bpf 357
> +# elif defined(__x86_64__)
> +#  define __NR_bpf 321
> +# elif defined(__aarch64__)
> +#  define __NR_bpf 280
> +# elif defined(__sparc__)
> +#  define __NR_bpf 349
> +# elif defined(__s390__)
> +#  define __NR_bpf 351
> +# else
> +#  error __NR_bpf not defined. libbpf does not support your arch.
> +# endif
> +#endif
> +
> +/**
> + * Helper function to convert a pointer to unsigned 64 bits
> + *
> + * @param[in] ptr
> + *   pointer to address
> + *
> + * @return
> + *   64 bit unsigned long type of pointer address
> + */
> +static inline __u64 ptr_to_u64(const void *ptr)
> +{
> +	return (__u64)(unsigned long)ptr;
> +}
> +
> +/**
> + * Call BPF system call
> + *
> + * @param[in] cmd
> + *   BPF command for program loading, map creation, map entry update, etc
> + *
> + * @param[in] attr
> + *   System call attributes relevant to system call command
> + *
> + * @param[in] size
> + *   size of attr parameter
> + *
> + * @return
> + *   -1 if BPF system call failed, 0 otherwise
> + */
> +static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
> +			unsigned int size)
> +{
> +	return syscall(__NR_bpf, cmd, attr, size);
> +}
> +
> +/**
> + * Load BPF instructions to kernel
> + *
> + * @param[in] type
> + *   BPF program type: classifieir or action
> + *
> + * @param[in] insns
> + *   Array of BPF instructions (equivalent to BPF instructions)
> + *
> + * @param[in] insns_cnt
> + *   Number of BPF instructions (size of array)
> + *
> + * @param[in] lincense
> + *   License string that must be acknowledged by the kernel
> + *
> + * @return
> + *   -1 if the BPF program couldn't be loaded, fd (file descriptor) otherwise
> + */
> +static int bpf_load(enum bpf_prog_type type,
> +		  const struct bpf_insn *insns,
> +		  size_t insns_cnt,
> +		  const char *license)
> +{
> +	union bpf_attr attr;
> +
> +	bzero(&attr, sizeof(attr));
> +	attr.prog_type = type;
> +	attr.insn_cnt = (__u32)insns_cnt;
> +	attr.insns = ptr_to_u64(insns);
> +	attr.license = ptr_to_u64(license);
> +	attr.log_buf = ptr_to_u64(NULL);
> +	attr.log_level = 0;
> +	attr.kern_version = 0;
> +
> +	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
> +}
> diff --git a/drivers/net/tap/tap_bpf_program.c b/drivers/net/tap/tap_bpf_program.c
> new file mode 100644
> index 0000000..08bc881
> --- /dev/null
> +++ b/drivers/net/tap/tap_bpf_program.c
> @@ -0,0 +1,221 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2017 Mellanox Technologies, Ltd.
> + */
> +
> +#include <stdint.h>
> +#include <stdbool.h>
> +#include <sys/types.h>
> +#include <sys/socket.h>
> +#include <asm/types.h>
> +#include <linux/in.h>
> +#include <linux/if.h>
> +#include <linux/if_ether.h>
> +#include <linux/ip.h>
> +#include <linux/ipv6.h>
> +#include <linux/if_tunnel.h>
> +#include <linux/filter.h>
> +#include <linux/bpf.h>
> +
> +#include "tap_rss.h"
> +
> +/** Create IPv4 address */
> +#define IPv4(a, b, c, d) ((__u32)(((a) & 0xff) << 24) | \
> +		(((b) & 0xff) << 16) | \
> +		(((c) & 0xff) << 8)  | \
> +		((d) & 0xff))
> +
> +#define PORT(a, b) ((__u16)(((a) & 0xff) << 8) | \
> +		((b) & 0xff))
> +
> +/*
> + * The queue number is offset by 1, to distinguish packets that have
> + * gone through this rule (skb->cb[1] != 0) from others.
> + */
> +#define QUEUE_OFFSET		1
> +#define PIN_GLOBAL_NS		2
> +
> +#define KEY_IDX			0
> +#define BPF_MAP_ID_KEY	1
> +
> +struct vlan_hdr {
> +	__be16 proto;
> +	__be16 tci;
> +};
> +
> +struct bpf_elf_map __attribute__((section("maps"), used))
> +map_keys = {
> +	.type           =       BPF_MAP_TYPE_HASH,
> +	.id             =       BPF_MAP_ID_KEY,
> +	.size_key       =       sizeof(__u32),
> +	.size_value     =       sizeof(struct rss_key),
> +	.max_elem       =       256,
> +	.pinning        =       PIN_GLOBAL_NS,
> +};
> +
> +__section("cls_q") int
> +match_q(struct __sk_buff *skb)
> +{
> +	__u32 queue = skb->cb[1];
> +	volatile __u32 q = 0xdeadbeef;
> +	__u32 match_queue = QUEUE_OFFSET + q;
> +
> +	/* printt("match_q$i() queue = %d\n", queue); */
> +
> +	if (queue != match_queue)
> +		return TC_ACT_OK;
> +	return TC_ACT_UNSPEC;
> +}
> +
> +
> +struct ipv4_l3_l4_tuple {
> +	__u32    src_addr;
> +	__u32    dst_addr;
> +	__u16    dport;
> +	__u16    sport;
> +} __attribute__((packed));
> +
> +struct ipv6_l3_l4_tuple {
> +	__u8        src_addr[16];
> +	__u8        dst_addr[16];
> +	__u16       dport;
> +	__u16       sport;
> +} __attribute__((packed));
> +
> +static const __u8 def_rss_key[] = {
> +	0xd1, 0x81, 0xc6, 0x2c,
> +	0xf7, 0xf4, 0xdb, 0x5b,
> +	0x19, 0x83, 0xa2, 0xfc,
> +	0x94, 0x3e, 0x1a, 0xdb,
> +	0xd9, 0x38, 0x9e, 0x6b,
> +	0xd1, 0x03, 0x9c, 0x2c,
> +	0xa7, 0x44, 0x99, 0xad,
> +	0x59, 0x3d, 0x56, 0xd9,
> +	0xf3, 0x25, 0x3c, 0x06,
> +	0x2a, 0xdc, 0x1f, 0xfc,
> +};
> +
> +static __u32  __attribute__((always_inline))
> +rte_softrss_be(const __u32 *input_tuple, const uint8_t *rss_key,
> +		__u8 input_len)
> +{
> +	__u32 i, j, hash = 0;
> +#pragma unroll
> +	for (j = 0; j < input_len; j++) {
> +#pragma unroll
> +		for (i = 0; i < 32; i++) {
> +			if (input_tuple[j] & (1 << (31 - i))) {
> +				hash ^= ((const __u32 *)def_rss_key)[j] << i |
> +				(__u32)((uint64_t)
> +				(((const __u32 *)def_rss_key)[j + 1])
> +					>> (32 - i));
> +			}
> +		}
> +	}
> +	return hash;
> +}
> +
> +static int __attribute__((always_inline))
> +rss_l3_l4(struct __sk_buff *skb)
> +{
> +	void *data_end = (void *)(long)skb->data_end;
> +	void *data = (void *)(long)skb->data;
> +	__u16 proto = (__u16)skb->protocol;
> +	__u32 key_idx = 0xdeadbeef;
> +	__u32 hash;
> +	struct rss_key *rsskey;
> +	__u64 off = ETH_HLEN;
> +	int j;
> +	__u8 *key = 0;
> +	__u32 len;
> +	__u32 queue = 0;
> +
> +	rsskey = map_lookup_elem(&map_keys, &key_idx);
> +	if (!rsskey) {
> +		printt("hash(): rss key is not configured\n");
> +		return TC_ACT_OK;
> +	}
> +	key = (__u8 *)rsskey->key;
> +
> +	/* Get correct proto for 802.1ad */
> +	if (skb->vlan_present && skb->vlan_proto == htons(ETH_P_8021AD)) {
> +		if (data + ETH_ALEN * 2 + sizeof(struct vlan_hdr) +
> +		    sizeof(proto) > data_end)
> +			return TC_ACT_OK;
> +		proto = *(__u16 *)(data + ETH_ALEN * 2 +
> +				   sizeof(struct vlan_hdr));
> +		off += sizeof(struct vlan_hdr);
> +	}
> +
> +	if (proto == htons(ETH_P_IP)) {
> +		if (data + off + sizeof(struct iphdr) + sizeof(__u32)
> +			> data_end)
> +			return TC_ACT_OK;
> +
> +		__u8 *src_dst_addr = data + off + offsetof(struct iphdr, saddr);
> +		__u8 *src_dst_port = data + off + sizeof(struct iphdr);
> +		struct ipv4_l3_l4_tuple v4_tuple = {
> +			.src_addr = IPv4(*(src_dst_addr + 0),
> +					*(src_dst_addr + 1),
> +					*(src_dst_addr + 2),
> +					*(src_dst_addr + 3)),
> +			.dst_addr = IPv4(*(src_dst_addr + 4),
> +					*(src_dst_addr + 5),
> +					*(src_dst_addr + 6),
> +					*(src_dst_addr + 7)),
> +			.sport = PORT(*(src_dst_port + 0),
> +					*(src_dst_port + 1)),
> +			.dport = PORT(*(src_dst_port + 2),
> +					*(src_dst_port + 3)),
> +		};
> +		__u8 input_len = sizeof(v4_tuple) / sizeof(__u32);
> +		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV4_L3))
> +			input_len--;
> +		hash = rte_softrss_be((__u32 *)&v4_tuple, key, 3);
> +	} else if (proto == htons(ETH_P_IPV6)) {
> +		if (data + off + sizeof(struct ipv6hdr) +
> +					sizeof(__u32) > data_end)
> +			return TC_ACT_OK;
> +		__u8 *src_dst_addr = data + off +
> +					offsetof(struct ipv6hdr, saddr);
> +		__u8 *src_dst_port = data + off +
> +					sizeof(struct ipv6hdr);
> +		struct ipv6_l3_l4_tuple v6_tuple;
> +		for (j = 0; j < 4; j++)
> +			*((uint32_t *)&v6_tuple.src_addr + j) =
> +				__builtin_bswap32(*((uint32_t *)
> +						src_dst_addr + j));
> +		for (j = 0; j < 4; j++)
> +			*((uint32_t *)&v6_tuple.dst_addr + j) =
> +				__builtin_bswap32(*((uint32_t *)
> +						src_dst_addr + 4 + j));
> +		v6_tuple.sport = PORT(*(src_dst_port + 0),
> +			      *(src_dst_port + 1));
> +		v6_tuple.dport = PORT(*(src_dst_port + 2),
> +			      *(src_dst_port + 3));
> +
> +		__u8 input_len = sizeof(v6_tuple) / sizeof(__u32);
> +		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV6_L3))
> +			input_len--;
> +		hash = rte_softrss_be((__u32 *)&v6_tuple, key, 9);
> +	} else {
> +		return TC_ACT_PIPE;
> +	}
> +
> +	queue = rsskey->queues[(hash % rsskey->nb_queues) &
> +				       (TAP_MAX_QUEUES - 1)];
> +	skb->cb[1] = QUEUE_OFFSET + queue;
> +	/* printt(">>>>> rss_l3_l4 hash=0x%x queue=%u\n", hash, queue); */
> +
> +	return TC_ACT_RECLASSIFY;
> +}
> +
> +#define RSS(L)						\
> +	__section(#L) int				\
> +		L ## _hash(struct __sk_buff *skb)	\
> +	{						\
> +		return rss_ ## L (skb);			\
> +	}
> +
> +RSS(l3_l4)
> +
> +BPF_LICENSE("Dual BSD/GPL");
> diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h
> index 9e332b0..6cc01b4 100644
> --- a/drivers/net/tap/tap_flow.h
> +++ b/drivers/net/tap/tap_flow.h
> @@ -50,6 +50,8 @@
>  #define GROUP_SHIFT 12
>  #define MAX_GROUP GROUP_MASK
>  
> +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
> +
>  /**
>   * These index are actually in reversed order: their priority is processed
>   * by subtracting their value to the lowest priority (PRIORITY_MASK).
> @@ -80,4 +82,7 @@ int tap_flow_implicit_destroy(struct pmd_internals *pmd,
>  int tap_flow_implicit_flush(struct pmd_internals *pmd,
>  			    struct rte_flow_error *error);
>  
> +int tap_flow_bpf_cls_q(__u32 queue_idx);
> +int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd);
> +
>  #endif /* _TAP_FLOW_H_ */

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v3 0/2] TAP RSS eBPF cover letter
  2018-01-10  7:06   ` [dpdk-dev] [PATCH v3 0/2] TAP RSS eBPF cover letter Ophir Munk
  2018-01-10  7:06     ` [dpdk-dev] [PATCH v3 1/2] net/tap: add eBPF instructions to TAP device Ophir Munk
  2018-01-10  7:06     ` [dpdk-dev] [PATCH v3 2/2] net/tap: implement RSS with eBPF classifier and action Ophir Munk
@ 2018-01-10 10:10     ` Jason Wang
  2018-01-10 15:34       ` Ophir Munk
  2018-01-11 17:45     ` [dpdk-dev] [PATCH v4 0/5] " Ophir Munk
  3 siblings, 1 reply; 42+ messages in thread
From: Jason Wang @ 2018-01-10 10:10 UTC (permalink / raw)
  To: Ophir Munk, dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern



On 2018年01月10日 15:06, Ophir Munk wrote:
> The patches of TAP RSS eBPF follow the RFC on this issue
> https://dpdk.org/dev/patchwork/patch/31781/
>
> v3 changes with respect to v2
> =============================
> * Add support for IPv6 RSS in BPF program
> * Bug fixes
> * Updated compatibility to kernel versions:
>    eBPF requires Linux version 4.9 configured with BPF
> * New license header (SPDX) for newly added files
>
> v2 changes with respect to v1
> =============================
> * v2 has new commits organization (3 --> 2)
> * BPF program was revised. It is successfully tested on
>    IPv4 L3 L4 layers (compatible to mlx4 device)
> * Licensing: no comments received for using "Dual BSD/GPL"
>    string during BPF program loading to the kernel.
>    (v1 and v2 are using the same license strings)
>    Any comments are welcome.
> * Compatibility to kernel versions:
>    eBPF requires Linux version 4.2 configured with BPF. TAP PMD will
>    successfully compile on systems with old or non-BPF configured kernels.
>    During compilation time the required Linux headers are searched for.
>    If they are not present missing definitions are locally added
>    (tap_autoconf.h).
>    If the kernel cannot support a BPF operation - at runtime it will
>    gracefully reject the netlink message (with BPF) sent to it.
>
> Commit #1:
> net/tap: add eBPF instructions to TAP device
> ===========================================
>    This commit introduces BPF program (tap_bpf_program.c)
>    with a classifier and an action sections.
>    The current implementation calculates RSS hash
>    over L3 addresses and L4 ports.
>    BPF program compilation is not part of dpdk compilation.
>    This commit includes the eBPF machine instructions
>    in the format of C arrays (tap_bpf_insns.c).
>
>    The option to update the BPF program and download new machine
>    instructions will be described in another commit.
>
> Commit #2:
> net/tap: implement RSS with eBPF classifier and action
> ======================================================
> This commit builds and sends netlink messages to the kernel
> that include BPF programs.
> There is a single BPF classifier for each TAP queue. Packets
> marked with an RSS queue will be directed to this queue using a traffic
> control with "skbedit" action otherwise they will be pipelined to
> the following rules.
> There is a single BPF action for each RSS rule (may add more
> to support IPv6).
> The action is to calculate Toeplitz hash based on L3 addresses and L4 ports,
> mark the packet with the RSS queue according the resulting hash,
> then reclassify the packet.
> Ophir Munk (2):
>    net/tap: add eBPF instructions to TAP device
>    net/tap: implement RSS with eBPF classifier and action
>
>   drivers/net/tap/Makefile          |   31 +
>   drivers/net/tap/rte_eth_tap.h     |    9 +-
>   drivers/net/tap/tap_bpf.h         |   92 ++
>   drivers/net/tap/tap_bpf_insns.c   | 1905 +++++++++++++++++++++++++++++++++++++
>   drivers/net/tap/tap_bpf_program.c |  221 +++++
>   drivers/net/tap/tap_flow.c        |  635 +++++++++++--
>   drivers/net/tap/tap_flow.h        |   15 +
>   drivers/net/tap/tap_rss.h         |   32 +
>   drivers/net/tap/tap_tcmsgs.h      |    4 +
>   9 files changed, 2848 insertions(+), 96 deletions(-)
>   create mode 100644 drivers/net/tap/tap_bpf.h
>   create mode 100644 drivers/net/tap/tap_bpf_insns.c
>   create mode 100644 drivers/net/tap/tap_bpf_program.c
>   create mode 100644 drivers/net/tap/tap_rss.h
>

TAP will support eBPF classification directly [1] through eBPF socket 
filter. Compare to tc-bpf, it was more portable for other backends (e.g 
macvtap).

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/commit/drivers/net/tun.c?id=96f84061620c6325a2ca9a9a05b410e6461d03c3

Thanks

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/2] net/tap: add eBPF instructions to TAP device
  2018-01-10  9:34       ` Pascal Mazon
@ 2018-01-10 10:12         ` Ophir Munk
  0 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-10 10:12 UTC (permalink / raw)
  To: Pascal Mazon, dev; +Cc: Thomas Monjalon, Olga Shern

Hi Pascal,
Please see inline

> -----Original Message-----
> From: Pascal Mazon [mailto:pascal.mazon@6wind.com]
> Sent: Wednesday, January 10, 2018 11:35 AM
> To: Ophir Munk <ophirmu@mellanox.com>; dev@dpdk.org
> Cc: Thomas Monjalon <thomas@monjalon.net>; Olga Shern
> <olgas@mellanox.com>
> Subject: Re: [PATCH v3 1/2] net/tap: add eBPF instructions to TAP device
> 
> Hi Ophir,
> 
> I have a few remarks.
> 
> - Why do you define ARRAY_SIZE in tap_flow.h while it's used only in
> tap_bpf_insns.c?
> 

ARRAY_SIZE is not defined only in tap_bpf_insns.c. 
Please note ARRAY_SIZE is used several times in tap_flow.c as well.

> - I really dislike having the BPF bytecode hardcoded in tap_bpf_insns.c.
>   You don't provide the commands used to generate that bytecode.
>   And you don't provide the way to translate bytecode into these insns[]
> arrays.
>   So we're just supposed to trust that these instructions are indeed
> what they pretend to be.
>   The process is not repeatable nor verifiable.
> 

Please note that file tap_bpf_program.c is the C source code for the bytecode.

The plan for next release (18.05) is:
1. Ask the user to install clang version 3.7 in order to compile the C source into BPF assembly object file
2. Supply a tool that will generate the bytecode from the object file
3. Advanced option: use the generated bytecode to transparently compile TAP PMD

If a user is reluctant to install clang 3.7 he has the option to compile TAP PMD without external tool dependency.
For this release please confirm the bytecode alone without the tool (expected in next release)

> 
> On 10/01/2018 08:06, Ophir Munk wrote:
> > TAP PMD is required to support RSS queue mapping based on rte_flow API.
> An
> > example usage for this requirement is failsafe transparent switching from a
> > PCI device to TAP device while keep redirecting packets to the same RSS
> > queues on both devices.
> >
> > TAP RSS implementation is based on eBPF programs sent to Linux kernel
> > through BPF system calls and using netlink messages to reference the
> > programs as part of traffic control commands.
> >
> > An eBPF program acts as a traffic control classifier or action. Each
> > program is written in C code under a different ELF section name. Clang 3.7
> > is used to compile the C code into eBPF-formatted object file. The ELF file
> > is parsed and its sections (programs) can be downloaded to the kernel using
> > BPF system call. The BPF system call parameters contain the array of eBPF
> > instructions. This commit includes BPF classifier and action programs
> > (tap_bpf_program.c) as reference and their corresponding arrays of eBPF
> > instructions (tap_bpf_insns.c). The reference file does not take part in
> > dpdk compilation. The details on how to generate new eBPF code will be
> > presented in another commit.
> >
> > In a follow up commit TAP PMD will use the eBPF programs to implement
> RSS
> > flow rules.
> >
> > TAP eBPF requires Linux version 4.9 configured with BPF. TAP PMD will
> > successfully compile on systems with old or non-BPF configured kernels but
> > RSS rules creation on TAP devices will not be supported.
> >
> > Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
> > ---
> >  drivers/net/tap/Makefile          |   11 +
> >  drivers/net/tap/tap_bpf.h         |   96 ++
> >  drivers/net/tap/tap_bpf_insns.c   | 1845
> +++++++++++++++++++++++++++++++++++++
> >  drivers/net/tap/tap_bpf_program.c |  221 +++++
> >  drivers/net/tap/tap_flow.h        |    5 +
> >  5 files changed, 2178 insertions(+)
> >  create mode 100644 drivers/net/tap/tap_bpf.h
> >  create mode 100644 drivers/net/tap/tap_bpf_insns.c
> >  create mode 100644 drivers/net/tap/tap_bpf_program.c
> >
> > diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
> > index fd4195f..feaa5b7 100644
> > --- a/drivers/net/tap/Makefile
> > +++ b/drivers/net/tap/Makefile
> > @@ -12,6 +12,9 @@ EXPORT_MAP := rte_pmd_tap_version.map
> >
> >  LIBABIVER := 1
> >
> > +# TAP_MAX_QUEUES must be a power of 2 as it will be used for masking
> */
> > +TAP_MAX_QUEUES = 16
> > +
> >  CFLAGS += -O3
> >  CFLAGS += -I$(SRCDIR)
> >  CFLAGS += -I.
> > @@ -20,6 +23,8 @@ LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -
> lrte_ring
> >  LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
> >  LDLIBS += -lrte_bus_vdev
> >
> > +CFLAGS += -DTAP_MAX_QUEUES=$(TAP_MAX_QUEUES)
> > +
> >  #
> >  # all source are stored in SRCS-y
> >  #
> > @@ -27,6 +32,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) +=
> rte_eth_tap.c
> >  SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_flow.c
> >  SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_netlink.c
> >  SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_tcmsgs.c
> > +SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_bpf_insns.c
> >
> >  include $(RTE_SDK)/mk/rte.lib.mk
> >
> > @@ -53,6 +59,11 @@ tap_autoconf.h.new: $(RTE_SDK)/buildtools/auto-
> config-h.sh
> >  		linux/pkt_cls.h \
> >  		enum TCA_FLOWER_KEY_VLAN_PRIO \
> >  		$(AUTOCONF_OUTPUT)
> > +	$Q sh -- '$<' '$@' \
> > +		HAVE_BPF_PROG_LOAD \
> > +		linux/bpf.h \
> > +		enum BPF_PROG_LOAD \
> > +		$(AUTOCONF_OUTPUT)
> >
> >  # Create tap_autoconf.h or update it in case it differs from the new one.
> >
> > diff --git a/drivers/net/tap/tap_bpf.h b/drivers/net/tap/tap_bpf.h
> > new file mode 100644
> > index 0000000..82775b7
> > --- /dev/null
> > +++ b/drivers/net/tap/tap_bpf.h
> > @@ -0,0 +1,96 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright 2017 Mellanox Technologies, Ltd.
> > + */
> > +
> > +#ifndef __TAP_BPF_H__
> > +#define __TAP_BPF_H__
> > +
> > +#include <tap_autoconf.h>
> > +
> > +#ifdef HAVE_BPF_PROG_LOAD
> > +#include <linux/bpf.h>
> > +#else
> > +/* BPF_MAP_UPDATE_ELEM command flags */
> > +#define	BPF_ANY	0 /* create a new element or update an
> existing */
> > +
> > +/* BPF architecture instruction struct */
> > +struct bpf_insn {
> > +	__u8	code;
> > +	__u8	dst_reg:4;
> > +	__u8	src_reg:4;
> > +	__s16	off;
> > +	__s32	imm; /* immediate value */
> > +};
> > +
> > +/* BPF program types */
> > +enum bpf_prog_type {
> > +	BPF_PROG_TYPE_UNSPEC,
> > +	BPF_PROG_TYPE_SOCKET_FILTER,
> > +	BPF_PROG_TYPE_KPROBE,
> > +	BPF_PROG_TYPE_SCHED_CLS,
> > +	BPF_PROG_TYPE_SCHED_ACT,
> > +};
> > +
> > +/* BPF commands types */
> > +enum bpf_cmd {
> > +	BPF_MAP_CREATE,
> > +	BPF_MAP_LOOKUP_ELEM,
> > +	BPF_MAP_UPDATE_ELEM,
> > +	BPF_MAP_DELETE_ELEM,
> > +	BPF_MAP_GET_NEXT_KEY,
> > +	BPF_PROG_LOAD,
> > +};
> > +
> > +/* BPF maps types */
> > +enum bpf_map_type {
> > +	BPF_MAP_TYPE_UNSPEC,
> > +	BPF_MAP_TYPE_HASH,
> > +};
> > +
> > +/* union of anonymous structs used with TAP BPF commands */
> > +union bpf_attr {
> > +	/* BPF_MAP_CREATE command */
> > +	struct {
> > +		__u32	map_type;
> > +		__u32	key_size;
> > +		__u32	value_size;
> > +		__u32	max_entries;
> > +		__u32	map_flags;
> > +		__u32	inner_map_fd;
> > +	};
> > +
> > +	/* BPF_MAP_UPDATE_ELEM, BPF_MAP_DELETE_ELEM commands
> */
> > +	struct {
> > +		__u32		map_fd;
> > +		__aligned_u64	key;
> > +		union {
> > +			__aligned_u64 value;
> > +			__aligned_u64 next_key;
> > +		};
> > +		__u64		flags;
> > +	};
> > +
> > +	/* BPF_PROG_LOAD command */
> > +	struct {
> > +		__u32		prog_type;
> > +		__u32		insn_cnt;
> > +		__aligned_u64	insns;
> > +		__aligned_u64	license;
> > +		__u32		log_level;
> > +		__u32		log_size;
> > +		__aligned_u64	log_buf;
> > +		__u32		kern_version;
> > +		__u32		prog_flags;
> > +	};
> > +} __attribute__((aligned(8)));
> > +#endif
> > +
> > +enum {
> > +	BPF_MAP_ID_KEY,
> > +	BPF_MAP_ID_SIMPLE,
> > +};
> > +
> > +static int bpf_load(enum bpf_prog_type type, const struct bpf_insn *insns,
> > +		size_t insns_cnt, const char *license);
> > +
> > +#endif /* __TAP_BPF_H__ */
> > diff --git a/drivers/net/tap/tap_bpf_insns.c
> b/drivers/net/tap/tap_bpf_insns.c
> > new file mode 100644
> > index 0000000..25aa82c
> > --- /dev/null
> > +++ b/drivers/net/tap/tap_bpf_insns.c
> > @@ -0,0 +1,1845 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright 2017 Mellanox Technologies, Ltd.
> > + */
> > +
> > +#include <errno.h>
> > +#include <string.h>
> > +#include <unistd.h>
> > +#include <sys/queue.h>
> > +#include <sys/mount.h>
> > +
> > +#include <rte_byteorder.h>
> > +#include <rte_jhash.h>
> > +#include <rte_malloc.h>
> > +#include <rte_eth_tap.h>
> > +#include <tap_flow.h>
> > +#include <tap_autoconf.h>
> > +#include <tap_tcmsgs.h>
> > +#include <tap_bpf.h>
> > +
> > +#define ERROR                   0
> > +
> > +/*
> > + * The queue number is offset by 1, to distinguish packets that have
> > + * gone through this rule (skb->cb[1] != 0) from others.
> > + */
> > +#define QUEUE_OFFSET 1
> > +
> > +/* bpf_insn array matching cls_q section. See tap_bpf_program.c file */
> > +static struct bpf_insn cls_q_insns[] = {
> > +	{0x61,    1,    1,       52, 0x00000000},
> > +	{0x18,    2,    0,        0, 0xdeadbeef},
> > +	{0x00,    0,    0,        0, 0x00000000},
> > +	{0x63,   10,    2,       -4, 0x00000000},
> > +	{0x61,    2,   10,       -4, 0x00000000},
> > +	{0x07,    2,    0,        0, 0x00000001},
> > +	{0x67,    2,    0,        0, 0x00000020},
> > +	{0x77,    2,    0,        0, 0x00000020},
> > +	{0xb7,    0,    0,        0, 0xffffffff},
> > +	{0x1d,    1,    2,        1, 0x00000000},
> > +	{0xb7,    0,    0,        0, 0x00000000},
> > +	{0x95,    0,    0,        0, 0x00000000},
> > +};
> > +
> > +/**
> > + * Load BPF program (section cls_q) into the kernel and return a bpf fd
> > + *
> > + * @param queue_idx
> > + *   Queue index matching packet cb
> > + *
> > + * @return
> > + *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
> > + */
> > +int tap_flow_bpf_cls_q(__u32 queue_idx)
> > +{
> > +	cls_q_insns[1].imm = queue_idx;
> > +
> > +	return bpf_load(BPF_PROG_TYPE_SCHED_CLS,
> > +		(struct bpf_insn *)cls_q_insns,
> > +		ARRAY_SIZE(cls_q_insns),
> > +		"Dual BSD/GPL");
> > +}
> > +
> > +/* bpf_insn array matching l3_l4 section. see tap_bpf_program.c file */
> > +static struct bpf_insn l3_l4_hash_insns[] = {
> > +	{0xbf,    7,    1,        0, 0x00000000},
> > +	{0x61,    8,    7,       16, 0x00000000},
> > +	{0x61,    6,    7,       76, 0x00000000},
> > +	{0x61,    9,    7,       80, 0x00000000},
> > +	{0x18,    1,    0,        0, 0xdeadbeef},
> > +	{0x00,    0,    0,        0, 0x00000000},
> > +	{0x63,   10,    1,       -4, 0x00000000},
> > +	{0xbf,    2,   10,        0, 0x00000000},
> > +	{0x07,    2,    0,        0, 0xfffffffc},
> > +	{0x18,    1,    1,        0, 0x0000cafe},
> > +	{0x00,    0,    0,        0, 0x00000000},
> > +	{0x85,    0,    0,        0, 0x00000001},
> > +	{0x55,    0,    0,       21, 0x00000000},
> > +	{0xb7,    1,    0,        0, 0x00000a64},
> > +	{0x6b,   10,    1,      -16, 0x00000000},
> > +	{0x18,    1,    0,        0, 0x69666e6f},
> > +	{0x00,    0,    0,        0, 0x65727567},
> > +	{0x7b,   10,    1,      -24, 0x00000000},
> > +	{0x18,    1,    0,        0, 0x6e207369},
> > +	{0x00,    0,    0,        0, 0x6320746f},
> > +	{0x7b,   10,    1,      -32, 0x00000000},
> > +	{0x18,    1,    0,        0, 0x20737372},
> > +	{0x00,    0,    0,        0, 0x2079656b},
> > +	{0x7b,   10,    1,      -40, 0x00000000},
> > +	{0x18,    1,    0,        0, 0x68736168},
> > +	{0x00,    0,    0,        0, 0x203a2928},
> > +	{0x7b,   10,    1,      -48, 0x00000000},
> > +	{0xb7,    7,    0,        0, 0x00000000},
> > +	{0x73,   10,    7,      -14, 0x00000000},
> > +	{0xbf,    1,   10,        0, 0x00000000},
> > +	{0x07,    1,    0,        0, 0xffffffd0},
> > +	{0xb7,    2,    0,        0, 0x00000023},
> > +	{0x85,    0,    0,        0, 0x00000006},
> > +	{0x05,    0,    0,     1632, 0x00000000},
> > +	{0xb7,    1,    0,        0, 0x0000000e},
> > +	{0x61,    2,    7,       20, 0x00000000},
> > +	{0x15,    2,    0,       10, 0x00000000},
> > +	{0x61,    2,    7,       28, 0x00000000},
> > +	{0x55,    2,    0,        8, 0x0000a888},
> > +	{0xbf,    2,    7,        0, 0x00000000},
> > +	{0xb7,    7,    0,        0, 0x00000000},
> > +	{0xbf,    1,    6,        0, 0x00000000},
> > +	{0x07,    1,    0,        0, 0x00000012},
> > +	{0x2d,    1,    9,     1622, 0x00000000},
> > +	{0xb7,    1,    0,        0, 0x00000012},
> > +	{0x69,    8,    6,       16, 0x00000000},
> > +	{0xbf,    7,    2,        0, 0x00000000},
> > +	{0x7b,   10,    7,      -56, 0x00000000},
> > +	{0x57,    8,    0,        0, 0x0000ffff},
> > +	{0x15,    8,    0,      409, 0x0000dd86},
> > +	{0xb7,    7,    0,        0, 0x00000003},
> > +	{0x55,    8,    0,     1614, 0x00000008},
> > +	{0x0f,    6,    1,        0, 0x00000000},
> > +	{0xb7,    7,    0,        0, 0x00000000},
> > +	{0xbf,    1,    6,        0, 0x00000000},
> > +	{0x07,    1,    0,        0, 0x00000018},
> > +	{0x2d,    1,    9,     1609, 0x00000000},
> > +	{0x71,    3,    6,       12, 0x00000000},
> > +	{0xbf,    1,    3,        0, 0x00000000},
> > +	{0x67,    1,    0,        0, 0x00000038},
> > +	{0xc7,    1,    0,        0, 0x00000020},
> > +	{0x77,    1,    0,        0, 0x0000001f},
> > +	{0x57,    1,    0,        0, 0x2cc681d1},
> > +	{0x67,    3,    0,        0, 0x00000018},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x40000000},
> > +	{0xb7,    2,    0,        0, 0x00000000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x598d03a2},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x20000000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xb31a0745},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x10000000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x66340e8a},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x08000000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xcc681d15},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x04000000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x98d03a2b},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x02000000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x31a07456},
> > +	{0x57,    3,    0,        0, 0x01000000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x6340e8ad},
> > +	{0x71,    3,    6,       13, 0x00000000},
> > +	{0x67,    3,    0,        0, 0x00000010},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00800000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xc681d15b},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00400000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x8d03a2b7},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00200000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x1a07456f},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00100000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x340e8ade},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00080000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x681d15bd},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00040000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xd03a2b7b},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00020000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xa07456f6},
> > +	{0x57,    3,    0,        0, 0x00010000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x40e8aded},
> > +	{0x71,    3,    6,       14, 0x00000000},
> > +	{0x67,    3,    0,        0, 0x00000008},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00008000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x81d15bdb},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00004000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x03a2b7b7},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00002000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x07456f6f},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00001000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x0e8adedf},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000800},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x1d15bdbf},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000400},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x3a2b7b7e},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000200},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x7456f6fd},
> > +	{0x57,    3,    0,        0, 0x00000100},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xe8adedfa},
> > +	{0x71,    3,    6,       15, 0x00000000},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000080},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xd15bdbf4},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000040},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xa2b7b7e9},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000020},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x456f6fd3},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000010},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x8adedfa7},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000008},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x15bdbf4f},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000004},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x2b7b7e9e},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000002},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x56f6fd3d},
> > +	{0x57,    3,    0,        0, 0x00000001},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xadedfa7b},
> > +	{0x71,    4,    6,       16, 0x00000000},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x67,    5,    0,        0, 0x00000038},
> > +	{0xc7,    5,    0,        0, 0x00000020},
> > +	{0xb7,    3,    0,        0, 0xffffffff},
> > +	{0x6d,    5,    3,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x5bdbf4f7},
> > +	{0x67,    4,    0,        0, 0x00000018},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x40000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xb7b7e9ef},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x20000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x6f6fd3df},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x10000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xdedfa7bf},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x08000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xbdbf4f7f},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x04000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x7b7e9eff},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x02000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xf6fd3dff},
> > +	{0x57,    4,    0,        0, 0x01000000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xedfa7bfe},
> > +	{0x71,    4,    6,       17, 0x00000000},
> > +	{0x67,    4,    0,        0, 0x00000010},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00800000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xdbf4f7fc},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00400000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xb7e9eff9},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00200000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x6fd3dff2},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00100000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xdfa7bfe5},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00080000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xbf4f7fca},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00040000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x7e9eff94},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00020000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xfd3dff28},
> > +	{0x57,    4,    0,        0, 0x00010000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xfa7bfe51},
> > +	{0x71,    4,    6,       18, 0x00000000},
> > +	{0x67,    4,    0,        0, 0x00000008},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00008000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xf4f7fca2},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00004000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xe9eff945},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00002000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xd3dff28a},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00001000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xa7bfe514},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000800},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x4f7fca28},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000400},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x9eff9450},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000200},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x3dff28a0},
> > +	{0x57,    4,    0,        0, 0x00000100},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x7bfe5141},
> > +	{0x71,    4,    6,       19, 0x00000000},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000080},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xf7fca283},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000040},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xeff94506},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000020},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xdff28a0c},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000010},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xbfe51418},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000008},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x7fca2831},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000004},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xff945063},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000002},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xff28a0c6},
> > +	{0x57,    4,    0,        0, 0x00000001},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xfe51418c},
> > +	{0x71,    4,    6,       20, 0x00000000},
> > +	{0x67,    4,    0,        0, 0x00000008},
> > +	{0x71,    5,    6,       21, 0x00000000},
> > +	{0x4f,    4,    5,        0, 0x00000000},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x67,    5,    0,        0, 0x00000030},
> > +	{0xc7,    5,    0,        0, 0x00000020},
> > +	{0x6d,    5,    3,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xfca28319},
> > +	{0x67,    4,    0,        0, 0x00000010},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x40000000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xf9450633},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x20000000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xf28a0c67},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x10000000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xe51418ce},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x08000000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xca28319d},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x04000000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x9450633b},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x02000000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x28a0c676},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x01000000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x51418ced},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00800000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xa28319db},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00400000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x450633b6},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00200000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x8a0c676c},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00100000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x1418ced8},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00080000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x28319db1},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00040000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x50633b63},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00020000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xa0c676c6},
> > +	{0x57,    4,    0,        0, 0x00010000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x418ced8d},
> > +	{0x71,    3,    6,       22, 0x00000000},
> > +	{0x67,    3,    0,        0, 0x00000008},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00008000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x8319db1a},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00004000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x0633b634},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00002000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x0c676c68},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00001000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x18ced8d1},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000800},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x319db1a3},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000400},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x633b6347},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000200},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xc676c68f},
> > +	{0x57,    3,    0,        0, 0x00000100},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x8ced8d1f},
> > +	{0x71,    3,    6,       23, 0x00000000},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000080},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x19db1a3e},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000040},
> > +	{0x79,    5,   10,      -56, 0x00000000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x33b6347d},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000020},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x676c68fa},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000010},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xced8d1f4},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000008},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x9db1a3e9},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000004},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x3b6347d2},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000002},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x76c68fa5},
> > +	{0x57,    3,    0,        0, 0x00000001},
> > +	{0x1d,    3,    2,     1177, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xed8d1f4a},
> > +	{0x05,    0,    0,     1175, 0x00000000},
> > +	{0x0f,    6,    1,        0, 0x00000000},
> > +	{0xb7,    7,    0,        0, 0x00000000},
> > +	{0xbf,    1,    6,        0, 0x00000000},
> > +	{0x07,    1,    0,        0, 0x0000002c},
> > +	{0x2d,    1,    9,     1202, 0x00000000},
> > +	{0x61,    4,    6,        8, 0x00000000},
> > +	{0xbf,    1,    4,        0, 0x00000000},
> > +	{0x67,    1,    0,        0, 0x00000038},
> > +	{0xc7,    1,    0,        0, 0x00000020},
> > +	{0x77,    1,    0,        0, 0x0000001f},
> > +	{0x57,    1,    0,        0, 0x2cc681d1},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00000040},
> > +	{0xb7,    2,    0,        0, 0x00000000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x598d03a2},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00000020},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xb31a0745},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00000010},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x66340e8a},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00000008},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xcc681d15},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00000004},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x98d03a2b},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00000002},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x31a07456},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00000001},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x6340e8ad},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00008000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xc681d15b},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00004000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x8d03a2b7},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00002000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x1a07456f},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00001000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x340e8ade},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00000800},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x681d15bd},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00000400},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xd03a2b7b},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00000200},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xa07456f6},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00000100},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x40e8aded},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00800000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x81d15bdb},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00400000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x03a2b7b7},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00200000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x07456f6f},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00100000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x0e8adedf},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00080000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x1d15bdbf},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00040000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x3a2b7b7e},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00020000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x7456f6fd},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00010000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xe8adedfa},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x67,    5,    0,        0, 0x00000020},
> > +	{0xc7,    5,    0,        0, 0x00000020},
> > +	{0xb7,    3,    0,        0, 0xffffffff},
> > +	{0x6d,    5,    3,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xd15bdbf4},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x40000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xa2b7b7e9},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x20000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x456f6fd3},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x10000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x8adedfa7},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x08000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x15bdbf4f},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x04000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x2b7b7e9e},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x02000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x56f6fd3d},
> > +	{0x57,    4,    0,        0, 0x01000000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xadedfa7b},
> > +	{0x61,    4,    6,       12, 0x00000000},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000080},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x5bdbf4f7},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000040},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xb7b7e9ef},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000020},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x6f6fd3df},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000010},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xdedfa7bf},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000008},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xbdbf4f7f},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000004},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x7b7e9eff},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000002},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xf6fd3dff},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000001},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xedfa7bfe},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00008000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xdbf4f7fc},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00004000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xb7e9eff9},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00002000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x6fd3dff2},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00001000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xdfa7bfe5},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000800},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xbf4f7fca},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000400},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x7e9eff94},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000200},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xfd3dff28},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000100},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xfa7bfe51},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00800000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xf4f7fca2},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00400000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xe9eff945},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00200000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xd3dff28a},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00100000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xa7bfe514},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00080000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x4f7fca28},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00040000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x9eff9450},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00020000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x3dff28a0},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00010000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x7bfe5141},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x67,    5,    0,        0, 0x00000020},
> > +	{0xc7,    5,    0,        0, 0x00000020},
> > +	{0x6d,    5,    3,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xf7fca283},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x40000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xeff94506},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x20000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xdff28a0c},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x10000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xbfe51418},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x08000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x7fca2831},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x04000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xff945063},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x02000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xff28a0c6},
> > +	{0x57,    4,    0,        0, 0x01000000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xfe51418c},
> > +	{0x61,    4,    6,       16, 0x00000000},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000080},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xfca28319},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000040},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xf9450633},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000020},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xf28a0c67},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000010},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xe51418ce},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000008},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xca28319d},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000004},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x9450633b},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000002},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x28a0c676},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000001},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x51418ced},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00008000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xa28319db},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00004000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x450633b6},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00002000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x8a0c676c},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00001000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x1418ced8},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000800},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x28319db1},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000400},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x50633b63},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000200},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xa0c676c6},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000100},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x418ced8d},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00800000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x8319db1a},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00400000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x0633b634},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00200000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x0c676c68},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00100000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x18ced8d1},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00080000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x319db1a3},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00040000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x633b6347},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00020000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xc676c68f},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00010000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x8ced8d1f},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x67,    5,    0,        0, 0x00000020},
> > +	{0xc7,    5,    0,        0, 0x00000020},
> > +	{0x6d,    5,    3,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x19db1a3e},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x40000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x33b6347d},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x20000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x676c68fa},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x10000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xced8d1f4},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x08000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x9db1a3e9},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x04000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x3b6347d2},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x02000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x76c68fa5},
> > +	{0x57,    4,    0,        0, 0x01000000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xed8d1f4a},
> > +	{0x61,    4,    6,       20, 0x00000000},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000080},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xdb1a3e94},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000040},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xb6347d28},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000020},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x6c68fa51},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000010},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xd8d1f4a3},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000008},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xb1a3e946},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000004},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x6347d28d},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000002},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xc68fa51a},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000001},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x8d1f4a35},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00008000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x1a3e946b},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00004000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x347d28d7},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00002000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x68fa51ae},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00001000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xd1f4a35c},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000800},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xa3e946b9},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000400},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x47d28d73},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000200},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x8fa51ae7},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000100},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x1f4a35cf},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00800000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x3e946b9e},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00400000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x7d28d73c},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00200000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xfa51ae78},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00100000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xf4a35cf1},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00080000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xe946b9e3},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00040000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xd28d73c7},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00020000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xa51ae78e},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00010000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x4a35cf1c},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x67,    5,    0,        0, 0x00000020},
> > +	{0xc7,    5,    0,        0, 0x00000020},
> > +	{0x6d,    5,    3,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x946b9e38},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x40000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x28d73c71},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x20000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x51ae78e3},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x10000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xa35cf1c6},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x08000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x46b9e38d},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x04000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x8d73c71b},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x02000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x1ae78e36},
> > +	{0x57,    4,    0,        0, 0x01000000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x35cf1c6c},
> > +	{0x61,    4,    6,       24, 0x00000000},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000080},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x6b9e38d9},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000040},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xd73c71b2},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000020},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xae78e364},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000010},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x5cf1c6c9},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000008},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xb9e38d92},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000004},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x73c71b25},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000002},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xe78e364b},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000001},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xcf1c6c96},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00008000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x9e38d92c},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00004000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x3c71b259},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00002000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x78e364b2},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00001000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xf1c6c964},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000800},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xe38d92c9},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000400},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xc71b2593},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000200},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x8e364b27},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000100},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x1c6c964e},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00800000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x38d92c9c},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00400000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x71b25938},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00200000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xe364b270},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00100000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xc6c964e0},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00080000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x8d92c9c0},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00040000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x1b259380},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00020000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x364b2700},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00010000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x6c964e01},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x67,    5,    0,        0, 0x00000020},
> > +	{0xc7,    5,    0,        0, 0x00000020},
> > +	{0x6d,    5,    3,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xd92c9c03},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x40000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xb2593807},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x20000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x64b2700f},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x10000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xc964e01e},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x08000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x92c9c03d},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x04000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x2593807a},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x02000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x4b2700f4},
> > +	{0x57,    4,    0,        0, 0x01000000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x964e01e8},
> > +	{0x61,    4,    6,       28, 0x00000000},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000080},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x2c9c03d1},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000040},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x593807a3},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000020},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xb2700f46},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000010},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x64e01e8d},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000008},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xc9c03d1a},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000004},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x93807a35},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000002},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x2700f46b},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000001},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x4e01e8d6},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00008000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x9c03d1ad},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00004000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x3807a35b},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00002000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x700f46b6},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00001000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xe01e8d6c},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000800},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xc03d1ad9},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000400},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x807a35b3},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000200},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x00f46b66},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000100},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x01e8d6cc},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00800000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x03d1ad99},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00400000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x07a35b32},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00200000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x0f46b665},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00100000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x1e8d6cca},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00080000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x3d1ad994},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00040000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x7a35b328},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00020000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xf46b6651},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00010000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xe8d6cca2},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x67,    5,    0,        0, 0x00000020},
> > +	{0xc7,    5,    0,        0, 0x00000020},
> > +	{0x6d,    5,    3,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xd1ad9944},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x40000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xa35b3289},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x20000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x46b66512},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x10000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x8d6cca25},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x08000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x1ad9944a},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x04000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x35b32894},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x02000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x6b665129},
> > +	{0x57,    4,    0,        0, 0x01000000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xd6cca253},
> > +	{0x61,    4,    6,       32, 0x00000000},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000080},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xad9944a7},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000040},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x5b32894f},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000020},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xb665129f},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000010},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x6cca253e},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000008},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xd9944a7d},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000004},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xb32894fb},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000002},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x665129f6},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000001},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xcca253ec},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00008000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x9944a7d9},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00004000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x32894fb2},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00002000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x65129f65},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00001000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xca253eca},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000800},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x944a7d95},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000400},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x2894fb2a},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000200},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x5129f655},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000100},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xa253ecab},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00800000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x44a7d956},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00400000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x894fb2ac},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00200000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x129f6558},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00100000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x253ecab1},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00080000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x4a7d9563},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00040000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x94fb2ac7},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00020000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x29f6558f},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00010000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x53ecab1e},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x67,    5,    0,        0, 0x00000020},
> > +	{0xc7,    5,    0,        0, 0x00000020},
> > +	{0x6d,    5,    3,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xa7d9563d},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x40000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x4fb2ac7a},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x20000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x9f6558f5},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x10000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x3ecab1ea},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x08000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x7d9563d5},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x04000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xfb2ac7ab},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x02000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xf6558f56},
> > +	{0x57,    4,    0,        0, 0x01000000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xecab1eac},
> > +	{0x61,    4,    6,       36, 0x00000000},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000080},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xd9563d59},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000040},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xb2ac7ab2},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000020},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x6558f564},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000010},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xcab1eac8},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000008},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x9563d590},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000004},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x2ac7ab20},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000002},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x558f5641},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000001},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xab1eac83},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00008000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x563d5906},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00004000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xac7ab20c},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00002000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x58f56418},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00001000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xb1eac831},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000800},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x63d59063},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000400},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xc7ab20c7},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000200},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x8f56418f},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00000100},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x1eac831e},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00800000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x3d59063c},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00400000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x7ab20c78},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00200000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xf56418f0},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00100000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xeac831e1},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00080000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xd59063c2},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00040000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xab20c784},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00020000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x56418f09},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x00010000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xac831e12},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x67,    5,    0,        0, 0x00000020},
> > +	{0xc7,    5,    0,        0, 0x00000020},
> > +	{0x6d,    5,    3,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x59063c25},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x40000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xb20c784b},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x20000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x6418f097},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x10000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xc831e12f},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x08000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x9063c25f},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x04000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x20c784be},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x57,    5,    0,        0, 0x02000000},
> > +	{0x1d,    5,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x418f097c},
> > +	{0x57,    4,    0,        0, 0x01000000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x831e12f9},
> > +	{0x71,    4,    6,       40, 0x00000000},
> > +	{0x67,    4,    0,        0, 0x00000008},
> > +	{0x71,    5,    6,       41, 0x00000000},
> > +	{0x4f,    4,    5,        0, 0x00000000},
> > +	{0xbf,    5,    4,        0, 0x00000000},
> > +	{0x67,    5,    0,        0, 0x00000030},
> > +	{0xc7,    5,    0,        0, 0x00000020},
> > +	{0x6d,    5,    3,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x063c25f3},
> > +	{0x67,    4,    0,        0, 0x00000010},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x40000000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x0c784be7},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x20000000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x18f097cf},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x10000000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x31e12f9f},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x08000000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x63c25f3f},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x04000000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xc784be7f},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x02000000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x8f097cff},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x01000000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x1e12f9fe},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00800000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x3c25f3fc},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00400000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x784be7f8},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00200000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xf097cff0},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00100000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xe12f9fe0},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00080000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xc25f3fc1},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00040000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x84be7f83},
> > +	{0xbf,    3,    4,        0, 0x00000000},
> > +	{0x57,    3,    0,        0, 0x00020000},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x097cff07},
> > +	{0x57,    4,    0,        0, 0x00010000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x12f9fe0f},
> > +	{0x71,    3,    6,       42, 0x00000000},
> > +	{0x67,    3,    0,        0, 0x00000008},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00008000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x25f3fc1f},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00004000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x4be7f83f},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00002000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x97cff07f},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00001000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x2f9fe0fe},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000800},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x5f3fc1fd},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000400},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xbe7f83fb},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000200},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x7cff07f7},
> > +	{0x57,    3,    0,        0, 0x00000100},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xf9fe0fee},
> > +	{0x71,    3,    6,       43, 0x00000000},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000080},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xf3fc1fdc},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000040},
> > +	{0x79,    5,   10,      -56, 0x00000000},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xe7f83fb8},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000020},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xcff07f70},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000010},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x9fe0fee1},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000008},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x3fc1fdc2},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000004},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0x7f83fb85},
> > +	{0xbf,    4,    3,        0, 0x00000000},
> > +	{0x57,    4,    0,        0, 0x00000002},
> > +	{0x1d,    4,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xff07f70a},
> > +	{0x57,    3,    0,        0, 0x00000001},
> > +	{0x1d,    3,    2,        1, 0x00000000},
> > +	{0xa7,    1,    0,        0, 0xfe0fee15},
> > +	{0x71,    2,    0,      201, 0x00000000},
> > +	{0x67,    2,    0,        0, 0x00000008},
> > +	{0x71,    3,    0,      200, 0x00000000},
> > +	{0x4f,    2,    3,        0, 0x00000000},
> > +	{0x71,    3,    0,      203, 0x00000000},
> > +	{0x67,    3,    0,        0, 0x00000008},
> > +	{0x71,    4,    0,      202, 0x00000000},
> > +	{0x4f,    3,    4,        0, 0x00000000},
> > +	{0x67,    3,    0,        0, 0x00000010},
> > +	{0x4f,    3,    2,        0, 0x00000000},
> > +	{0x67,    1,    0,        0, 0x00000020},
> > +	{0x77,    1,    0,        0, 0x00000020},
> > +	{0xbf,    2,    1,        0, 0x00000000},
> > +	{0x3f,    2,    3,        0, 0x00000000},
> > +	{0x2f,    2,    3,        0, 0x00000000},
> > +	{0x1f,    1,    2,        0, 0x00000000},
> > +	{0x57,    1,    0,        0, 0x0000000f},
> > +	{0x67,    1,    0,        0, 0x00000002},
> > +	{0x0f,    0,    1,        0, 0x00000000},
> > +	{0x71,    1,    0,      137, 0x00000000},
> > +	{0x67,    1,    0,        0, 0x00000008},
> > +	{0x71,    2,    0,      136, 0x00000000},
> > +	{0x4f,    1,    2,        0, 0x00000000},
> > +	{0x71,    2,    0,      138, 0x00000000},
> > +	{0x71,    3,    0,      139, 0x00000000},
> > +	{0x67,    3,    0,        0, 0x00000008},
> > +	{0x4f,    3,    2,        0, 0x00000000},
> > +	{0x67,    3,    0,        0, 0x00000010},
> > +	{0x4f,    3,    1,        0, 0x00000000},
> > +	{0x07,    3,    0,        0, 0x00000001},
> > +	{0x63,    5,    3,       52, 0x00000000},
> > +	{0xb7,    7,    0,        0, 0x00000001},
> > +	{0xbf,    0,    7,        0, 0x00000000},
> > +	{0x95,    0,    0,        0, 0x00000000},
> > +};
> > +
> > +/**
> > + * Load BPF program (section l3_l4) into the kernel and return a bpf fd.
> > + *
> > + * @param[in] key_idx
> > + *   RSS MAP key index
> > + *
> > + * @param[in] map_fd
> > + *   BPF RSS map file descriptor
> > + *
> > + * @return
> > + *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
> > + */
> > +int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd)
> > +{
> > +	l3_l4_hash_insns[4].imm = key_idx;
> > +	l3_l4_hash_insns[9].imm = map_fd;
> > +
> > +	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
> > +		(struct bpf_insn *)l3_l4_hash_insns,
> > +		ARRAY_SIZE(l3_l4_hash_insns),
> > +		"Dual BSD/GPL");
> > +}
> > +
> > +
> > +#ifndef __NR_bpf
> > +# if defined(__i386__)
> > +#  define __NR_bpf 357
> > +# elif defined(__x86_64__)
> > +#  define __NR_bpf 321
> > +# elif defined(__aarch64__)
> > +#  define __NR_bpf 280
> > +# elif defined(__sparc__)
> > +#  define __NR_bpf 349
> > +# elif defined(__s390__)
> > +#  define __NR_bpf 351
> > +# else
> > +#  error __NR_bpf not defined. libbpf does not support your arch.
> > +# endif
> > +#endif
> > +
> > +/**
> > + * Helper function to convert a pointer to unsigned 64 bits
> > + *
> > + * @param[in] ptr
> > + *   pointer to address
> > + *
> > + * @return
> > + *   64 bit unsigned long type of pointer address
> > + */
> > +static inline __u64 ptr_to_u64(const void *ptr)
> > +{
> > +	return (__u64)(unsigned long)ptr;
> > +}
> > +
> > +/**
> > + * Call BPF system call
> > + *
> > + * @param[in] cmd
> > + *   BPF command for program loading, map creation, map entry update,
> etc
> > + *
> > + * @param[in] attr
> > + *   System call attributes relevant to system call command
> > + *
> > + * @param[in] size
> > + *   size of attr parameter
> > + *
> > + * @return
> > + *   -1 if BPF system call failed, 0 otherwise
> > + */
> > +static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
> > +			unsigned int size)
> > +{
> > +	return syscall(__NR_bpf, cmd, attr, size);
> > +}
> > +
> > +/**
> > + * Load BPF instructions to kernel
> > + *
> > + * @param[in] type
> > + *   BPF program type: classifieir or action
> > + *
> > + * @param[in] insns
> > + *   Array of BPF instructions (equivalent to BPF instructions)
> > + *
> > + * @param[in] insns_cnt
> > + *   Number of BPF instructions (size of array)
> > + *
> > + * @param[in] lincense
> > + *   License string that must be acknowledged by the kernel
> > + *
> > + * @return
> > + *   -1 if the BPF program couldn't be loaded, fd (file descriptor) otherwise
> > + */
> > +static int bpf_load(enum bpf_prog_type type,
> > +		  const struct bpf_insn *insns,
> > +		  size_t insns_cnt,
> > +		  const char *license)
> > +{
> > +	union bpf_attr attr;
> > +
> > +	bzero(&attr, sizeof(attr));
> > +	attr.prog_type = type;
> > +	attr.insn_cnt = (__u32)insns_cnt;
> > +	attr.insns = ptr_to_u64(insns);
> > +	attr.license = ptr_to_u64(license);
> > +	attr.log_buf = ptr_to_u64(NULL);
> > +	attr.log_level = 0;
> > +	attr.kern_version = 0;
> > +
> > +	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
> > +}
> > diff --git a/drivers/net/tap/tap_bpf_program.c
> b/drivers/net/tap/tap_bpf_program.c
> > new file mode 100644
> > index 0000000..08bc881
> > --- /dev/null
> > +++ b/drivers/net/tap/tap_bpf_program.c
> > @@ -0,0 +1,221 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright 2017 Mellanox Technologies, Ltd.
> > + */
> > +
> > +#include <stdint.h>
> > +#include <stdbool.h>
> > +#include <sys/types.h>
> > +#include <sys/socket.h>
> > +#include <asm/types.h>
> > +#include <linux/in.h>
> > +#include <linux/if.h>
> > +#include <linux/if_ether.h>
> > +#include <linux/ip.h>
> > +#include <linux/ipv6.h>
> > +#include <linux/if_tunnel.h>
> > +#include <linux/filter.h>
> > +#include <linux/bpf.h>
> > +
> > +#include "tap_rss.h"
> > +
> > +/** Create IPv4 address */
> > +#define IPv4(a, b, c, d) ((__u32)(((a) & 0xff) << 24) | \
> > +		(((b) & 0xff) << 16) | \
> > +		(((c) & 0xff) << 8)  | \
> > +		((d) & 0xff))
> > +
> > +#define PORT(a, b) ((__u16)(((a) & 0xff) << 8) | \
> > +		((b) & 0xff))
> > +
> > +/*
> > + * The queue number is offset by 1, to distinguish packets that have
> > + * gone through this rule (skb->cb[1] != 0) from others.
> > + */
> > +#define QUEUE_OFFSET		1
> > +#define PIN_GLOBAL_NS		2
> > +
> > +#define KEY_IDX			0
> > +#define BPF_MAP_ID_KEY	1
> > +
> > +struct vlan_hdr {
> > +	__be16 proto;
> > +	__be16 tci;
> > +};
> > +
> > +struct bpf_elf_map __attribute__((section("maps"), used))
> > +map_keys = {
> > +	.type           =       BPF_MAP_TYPE_HASH,
> > +	.id             =       BPF_MAP_ID_KEY,
> > +	.size_key       =       sizeof(__u32),
> > +	.size_value     =       sizeof(struct rss_key),
> > +	.max_elem       =       256,
> > +	.pinning        =       PIN_GLOBAL_NS,
> > +};
> > +
> > +__section("cls_q") int
> > +match_q(struct __sk_buff *skb)
> > +{
> > +	__u32 queue = skb->cb[1];
> > +	volatile __u32 q = 0xdeadbeef;
> > +	__u32 match_queue = QUEUE_OFFSET + q;
> > +
> > +	/* printt("match_q$i() queue = %d\n", queue); */
> > +
> > +	if (queue != match_queue)
> > +		return TC_ACT_OK;
> > +	return TC_ACT_UNSPEC;
> > +}
> > +
> > +
> > +struct ipv4_l3_l4_tuple {
> > +	__u32    src_addr;
> > +	__u32    dst_addr;
> > +	__u16    dport;
> > +	__u16    sport;
> > +} __attribute__((packed));
> > +
> > +struct ipv6_l3_l4_tuple {
> > +	__u8        src_addr[16];
> > +	__u8        dst_addr[16];
> > +	__u16       dport;
> > +	__u16       sport;
> > +} __attribute__((packed));
> > +
> > +static const __u8 def_rss_key[] = {
> > +	0xd1, 0x81, 0xc6, 0x2c,
> > +	0xf7, 0xf4, 0xdb, 0x5b,
> > +	0x19, 0x83, 0xa2, 0xfc,
> > +	0x94, 0x3e, 0x1a, 0xdb,
> > +	0xd9, 0x38, 0x9e, 0x6b,
> > +	0xd1, 0x03, 0x9c, 0x2c,
> > +	0xa7, 0x44, 0x99, 0xad,
> > +	0x59, 0x3d, 0x56, 0xd9,
> > +	0xf3, 0x25, 0x3c, 0x06,
> > +	0x2a, 0xdc, 0x1f, 0xfc,
> > +};
> > +
> > +static __u32  __attribute__((always_inline))
> > +rte_softrss_be(const __u32 *input_tuple, const uint8_t *rss_key,
> > +		__u8 input_len)
> > +{
> > +	__u32 i, j, hash = 0;
> > +#pragma unroll
> > +	for (j = 0; j < input_len; j++) {
> > +#pragma unroll
> > +		for (i = 0; i < 32; i++) {
> > +			if (input_tuple[j] & (1 << (31 - i))) {
> > +				hash ^= ((const __u32 *)def_rss_key)[j] << i |
> > +				(__u32)((uint64_t)
> > +				(((const __u32 *)def_rss_key)[j + 1])
> > +					>> (32 - i));
> > +			}
> > +		}
> > +	}
> > +	return hash;
> > +}
> > +
> > +static int __attribute__((always_inline))
> > +rss_l3_l4(struct __sk_buff *skb)
> > +{
> > +	void *data_end = (void *)(long)skb->data_end;
> > +	void *data = (void *)(long)skb->data;
> > +	__u16 proto = (__u16)skb->protocol;
> > +	__u32 key_idx = 0xdeadbeef;
> > +	__u32 hash;
> > +	struct rss_key *rsskey;
> > +	__u64 off = ETH_HLEN;
> > +	int j;
> > +	__u8 *key = 0;
> > +	__u32 len;
> > +	__u32 queue = 0;
> > +
> > +	rsskey = map_lookup_elem(&map_keys, &key_idx);
> > +	if (!rsskey) {
> > +		printt("hash(): rss key is not configured\n");
> > +		return TC_ACT_OK;
> > +	}
> > +	key = (__u8 *)rsskey->key;
> > +
> > +	/* Get correct proto for 802.1ad */
> > +	if (skb->vlan_present && skb->vlan_proto == htons(ETH_P_8021AD))
> {
> > +		if (data + ETH_ALEN * 2 + sizeof(struct vlan_hdr) +
> > +		    sizeof(proto) > data_end)
> > +			return TC_ACT_OK;
> > +		proto = *(__u16 *)(data + ETH_ALEN * 2 +
> > +				   sizeof(struct vlan_hdr));
> > +		off += sizeof(struct vlan_hdr);
> > +	}
> > +
> > +	if (proto == htons(ETH_P_IP)) {
> > +		if (data + off + sizeof(struct iphdr) + sizeof(__u32)
> > +			> data_end)
> > +			return TC_ACT_OK;
> > +
> > +		__u8 *src_dst_addr = data + off + offsetof(struct iphdr,
> saddr);
> > +		__u8 *src_dst_port = data + off + sizeof(struct iphdr);
> > +		struct ipv4_l3_l4_tuple v4_tuple = {
> > +			.src_addr = IPv4(*(src_dst_addr + 0),
> > +					*(src_dst_addr + 1),
> > +					*(src_dst_addr + 2),
> > +					*(src_dst_addr + 3)),
> > +			.dst_addr = IPv4(*(src_dst_addr + 4),
> > +					*(src_dst_addr + 5),
> > +					*(src_dst_addr + 6),
> > +					*(src_dst_addr + 7)),
> > +			.sport = PORT(*(src_dst_port + 0),
> > +					*(src_dst_port + 1)),
> > +			.dport = PORT(*(src_dst_port + 2),
> > +					*(src_dst_port + 3)),
> > +		};
> > +		__u8 input_len = sizeof(v4_tuple) / sizeof(__u32);
> > +		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV4_L3))
> > +			input_len--;
> > +		hash = rte_softrss_be((__u32 *)&v4_tuple, key, 3);
> > +	} else if (proto == htons(ETH_P_IPV6)) {
> > +		if (data + off + sizeof(struct ipv6hdr) +
> > +					sizeof(__u32) > data_end)
> > +			return TC_ACT_OK;
> > +		__u8 *src_dst_addr = data + off +
> > +					offsetof(struct ipv6hdr, saddr);
> > +		__u8 *src_dst_port = data + off +
> > +					sizeof(struct ipv6hdr);
> > +		struct ipv6_l3_l4_tuple v6_tuple;
> > +		for (j = 0; j < 4; j++)
> > +			*((uint32_t *)&v6_tuple.src_addr + j) =
> > +				__builtin_bswap32(*((uint32_t *)
> > +						src_dst_addr + j));
> > +		for (j = 0; j < 4; j++)
> > +			*((uint32_t *)&v6_tuple.dst_addr + j) =
> > +				__builtin_bswap32(*((uint32_t *)
> > +						src_dst_addr + 4 + j));
> > +		v6_tuple.sport = PORT(*(src_dst_port + 0),
> > +			      *(src_dst_port + 1));
> > +		v6_tuple.dport = PORT(*(src_dst_port + 2),
> > +			      *(src_dst_port + 3));
> > +
> > +		__u8 input_len = sizeof(v6_tuple) / sizeof(__u32);
> > +		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV6_L3))
> > +			input_len--;
> > +		hash = rte_softrss_be((__u32 *)&v6_tuple, key, 9);
> > +	} else {
> > +		return TC_ACT_PIPE;
> > +	}
> > +
> > +	queue = rsskey->queues[(hash % rsskey->nb_queues) &
> > +				       (TAP_MAX_QUEUES - 1)];
> > +	skb->cb[1] = QUEUE_OFFSET + queue;
> > +	/* printt(">>>>> rss_l3_l4 hash=0x%x queue=%u\n", hash, queue); */
> > +
> > +	return TC_ACT_RECLASSIFY;
> > +}
> > +
> > +#define RSS(L)						\
> > +	__section(#L) int				\
> > +		L ## _hash(struct __sk_buff *skb)	\
> > +	{						\
> > +		return rss_ ## L (skb);			\
> > +	}
> > +
> > +RSS(l3_l4)
> > +
> > +BPF_LICENSE("Dual BSD/GPL");
> > diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h
> > index 9e332b0..6cc01b4 100644
> > --- a/drivers/net/tap/tap_flow.h
> > +++ b/drivers/net/tap/tap_flow.h
> > @@ -50,6 +50,8 @@
> >  #define GROUP_SHIFT 12
> >  #define MAX_GROUP GROUP_MASK
> >
> > +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
> > +
> >  /**
> >   * These index are actually in reversed order: their priority is processed
> >   * by subtracting their value to the lowest priority (PRIORITY_MASK).
> > @@ -80,4 +82,7 @@ int tap_flow_implicit_destroy(struct pmd_internals
> *pmd,
> >  int tap_flow_implicit_flush(struct pmd_internals *pmd,
> >  			    struct rte_flow_error *error);
> >
> > +int tap_flow_bpf_cls_q(__u32 queue_idx);
> > +int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd);
> > +
> >  #endif /* _TAP_FLOW_H_ */


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v3 2/2] net/tap: implement RSS with eBPF classifier and action
  2018-01-10  7:06     ` [dpdk-dev] [PATCH v3 2/2] net/tap: implement RSS with eBPF classifier and action Ophir Munk
@ 2018-01-10 10:19       ` Pascal Mazon
  2018-01-11 17:20         ` Ophir Munk
  0 siblings, 1 reply; 42+ messages in thread
From: Pascal Mazon @ 2018-01-10 10:19 UTC (permalink / raw)
  To: Ophir Munk, dev; +Cc: Thomas Monjalon, Olga Shern

Ok, now I get why ARRAY_SIZE was where it was. Nevermind.

I think you're doing too much in one patch. As the subject is not
trivial, I would rather have it split.
Can you make a first patch that just adds support for several actions,
then your patch that adds BPF rule support?

Otherwise your code looks neat.

Comments inline.

Best regards,

Pascal

On 10/01/2018 08:06, Ophir Munk wrote:
> Add BPF classifier for each TAP queue. According to this classifier packets
> marked with an RSS queue will be directed to this queue using a traffic
> control with "skbedit" action.
> The BPF classifier program is downloaded to the kernel once per TAP Rx
> queue.
>
> Add RSS BPF map entry for each new RSS rule. A BPF map entry contains the
> RSS queues of that rule.
>
> Add BPF action for each new RSS rule in which the Toeplitz RSS hash is
> calculated based on L3 addresses and L4 ports. Mark the packet with the RSS
> queue according the resulting RSS hash, then reclassify the packet.
>
> Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
> ---
>  drivers/net/tap/Makefile        |  20 ++
>  drivers/net/tap/rte_eth_tap.h   |   9 +-
>  drivers/net/tap/tap_bpf_insns.c |  62 +++-
>  drivers/net/tap/tap_flow.c      | 635 ++++++++++++++++++++++++++++++++++------
>  drivers/net/tap/tap_flow.h      |  10 +
>  drivers/net/tap/tap_rss.h       |  32 ++
>  drivers/net/tap/tap_tcmsgs.h    |   4 +
>  7 files changed, 675 insertions(+), 97 deletions(-)
>  create mode 100644 drivers/net/tap/tap_rss.h
>
> diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
> index feaa5b7..0e7c494 100644
> --- a/drivers/net/tap/Makefile
> +++ b/drivers/net/tap/Makefile
> @@ -60,6 +60,26 @@ tap_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
>  		enum TCA_FLOWER_KEY_VLAN_PRIO \
>  		$(AUTOCONF_OUTPUT)
>  	$Q sh -- '$<' '$@' \
> +		HAVE_TC_BPF \
> +		linux/pkt_cls.h \
> +		enum TCA_BPF_UNSPEC \
> +		$(AUTOCONF_OUTPUT)
> +	$Q sh -- '$<' '$@' \
> +		HAVE_TC_BPF_FD \
> +		linux/pkt_cls.h \
> +		enum TCA_BPF_FD \
> +		$(AUTOCONF_OUTPUT)
> +	$Q sh -- '$<' '$@' \
> +		HAVE_TC_ACT_BPF \
> +		linux/tc_act/tc_bpf.h \
> +		enum TCA_ACT_BPF_UNSPEC \
> +		$(AUTOCONF_OUTPUT)
> +	$Q sh -- '$<' '$@' \
> +		HAVE_TC_ACT_BPF_FD \
> +		linux/tc_act/tc_bpf.h \
> +		enum TCA_ACT_BPF_FD \
> +		$(AUTOCONF_OUTPUT)
> +	$Q sh -- '$<' '$@' \
>  		HAVE_BPF_PROG_LOAD \
>  		linux/bpf.h \
>  		enum BPF_PROG_LOAD \
> diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
> index 829f32f..c185473 100644
> --- a/drivers/net/tap/rte_eth_tap.h
> +++ b/drivers/net/tap/rte_eth_tap.h
> @@ -45,7 +45,7 @@
>  #include <rte_ether.h>
>  
>  #ifdef IFF_MULTI_QUEUE
> -#define RTE_PMD_TAP_MAX_QUEUES	16
> +#define RTE_PMD_TAP_MAX_QUEUES	TAP_MAX_QUEUES
>  #else
>  #define RTE_PMD_TAP_MAX_QUEUES	1
>  #endif
> @@ -90,6 +90,13 @@ struct pmd_internals {
>  	int ioctl_sock;                   /* socket for ioctl calls */
>  	int nlsk_fd;                      /* Netlink socket fd */
>  	int flow_isolate;                 /* 1 if flow isolation is enabled */
> +	int flower_support;               /* 1 if kernel supports, else 0 */
> +	int flower_vlan_support;          /* 1 if kernel supports, else 0 */
> +	int rss_enabled;                  /* 1 if RSS is enabled, else 0 */
> +	/* implicit rules set when RSS is enabled */
> +	int map_fd;                       /* BPF RSS map fd */
> +	int bpf_fd[RTE_PMD_TAP_MAX_QUEUES];/* List of bpf fds per queue */
> +	LIST_HEAD(tap_rss_flows, rte_flow) rss_flows;
>  	LIST_HEAD(tap_flows, rte_flow) flows;        /* rte_flow rules */
>  	/* implicit rte_flow rules set when a remote device is active */
>  	LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows;
> diff --git a/drivers/net/tap/tap_bpf_insns.c b/drivers/net/tap/tap_bpf_insns.c
> index 25aa82c..bf95f2d 100644
> --- a/drivers/net/tap/tap_bpf_insns.c
> +++ b/drivers/net/tap/tap_bpf_insns.c
> @@ -1830,7 +1830,7 @@ static int bpf_load(enum bpf_prog_type type,
>  		  size_t insns_cnt,
>  		  const char *license)
>  {
> -	union bpf_attr attr;
> +	union bpf_attr attr = {};

Should be squashed in previous commit.

>  
>  	bzero(&attr, sizeof(attr));
>  	attr.prog_type = type;
> @@ -1843,3 +1843,63 @@ static int bpf_load(enum bpf_prog_type type,
>  
>  	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
>  }
> +
> +/**
> + * Create BPF map for RSS rules
> + *
> + * @param[in] key_size
> + *   map RSS key size
> + *
> + * @param[in] value_size
> + *   Map RSS value size
> + *
> + * @param[in] max_entries
> + *   Map max number of RSS entries (limit on max RSS rules)
> + *
> + * @return
> + *   -1 if BPF map couldn't be created, map fd otherwise
> + */
> +int tap_flow_bpf_rss_map_create(unsigned int key_size,
> +		unsigned int value_size,
> +		unsigned int max_entries)
> +{
> +	union bpf_attr attr = {};
> +
> +	bzero(&attr, sizeof(attr));
> +	attr.map_type    = BPF_MAP_TYPE_HASH;
> +	attr.key_size    = key_size;
> +	attr.value_size  = value_size;
> +	attr.max_entries = max_entries;
> +
> +	return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
> +}
> +
> +/**
> + * Update RSS entry in BPF map
> + *
> + * @param[in] fd
> + *   RSS map fd
> + *
> + * @param[in] key
> + *   Pointer to RSS key whose entry is updated
> + *
> + * @param[in] value
> + *   Pointer to RSS new updated value
> + *
> + * @return
> + *   -1 if RSS entry failed to be updated, 0 otherwise
> + */
> +int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value)
> +{
> +	union bpf_attr attr = {};
> +
> +	bzero(&attr, sizeof(attr));
> +
> +	attr.map_type = BPF_MAP_TYPE_HASH;
> +	attr.map_fd = fd;
> +	attr.key = ptr_to_u64(key);
> +	attr.value = ptr_to_u64(value);
> +	attr.flags = BPF_ANY;
> +
> +	return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
> +}
> diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
> index 90b2654..7c51614 100644
> --- a/drivers/net/tap/tap_flow.c
> +++ b/drivers/net/tap/tap_flow.c
> @@ -33,7 +33,9 @@
>  
>  #include <errno.h>
>  #include <string.h>
> +#include <unistd.h>
>  #include <sys/queue.h>
> +#include <sys/resource.h>
>  
>  #include <rte_byteorder.h>
>  #include <rte_jhash.h>
> @@ -42,6 +44,7 @@
>  #include <tap_flow.h>
>  #include <tap_autoconf.h>
>  #include <tap_tcmsgs.h>
> +#include <tap_rss.h>
>  
>  #ifndef HAVE_TC_FLOWER
>  /*
> @@ -81,12 +84,78 @@ enum {
>  	TCA_FLOWER_KEY_VLAN_ETH_TYPE,   /* be16 */
>  };
>  #endif
> +/*
> + * For kernels < 4.2 BPF related enums may not be defined.
> + * Runtime checks will be carried out to gracefully report on TC messages that
> + * are rejected by the kernel. Rejection reasons may be due to:
> + * 1. enum is not defined
> + * 2. enum is defined but kerenl is not configured to support BPF system calls,

Typo at "kerenl".

> + *    BPF classifications or BPF actions.
> + */
> +#ifndef HAVE_TC_BPF
> +enum {
> +	TCA_BPF_UNSPEC,
> +	TCA_BPF_ACT,
> +	TCA_BPF_POLICE,
> +	TCA_BPF_CLASSID,
> +	TCA_BPF_OPS_LEN,
> +	TCA_BPF_OPS,
> +};
> +#endif
> +#ifndef HAVE_TC_BPF_FD
> +enum {
> +	TCA_BPF_FD = TCA_BPF_OPS + 1,
> +	TCA_BPF_NAME,
> +};
> +#endif
> +#ifndef HAVE_TC_ACT_BPF
> +#define tc_gen \
> +	__u32                 index; \
> +	__u32                 capab; \
> +	int                   action; \
> +	int                   refcnt; \
> +	int                   bindcnt
> +
> +struct tc_act_bpf {
> +	tc_gen;
> +};
> +
> +enum {
> +	TCA_ACT_BPF_UNSPEC,
> +	TCA_ACT_BPF_TM,
> +	TCA_ACT_BPF_PARMS,
> +	TCA_ACT_BPF_OPS_LEN,
> +	TCA_ACT_BPF_OPS,
> +};
> +
> +#endif
> +#ifndef HAVE_TC_ACT_BPF_FD
> +enum {
> +	TCA_ACT_BPF_FD = TCA_ACT_BPF_OPS + 1,
> +	TCA_ACT_BPF_NAME,
> +};
> +#endif
> +
> +/* RSS key management */
> +enum bpf_rss_key_e {
> +	KEY_CMD_GET = 1,
> +	KEY_CMD_RELEASE,
> +	KEY_CMD_INIT,
> +	KEY_CMD_DEINIT,
> +};
> +
> +enum key_status_e {
> +	KEY_STAT_UNSPEC,
> +	KEY_STAT_USED,
> +	KEY_STAT_AVAILABLE,
> +};
>  
>  #define ISOLATE_HANDLE 1
>  
>  struct rte_flow {
>  	LIST_ENTRY(rte_flow) next; /* Pointer to the next rte_flow structure */
>  	struct rte_flow *remote_flow; /* associated remote flow */
> +	int bpf_fd[SEC_MAX]; /* list of bfs fds per ELF section */
>  	struct nlmsg msg;
>  };
>  
> @@ -104,6 +173,24 @@ struct remote_rule {
>  	int mirred;
>  };
>  
> +struct action_data {
> +	char id[16];
> +
> +	union {
> +		struct tc_gact gact;
> +		struct tc_mirred mirred;
> +		struct skbedit {
> +			struct tc_skbedit skbedit;
> +			uint16_t queue;
> +		} skbedit;
> +		struct bpf {
> +			struct tc_act_bpf bpf;
> +			int bpf_fd;
> +			const char *annotation;
> +		} bpf;
> +	};
> +};
> +
>  static int tap_flow_create_eth(const struct rte_flow_item *item, void *data);
>  static int tap_flow_create_vlan(const struct rte_flow_item *item, void *data);
>  static int tap_flow_create_ipv4(const struct rte_flow_item *item, void *data);
> @@ -134,6 +221,14 @@ tap_flow_isolate(struct rte_eth_dev *dev,
>  		 int set,
>  		 struct rte_flow_error *error);
>  
> +static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx);
> +static int rss_enable(struct pmd_internals *pmd,
> +			const struct rte_flow_attr *attr,
> +			struct rte_flow_error *error);
> +static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
> +			const struct rte_flow_action_rss *rss,
> +			struct rte_flow_error *error);
> +
>  static const struct rte_flow_ops tap_flow_ops = {
>  	.validate = tap_flow_validate,
>  	.create = tap_flow_create,
> @@ -819,111 +914,97 @@ tap_flow_item_validate(const struct rte_flow_item *item,
>  }
>  
>  /**
> - * Transform a DROP/PASSTHRU action item in the provided flow for TC.
> + * Configure the kernel with a TC action and its configured parameters
> + * Handled actions: "gact", "mirred", "skbedit", "bpf"
>   *
> - * @param[in, out] flow
> - *   Flow to be filled.
> - * @param[in] action
> - *   Appropriate action to be set in the TCA_GACT_PARMS structure.
> + * @param[in] flow
> + *   Pointer to rte flow containing the netlink message
>   *
> - * @return
> - *   0 if checks are alright, -1 otherwise.
> - */
> -static int
> -add_action_gact(struct rte_flow *flow, int action)
> -{
> -	struct nlmsg *msg = &flow->msg;
> -	size_t act_index = 1;
> -	struct tc_gact p = {
> -		.action = action
> -	};
> -
> -	if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
> -		return -1;
> -	if (tap_nlattr_nested_start(msg, act_index++) < 0)
> -		return -1;
> -	tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("gact"), "gact");
> -	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
> -		return -1;
> -	tap_nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(p), &p);
> -	tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
> -	tap_nlattr_nested_finish(msg); /* nested act_index */
> -	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
> -	return 0;
> -}
> -
> -/**
> - * Transform a MIRRED action item in the provided flow for TC.
> + * @param[in, out] act_index
> + *   Pointer to action sequence number in the TC command
>   *
> - * @param[in, out] flow
> - *   Flow to be filled.
> - * @param[in] ifindex
> - *   Netdevice ifindex, where to mirror/redirect packet to.
> - * @param[in] action_type
> - *   Either TCA_EGRESS_REDIR for redirection or TCA_EGRESS_MIRROR for mirroring.
> + * @param[in] adata
> + *  Pointer to struct holding the action parameters
>   *
>   * @return
> - *   0 if checks are alright, -1 otherwise.
> + *   -1 on failure, 0 on success
>   */
>  static int
> -add_action_mirred(struct rte_flow *flow, uint16_t ifindex, uint16_t action_type)
> +add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
>  {
>  	struct nlmsg *msg = &flow->msg;
> -	size_t act_index = 1;
> -	struct tc_mirred p = {
> -		.eaction = action_type,
> -		.ifindex = ifindex,
> -	};
>  
> -	if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
> -		return -1;
> -	if (tap_nlattr_nested_start(msg, act_index++) < 0)
> +	if (tap_nlattr_nested_start(msg, (*act_index)++) < 0)
>  		return -1;
> -	tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("mirred"), "mirred");
> +
> +	tap_nlattr_add(&msg->nh, TCA_ACT_KIND,
> +				strlen(adata->id) + 1, adata->id);
>  	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
>  		return -1;
> -	if (action_type == TCA_EGRESS_MIRROR)
> -		p.action = TC_ACT_PIPE;
> -	else /* REDIRECT */
> -		p.action = TC_ACT_STOLEN;
> -	tap_nlattr_add(&msg->nh, TCA_MIRRED_PARMS, sizeof(p), &p);
> +	if (strcmp("gact", adata->id) == 0) {
> +		tap_nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(adata->gact),
> +			   &adata->gact);
> +	} else if (strcmp("mirred", adata->id) == 0) {
> +		if (adata->mirred.eaction == TCA_EGRESS_MIRROR)
> +			adata->mirred.action = TC_ACT_PIPE;
> +		else /* REDIRECT */
> +			adata->mirred.action = TC_ACT_STOLEN;
> +		tap_nlattr_add(&msg->nh, TCA_MIRRED_PARMS,
> +			   sizeof(adata->mirred),
> +			   &adata->mirred);
> +	} else if (strcmp("skbedit", adata->id) == 0) {
> +		tap_nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS,
> +			   sizeof(adata->skbedit.skbedit),
> +			   &adata->skbedit.skbedit);
> +		tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING,
> +			     adata->skbedit.queue);
> +	} else if (strcmp("bpf", adata->id) == 0) {
> +		tap_nlattr_add32(&msg->nh, TCA_ACT_BPF_FD, adata->bpf.bpf_fd);
> +		tap_nlattr_add(&msg->nh, TCA_ACT_BPF_NAME,
> +			   strlen(adata->bpf.annotation) + 1,
> +			   adata->bpf.annotation);
> +		tap_nlattr_add(&msg->nh, TCA_ACT_BPF_PARMS,
> +			   sizeof(adata->bpf.bpf),
> +			   &adata->bpf.bpf);
> +	} else {
> +		return -1;
> +	}
>  	tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
>  	tap_nlattr_nested_finish(msg); /* nested act_index */
> -	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
>  	return 0;
>  }
>  
>  /**
> - * Transform a QUEUE action item in the provided flow for TC.
> + * Helper function to send a serie of TC actions to the kernel
>   *
> - * @param[in, out] flow
> - *   Flow to be filled.
> - * @param[in] queue
> - *   Queue id to use.
> + * @param[in] flow
> + *   Pointer to rte flow containing the netlink message
> + *
> + * @param[in] nb_actions
> + *   Number of actions in an array of action structs
> + *
> + * @param[in] data
> + *   Pointer to an array of action structs
> + *
> + * @param[in] classifier_actions
> + *   The classifier on behave of which the actions are configured
>   *
>   * @return
> - *   0 if checks are alright, -1 otherwise.
> + *   -1 on failure, 0 on success
>   */
>  static int
> -add_action_skbedit(struct rte_flow *flow, uint16_t queue)
> +add_actions(struct rte_flow *flow, int nb_actions, struct action_data *data,
> +	    int classifier_action)
>  {
>  	struct nlmsg *msg = &flow->msg;
>  	size_t act_index = 1;
> -	struct tc_skbedit p = {
> -		.action = TC_ACT_PIPE
> -	};
> +	int i;
>  
> -	if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
> -		return -1;
> -	if (tap_nlattr_nested_start(msg, act_index++) < 0)
> +	if (tap_nlattr_nested_start(msg, classifier_action) < 0)
>  		return -1;
> -	tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("skbedit"), "skbedit");
> -	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
> -		return -1;
> -	tap_nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS, sizeof(p), &p);
> -	tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING, queue);
> -	tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
> -	tap_nlattr_nested_finish(msg); /* nested act_index */
> +	for (i = 0; i < nb_actions; i++)
> +		if (add_action(flow, &act_index, data + i) < 0)
> +			return -1;
>  	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
>  	return 0;
>  }
> @@ -987,7 +1068,8 @@ priv_flow_process(struct pmd_internals *pmd,
>  		return -rte_errno;
>  	} else if (flow) {
>  		uint16_t group = attr->group << GROUP_SHIFT;
> -		uint16_t prio = group | (attr->priority + PRIORITY_OFFSET);
> +		uint16_t prio = group | (attr->priority +
> +				RSS_PRIORITY_OFFSET + PRIORITY_OFFSET);
>  		flow->msg.t.tcm_info = TC_H_MAKE(prio << 16,
>  						 flow->msg.t.tcm_info);
>  	}
> @@ -1056,7 +1138,12 @@ priv_flow_process(struct pmd_internals *pmd,
>  		}
>  	}
>  	if (mirred && flow) {
> -		uint16_t if_index = pmd->if_index;
> +		struct action_data adata = {
> +			.id = "mirred",
> +			.mirred = {
> +				.eaction = mirred,
> +			},
> +		};
>  
>  		/*
>  		 * If attr->egress && mirred, then this is a special
> @@ -1064,9 +1151,13 @@ priv_flow_process(struct pmd_internals *pmd,
>  		 * redirect packets coming from the DPDK App, out
>  		 * through the remote netdevice.
>  		 */
> -		if (attr->egress)
> -			if_index = pmd->remote_if_index;
> -		if (add_action_mirred(flow, if_index, mirred) < 0)
> +		adata.mirred.ifindex = attr->ingress ? pmd->if_index :
> +			pmd->remote_if_index;
> +		if (mirred == TCA_EGRESS_MIRROR)
> +			adata.mirred.action = TC_ACT_PIPE;
> +		else
> +			adata.mirred.action = TC_ACT_STOLEN;
> +		if (add_actions(flow, 1, &adata, TCA_FLOWER_ACT) < 0)
>  			goto exit_action_not_supported;
>  		else
>  			goto end;
> @@ -1080,14 +1171,33 @@ priv_flow_process(struct pmd_internals *pmd,
>  			if (action)
>  				goto exit_action_not_supported;
>  			action = 1;
> -			if (flow)
> -				err = add_action_gact(flow, TC_ACT_SHOT);
> +			if (flow) {
> +				struct action_data adata = {
> +					.id = "gact",
> +					.gact = {
> +						.action = TC_ACT_SHOT,
> +					},
> +				};
> +
> +				err = add_actions(flow, 1, &adata,
> +						  TCA_FLOWER_ACT);
> +			}
>  		} else if (actions->type == RTE_FLOW_ACTION_TYPE_PASSTHRU) {
>  			if (action)
>  				goto exit_action_not_supported;
>  			action = 1;
> -			if (flow)
> -				err = add_action_gact(flow, TC_ACT_UNSPEC);
> +			if (flow) {
> +				struct action_data adata = {
> +					.id = "gact",
> +					.gact = {
> +						/* continue */
> +						.action = TC_ACT_UNSPEC,
> +					},
> +				};
> +
> +				err = add_actions(flow, 1, &adata,
> +						  TCA_FLOWER_ACT);
> +			}
>  		} else if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
>  			const struct rte_flow_action_queue *queue =
>  				(const struct rte_flow_action_queue *)
> @@ -1099,22 +1209,35 @@ priv_flow_process(struct pmd_internals *pmd,
>  			if (!queue ||
>  			    (queue->index > pmd->dev->data->nb_rx_queues - 1))
>  				goto exit_action_not_supported;
> -			if (flow)
> -				err = add_action_skbedit(flow, queue->index);
> +			if (flow) {
> +				struct action_data adata = {
> +					.id = "skbedit",
> +					.skbedit = {
> +						.skbedit = {
> +							.action = TC_ACT_PIPE,
> +						},
> +						.queue = queue->index,
> +					},
> +				};
> +
> +				err = add_actions(flow, 1, &adata,
> +					TCA_FLOWER_ACT);
> +			}
>  		} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
> -			/* Fake RSS support. */
>  			const struct rte_flow_action_rss *rss =
>  				(const struct rte_flow_action_rss *)
>  				actions->conf;
>  
> -			if (action)
> -				goto exit_action_not_supported;
> -			action = 1;
> -			if (!rss || rss->num < 1 ||
> -			    (rss->queue[0] > pmd->dev->data->nb_rx_queues - 1))
> +			if (action++)
>  				goto exit_action_not_supported;
> -			if (flow)
> -				err = add_action_skbedit(flow, rss->queue[0]);
> +
> +			if (!pmd->rss_enabled) {
> +				err = rss_enable(pmd, attr, error);
> +				if (err)
> +					goto exit_action_not_supported;
> +			}
> +			if (flow && rss)
> +				err = rss_add_actions(flow, pmd, rss, error);
>  		} else {
>  			goto exit_action_not_supported;
>  		}
> @@ -1326,6 +1449,7 @@ tap_flow_destroy_pmd(struct pmd_internals *pmd,
>  		     struct rte_flow_error *error)
>  {
>  	struct rte_flow *remote_flow = flow->remote_flow;
> +	int i;
>  	int ret = 0;
>  
>  	LIST_REMOVE(flow, next);
> @@ -1351,6 +1475,13 @@ tap_flow_destroy_pmd(struct pmd_internals *pmd,
>  			"couldn't receive kernel ack to our request");
>  		goto end;
>  	}
> +	/* Close opened BPF file descriptors of this flow */
> +	for (i = 0; i < SEC_MAX; i++)
> +		if (flow->bpf_fd[i] != 0) {
> +			close(flow->bpf_fd[i]);
> +			flow->bpf_fd[i] = 0;
> +		}
> +
>  	if (remote_flow) {
>  		remote_flow->msg.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
>  		remote_flow->msg.nh.nlmsg_type = RTM_DELTFILTER;
> @@ -1635,6 +1766,320 @@ tap_flow_implicit_flush(struct pmd_internals *pmd, struct rte_flow_error *error)
>  	return 0;
>  }
>  
> +#define MAX_RSS_KEYS 256
> +#define SEC_NAME_CLS_Q "cls_q"
> +
> +const char *sec_name[SEC_MAX] = {
> +	[SEC_L3_L4] = "l3_l4",
> +};
> +
> +/**
> + * Enable RSS on tap: create TC rules for queuing.
> + *
> + * @param[in, out] pmd
> + *   Pointer to private structure.
> + *
> + * @param[in] attr
> + *   Pointer to rte_flow to get flow group
> + *
> + * @param[out] error
> + *   Pointer to error reporting if not NULL.
> + *
> + * @return 0 on success, negative value on failure.
> + */
> +static int rss_enable(struct pmd_internals *pmd,
> +			const struct rte_flow_attr *attr,
> +			struct rte_flow_error *error)
> +{
> +	struct rte_flow *rss_flow = NULL;
> +	struct nlmsg *msg = NULL;
> +	/* 4096 is the maximum number of instructions for a BPF program */
> +	char annotation[64];
> +	int i;
> +	int err = 0;
> +
> +	/* unlimit locked memory */
> +	struct rlimit limit = {
> +		.rlim_cur = RLIM_INFINITY,
> +		.rlim_max = RLIM_INFINITY,
> +	};
> +	setrlimit(RLIMIT_MEMLOCK, &limit);
> +
> +	 /* Get a new map key for a new RSS rule */
> +	err = bpf_rss_key(KEY_CMD_INIT, NULL);
> +	if (err < 0) {
> +		rte_flow_error_set(
> +			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> +			"Failed to initialize BPF RSS keys");
> +
> +		return -1;
> +	}
> +
> +	/*
> +	 *  Create BPF RSS MAP
> +	 */
> +	pmd->map_fd = tap_flow_bpf_rss_map_create(sizeof(__u32), /* key size */
> +				sizeof(struct rss_key),
> +				MAX_RSS_KEYS);
> +	if (pmd->map_fd < 0) {
> +		RTE_LOG(ERR, PMD,
> +			"Failed to create BPF map (%d): %s\n",
> +				errno, strerror(errno));
> +		rte_flow_error_set(
> +			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> +			"Kernel too old or not configured "
> +			"to support BPF maps");
> +
> +		return -ENOTSUP;
> +	}
> +
> +	/*
> +	 * Add a rule per queue to match reclassified packets and direct them to
> +	 * the correct queue.
> +	 */
> +	for (i = 0; i < pmd->dev->data->nb_rx_queues; i++) {
> +		pmd->bpf_fd[i] = tap_flow_bpf_cls_q(i);
> +		if (pmd->bpf_fd[i] < 0) {
> +			RTE_LOG(ERR, PMD,
> +				"Failed to load BPF section %s for queue %d",
> +				SEC_NAME_CLS_Q, i);
> +			rte_flow_error_set(
> +				error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
> +				NULL,
> +				"Kernel too old or not configured "
> +				"to support BPF programs loading");
> +
> +			return -ENOTSUP;
> +		}
> +
> +		rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
> +		if (!rss_flow) {
> +			RTE_LOG(ERR, PMD,
> +				"Cannot allocate memory for rte_flow");
> +			return -1;
> +		}
> +		msg = &rss_flow->msg;
> +		tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER, NLM_F_REQUEST |
> +			    NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE);
> +		msg->t.tcm_info = TC_H_MAKE(0, htons(ETH_P_ALL));
> +		tap_flow_set_handle(rss_flow);
> +		uint16_t group = attr->group << GROUP_SHIFT;
> +		uint16_t prio = group | (i + PRIORITY_OFFSET);
> +		msg->t.tcm_info = TC_H_MAKE(prio << 16, msg->t.tcm_info);
> +		msg->t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
> +
> +		tap_nlattr_add(&msg->nh, TCA_KIND, sizeof("bpf"), "bpf");
> +		if (tap_nlattr_nested_start(msg, TCA_OPTIONS) < 0)
> +			return -1;
> +		tap_nlattr_add32(&msg->nh, TCA_BPF_FD, pmd->bpf_fd[i]);
> +		snprintf(annotation, sizeof(annotation), "[%s%d]",
> +			SEC_NAME_CLS_Q, i);
> +		tap_nlattr_add(&msg->nh, TCA_BPF_NAME, strlen(annotation) + 1,
> +			   annotation);
> +		/* Actions */
> +		{
> +			struct action_data adata = {
> +				.id = "skbedit",
> +				.skbedit = {
> +					.skbedit = {
> +						.action = TC_ACT_PIPE,
> +					},
> +					.queue = i,
> +				},
> +			};
> +			if (add_actions(rss_flow, 1, &adata, TCA_BPF_ACT) < 0)
> +				return -1;
> +		}
> +		tap_nlattr_nested_finish(msg); /* nested TCA_OPTIONS */
> +
> +		/* Netlink message is now ready to be sent */
> +		if (tap_nl_send(pmd->nlsk_fd, &msg->nh) < 0)
> +			return -1;
> +		err = tap_nl_recv_ack(pmd->nlsk_fd);
> +		if (err < 0) {
> +			RTE_LOG(ERR, PMD,
> +				"Kernel refused TC filter rule creation (%d): %s\n",
> +				errno, strerror(errno));
> +			return err;
> +		}
> +		LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
> +	}
> +
> +	pmd->rss_enabled = 1;
> +	return err;
> +}
> +
> +/**
> + * Manage bpf RSS keys repository with operations: init, get, release
> + *
> + * @param[in] cmd
> + *   Command on RSS keys: init, get, release
> + *
> + * @param[in, out] key_idx
> + *   Pointer to RSS Key index (out for get command, in for release command)
> + *
> + * @return -1 if couldn't get, release or init the RSS keys, 0 otherwise.
> + */
> +static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx)
> +{
> +	__u32 i;
> +	int err = -1;
> +	static __u32 num_used_keys;
> +	static __u32 rss_keys[MAX_RSS_KEYS] = {KEY_STAT_UNSPEC};
> +	static __u32 rss_keys_initialized;
> +
> +	switch (cmd) {
> +	case KEY_CMD_GET:
> +		if (!rss_keys_initialized)
> +			break;
> +
> +		if (num_used_keys == ARRAY_SIZE(rss_keys))
> +			break;
> +
> +		*key_idx = num_used_keys % ARRAY_SIZE(rss_keys);
> +		while (rss_keys[*key_idx] == KEY_STAT_USED)
> +			*key_idx = (*key_idx + 1) % ARRAY_SIZE(rss_keys);
> +
> +		rss_keys[*key_idx] = KEY_STAT_USED;
> +		num_used_keys++;
> +		err = 0;
> +	break;
> +
> +	case KEY_CMD_RELEASE:
> +		if (!rss_keys_initialized)
> +			break;
> +
> +		if (rss_keys[*key_idx] == KEY_STAT_USED) {
> +			rss_keys[*key_idx] = KEY_STAT_AVAILABLE;
> +			num_used_keys--;
> +			err = 0;
> +		}
> +	break;
> +
> +	case KEY_CMD_INIT:
> +		for (i = 0; i < ARRAY_SIZE(rss_keys); i++)
> +			rss_keys[i] = KEY_STAT_AVAILABLE;
> +
> +		rss_keys_initialized = 1;
> +		num_used_keys = 0;
> +		err = 0;
> +	break;
> +
> +	case KEY_CMD_DEINIT:
> +		for (i = 0; i < ARRAY_SIZE(rss_keys); i++)
> +			rss_keys[i] = KEY_STAT_UNSPEC;
> +
> +		rss_keys_initialized = 0;
> +		num_used_keys = 0;
> +		err = 0;
> +	break;
> +
> +	default:
> +		break;
> +	}
> +
> +	return err;
> +}
> +
> +/**
> + * Add RSS hash calculations and queue selection
> + *
> + * @param[in, out] pmd
> + *   Pointer to internal structure. Used to set/get RSS map fd
> + *
> + * @param[in] rss
> + *   Pointer to RSS flow actions
> + *
> + * @param[out] error
> + *   Pointer to error reporting if not NULL.
> + *
> + * @return 0 on success, negative value on failure
> + */
> +static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
> +			   const struct rte_flow_action_rss *rss,
> +			   struct rte_flow_error *error)
> +{
> +	/* 4096 is the maximum number of instructions for a BPF program */
> +	int i;
> +	__u32 key_idx;
> +	int err;
> +	struct rss_key rss_entry = { .hash_fields = 0,
> +				     .key_size = 0 };
> +
> +	/* Get a new map key for a new RSS rule */
> +	err = bpf_rss_key(KEY_CMD_GET, &key_idx);
> +	if (err < 0) {
> +		rte_flow_error_set(
> +			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> +			"Failed to get BPF RSS key");
> +
> +		return -1;
> +	}
> +
> +	/* Update RSS map entry with queues */
> +	rss_entry.nb_queues = rss->num;
> +	for (i = 0; i < rss->num; i++)
> +		rss_entry.queues[i] = rss->queue[i];
> +	rss_entry.hash_fields =
> +		(1 << HASH_FIELD_IPV4_L3_L4) | (1 << HASH_FIELD_IPV6_L3_L4);
> +
> +	/* Add this RSS entry to map */
> +	err = tap_flow_bpf_update_rss_elem(pmd->map_fd, &key_idx, &rss_entry);
> +
> +	if (err) {
> +		RTE_LOG(ERR, PMD,
> +			"Failed to update BPF map entry #%u (%d): %s\n",
> +			key_idx, errno, strerror(errno));
> +		rte_flow_error_set(
> +			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> +			"Kernel too old or not configured "
> +			"to support BPF maps updates");
> +
> +		return -ENOTSUP;
> +	}
> +
> +
> +	/*
> +	 * Load bpf rules to calculate hash for this key_idx
> +	 */
> +
> +	flow->bpf_fd[SEC_L3_L4] =
> +		tap_flow_bpf_calc_l3_l4_hash(key_idx, pmd->map_fd);
> +	if (flow->bpf_fd[SEC_L3_L4] < 0) {
> +		RTE_LOG(ERR, PMD,
> +			"Failed to load BPF section %s (%d): %s\n",
> +				sec_name[SEC_L3_L4], errno, strerror(errno));
> +		rte_flow_error_set(
> +			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> +			"Kernel too old or not configured "
> +			"to support BPF program loading");
> +
> +		return -ENOTSUP;
> +	}
> +
> +	/* Actions */
> +	{
> +		struct action_data adata[] = {
> +			{
> +				.id = "bpf",
> +				.bpf = {
> +					.bpf_fd = flow->bpf_fd[SEC_L3_L4],
> +					.annotation = sec_name[SEC_L3_L4],
> +					.bpf = {
> +						.action = TC_ACT_PIPE,
> +					},
> +				},
> +			},
> +		};
> +
> +		if (add_actions(flow, ARRAY_SIZE(adata), adata,
> +			TCA_FLOWER_ACT) < 0)
> +			return -1;
> +	}
> +
> +	return 0;
> +}
> +
>  /**
>   * Manage filter operations.
>   *
> diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h
> index 6cc01b4..dbb7ff6 100644
> --- a/drivers/net/tap/tap_flow.h
> +++ b/drivers/net/tap/tap_flow.h
> @@ -37,6 +37,7 @@
>  #include <rte_flow.h>
>  #include <rte_flow_driver.h>
>  #include <rte_eth_tap.h>
> +#include <tap_autoconf.h>
>  
>  /**
>   * In TC, priority 0 means we require the kernel to allocate one for us.
> @@ -49,6 +50,7 @@
>  #define GROUP_MASK (0xf)
>  #define GROUP_SHIFT 12
>  #define MAX_GROUP GROUP_MASK
> +#define RSS_PRIORITY_OFFSET 256

Shouldn't RSS_PRIORITY_OFFSET be equal to the number of queues, as
there's one implicit rule (skbedit action) per queue at start?

>  
>  #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
>  
> @@ -69,6 +71,11 @@ enum implicit_rule_index {
>  	TAP_REMOTE_MAX_IDX,
>  };
>  
> +enum bpf_fd_idx {
> +	SEC_L3_L4,
> +	SEC_MAX,
> +};
> +
>  int tap_dev_filter_ctrl(struct rte_eth_dev *dev,
>  			enum rte_filter_type filter_type,
>  			enum rte_filter_op filter_op,
> @@ -84,5 +91,8 @@ int tap_flow_implicit_flush(struct pmd_internals *pmd,
>  
>  int tap_flow_bpf_cls_q(__u32 queue_idx);
>  int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd);
> +int tap_flow_bpf_rss_map_create(unsigned int key_size, unsigned int value_size,
> +			unsigned int max_entries);
> +int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value);
>  
>  #endif /* _TAP_FLOW_H_ */
> diff --git a/drivers/net/tap/tap_rss.h b/drivers/net/tap/tap_rss.h
> new file mode 100644
> index 0000000..5e12531
> --- /dev/null
> +++ b/drivers/net/tap/tap_rss.h
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2017 Mellanox Technologies, Ltd.
> + */
> +
> +#ifndef _TAP_RSS_H_
> +#define _TAP_RSS_H_
> +
> +#define TAP_MAX_QUEUES 16
> +
> +/* hashed fields for RSS */
> +enum hash_field {
> +	HASH_FIELD_IPV4_L3,	/* IPv4 src/dst addr */
> +	HASH_FIELD_IPV4_L3_L4,	/* IPv4 src/dst addr + L4 src/dst ports */
> +	HASH_FIELD_IPV6_L3,	/* IPv6 src/dst addr */
> +	HASH_FIELD_IPV6_L3_L4,	/* IPv6 src/dst addr + L4 src/dst ports */
> +	HASH_FIELD_L2_SRC,	/* Ethernet src addr */
> +	HASH_FIELD_L2_DST,	/* Ethernet dst addr */
> +	HASH_FIELD_L3_SRC,	/* L3 src addr */
> +	HASH_FIELD_L3_DST,	/* L3 dst addr */
> +	HASH_FIELD_L4_SRC,	/* TCP/UDP src ports */
> +	HASH_FIELD_L4_DST,	/* TCP/UDP dst ports */
> +};
> +
> +struct rss_key {
> +	 __u8 key[128];
> +	__u32 hash_fields;
> +	__u32 key_size;
> +	__u32 queues[TAP_MAX_QUEUES];
> +	__u32 nb_queues;
> +} __attribute__((packed));
> +
> +#endif /* _TAP_RSS_H_ */
> diff --git a/drivers/net/tap/tap_tcmsgs.h b/drivers/net/tap/tap_tcmsgs.h
> index 7895957..07c5074 100644
> --- a/drivers/net/tap/tap_tcmsgs.h
> +++ b/drivers/net/tap/tap_tcmsgs.h
> @@ -34,6 +34,7 @@
>  #ifndef _TAP_TCMSGS_H_
>  #define _TAP_TCMSGS_H_
>  
> +#include <tap_autoconf.h>
>  #include <linux/if_ether.h>
>  #include <linux/rtnetlink.h>
>  #include <linux/pkt_sched.h>
> @@ -41,6 +42,9 @@
>  #include <linux/tc_act/tc_mirred.h>
>  #include <linux/tc_act/tc_gact.h>
>  #include <linux/tc_act/tc_skbedit.h>
> +#ifdef HAVE_TC_ACT_BPF
> +#include <linux/tc_act/tc_bpf.h>
> +#endif
>  #include <inttypes.h>
>  
>  #include <rte_ether.h>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v3 0/2] TAP RSS eBPF cover letter
  2018-01-10 10:10     ` [dpdk-dev] [PATCH v3 0/2] TAP RSS eBPF cover letter Jason Wang
@ 2018-01-10 15:34       ` Ophir Munk
  2018-01-11  2:45         ` Jason Wang
  0 siblings, 1 reply; 42+ messages in thread
From: Ophir Munk @ 2018-01-10 15:34 UTC (permalink / raw)
  To: Jason Wang, dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern

Hi Jason,
Thanks for your inputs.
Please see inline

> -----Original Message-----
> From: Jason Wang [mailto:jasowang@redhat.com]
> Sent: Wednesday, January 10, 2018 12:11 PM
> To: Ophir Munk <ophirmu@mellanox.com>; dev@dpdk.org; Pascal Mazon
> <pascal.mazon@6wind.com>
> Cc: Thomas Monjalon <thomas@monjalon.net>; Olga Shern
> <olgas@mellanox.com>
> Subject: Re: [dpdk-dev] [PATCH v3 0/2] TAP RSS eBPF cover letter
> 
> 
> 
> On 2018年01月10日 15:06, Ophir Munk wrote:
> > The patches of TAP RSS eBPF follow the RFC on this issue
> >
> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdpd
> >
> k.org%2Fdev%2Fpatchwork%2Fpatch%2F31781%2F&data=02%7C01%7Coph
> irmu%40me
> >
> llanox.com%7C8edca4ebac3440cf465c08d55812768b%7Ca652971c7d2e4d9
> ba6a4d1
> >
> 49256f461b%7C0%7C0%7C636511758701461920&sdata=2WBaV4iU9kE5ub
> o2lgL0adDH
> > %2BcTxce6SP4KBevyRcsI%3D&reserved=0
> >
> > v3 changes with respect to v2
> > =============================
> > * Add support for IPv6 RSS in BPF program
> > * Bug fixes
> > * Updated compatibility to kernel versions:
> >    eBPF requires Linux version 4.9 configured with BPF
> > * New license header (SPDX) for newly added files
> >
> > v2 changes with respect to v1
> > =============================
> > * v2 has new commits organization (3 --> 2)
> > * BPF program was revised. It is successfully tested on
> >    IPv4 L3 L4 layers (compatible to mlx4 device)
> > * Licensing: no comments received for using "Dual BSD/GPL"
> >    string during BPF program loading to the kernel.
> >    (v1 and v2 are using the same license strings)
> >    Any comments are welcome.
> > * Compatibility to kernel versions:
> >    eBPF requires Linux version 4.2 configured with BPF. TAP PMD will
> >    successfully compile on systems with old or non-BPF configured kernels.
> >    During compilation time the required Linux headers are searched for.
> >    If they are not present missing definitions are locally added
> >    (tap_autoconf.h).
> >    If the kernel cannot support a BPF operation - at runtime it will
> >    gracefully reject the netlink message (with BPF) sent to it.
> >
> > Commit #1:
> > net/tap: add eBPF instructions to TAP device
> > ===========================================
> >    This commit introduces BPF program (tap_bpf_program.c)
> >    with a classifier and an action sections.
> >    The current implementation calculates RSS hash
> >    over L3 addresses and L4 ports.
> >    BPF program compilation is not part of dpdk compilation.
> >    This commit includes the eBPF machine instructions
> >    in the format of C arrays (tap_bpf_insns.c).
> >
> >    The option to update the BPF program and download new machine
> >    instructions will be described in another commit.
> >
> > Commit #2:
> > net/tap: implement RSS with eBPF classifier and action
> > ======================================================
> > This commit builds and sends netlink messages to the kernel that
> > include BPF programs.
> > There is a single BPF classifier for each TAP queue. Packets marked
> > with an RSS queue will be directed to this queue using a traffic
> > control with "skbedit" action otherwise they will be pipelined to the
> > following rules.
> > There is a single BPF action for each RSS rule (may add more to
> > support IPv6).
> > The action is to calculate Toeplitz hash based on L3 addresses and L4
> > ports, mark the packet with the RSS queue according the resulting
> > hash, then reclassify the packet.
> > Ophir Munk (2):
> >    net/tap: add eBPF instructions to TAP device
> >    net/tap: implement RSS with eBPF classifier and action
> >
> >   drivers/net/tap/Makefile          |   31 +
> >   drivers/net/tap/rte_eth_tap.h     |    9 +-
> >   drivers/net/tap/tap_bpf.h         |   92 ++
> >   drivers/net/tap/tap_bpf_insns.c   | 1905
> +++++++++++++++++++++++++++++++++++++
> >   drivers/net/tap/tap_bpf_program.c |  221 +++++
> >   drivers/net/tap/tap_flow.c        |  635 +++++++++++--
> >   drivers/net/tap/tap_flow.h        |   15 +
> >   drivers/net/tap/tap_rss.h         |   32 +
> >   drivers/net/tap/tap_tcmsgs.h      |    4 +
> >   9 files changed, 2848 insertions(+), 96 deletions(-)
> >   create mode 100644 drivers/net/tap/tap_bpf.h
> >   create mode 100644 drivers/net/tap/tap_bpf_insns.c
> >   create mode 100644 drivers/net/tap/tap_bpf_program.c
> >   create mode 100644 drivers/net/tap/tap_rss.h
> >
> 
> TAP will support eBPF classification directly [1] through eBPF socket filter.
> Compare to tc-bpf, it was more portable for other backends (e.g macvtap).
> 

I agree that classifying directly through eBPF using socket filter is easier than building a set of rules in TC, however there are more concerns that justify using eBPF with TC. 
1. An RSS rule can come in the middle of non-RSS rules. It seems natural to have it as part of TC. How do I know if a packet needs to be treated with RSS or not? (there may be a higher priority rule that sends the packet to a specific queue regardless of RSS).
2. BPF complexity comes mainly in writing BPF programs, compiling them and sending BPF instructions to the kernel. In both mechanisms (socket filter or TC) this complexity is the same.

Please let me have your feedback.

> [1]
> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.
> kernel.org%2Fpub%2Fscm%2Flinux%2Fkernel%2Fgit%2Fdavem%2Fnet-
> next.git%2Fcommit%2Fdrivers%2Fnet%2Ftun.c%3Fid%3D96f84061620c6325
> a2ca9a9a05b410e6461d03c3&data=02%7C01%7Cophirmu%40mellanox.co
> m%7C8edca4ebac3440cf465c08d55812768b%7Ca652971c7d2e4d9ba6a4d1
> 49256f461b%7C0%7C0%7C636511758701461920&sdata=8zPaZlAHYSsFCQw
> XcDLtro5QcrIN5pwKsj%2FUwFJ9q8s%3D&reserved=0
> 
> Thanks

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v3 0/2] TAP RSS eBPF cover letter
  2018-01-10 15:34       ` Ophir Munk
@ 2018-01-11  2:45         ` Jason Wang
  0 siblings, 0 replies; 42+ messages in thread
From: Jason Wang @ 2018-01-11  2:45 UTC (permalink / raw)
  To: Ophir Munk, dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern



On 2018年01月10日 23:34, Ophir Munk wrote:
> I agree that classifying directly through eBPF using socket filter is easier than building a set of rules in TC, however there are more concerns that justify using eBPF with TC.
> 1. An RSS rule can come in the middle of non-RSS rules. It seems natural to have it as part of TC. How do I know if a packet needs to be treated with RSS or not? (there may be a higher priority rule that sends the packet to a specific queue regardless of RSS).

Well this could be done through eBPF too, just check the high priority 
rule before before indirection table should be ok.

Btw, want to review the code, but the bpf byte code is rather hard to 
review unless you add some comments.

> 2. BPF complexity comes mainly in writing BPF programs, compiling them and sending BPF instructions to the kernel. In both mechanisms (socket filter or TC) this complexity is the same.

Yes, I agree. But using socket filter can make it work for e.g macvtap 
(though not implemented) or even a vhost-user backend which tc-bpf won't 
work.

>
> Please let me have your feedback.

I don't object the method, it looks rather interesting (I'm planing to 
implement RSS emulation in qemu through TAP eBPF socket filter, your 
patch is a very good reference for me).

Thanks

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v3 2/2] net/tap: implement RSS with eBPF classifier and action
  2018-01-10 10:19       ` Pascal Mazon
@ 2018-01-11 17:20         ` Ophir Munk
  0 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-11 17:20 UTC (permalink / raw)
  To: Pascal Mazon, dev; +Cc: Thomas Monjalon, Olga Shern

Hi Pascal,
Please see inline

> -----Original Message-----
> From: Pascal Mazon [mailto:pascal.mazon@6wind.com]
> Sent: Wednesday, January 10, 2018 12:20 PM
> To: Ophir Munk <ophirmu@mellanox.com>; dev@dpdk.org
> Cc: Thomas Monjalon <thomas@monjalon.net>; Olga Shern
> <olgas@mellanox.com>
> Subject: Re: [PATCH v3 2/2] net/tap: implement RSS with eBPF classifier and
> action
> 
> Ok, now I get why ARRAY_SIZE was where it was. Nevermind.
> 
> I think you're doing too much in one patch. As the subject is not trivial, I
> would rather have it split.
> Can you make a first patch that just adds support for several actions, then
> your patch that adds BPF rule support?
> 
> Otherwise your code looks neat.
> 
> Comments inline.

All comments accepted for v4, see inline

> 
> Best regards,
> 
> Pascal
> 
> On 10/01/2018 08:06, Ophir Munk wrote:
> > Add BPF classifier for each TAP queue. According to this classifier
> > packets marked with an RSS queue will be directed to this queue using
> > a traffic control with "skbedit" action.
> > The BPF classifier program is downloaded to the kernel once per TAP Rx
> > queue.
> >
> > Add RSS BPF map entry for each new RSS rule. A BPF map entry contains
> > the RSS queues of that rule.
> >
> > Add BPF action for each new RSS rule in which the Toeplitz RSS hash is
> > calculated based on L3 addresses and L4 ports. Mark the packet with
> > the RSS queue according the resulting RSS hash, then reclassify the packet.
> >
> > Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
> > ---
> >  drivers/net/tap/Makefile        |  20 ++
> >  drivers/net/tap/rte_eth_tap.h   |   9 +-
> >  drivers/net/tap/tap_bpf_insns.c |  62 +++-
> >  drivers/net/tap/tap_flow.c      | 635
> ++++++++++++++++++++++++++++++++++------
> >  drivers/net/tap/tap_flow.h      |  10 +
> >  drivers/net/tap/tap_rss.h       |  32 ++
> >  drivers/net/tap/tap_tcmsgs.h    |   4 +
> >  7 files changed, 675 insertions(+), 97 deletions(-)  create mode
> > 100644 drivers/net/tap/tap_rss.h
> >
> > diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile index
> > feaa5b7..0e7c494 100644
> > --- a/drivers/net/tap/Makefile
> > +++ b/drivers/net/tap/Makefile
> > @@ -60,6 +60,26 @@ tap_autoconf.h.new: $(RTE_SDK)/buildtools/auto-
> config-h.sh
> >  		enum TCA_FLOWER_KEY_VLAN_PRIO \
> >  		$(AUTOCONF_OUTPUT)
> >  	$Q sh -- '$<' '$@' \
> > +		HAVE_TC_BPF \
> > +		linux/pkt_cls.h \
> > +		enum TCA_BPF_UNSPEC \
> > +		$(AUTOCONF_OUTPUT)
> > +	$Q sh -- '$<' '$@' \
> > +		HAVE_TC_BPF_FD \
> > +		linux/pkt_cls.h \
> > +		enum TCA_BPF_FD \
> > +		$(AUTOCONF_OUTPUT)
> > +	$Q sh -- '$<' '$@' \
> > +		HAVE_TC_ACT_BPF \
> > +		linux/tc_act/tc_bpf.h \
> > +		enum TCA_ACT_BPF_UNSPEC \
> > +		$(AUTOCONF_OUTPUT)
> > +	$Q sh -- '$<' '$@' \
> > +		HAVE_TC_ACT_BPF_FD \
> > +		linux/tc_act/tc_bpf.h \
> > +		enum TCA_ACT_BPF_FD \
> > +		$(AUTOCONF_OUTPUT)
> > +	$Q sh -- '$<' '$@' \
> >  		HAVE_BPF_PROG_LOAD \
> >  		linux/bpf.h \
> >  		enum BPF_PROG_LOAD \
> > diff --git a/drivers/net/tap/rte_eth_tap.h
> > b/drivers/net/tap/rte_eth_tap.h index 829f32f..c185473 100644
> > --- a/drivers/net/tap/rte_eth_tap.h
> > +++ b/drivers/net/tap/rte_eth_tap.h
> > @@ -45,7 +45,7 @@
> >  #include <rte_ether.h>
> >
> >  #ifdef IFF_MULTI_QUEUE
> > -#define RTE_PMD_TAP_MAX_QUEUES	16
> > +#define RTE_PMD_TAP_MAX_QUEUES	TAP_MAX_QUEUES
> >  #else
> >  #define RTE_PMD_TAP_MAX_QUEUES	1
> >  #endif
> > @@ -90,6 +90,13 @@ struct pmd_internals {
> >  	int ioctl_sock;                   /* socket for ioctl calls */
> >  	int nlsk_fd;                      /* Netlink socket fd */
> >  	int flow_isolate;                 /* 1 if flow isolation is enabled */
> > +	int flower_support;               /* 1 if kernel supports, else 0 */
> > +	int flower_vlan_support;          /* 1 if kernel supports, else 0 */
> > +	int rss_enabled;                  /* 1 if RSS is enabled, else 0 */
> > +	/* implicit rules set when RSS is enabled */
> > +	int map_fd;                       /* BPF RSS map fd */
> > +	int bpf_fd[RTE_PMD_TAP_MAX_QUEUES];/* List of bpf fds per
> queue */
> > +	LIST_HEAD(tap_rss_flows, rte_flow) rss_flows;
> >  	LIST_HEAD(tap_flows, rte_flow) flows;        /* rte_flow rules */
> >  	/* implicit rte_flow rules set when a remote device is active */
> >  	LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows; diff --git
> > a/drivers/net/tap/tap_bpf_insns.c b/drivers/net/tap/tap_bpf_insns.c
> > index 25aa82c..bf95f2d 100644
> > --- a/drivers/net/tap/tap_bpf_insns.c
> > +++ b/drivers/net/tap/tap_bpf_insns.c
> > @@ -1830,7 +1830,7 @@ static int bpf_load(enum bpf_prog_type type,
> >  		  size_t insns_cnt,
> >  		  const char *license)
> >  {
> > -	union bpf_attr attr;
> > +	union bpf_attr attr = {};
> 
> Should be squashed in previous commit.
> 

Done for v4

> >
> >  	bzero(&attr, sizeof(attr));
> >  	attr.prog_type = type;
> > @@ -1843,3 +1843,63 @@ static int bpf_load(enum bpf_prog_type type,
> >
> >  	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));  }
> > +
> > +/**
> > + * Create BPF map for RSS rules
> > + *
> > + * @param[in] key_size
> > + *   map RSS key size
> > + *
> > + * @param[in] value_size
> > + *   Map RSS value size
> > + *
> > + * @param[in] max_entries
> > + *   Map max number of RSS entries (limit on max RSS rules)
> > + *
> > + * @return
> > + *   -1 if BPF map couldn't be created, map fd otherwise
> > + */
> > +int tap_flow_bpf_rss_map_create(unsigned int key_size,
> > +		unsigned int value_size,
> > +		unsigned int max_entries)
> > +{
> > +	union bpf_attr attr = {};
> > +
> > +	bzero(&attr, sizeof(attr));
> > +	attr.map_type    = BPF_MAP_TYPE_HASH;
> > +	attr.key_size    = key_size;
> > +	attr.value_size  = value_size;
> > +	attr.max_entries = max_entries;
> > +
> > +	return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr)); }
> > +
> > +/**
> > + * Update RSS entry in BPF map
> > + *
> > + * @param[in] fd
> > + *   RSS map fd
> > + *
> > + * @param[in] key
> > + *   Pointer to RSS key whose entry is updated
> > + *
> > + * @param[in] value
> > + *   Pointer to RSS new updated value
> > + *
> > + * @return
> > + *   -1 if RSS entry failed to be updated, 0 otherwise
> > + */
> > +int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value) {
> > +	union bpf_attr attr = {};
> > +
> > +	bzero(&attr, sizeof(attr));
> > +
> > +	attr.map_type = BPF_MAP_TYPE_HASH;
> > +	attr.map_fd = fd;
> > +	attr.key = ptr_to_u64(key);
> > +	attr.value = ptr_to_u64(value);
> > +	attr.flags = BPF_ANY;
> > +
> > +	return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)); }
> > diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
> > index 90b2654..7c51614 100644
> > --- a/drivers/net/tap/tap_flow.c
> > +++ b/drivers/net/tap/tap_flow.c
> > @@ -33,7 +33,9 @@
> >
> >  #include <errno.h>
> >  #include <string.h>
> > +#include <unistd.h>
> >  #include <sys/queue.h>
> > +#include <sys/resource.h>
> >
> >  #include <rte_byteorder.h>
> >  #include <rte_jhash.h>
> > @@ -42,6 +44,7 @@
> >  #include <tap_flow.h>
> >  #include <tap_autoconf.h>
> >  #include <tap_tcmsgs.h>
> > +#include <tap_rss.h>
> >
> >  #ifndef HAVE_TC_FLOWER
> >  /*
> > @@ -81,12 +84,78 @@ enum {
> >  	TCA_FLOWER_KEY_VLAN_ETH_TYPE,   /* be16 */
> >  };
> >  #endif
> > +/*
> > + * For kernels < 4.2 BPF related enums may not be defined.
> > + * Runtime checks will be carried out to gracefully report on TC
> > +messages that
> > + * are rejected by the kernel. Rejection reasons may be due to:
> > + * 1. enum is not defined
> > + * 2. enum is defined but kerenl is not configured to support BPF
> > +system calls,
> 
> Typo at "kerenl".

Fixed for v4

> 
> > + *    BPF classifications or BPF actions.
> > + */
> > +#ifndef HAVE_TC_BPF
> > +enum {
> > +	TCA_BPF_UNSPEC,
> > +	TCA_BPF_ACT,
> > +	TCA_BPF_POLICE,
> > +	TCA_BPF_CLASSID,
> > +	TCA_BPF_OPS_LEN,
> > +	TCA_BPF_OPS,
> > +};
> > +#endif
> > +#ifndef HAVE_TC_BPF_FD
> > +enum {
> > +	TCA_BPF_FD = TCA_BPF_OPS + 1,
> > +	TCA_BPF_NAME,
> > +};
> > +#endif
> > +#ifndef HAVE_TC_ACT_BPF
> > +#define tc_gen \
> > +	__u32                 index; \
> > +	__u32                 capab; \
> > +	int                   action; \
> > +	int                   refcnt; \
> > +	int                   bindcnt
> > +
> > +struct tc_act_bpf {
> > +	tc_gen;
> > +};
> > +
> > +enum {
> > +	TCA_ACT_BPF_UNSPEC,
> > +	TCA_ACT_BPF_TM,
> > +	TCA_ACT_BPF_PARMS,
> > +	TCA_ACT_BPF_OPS_LEN,
> > +	TCA_ACT_BPF_OPS,
> > +};
> > +
> > +#endif
> > +#ifndef HAVE_TC_ACT_BPF_FD
> > +enum {
> > +	TCA_ACT_BPF_FD = TCA_ACT_BPF_OPS + 1,
> > +	TCA_ACT_BPF_NAME,
> > +};
> > +#endif
> > +
> > +/* RSS key management */
> > +enum bpf_rss_key_e {
> > +	KEY_CMD_GET = 1,
> > +	KEY_CMD_RELEASE,
> > +	KEY_CMD_INIT,
> > +	KEY_CMD_DEINIT,
> > +};
> > +
> > +enum key_status_e {
> > +	KEY_STAT_UNSPEC,
> > +	KEY_STAT_USED,
> > +	KEY_STAT_AVAILABLE,
> > +};
> >
> >  #define ISOLATE_HANDLE 1
> >
> >  struct rte_flow {
> >  	LIST_ENTRY(rte_flow) next; /* Pointer to the next rte_flow structure
> */
> >  	struct rte_flow *remote_flow; /* associated remote flow */
> > +	int bpf_fd[SEC_MAX]; /* list of bfs fds per ELF section */
> >  	struct nlmsg msg;
> >  };
> >
> > @@ -104,6 +173,24 @@ struct remote_rule {
> >  	int mirred;
> >  };
> >
> > +struct action_data {
> > +	char id[16];
> > +
> > +	union {
> > +		struct tc_gact gact;
> > +		struct tc_mirred mirred;
> > +		struct skbedit {
> > +			struct tc_skbedit skbedit;
> > +			uint16_t queue;
> > +		} skbedit;
> > +		struct bpf {
> > +			struct tc_act_bpf bpf;
> > +			int bpf_fd;
> > +			const char *annotation;
> > +		} bpf;
> > +	};
> > +};
> > +
> >  static int tap_flow_create_eth(const struct rte_flow_item *item, void
> > *data);  static int tap_flow_create_vlan(const struct rte_flow_item
> > *item, void *data);  static int tap_flow_create_ipv4(const struct
> > rte_flow_item *item, void *data); @@ -134,6 +221,14 @@
> tap_flow_isolate(struct rte_eth_dev *dev,
> >  		 int set,
> >  		 struct rte_flow_error *error);
> >
> > +static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx);
> > +static int rss_enable(struct pmd_internals *pmd,
> > +			const struct rte_flow_attr *attr,
> > +			struct rte_flow_error *error);
> > +static int rss_add_actions(struct rte_flow *flow, struct pmd_internals
> *pmd,
> > +			const struct rte_flow_action_rss *rss,
> > +			struct rte_flow_error *error);
> > +
> >  static const struct rte_flow_ops tap_flow_ops = {
> >  	.validate = tap_flow_validate,
> >  	.create = tap_flow_create,
> > @@ -819,111 +914,97 @@ tap_flow_item_validate(const struct
> > rte_flow_item *item,  }
> >
> >  /**
> > - * Transform a DROP/PASSTHRU action item in the provided flow for TC.
> > + * Configure the kernel with a TC action and its configured
> > + parameters
> > + * Handled actions: "gact", "mirred", "skbedit", "bpf"
> >   *
> > - * @param[in, out] flow
> > - *   Flow to be filled.
> > - * @param[in] action
> > - *   Appropriate action to be set in the TCA_GACT_PARMS structure.
> > + * @param[in] flow
> > + *   Pointer to rte flow containing the netlink message
> >   *
> > - * @return
> > - *   0 if checks are alright, -1 otherwise.
> > - */
> > -static int
> > -add_action_gact(struct rte_flow *flow, int action) -{
> > -	struct nlmsg *msg = &flow->msg;
> > -	size_t act_index = 1;
> > -	struct tc_gact p = {
> > -		.action = action
> > -	};
> > -
> > -	if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
> > -		return -1;
> > -	if (tap_nlattr_nested_start(msg, act_index++) < 0)
> > -		return -1;
> > -	tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("gact"), "gact");
> > -	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
> > -		return -1;
> > -	tap_nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(p), &p);
> > -	tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
> > -	tap_nlattr_nested_finish(msg); /* nested act_index */
> > -	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
> > -	return 0;
> > -}
> > -
> > -/**
> > - * Transform a MIRRED action item in the provided flow for TC.
> > + * @param[in, out] act_index
> > + *   Pointer to action sequence number in the TC command
> >   *
> > - * @param[in, out] flow
> > - *   Flow to be filled.
> > - * @param[in] ifindex
> > - *   Netdevice ifindex, where to mirror/redirect packet to.
> > - * @param[in] action_type
> > - *   Either TCA_EGRESS_REDIR for redirection or TCA_EGRESS_MIRROR for
> mirroring.
> > + * @param[in] adata
> > + *  Pointer to struct holding the action parameters
> >   *
> >   * @return
> > - *   0 if checks are alright, -1 otherwise.
> > + *   -1 on failure, 0 on success
> >   */
> >  static int
> > -add_action_mirred(struct rte_flow *flow, uint16_t ifindex, uint16_t
> > action_type)
> > +add_action(struct rte_flow *flow, size_t *act_index, struct
> > +action_data *adata)
> >  {
> >  	struct nlmsg *msg = &flow->msg;
> > -	size_t act_index = 1;
> > -	struct tc_mirred p = {
> > -		.eaction = action_type,
> > -		.ifindex = ifindex,
> > -	};
> >
> > -	if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
> > -		return -1;
> > -	if (tap_nlattr_nested_start(msg, act_index++) < 0)
> > +	if (tap_nlattr_nested_start(msg, (*act_index)++) < 0)
> >  		return -1;
> > -	tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("mirred"),
> "mirred");
> > +
> > +	tap_nlattr_add(&msg->nh, TCA_ACT_KIND,
> > +				strlen(adata->id) + 1, adata->id);
> >  	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
> >  		return -1;
> > -	if (action_type == TCA_EGRESS_MIRROR)
> > -		p.action = TC_ACT_PIPE;
> > -	else /* REDIRECT */
> > -		p.action = TC_ACT_STOLEN;
> > -	tap_nlattr_add(&msg->nh, TCA_MIRRED_PARMS, sizeof(p), &p);
> > +	if (strcmp("gact", adata->id) == 0) {
> > +		tap_nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(adata-
> >gact),
> > +			   &adata->gact);
> > +	} else if (strcmp("mirred", adata->id) == 0) {
> > +		if (adata->mirred.eaction == TCA_EGRESS_MIRROR)
> > +			adata->mirred.action = TC_ACT_PIPE;
> > +		else /* REDIRECT */
> > +			adata->mirred.action = TC_ACT_STOLEN;
> > +		tap_nlattr_add(&msg->nh, TCA_MIRRED_PARMS,
> > +			   sizeof(adata->mirred),
> > +			   &adata->mirred);
> > +	} else if (strcmp("skbedit", adata->id) == 0) {
> > +		tap_nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS,
> > +			   sizeof(adata->skbedit.skbedit),
> > +			   &adata->skbedit.skbedit);
> > +		tap_nlattr_add16(&msg->nh,
> TCA_SKBEDIT_QUEUE_MAPPING,
> > +			     adata->skbedit.queue);
> > +	} else if (strcmp("bpf", adata->id) == 0) {
> > +		tap_nlattr_add32(&msg->nh, TCA_ACT_BPF_FD, adata-
> >bpf.bpf_fd);
> > +		tap_nlattr_add(&msg->nh, TCA_ACT_BPF_NAME,
> > +			   strlen(adata->bpf.annotation) + 1,
> > +			   adata->bpf.annotation);
> > +		tap_nlattr_add(&msg->nh, TCA_ACT_BPF_PARMS,
> > +			   sizeof(adata->bpf.bpf),
> > +			   &adata->bpf.bpf);
> > +	} else {
> > +		return -1;
> > +	}
> >  	tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
> >  	tap_nlattr_nested_finish(msg); /* nested act_index */
> > -	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
> >  	return 0;
> >  }
> >
> >  /**
> > - * Transform a QUEUE action item in the provided flow for TC.
> > + * Helper function to send a serie of TC actions to the kernel
> >   *
> > - * @param[in, out] flow
> > - *   Flow to be filled.
> > - * @param[in] queue
> > - *   Queue id to use.
> > + * @param[in] flow
> > + *   Pointer to rte flow containing the netlink message
> > + *
> > + * @param[in] nb_actions
> > + *   Number of actions in an array of action structs
> > + *
> > + * @param[in] data
> > + *   Pointer to an array of action structs
> > + *
> > + * @param[in] classifier_actions
> > + *   The classifier on behave of which the actions are configured
> >   *
> >   * @return
> > - *   0 if checks are alright, -1 otherwise.
> > + *   -1 on failure, 0 on success
> >   */
> >  static int
> > -add_action_skbedit(struct rte_flow *flow, uint16_t queue)
> > +add_actions(struct rte_flow *flow, int nb_actions, struct action_data
> *data,
> > +	    int classifier_action)
> >  {
> >  	struct nlmsg *msg = &flow->msg;
> >  	size_t act_index = 1;
> > -	struct tc_skbedit p = {
> > -		.action = TC_ACT_PIPE
> > -	};
> > +	int i;
> >
> > -	if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
> > -		return -1;
> > -	if (tap_nlattr_nested_start(msg, act_index++) < 0)
> > +	if (tap_nlattr_nested_start(msg, classifier_action) < 0)
> >  		return -1;
> > -	tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("skbedit"),
> "skbedit");
> > -	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
> > -		return -1;
> > -	tap_nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS, sizeof(p), &p);
> > -	tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING,
> queue);
> > -	tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
> > -	tap_nlattr_nested_finish(msg); /* nested act_index */
> > +	for (i = 0; i < nb_actions; i++)
> > +		if (add_action(flow, &act_index, data + i) < 0)
> > +			return -1;
> >  	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
> >  	return 0;
> >  }
> > @@ -987,7 +1068,8 @@ priv_flow_process(struct pmd_internals *pmd,
> >  		return -rte_errno;
> >  	} else if (flow) {
> >  		uint16_t group = attr->group << GROUP_SHIFT;
> > -		uint16_t prio = group | (attr->priority + PRIORITY_OFFSET);
> > +		uint16_t prio = group | (attr->priority +
> > +				RSS_PRIORITY_OFFSET + PRIORITY_OFFSET);
> >  		flow->msg.t.tcm_info = TC_H_MAKE(prio << 16,
> >  						 flow->msg.t.tcm_info);
> >  	}
> > @@ -1056,7 +1138,12 @@ priv_flow_process(struct pmd_internals *pmd,
> >  		}
> >  	}
> >  	if (mirred && flow) {
> > -		uint16_t if_index = pmd->if_index;
> > +		struct action_data adata = {
> > +			.id = "mirred",
> > +			.mirred = {
> > +				.eaction = mirred,
> > +			},
> > +		};
> >
> >  		/*
> >  		 * If attr->egress && mirred, then this is a special @@ -
> 1064,9
> > +1151,13 @@ priv_flow_process(struct pmd_internals *pmd,
> >  		 * redirect packets coming from the DPDK App, out
> >  		 * through the remote netdevice.
> >  		 */
> > -		if (attr->egress)
> > -			if_index = pmd->remote_if_index;
> > -		if (add_action_mirred(flow, if_index, mirred) < 0)
> > +		adata.mirred.ifindex = attr->ingress ? pmd->if_index :
> > +			pmd->remote_if_index;
> > +		if (mirred == TCA_EGRESS_MIRROR)
> > +			adata.mirred.action = TC_ACT_PIPE;
> > +		else
> > +			adata.mirred.action = TC_ACT_STOLEN;
> > +		if (add_actions(flow, 1, &adata, TCA_FLOWER_ACT) < 0)
> >  			goto exit_action_not_supported;
> >  		else
> >  			goto end;
> > @@ -1080,14 +1171,33 @@ priv_flow_process(struct pmd_internals
> *pmd,
> >  			if (action)
> >  				goto exit_action_not_supported;
> >  			action = 1;
> > -			if (flow)
> > -				err = add_action_gact(flow, TC_ACT_SHOT);
> > +			if (flow) {
> > +				struct action_data adata = {
> > +					.id = "gact",
> > +					.gact = {
> > +						.action = TC_ACT_SHOT,
> > +					},
> > +				};
> > +
> > +				err = add_actions(flow, 1, &adata,
> > +						  TCA_FLOWER_ACT);
> > +			}
> >  		} else if (actions->type ==
> RTE_FLOW_ACTION_TYPE_PASSTHRU) {
> >  			if (action)
> >  				goto exit_action_not_supported;
> >  			action = 1;
> > -			if (flow)
> > -				err = add_action_gact(flow,
> TC_ACT_UNSPEC);
> > +			if (flow) {
> > +				struct action_data adata = {
> > +					.id = "gact",
> > +					.gact = {
> > +						/* continue */
> > +						.action = TC_ACT_UNSPEC,
> > +					},
> > +				};
> > +
> > +				err = add_actions(flow, 1, &adata,
> > +						  TCA_FLOWER_ACT);
> > +			}
> >  		} else if (actions->type ==
> RTE_FLOW_ACTION_TYPE_QUEUE) {
> >  			const struct rte_flow_action_queue *queue =
> >  				(const struct rte_flow_action_queue *) @@ -
> 1099,22 +1209,35 @@
> > priv_flow_process(struct pmd_internals *pmd,
> >  			if (!queue ||
> >  			    (queue->index > pmd->dev->data->nb_rx_queues -
> 1))
> >  				goto exit_action_not_supported;
> > -			if (flow)
> > -				err = add_action_skbedit(flow, queue-
> >index);
> > +			if (flow) {
> > +				struct action_data adata = {
> > +					.id = "skbedit",
> > +					.skbedit = {
> > +						.skbedit = {
> > +							.action =
> TC_ACT_PIPE,
> > +						},
> > +						.queue = queue->index,
> > +					},
> > +				};
> > +
> > +				err = add_actions(flow, 1, &adata,
> > +					TCA_FLOWER_ACT);
> > +			}
> >  		} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
> > -			/* Fake RSS support. */
> >  			const struct rte_flow_action_rss *rss =
> >  				(const struct rte_flow_action_rss *)
> >  				actions->conf;
> >
> > -			if (action)
> > -				goto exit_action_not_supported;
> > -			action = 1;
> > -			if (!rss || rss->num < 1 ||
> > -			    (rss->queue[0] > pmd->dev->data->nb_rx_queues -
> 1))
> > +			if (action++)
> >  				goto exit_action_not_supported;
> > -			if (flow)
> > -				err = add_action_skbedit(flow, rss-
> >queue[0]);
> > +
> > +			if (!pmd->rss_enabled) {
> > +				err = rss_enable(pmd, attr, error);
> > +				if (err)
> > +					goto exit_action_not_supported;
> > +			}
> > +			if (flow && rss)
> > +				err = rss_add_actions(flow, pmd, rss, error);
> >  		} else {
> >  			goto exit_action_not_supported;
> >  		}
> > @@ -1326,6 +1449,7 @@ tap_flow_destroy_pmd(struct pmd_internals
> *pmd,
> >  		     struct rte_flow_error *error)
> >  {
> >  	struct rte_flow *remote_flow = flow->remote_flow;
> > +	int i;
> >  	int ret = 0;
> >
> >  	LIST_REMOVE(flow, next);
> > @@ -1351,6 +1475,13 @@ tap_flow_destroy_pmd(struct pmd_internals
> *pmd,
> >  			"couldn't receive kernel ack to our request");
> >  		goto end;
> >  	}
> > +	/* Close opened BPF file descriptors of this flow */
> > +	for (i = 0; i < SEC_MAX; i++)
> > +		if (flow->bpf_fd[i] != 0) {
> > +			close(flow->bpf_fd[i]);
> > +			flow->bpf_fd[i] = 0;
> > +		}
> > +
> >  	if (remote_flow) {
> >  		remote_flow->msg.nh.nlmsg_flags = NLM_F_REQUEST |
> NLM_F_ACK;
> >  		remote_flow->msg.nh.nlmsg_type = RTM_DELTFILTER; @@
> -1635,6
> > +1766,320 @@ tap_flow_implicit_flush(struct pmd_internals *pmd, struct
> rte_flow_error *error)
> >  	return 0;
> >  }
> >
> > +#define MAX_RSS_KEYS 256
> > +#define SEC_NAME_CLS_Q "cls_q"
> > +
> > +const char *sec_name[SEC_MAX] = {
> > +	[SEC_L3_L4] = "l3_l4",
> > +};
> > +
> > +/**
> > + * Enable RSS on tap: create TC rules for queuing.
> > + *
> > + * @param[in, out] pmd
> > + *   Pointer to private structure.
> > + *
> > + * @param[in] attr
> > + *   Pointer to rte_flow to get flow group
> > + *
> > + * @param[out] error
> > + *   Pointer to error reporting if not NULL.
> > + *
> > + * @return 0 on success, negative value on failure.
> > + */
> > +static int rss_enable(struct pmd_internals *pmd,
> > +			const struct rte_flow_attr *attr,
> > +			struct rte_flow_error *error)
> > +{
> > +	struct rte_flow *rss_flow = NULL;
> > +	struct nlmsg *msg = NULL;
> > +	/* 4096 is the maximum number of instructions for a BPF program */
> > +	char annotation[64];
> > +	int i;
> > +	int err = 0;
> > +
> > +	/* unlimit locked memory */
> > +	struct rlimit limit = {
> > +		.rlim_cur = RLIM_INFINITY,
> > +		.rlim_max = RLIM_INFINITY,
> > +	};
> > +	setrlimit(RLIMIT_MEMLOCK, &limit);
> > +
> > +	 /* Get a new map key for a new RSS rule */
> > +	err = bpf_rss_key(KEY_CMD_INIT, NULL);
> > +	if (err < 0) {
> > +		rte_flow_error_set(
> > +			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE,
> NULL,
> > +			"Failed to initialize BPF RSS keys");
> > +
> > +		return -1;
> > +	}
> > +
> > +	/*
> > +	 *  Create BPF RSS MAP
> > +	 */
> > +	pmd->map_fd = tap_flow_bpf_rss_map_create(sizeof(__u32), /* key
> size */
> > +				sizeof(struct rss_key),
> > +				MAX_RSS_KEYS);
> > +	if (pmd->map_fd < 0) {
> > +		RTE_LOG(ERR, PMD,
> > +			"Failed to create BPF map (%d): %s\n",
> > +				errno, strerror(errno));
> > +		rte_flow_error_set(
> > +			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
> NULL,
> > +			"Kernel too old or not configured "
> > +			"to support BPF maps");
> > +
> > +		return -ENOTSUP;
> > +	}
> > +
> > +	/*
> > +	 * Add a rule per queue to match reclassified packets and direct them
> to
> > +	 * the correct queue.
> > +	 */
> > +	for (i = 0; i < pmd->dev->data->nb_rx_queues; i++) {
> > +		pmd->bpf_fd[i] = tap_flow_bpf_cls_q(i);
> > +		if (pmd->bpf_fd[i] < 0) {
> > +			RTE_LOG(ERR, PMD,
> > +				"Failed to load BPF section %s for queue %d",
> > +				SEC_NAME_CLS_Q, i);
> > +			rte_flow_error_set(
> > +				error, ENOTSUP,
> RTE_FLOW_ERROR_TYPE_HANDLE,
> > +				NULL,
> > +				"Kernel too old or not configured "
> > +				"to support BPF programs loading");
> > +
> > +			return -ENOTSUP;
> > +		}
> > +
> > +		rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
> > +		if (!rss_flow) {
> > +			RTE_LOG(ERR, PMD,
> > +				"Cannot allocate memory for rte_flow");
> > +			return -1;
> > +		}
> > +		msg = &rss_flow->msg;
> > +		tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER,
> NLM_F_REQUEST |
> > +			    NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE);
> > +		msg->t.tcm_info = TC_H_MAKE(0, htons(ETH_P_ALL));
> > +		tap_flow_set_handle(rss_flow);
> > +		uint16_t group = attr->group << GROUP_SHIFT;
> > +		uint16_t prio = group | (i + PRIORITY_OFFSET);
> > +		msg->t.tcm_info = TC_H_MAKE(prio << 16, msg-
> >t.tcm_info);
> > +		msg->t.tcm_parent =
> TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
> > +
> > +		tap_nlattr_add(&msg->nh, TCA_KIND, sizeof("bpf"), "bpf");
> > +		if (tap_nlattr_nested_start(msg, TCA_OPTIONS) < 0)
> > +			return -1;
> > +		tap_nlattr_add32(&msg->nh, TCA_BPF_FD, pmd->bpf_fd[i]);
> > +		snprintf(annotation, sizeof(annotation), "[%s%d]",
> > +			SEC_NAME_CLS_Q, i);
> > +		tap_nlattr_add(&msg->nh, TCA_BPF_NAME,
> strlen(annotation) + 1,
> > +			   annotation);
> > +		/* Actions */
> > +		{
> > +			struct action_data adata = {
> > +				.id = "skbedit",
> > +				.skbedit = {
> > +					.skbedit = {
> > +						.action = TC_ACT_PIPE,
> > +					},
> > +					.queue = i,
> > +				},
> > +			};
> > +			if (add_actions(rss_flow, 1, &adata, TCA_BPF_ACT) <
> 0)
> > +				return -1;
> > +		}
> > +		tap_nlattr_nested_finish(msg); /* nested TCA_OPTIONS */
> > +
> > +		/* Netlink message is now ready to be sent */
> > +		if (tap_nl_send(pmd->nlsk_fd, &msg->nh) < 0)
> > +			return -1;
> > +		err = tap_nl_recv_ack(pmd->nlsk_fd);
> > +		if (err < 0) {
> > +			RTE_LOG(ERR, PMD,
> > +				"Kernel refused TC filter rule creation (%d):
> %s\n",
> > +				errno, strerror(errno));
> > +			return err;
> > +		}
> > +		LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
> > +	}
> > +
> > +	pmd->rss_enabled = 1;
> > +	return err;
> > +}
> > +
> > +/**
> > + * Manage bpf RSS keys repository with operations: init, get, release
> > + *
> > + * @param[in] cmd
> > + *   Command on RSS keys: init, get, release
> > + *
> > + * @param[in, out] key_idx
> > + *   Pointer to RSS Key index (out for get command, in for release
> command)
> > + *
> > + * @return -1 if couldn't get, release or init the RSS keys, 0 otherwise.
> > + */
> > +static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx) {
> > +	__u32 i;
> > +	int err = -1;
> > +	static __u32 num_used_keys;
> > +	static __u32 rss_keys[MAX_RSS_KEYS] = {KEY_STAT_UNSPEC};
> > +	static __u32 rss_keys_initialized;
> > +
> > +	switch (cmd) {
> > +	case KEY_CMD_GET:
> > +		if (!rss_keys_initialized)
> > +			break;
> > +
> > +		if (num_used_keys == ARRAY_SIZE(rss_keys))
> > +			break;
> > +
> > +		*key_idx = num_used_keys % ARRAY_SIZE(rss_keys);
> > +		while (rss_keys[*key_idx] == KEY_STAT_USED)
> > +			*key_idx = (*key_idx + 1) % ARRAY_SIZE(rss_keys);
> > +
> > +		rss_keys[*key_idx] = KEY_STAT_USED;
> > +		num_used_keys++;
> > +		err = 0;
> > +	break;
> > +
> > +	case KEY_CMD_RELEASE:
> > +		if (!rss_keys_initialized)
> > +			break;
> > +
> > +		if (rss_keys[*key_idx] == KEY_STAT_USED) {
> > +			rss_keys[*key_idx] = KEY_STAT_AVAILABLE;
> > +			num_used_keys--;
> > +			err = 0;
> > +		}
> > +	break;
> > +
> > +	case KEY_CMD_INIT:
> > +		for (i = 0; i < ARRAY_SIZE(rss_keys); i++)
> > +			rss_keys[i] = KEY_STAT_AVAILABLE;
> > +
> > +		rss_keys_initialized = 1;
> > +		num_used_keys = 0;
> > +		err = 0;
> > +	break;
> > +
> > +	case KEY_CMD_DEINIT:
> > +		for (i = 0; i < ARRAY_SIZE(rss_keys); i++)
> > +			rss_keys[i] = KEY_STAT_UNSPEC;
> > +
> > +		rss_keys_initialized = 0;
> > +		num_used_keys = 0;
> > +		err = 0;
> > +	break;
> > +
> > +	default:
> > +		break;
> > +	}
> > +
> > +	return err;
> > +}
> > +
> > +/**
> > + * Add RSS hash calculations and queue selection
> > + *
> > + * @param[in, out] pmd
> > + *   Pointer to internal structure. Used to set/get RSS map fd
> > + *
> > + * @param[in] rss
> > + *   Pointer to RSS flow actions
> > + *
> > + * @param[out] error
> > + *   Pointer to error reporting if not NULL.
> > + *
> > + * @return 0 on success, negative value on failure  */ static int
> > +rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
> > +			   const struct rte_flow_action_rss *rss,
> > +			   struct rte_flow_error *error)
> > +{
> > +	/* 4096 is the maximum number of instructions for a BPF program */
> > +	int i;
> > +	__u32 key_idx;
> > +	int err;
> > +	struct rss_key rss_entry = { .hash_fields = 0,
> > +				     .key_size = 0 };
> > +
> > +	/* Get a new map key for a new RSS rule */
> > +	err = bpf_rss_key(KEY_CMD_GET, &key_idx);
> > +	if (err < 0) {
> > +		rte_flow_error_set(
> > +			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE,
> NULL,
> > +			"Failed to get BPF RSS key");
> > +
> > +		return -1;
> > +	}
> > +
> > +	/* Update RSS map entry with queues */
> > +	rss_entry.nb_queues = rss->num;
> > +	for (i = 0; i < rss->num; i++)
> > +		rss_entry.queues[i] = rss->queue[i];
> > +	rss_entry.hash_fields =
> > +		(1 << HASH_FIELD_IPV4_L3_L4) | (1 <<
> HASH_FIELD_IPV6_L3_L4);
> > +
> > +	/* Add this RSS entry to map */
> > +	err = tap_flow_bpf_update_rss_elem(pmd->map_fd, &key_idx,
> > +&rss_entry);
> > +
> > +	if (err) {
> > +		RTE_LOG(ERR, PMD,
> > +			"Failed to update BPF map entry #%u (%d): %s\n",
> > +			key_idx, errno, strerror(errno));
> > +		rte_flow_error_set(
> > +			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
> NULL,
> > +			"Kernel too old or not configured "
> > +			"to support BPF maps updates");
> > +
> > +		return -ENOTSUP;
> > +	}
> > +
> > +
> > +	/*
> > +	 * Load bpf rules to calculate hash for this key_idx
> > +	 */
> > +
> > +	flow->bpf_fd[SEC_L3_L4] =
> > +		tap_flow_bpf_calc_l3_l4_hash(key_idx, pmd->map_fd);
> > +	if (flow->bpf_fd[SEC_L3_L4] < 0) {
> > +		RTE_LOG(ERR, PMD,
> > +			"Failed to load BPF section %s (%d): %s\n",
> > +				sec_name[SEC_L3_L4], errno,
> strerror(errno));
> > +		rte_flow_error_set(
> > +			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
> NULL,
> > +			"Kernel too old or not configured "
> > +			"to support BPF program loading");
> > +
> > +		return -ENOTSUP;
> > +	}
> > +
> > +	/* Actions */
> > +	{
> > +		struct action_data adata[] = {
> > +			{
> > +				.id = "bpf",
> > +				.bpf = {
> > +					.bpf_fd = flow->bpf_fd[SEC_L3_L4],
> > +					.annotation = sec_name[SEC_L3_L4],
> > +					.bpf = {
> > +						.action = TC_ACT_PIPE,
> > +					},
> > +				},
> > +			},
> > +		};
> > +
> > +		if (add_actions(flow, ARRAY_SIZE(adata), adata,
> > +			TCA_FLOWER_ACT) < 0)
> > +			return -1;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  /**
> >   * Manage filter operations.
> >   *
> > diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h
> > index 6cc01b4..dbb7ff6 100644
> > --- a/drivers/net/tap/tap_flow.h
> > +++ b/drivers/net/tap/tap_flow.h
> > @@ -37,6 +37,7 @@
> >  #include <rte_flow.h>
> >  #include <rte_flow_driver.h>
> >  #include <rte_eth_tap.h>
> > +#include <tap_autoconf.h>
> >
> >  /**
> >   * In TC, priority 0 means we require the kernel to allocate one for us.
> > @@ -49,6 +50,7 @@
> >  #define GROUP_MASK (0xf)
> >  #define GROUP_SHIFT 12
> >  #define MAX_GROUP GROUP_MASK
> > +#define RSS_PRIORITY_OFFSET 256
> 
> Shouldn't RSS_PRIORITY_OFFSET be equal to the number of queues, as
> there's one implicit rule (skbedit action) per queue at start?
> 

Done for v4

> >
> >  #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
> >
> > @@ -69,6 +71,11 @@ enum implicit_rule_index {
> >  	TAP_REMOTE_MAX_IDX,
> >  };
> >
> > +enum bpf_fd_idx {
> > +	SEC_L3_L4,
> > +	SEC_MAX,
> > +};
> > +
> >  int tap_dev_filter_ctrl(struct rte_eth_dev *dev,
> >  			enum rte_filter_type filter_type,
> >  			enum rte_filter_op filter_op,
> > @@ -84,5 +91,8 @@ int tap_flow_implicit_flush(struct pmd_internals
> > *pmd,
> >
> >  int tap_flow_bpf_cls_q(__u32 queue_idx);  int
> > tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd);
> > +int tap_flow_bpf_rss_map_create(unsigned int key_size, unsigned int
> value_size,
> > +			unsigned int max_entries);
> > +int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value);
> >
> >  #endif /* _TAP_FLOW_H_ */
> > diff --git a/drivers/net/tap/tap_rss.h b/drivers/net/tap/tap_rss.h new
> > file mode 100644 index 0000000..5e12531
> > --- /dev/null
> > +++ b/drivers/net/tap/tap_rss.h
> > @@ -0,0 +1,32 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright 2017 Mellanox Technologies, Ltd.
> > + */
> > +
> > +#ifndef _TAP_RSS_H_
> > +#define _TAP_RSS_H_
> > +
> > +#define TAP_MAX_QUEUES 16
> > +
> > +/* hashed fields for RSS */
> > +enum hash_field {
> > +	HASH_FIELD_IPV4_L3,	/* IPv4 src/dst addr */
> > +	HASH_FIELD_IPV4_L3_L4,	/* IPv4 src/dst addr + L4 src/dst ports
> */
> > +	HASH_FIELD_IPV6_L3,	/* IPv6 src/dst addr */
> > +	HASH_FIELD_IPV6_L3_L4,	/* IPv6 src/dst addr + L4 src/dst ports
> */
> > +	HASH_FIELD_L2_SRC,	/* Ethernet src addr */
> > +	HASH_FIELD_L2_DST,	/* Ethernet dst addr */
> > +	HASH_FIELD_L3_SRC,	/* L3 src addr */
> > +	HASH_FIELD_L3_DST,	/* L3 dst addr */
> > +	HASH_FIELD_L4_SRC,	/* TCP/UDP src ports */
> > +	HASH_FIELD_L4_DST,	/* TCP/UDP dst ports */
> > +};
> > +
> > +struct rss_key {
> > +	 __u8 key[128];
> > +	__u32 hash_fields;
> > +	__u32 key_size;
> > +	__u32 queues[TAP_MAX_QUEUES];
> > +	__u32 nb_queues;
> > +} __attribute__((packed));
> > +
> > +#endif /* _TAP_RSS_H_ */
> > diff --git a/drivers/net/tap/tap_tcmsgs.h
> > b/drivers/net/tap/tap_tcmsgs.h index 7895957..07c5074 100644
> > --- a/drivers/net/tap/tap_tcmsgs.h
> > +++ b/drivers/net/tap/tap_tcmsgs.h
> > @@ -34,6 +34,7 @@
> >  #ifndef _TAP_TCMSGS_H_
> >  #define _TAP_TCMSGS_H_
> >
> > +#include <tap_autoconf.h>
> >  #include <linux/if_ether.h>
> >  #include <linux/rtnetlink.h>
> >  #include <linux/pkt_sched.h>
> > @@ -41,6 +42,9 @@
> >  #include <linux/tc_act/tc_mirred.h>
> >  #include <linux/tc_act/tc_gact.h>
> >  #include <linux/tc_act/tc_skbedit.h>
> > +#ifdef HAVE_TC_ACT_BPF
> > +#include <linux/tc_act/tc_bpf.h>
> > +#endif
> >  #include <inttypes.h>
> >
> >  #include <rte_ether.h>


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v4 0/5] TAP RSS eBPF cover letter
  2018-01-10  7:06   ` [dpdk-dev] [PATCH v3 0/2] TAP RSS eBPF cover letter Ophir Munk
                       ` (2 preceding siblings ...)
  2018-01-10 10:10     ` [dpdk-dev] [PATCH v3 0/2] TAP RSS eBPF cover letter Jason Wang
@ 2018-01-11 17:45     ` Ophir Munk
  2018-01-11 17:45       ` [dpdk-dev] [PATCH v4 1/5] net/tap: support actions for different classifiers Ophir Munk
                         ` (5 more replies)
  3 siblings, 6 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-11 17:45 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

The patches of TAP RSS eBPF follow the RFC on this issue
https://dpdk.org/dev/patchwork/patch/31781/

v4 changes with respect to v3
=============================
* Code updates based on review comments
* New commits organization (2-->5) based on review comments
  1. net/tap: support actions for different classifiers (preparations for BPF. 
     No BPF code yet)
  2. net/tap: add eBPF bytes code (BPF bytes code in a separate file)
  3. net/tap: add eBPF program file (Program source code of bytes code)
  4. net/tap: add eBPF API (BPF API to be used by TAP)
  5. net/tap: implement TAP RSS using eBPF

v3 changes with respect to v2
=============================
* Add support for IPv6 RSS in BPF program
* Bug fixes
* Updated compatibility to kernel versions:
  eBPF requires Linux version 4.9 configured with BPF
* New license header (SPDX) for newly added files

v2 changes with respect to v1
=============================
* v2 has new commits organization (3 --> 2)
* BPF program was revised. It is successfully tested on
  IPv4 L3 L4 layers (compatible to mlx4 device)
* Licensing: no comments received for using "Dual BSD/GPL"
  string during BPF program loading to the kernel.
  (v1 and v2 are using the same license strings)
  Any comments are welcome.
* Compatibility to kernel versions:
  eBPF requires Linux version 4.2 configured with BPF. TAP PMD will
  successfully compile on systems with old or non-BPF configured kernels.
  During compilation time the required Linux headers are searched for.
  If they are not present missing definitions are locally added
  (tap_autoconf.h).
  If the kernel cannot support a BPF operation - at runtime it will
  gracefully reject the netlink message (with BPF) sent to it.



Ophir Munk (5):
  net/tap: support actions for different classifiers
  net/tap: add eBPF bytes code
  net/tap: add eBPF program file
  net/tap: add eBPF API
  net/tap: implement TAP RSS using eBPF

 drivers/net/tap/Makefile          |   34 +
 drivers/net/tap/rte_eth_tap.h     |    9 +-
 drivers/net/tap/tap_bpf.h         |  112 +++
 drivers/net/tap/tap_bpf_api.c     |  190 +++++
 drivers/net/tap/tap_bpf_insns.h   | 1693 +++++++++++++++++++++++++++++++++++++
 drivers/net/tap/tap_bpf_program.c |  221 +++++
 drivers/net/tap/tap_flow.c        |  648 +++++++++++---
 drivers/net/tap/tap_flow.h        |   13 +
 drivers/net/tap/tap_rss.h         |   34 +
 drivers/net/tap/tap_tcmsgs.h      |    4 +
 10 files changed, 2862 insertions(+), 96 deletions(-)
 create mode 100644 drivers/net/tap/tap_bpf.h
 create mode 100644 drivers/net/tap/tap_bpf_api.c
 create mode 100644 drivers/net/tap/tap_bpf_insns.h
 create mode 100644 drivers/net/tap/tap_bpf_program.c
 create mode 100644 drivers/net/tap/tap_rss.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v4 1/5] net/tap: support actions for different classifiers
  2018-01-11 17:45     ` [dpdk-dev] [PATCH v4 0/5] " Ophir Munk
@ 2018-01-11 17:45       ` Ophir Munk
  2018-01-11 17:45       ` [dpdk-dev] [PATCH v4 2/5] net/tap: add eBPF bytes code Ophir Munk
                         ` (4 subsequent siblings)
  5 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-11 17:45 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

Add a generic TC actions handling for TC actions: "mirred",
"gact", "skbedit". This will be useful when introducing
BPF actions, as it uses TCA_BPF_ACT instead of TCA_FLOWER_ACT

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 drivers/net/tap/Makefile      |   8 ++
 drivers/net/tap/rte_eth_tap.h |   4 +-
 drivers/net/tap/tap_flow.c    | 224 +++++++++++++++++++++++++-----------------
 3 files changed, 145 insertions(+), 91 deletions(-)

diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index fd4195f..fbf84e1 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -12,6 +12,12 @@ EXPORT_MAP := rte_pmd_tap_version.map
 
 LIBABIVER := 1
 
+#
+# TAP_MAX_QUEUES must be a power of 2
+#
+ifeq ($(TAP_MAX_QUEUES),)
+	TAP_MAX_QUEUES = 16
+endif
 CFLAGS += -O3
 CFLAGS += -I$(SRCDIR)
 CFLAGS += -I.
@@ -20,6 +26,8 @@ LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
 LDLIBS += -lrte_bus_vdev
 
+CFLAGS += -DTAP_MAX_QUEUES=$(TAP_MAX_QUEUES)
+
 #
 # all source are stored in SRCS-y
 #
diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
index 829f32f..202b3cd 100644
--- a/drivers/net/tap/rte_eth_tap.h
+++ b/drivers/net/tap/rte_eth_tap.h
@@ -45,7 +45,7 @@
 #include <rte_ether.h>
 
 #ifdef IFF_MULTI_QUEUE
-#define RTE_PMD_TAP_MAX_QUEUES	16
+#define RTE_PMD_TAP_MAX_QUEUES	TAP_MAX_QUEUES
 #else
 #define RTE_PMD_TAP_MAX_QUEUES	1
 #endif
@@ -90,6 +90,8 @@ struct pmd_internals {
 	int ioctl_sock;                   /* socket for ioctl calls */
 	int nlsk_fd;                      /* Netlink socket fd */
 	int flow_isolate;                 /* 1 if flow isolation is enabled */
+	int flower_support;               /* 1 if kernel supports, else 0 */
+	int flower_vlan_support;          /* 1 if kernel supports, else 0 */
 	LIST_HEAD(tap_flows, rte_flow) flows;        /* rte_flow rules */
 	/* implicit rte_flow rules set when a remote device is active */
 	LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows;
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index 90b2654..d2a69a7 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -33,6 +33,7 @@
 
 #include <errno.h>
 #include <string.h>
+#include <unistd.h>
 #include <sys/queue.h>
 
 #include <rte_byteorder.h>
@@ -104,6 +105,19 @@ struct remote_rule {
 	int mirred;
 };
 
+struct action_data {
+	char id[16];
+
+	union {
+		struct tc_gact gact;
+		struct tc_mirred mirred;
+		struct skbedit {
+			struct tc_skbedit skbedit;
+			uint16_t queue;
+		} skbedit;
+	};
+};
+
 static int tap_flow_create_eth(const struct rte_flow_item *item, void *data);
 static int tap_flow_create_vlan(const struct rte_flow_item *item, void *data);
 static int tap_flow_create_ipv4(const struct rte_flow_item *item, void *data);
@@ -819,111 +833,89 @@ tap_flow_item_validate(const struct rte_flow_item *item,
 }
 
 /**
- * Transform a DROP/PASSTHRU action item in the provided flow for TC.
+ * Configure the kernel with a TC action and its configured parameters
+ * Handled actions: "gact", "mirred", "skbedit", "bpf"
  *
- * @param[in, out] flow
- *   Flow to be filled.
- * @param[in] action
- *   Appropriate action to be set in the TCA_GACT_PARMS structure.
+ * @param[in] flow
+ *   Pointer to rte flow containing the netlink message
  *
- * @return
- *   0 if checks are alright, -1 otherwise.
- */
-static int
-add_action_gact(struct rte_flow *flow, int action)
-{
-	struct nlmsg *msg = &flow->msg;
-	size_t act_index = 1;
-	struct tc_gact p = {
-		.action = action
-	};
-
-	if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
-		return -1;
-	if (tap_nlattr_nested_start(msg, act_index++) < 0)
-		return -1;
-	tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("gact"), "gact");
-	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
-		return -1;
-	tap_nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(p), &p);
-	tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
-	tap_nlattr_nested_finish(msg); /* nested act_index */
-	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
-	return 0;
-}
-
-/**
- * Transform a MIRRED action item in the provided flow for TC.
+ * @param[in, out] act_index
+ *   Pointer to action sequence number in the TC command
  *
- * @param[in, out] flow
- *   Flow to be filled.
- * @param[in] ifindex
- *   Netdevice ifindex, where to mirror/redirect packet to.
- * @param[in] action_type
- *   Either TCA_EGRESS_REDIR for redirection or TCA_EGRESS_MIRROR for mirroring.
+ * @param[in] adata
+ *  Pointer to struct holding the action parameters
  *
  * @return
- *   0 if checks are alright, -1 otherwise.
+ *   -1 on failure, 0 on success
  */
 static int
-add_action_mirred(struct rte_flow *flow, uint16_t ifindex, uint16_t action_type)
+add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
 {
 	struct nlmsg *msg = &flow->msg;
-	size_t act_index = 1;
-	struct tc_mirred p = {
-		.eaction = action_type,
-		.ifindex = ifindex,
-	};
 
-	if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
-		return -1;
-	if (tap_nlattr_nested_start(msg, act_index++) < 0)
+	if (tap_nlattr_nested_start(msg, (*act_index)++) < 0)
 		return -1;
-	tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("mirred"), "mirred");
+
+	tap_nlattr_add(&msg->nh, TCA_ACT_KIND,
+				strlen(adata->id) + 1, adata->id);
 	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
 		return -1;
-	if (action_type == TCA_EGRESS_MIRROR)
-		p.action = TC_ACT_PIPE;
-	else /* REDIRECT */
-		p.action = TC_ACT_STOLEN;
-	tap_nlattr_add(&msg->nh, TCA_MIRRED_PARMS, sizeof(p), &p);
+	if (strcmp("gact", adata->id) == 0) {
+		tap_nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(adata->gact),
+			   &adata->gact);
+	} else if (strcmp("mirred", adata->id) == 0) {
+		if (adata->mirred.eaction == TCA_EGRESS_MIRROR)
+			adata->mirred.action = TC_ACT_PIPE;
+		else /* REDIRECT */
+			adata->mirred.action = TC_ACT_STOLEN;
+		tap_nlattr_add(&msg->nh, TCA_MIRRED_PARMS,
+			   sizeof(adata->mirred),
+			   &adata->mirred);
+	} else if (strcmp("skbedit", adata->id) == 0) {
+		tap_nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS,
+			   sizeof(adata->skbedit.skbedit),
+			   &adata->skbedit.skbedit);
+		tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING,
+			     adata->skbedit.queue);
+	} else {
+		return -1;
+	}
 	tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
 	tap_nlattr_nested_finish(msg); /* nested act_index */
-	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
 	return 0;
 }
 
 /**
- * Transform a QUEUE action item in the provided flow for TC.
+ * Helper function to send a serie of TC actions to the kernel
  *
- * @param[in, out] flow
- *   Flow to be filled.
- * @param[in] queue
- *   Queue id to use.
+ * @param[in] flow
+ *   Pointer to rte flow containing the netlink message
+ *
+ * @param[in] nb_actions
+ *   Number of actions in an array of action structs
+ *
+ * @param[in] data
+ *   Pointer to an array of action structs
+ *
+ * @param[in] classifier_actions
+ *   The classifier on behave of which the actions are configured
  *
  * @return
- *   0 if checks are alright, -1 otherwise.
+ *   -1 on failure, 0 on success
  */
 static int
-add_action_skbedit(struct rte_flow *flow, uint16_t queue)
+add_actions(struct rte_flow *flow, int nb_actions, struct action_data *data,
+	    int classifier_action)
 {
 	struct nlmsg *msg = &flow->msg;
 	size_t act_index = 1;
-	struct tc_skbedit p = {
-		.action = TC_ACT_PIPE
-	};
+	int i;
 
-	if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
-		return -1;
-	if (tap_nlattr_nested_start(msg, act_index++) < 0)
+	if (tap_nlattr_nested_start(msg, classifier_action) < 0)
 		return -1;
-	tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("skbedit"), "skbedit");
-	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
-		return -1;
-	tap_nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS, sizeof(p), &p);
-	tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING, queue);
-	tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
-	tap_nlattr_nested_finish(msg); /* nested act_index */
+	for (i = 0; i < nb_actions; i++)
+		if (add_action(flow, &act_index, data + i) < 0)
+			return -1;
 	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
 	return 0;
 }
@@ -1056,7 +1048,12 @@ priv_flow_process(struct pmd_internals *pmd,
 		}
 	}
 	if (mirred && flow) {
-		uint16_t if_index = pmd->if_index;
+		struct action_data adata = {
+			.id = "mirred",
+			.mirred = {
+				.eaction = mirred,
+			},
+		};
 
 		/*
 		 * If attr->egress && mirred, then this is a special
@@ -1064,9 +1061,13 @@ priv_flow_process(struct pmd_internals *pmd,
 		 * redirect packets coming from the DPDK App, out
 		 * through the remote netdevice.
 		 */
-		if (attr->egress)
-			if_index = pmd->remote_if_index;
-		if (add_action_mirred(flow, if_index, mirred) < 0)
+		adata.mirred.ifindex = attr->ingress ? pmd->if_index :
+			pmd->remote_if_index;
+		if (mirred == TCA_EGRESS_MIRROR)
+			adata.mirred.action = TC_ACT_PIPE;
+		else
+			adata.mirred.action = TC_ACT_STOLEN;
+		if (add_actions(flow, 1, &adata, TCA_FLOWER_ACT) < 0)
 			goto exit_action_not_supported;
 		else
 			goto end;
@@ -1080,14 +1081,33 @@ priv_flow_process(struct pmd_internals *pmd,
 			if (action)
 				goto exit_action_not_supported;
 			action = 1;
-			if (flow)
-				err = add_action_gact(flow, TC_ACT_SHOT);
+			if (flow) {
+				struct action_data adata = {
+					.id = "gact",
+					.gact = {
+						.action = TC_ACT_SHOT,
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+						  TCA_FLOWER_ACT);
+			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_PASSTHRU) {
 			if (action)
 				goto exit_action_not_supported;
 			action = 1;
-			if (flow)
-				err = add_action_gact(flow, TC_ACT_UNSPEC);
+			if (flow) {
+				struct action_data adata = {
+					.id = "gact",
+					.gact = {
+						/* continue */
+						.action = TC_ACT_UNSPEC,
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+						  TCA_FLOWER_ACT);
+			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
 			const struct rte_flow_action_queue *queue =
 				(const struct rte_flow_action_queue *)
@@ -1099,22 +1119,46 @@ priv_flow_process(struct pmd_internals *pmd,
 			if (!queue ||
 			    (queue->index > pmd->dev->data->nb_rx_queues - 1))
 				goto exit_action_not_supported;
-			if (flow)
-				err = add_action_skbedit(flow, queue->index);
+			if (flow) {
+				struct action_data adata = {
+					.id = "skbedit",
+					.skbedit = {
+						.skbedit = {
+							.action = TC_ACT_PIPE,
+						},
+						.queue = queue->index,
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+					TCA_FLOWER_ACT);
+			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
 			/* Fake RSS support. */
 			const struct rte_flow_action_rss *rss =
 				(const struct rte_flow_action_rss *)
 				actions->conf;
 
-			if (action)
+			if (action++)
 				goto exit_action_not_supported;
-			action = 1;
+
 			if (!rss || rss->num < 1 ||
 			    (rss->queue[0] > pmd->dev->data->nb_rx_queues - 1))
 				goto exit_action_not_supported;
-			if (flow)
-				err = add_action_skbedit(flow, rss->queue[0]);
+			if (flow) {
+				struct action_data adata = {
+					.id = "skbedit",
+					.skbedit = {
+						.skbedit = {
+							.action = TC_ACT_PIPE,
+						},
+						.queue = rss->queue[0],
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+					TCA_FLOWER_ACT);
+			}
 		} else {
 			goto exit_action_not_supported;
 		}
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v4 2/5] net/tap: add eBPF bytes code
  2018-01-11 17:45     ` [dpdk-dev] [PATCH v4 0/5] " Ophir Munk
  2018-01-11 17:45       ` [dpdk-dev] [PATCH v4 1/5] net/tap: support actions for different classifiers Ophir Munk
@ 2018-01-11 17:45       ` Ophir Munk
  2018-01-11 17:45       ` [dpdk-dev] [PATCH v4 3/5] net/tap: add eBPF program file Ophir Munk
                         ` (3 subsequent siblings)
  5 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-11 17:45 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

File tap_bpf_insns.h was added with eBPF bytes code.
The bytes code is in the format of C array of struct bpf_insn
It was generated from C source file by external tools.
1. The C file was compiled via LLVM into an object file in ELF
format as:
 clang -O2 -emit-llvm -c tap_bpf_program.c -o - | llc -march=bpf
 -filetype=obj -o <tap_bpf_program.o>

clang version must be 3.7 and above
The C functions are under different ELF sections and are considered
different BPF programs that can be downloaded to the kernel

2. Using an external tool the ELF sections are parsed and the C array
of struct bpf_insn is generated. Each C array (corresponding to BPF
bytes code) is downloaded to the kernel using BPF systm call.
The C program and the external tool source files will be added in
separate commits.

In this commit the bytes code is not part of DPDK compilation

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 drivers/net/tap/tap_bpf_insns.h | 1693 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 1693 insertions(+)
 create mode 100644 drivers/net/tap/tap_bpf_insns.h

diff --git a/drivers/net/tap/tap_bpf_insns.h b/drivers/net/tap/tap_bpf_insns.h
new file mode 100644
index 0000000..c406f78
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_insns.h
@@ -0,0 +1,1693 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#include <tap_bpf.h>
+
+/* bpf_insn array matching cls_q section. See tap_bpf_program.c file */
+struct bpf_insn cls_q_insns[] = {
+	{0x61,    1,    1,       52, 0x00000000},
+	{0x18,    2,    0,        0, 0xdeadbeef},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0x63,   10,    2,       -4, 0x00000000},
+	{0x61,    2,   10,       -4, 0x00000000},
+	{0x07,    2,    0,        0, 0x00000001},
+	{0x67,    2,    0,        0, 0x00000020},
+	{0x77,    2,    0,        0, 0x00000020},
+	{0xb7,    0,    0,        0, 0xffffffff},
+	{0x1d,    1,    2,        1, 0x00000000},
+	{0xb7,    0,    0,        0, 0x00000000},
+	{0x95,    0,    0,        0, 0x00000000},
+};
+
+/* bpf_insn array matching l3_l4 section. see tap_bpf_program.c file */
+struct bpf_insn l3_l4_hash_insns[] = {
+	{0xbf,    7,    1,        0, 0x00000000},
+	{0x61,    8,    7,       16, 0x00000000},
+	{0x61,    6,    7,       76, 0x00000000},
+	{0x61,    9,    7,       80, 0x00000000},
+	{0x18,    1,    0,        0, 0xdeadbeef},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0x63,   10,    1,       -4, 0x00000000},
+	{0xbf,    2,   10,        0, 0x00000000},
+	{0x07,    2,    0,        0, 0xfffffffc},
+	{0x18,    1,    1,        0, 0x0000cafe},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0x85,    0,    0,        0, 0x00000001},
+	{0x55,    0,    0,       21, 0x00000000},
+	{0xb7,    1,    0,        0, 0x00000a64},
+	{0x6b,   10,    1,      -16, 0x00000000},
+	{0x18,    1,    0,        0, 0x69666e6f},
+	{0x00,    0,    0,        0, 0x65727567},
+	{0x7b,   10,    1,      -24, 0x00000000},
+	{0x18,    1,    0,        0, 0x6e207369},
+	{0x00,    0,    0,        0, 0x6320746f},
+	{0x7b,   10,    1,      -32, 0x00000000},
+	{0x18,    1,    0,        0, 0x20737372},
+	{0x00,    0,    0,        0, 0x2079656b},
+	{0x7b,   10,    1,      -40, 0x00000000},
+	{0x18,    1,    0,        0, 0x68736168},
+	{0x00,    0,    0,        0, 0x203a2928},
+	{0x7b,   10,    1,      -48, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0x73,   10,    7,      -14, 0x00000000},
+	{0xbf,    1,   10,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0xffffffd0},
+	{0xb7,    2,    0,        0, 0x00000023},
+	{0x85,    0,    0,        0, 0x00000006},
+	{0x05,    0,    0,     1632, 0x00000000},
+	{0xb7,    1,    0,        0, 0x0000000e},
+	{0x61,    2,    7,       20, 0x00000000},
+	{0x15,    2,    0,       10, 0x00000000},
+	{0x61,    2,    7,       28, 0x00000000},
+	{0x55,    2,    0,        8, 0x0000a888},
+	{0xbf,    2,    7,        0, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0xbf,    1,    6,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0x00000012},
+	{0x2d,    1,    9,     1622, 0x00000000},
+	{0xb7,    1,    0,        0, 0x00000012},
+	{0x69,    8,    6,       16, 0x00000000},
+	{0xbf,    7,    2,        0, 0x00000000},
+	{0x7b,   10,    7,      -56, 0x00000000},
+	{0x57,    8,    0,        0, 0x0000ffff},
+	{0x15,    8,    0,      409, 0x0000dd86},
+	{0xb7,    7,    0,        0, 0x00000003},
+	{0x55,    8,    0,     1614, 0x00000008},
+	{0x0f,    6,    1,        0, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0xbf,    1,    6,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0x00000018},
+	{0x2d,    1,    9,     1609, 0x00000000},
+	{0x71,    3,    6,       12, 0x00000000},
+	{0xbf,    1,    3,        0, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000038},
+	{0xc7,    1,    0,        0, 0x00000020},
+	{0x77,    1,    0,        0, 0x0000001f},
+	{0x57,    1,    0,        0, 0x2cc681d1},
+	{0x67,    3,    0,        0, 0x00000018},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x40000000},
+	{0xb7,    2,    0,        0, 0x00000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x598d03a2},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x20000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb31a0745},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x10000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x66340e8a},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x08000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcc681d15},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x04000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x98d03a2b},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x02000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x31a07456},
+	{0x57,    3,    0,        0, 0x01000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6340e8ad},
+	{0x71,    3,    6,       13, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000010},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00800000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc681d15b},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00400000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d03a2b7},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00200000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1a07456f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00100000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x340e8ade},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00080000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x681d15bd},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00040000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd03a2b7b},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00020000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa07456f6},
+	{0x57,    3,    0,        0, 0x00010000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x40e8aded},
+	{0x71,    3,    6,       14, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00008000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x81d15bdb},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00004000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x03a2b7b7},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00002000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x07456f6f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00001000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0e8adedf},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000800},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1d15bdbf},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000400},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3a2b7b7e},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000200},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7456f6fd},
+	{0x57,    3,    0,        0, 0x00000100},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe8adedfa},
+	{0x71,    3,    6,       15, 0x00000000},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000080},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd15bdbf4},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000040},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa2b7b7e9},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000020},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x456f6fd3},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000010},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8adedfa7},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000008},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x15bdbf4f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000004},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2b7b7e9e},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000002},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x56f6fd3d},
+	{0x57,    3,    0,        0, 0x00000001},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xadedfa7b},
+	{0x71,    4,    6,       16, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000038},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0xb7,    3,    0,        0, 0xffffffff},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5bdbf4f7},
+	{0x67,    4,    0,        0, 0x00000018},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb7b7e9ef},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6f6fd3df},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdedfa7bf},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbdbf4f7f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7b7e9eff},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf6fd3dff},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xedfa7bfe},
+	{0x71,    4,    6,       17, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000010},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdbf4f7fc},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb7e9eff9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6fd3dff2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdfa7bfe5},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbf4f7fca},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7e9eff94},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfd3dff28},
+	{0x57,    4,    0,        0, 0x00010000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfa7bfe51},
+	{0x71,    4,    6,       18, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000008},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf4f7fca2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe9eff945},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd3dff28a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa7bfe514},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4f7fca28},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9eff9450},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3dff28a0},
+	{0x57,    4,    0,        0, 0x00000100},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7bfe5141},
+	{0x71,    4,    6,       19, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf7fca283},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xeff94506},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdff28a0c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbfe51418},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7fca2831},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff945063},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff28a0c6},
+	{0x57,    4,    0,        0, 0x00000001},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfe51418c},
+	{0x71,    4,    6,       20, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000008},
+	{0x71,    5,    6,       21, 0x00000000},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000030},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfca28319},
+	{0x67,    4,    0,        0, 0x00000010},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x40000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf9450633},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x20000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf28a0c67},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x10000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe51418ce},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x08000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xca28319d},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x04000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9450633b},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x02000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28a0c676},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x01000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x51418ced},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00800000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa28319db},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00400000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x450633b6},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00200000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8a0c676c},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00100000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1418ced8},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00080000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28319db1},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00040000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x50633b63},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00020000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa0c676c6},
+	{0x57,    4,    0,        0, 0x00010000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x418ced8d},
+	{0x71,    3,    6,       22, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00008000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8319db1a},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00004000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0633b634},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00002000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0c676c68},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00001000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x18ced8d1},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000800},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x319db1a3},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000400},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x633b6347},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000200},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc676c68f},
+	{0x57,    3,    0,        0, 0x00000100},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8ced8d1f},
+	{0x71,    3,    6,       23, 0x00000000},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000080},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x19db1a3e},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000040},
+	{0x79,    5,   10,      -56, 0x00000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x33b6347d},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000020},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x676c68fa},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000010},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xced8d1f4},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000008},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9db1a3e9},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000004},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3b6347d2},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000002},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x76c68fa5},
+	{0x57,    3,    0,        0, 0x00000001},
+	{0x1d,    3,    2,     1177, 0x00000000},
+	{0xa7,    1,    0,        0, 0xed8d1f4a},
+	{0x05,    0,    0,     1175, 0x00000000},
+	{0x0f,    6,    1,        0, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0xbf,    1,    6,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0x0000002c},
+	{0x2d,    1,    9,     1202, 0x00000000},
+	{0x61,    4,    6,        8, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000038},
+	{0xc7,    1,    0,        0, 0x00000020},
+	{0x77,    1,    0,        0, 0x0000001f},
+	{0x57,    1,    0,        0, 0x2cc681d1},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000040},
+	{0xb7,    2,    0,        0, 0x00000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x598d03a2},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000020},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb31a0745},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000010},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x66340e8a},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000008},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcc681d15},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000004},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x98d03a2b},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000002},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x31a07456},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000001},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6340e8ad},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00008000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc681d15b},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00004000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d03a2b7},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00002000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1a07456f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00001000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x340e8ade},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000800},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x681d15bd},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000400},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd03a2b7b},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000200},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa07456f6},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000100},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x40e8aded},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00800000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x81d15bdb},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00400000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x03a2b7b7},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00200000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x07456f6f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00100000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0e8adedf},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00080000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1d15bdbf},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00040000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3a2b7b7e},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00020000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7456f6fd},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00010000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe8adedfa},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0xb7,    3,    0,        0, 0xffffffff},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd15bdbf4},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa2b7b7e9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x456f6fd3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8adedfa7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x15bdbf4f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2b7b7e9e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x56f6fd3d},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xadedfa7b},
+	{0x61,    4,    6,       12, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5bdbf4f7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb7b7e9ef},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6f6fd3df},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdedfa7bf},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbdbf4f7f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7b7e9eff},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf6fd3dff},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xedfa7bfe},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdbf4f7fc},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb7e9eff9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6fd3dff2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdfa7bfe5},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbf4f7fca},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7e9eff94},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfd3dff28},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfa7bfe51},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf4f7fca2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe9eff945},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd3dff28a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa7bfe514},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4f7fca28},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9eff9450},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3dff28a0},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7bfe5141},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf7fca283},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xeff94506},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdff28a0c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbfe51418},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7fca2831},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff945063},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff28a0c6},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfe51418c},
+	{0x61,    4,    6,       16, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfca28319},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf9450633},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf28a0c67},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe51418ce},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xca28319d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9450633b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28a0c676},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x51418ced},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa28319db},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x450633b6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8a0c676c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1418ced8},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28319db1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x50633b63},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa0c676c6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x418ced8d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8319db1a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0633b634},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0c676c68},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x18ced8d1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x319db1a3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x633b6347},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc676c68f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8ced8d1f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x19db1a3e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x33b6347d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x676c68fa},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xced8d1f4},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9db1a3e9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3b6347d2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x76c68fa5},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xed8d1f4a},
+	{0x61,    4,    6,       20, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdb1a3e94},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb6347d28},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6c68fa51},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd8d1f4a3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb1a3e946},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6347d28d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc68fa51a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d1f4a35},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1a3e946b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x347d28d7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x68fa51ae},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd1f4a35c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa3e946b9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x47d28d73},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8fa51ae7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1f4a35cf},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3e946b9e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7d28d73c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfa51ae78},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf4a35cf1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe946b9e3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd28d73c7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa51ae78e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4a35cf1c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x946b9e38},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28d73c71},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x51ae78e3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa35cf1c6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x46b9e38d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d73c71b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1ae78e36},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x35cf1c6c},
+	{0x61,    4,    6,       24, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6b9e38d9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd73c71b2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xae78e364},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5cf1c6c9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb9e38d92},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x73c71b25},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe78e364b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcf1c6c96},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9e38d92c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3c71b259},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x78e364b2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf1c6c964},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe38d92c9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc71b2593},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8e364b27},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1c6c964e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x38d92c9c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x71b25938},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe364b270},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc6c964e0},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d92c9c0},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1b259380},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x364b2700},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6c964e01},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd92c9c03},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb2593807},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x64b2700f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc964e01e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x92c9c03d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2593807a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4b2700f4},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x964e01e8},
+	{0x61,    4,    6,       28, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2c9c03d1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x593807a3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb2700f46},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x64e01e8d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc9c03d1a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x93807a35},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2700f46b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4e01e8d6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9c03d1ad},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3807a35b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x700f46b6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe01e8d6c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc03d1ad9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x807a35b3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x00f46b66},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x01e8d6cc},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x03d1ad99},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x07a35b32},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0f46b665},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1e8d6cca},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3d1ad994},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7a35b328},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf46b6651},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe8d6cca2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd1ad9944},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa35b3289},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x46b66512},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d6cca25},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1ad9944a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x35b32894},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6b665129},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd6cca253},
+	{0x61,    4,    6,       32, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xad9944a7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5b32894f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb665129f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6cca253e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd9944a7d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb32894fb},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x665129f6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcca253ec},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9944a7d9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x32894fb2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x65129f65},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xca253eca},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x944a7d95},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2894fb2a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5129f655},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa253ecab},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x44a7d956},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x894fb2ac},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x129f6558},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x253ecab1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4a7d9563},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x94fb2ac7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x29f6558f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x53ecab1e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa7d9563d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4fb2ac7a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9f6558f5},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3ecab1ea},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7d9563d5},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfb2ac7ab},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf6558f56},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xecab1eac},
+	{0x61,    4,    6,       36, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd9563d59},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb2ac7ab2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6558f564},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcab1eac8},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9563d590},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2ac7ab20},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x558f5641},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xab1eac83},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x563d5906},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xac7ab20c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x58f56418},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb1eac831},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x63d59063},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc7ab20c7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8f56418f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1eac831e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3d59063c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7ab20c78},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf56418f0},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xeac831e1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd59063c2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xab20c784},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x56418f09},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xac831e12},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x59063c25},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb20c784b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6418f097},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc831e12f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9063c25f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x20c784be},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x418f097c},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x831e12f9},
+	{0x71,    4,    6,       40, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000008},
+	{0x71,    5,    6,       41, 0x00000000},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000030},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x063c25f3},
+	{0x67,    4,    0,        0, 0x00000010},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x40000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0c784be7},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x20000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x18f097cf},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x10000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x31e12f9f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x08000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x63c25f3f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x04000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc784be7f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x02000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8f097cff},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x01000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1e12f9fe},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00800000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3c25f3fc},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00400000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x784be7f8},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00200000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf097cff0},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00100000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe12f9fe0},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00080000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc25f3fc1},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00040000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x84be7f83},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00020000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x097cff07},
+	{0x57,    4,    0,        0, 0x00010000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x12f9fe0f},
+	{0x71,    3,    6,       42, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00008000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x25f3fc1f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00004000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4be7f83f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00002000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x97cff07f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00001000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2f9fe0fe},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000800},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5f3fc1fd},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000400},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbe7f83fb},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000200},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7cff07f7},
+	{0x57,    3,    0,        0, 0x00000100},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf9fe0fee},
+	{0x71,    3,    6,       43, 0x00000000},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000080},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf3fc1fdc},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000040},
+	{0x79,    5,   10,      -56, 0x00000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe7f83fb8},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000020},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcff07f70},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000010},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9fe0fee1},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000008},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3fc1fdc2},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000004},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7f83fb85},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000002},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff07f70a},
+	{0x57,    3,    0,        0, 0x00000001},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfe0fee15},
+	{0x71,    2,    0,      201, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000008},
+	{0x71,    3,    0,      200, 0x00000000},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0x71,    3,    0,      203, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0x71,    4,    0,      202, 0x00000000},
+	{0x4f,    3,    4,        0, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000010},
+	{0x4f,    3,    2,        0, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000020},
+	{0x77,    1,    0,        0, 0x00000020},
+	{0xbf,    2,    1,        0, 0x00000000},
+	{0x3f,    2,    3,        0, 0x00000000},
+	{0x2f,    2,    3,        0, 0x00000000},
+	{0x1f,    1,    2,        0, 0x00000000},
+	{0x57,    1,    0,        0, 0x0000000f},
+	{0x67,    1,    0,        0, 0x00000002},
+	{0x0f,    0,    1,        0, 0x00000000},
+	{0x71,    1,    0,      137, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000008},
+	{0x71,    2,    0,      136, 0x00000000},
+	{0x4f,    1,    2,        0, 0x00000000},
+	{0x71,    2,    0,      138, 0x00000000},
+	{0x71,    3,    0,      139, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0x4f,    3,    2,        0, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000010},
+	{0x4f,    3,    1,        0, 0x00000000},
+	{0x07,    3,    0,        0, 0x00000001},
+	{0x63,    5,    3,       52, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000001},
+	{0xbf,    0,    7,        0, 0x00000000},
+	{0x95,    0,    0,        0, 0x00000000},
+};
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v4 3/5] net/tap: add eBPF program file
  2018-01-11 17:45     ` [dpdk-dev] [PATCH v4 0/5] " Ophir Munk
  2018-01-11 17:45       ` [dpdk-dev] [PATCH v4 1/5] net/tap: support actions for different classifiers Ophir Munk
  2018-01-11 17:45       ` [dpdk-dev] [PATCH v4 2/5] net/tap: add eBPF bytes code Ophir Munk
@ 2018-01-11 17:45       ` Ophir Munk
  2018-01-11 17:45       ` [dpdk-dev] [PATCH v4 4/5] net/tap: add eBPF API Ophir Munk
                         ` (2 subsequent siblings)
  5 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-11 17:45 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

File tap_bpf_program.c was added with two ELF sections
corresponding to two BPF programs and one BPF map.
It is the C source file used to generate the eBPF bytes code
(see "net/tap: add eBPF bytes code").

Section cls_q - BPF classifier to classify packets to their
corresponding queue after an RSS hash was calculated on the packet
and saved in skb->cb[1]
Section l3_l4 - BPF action to calculate RSS hash on packet layers 3
and 4
This file is not part of DPDK tree compilation.

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 drivers/net/tap/tap_bpf_program.c | 221 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 221 insertions(+)
 create mode 100644 drivers/net/tap/tap_bpf_program.c

diff --git a/drivers/net/tap/tap_bpf_program.c b/drivers/net/tap/tap_bpf_program.c
new file mode 100644
index 0000000..848c50b
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_program.c
@@ -0,0 +1,221 @@
+/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <asm/types.h>
+#include <linux/in.h>
+#include <linux/if.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/if_tunnel.h>
+#include <linux/filter.h>
+#include <linux/bpf.h>
+
+#include "tap_rss.h"
+
+/** Create IPv4 address */
+#define IPv4(a, b, c, d) ((__u32)(((a) & 0xff) << 24) | \
+		(((b) & 0xff) << 16) | \
+		(((c) & 0xff) << 8)  | \
+		((d) & 0xff))
+
+#define PORT(a, b) ((__u16)(((a) & 0xff) << 8) | \
+		((b) & 0xff))
+
+/*
+ * The queue number is offset by 1, to distinguish packets that have
+ * gone through this rule (skb->cb[1] != 0) from others.
+ */
+#define QUEUE_OFFSET		1
+#define PIN_GLOBAL_NS		2
+
+#define KEY_IDX			0
+#define BPF_MAP_ID_KEY	1
+
+struct vlan_hdr {
+	__be16 proto;
+	__be16 tci;
+};
+
+struct bpf_elf_map __attribute__((section("maps"), used))
+map_keys = {
+	.type           =       BPF_MAP_TYPE_HASH,
+	.id             =       BPF_MAP_ID_KEY,
+	.size_key       =       sizeof(__u32),
+	.size_value     =       sizeof(struct rss_key),
+	.max_elem       =       256,
+	.pinning        =       PIN_GLOBAL_NS,
+};
+
+__section("cls_q") int
+match_q(struct __sk_buff *skb)
+{
+	__u32 queue = skb->cb[1];
+	volatile __u32 q = 0xdeadbeef;
+	__u32 match_queue = QUEUE_OFFSET + q;
+
+	/* printt("match_q$i() queue = %d\n", queue); */
+
+	if (queue != match_queue)
+		return TC_ACT_OK;
+	return TC_ACT_UNSPEC;
+}
+
+
+struct ipv4_l3_l4_tuple {
+	__u32    src_addr;
+	__u32    dst_addr;
+	__u16    dport;
+	__u16    sport;
+} __attribute__((packed));
+
+struct ipv6_l3_l4_tuple {
+	__u8        src_addr[16];
+	__u8        dst_addr[16];
+	__u16       dport;
+	__u16       sport;
+} __attribute__((packed));
+
+static const __u8 def_rss_key[] = {
+	0xd1, 0x81, 0xc6, 0x2c,
+	0xf7, 0xf4, 0xdb, 0x5b,
+	0x19, 0x83, 0xa2, 0xfc,
+	0x94, 0x3e, 0x1a, 0xdb,
+	0xd9, 0x38, 0x9e, 0x6b,
+	0xd1, 0x03, 0x9c, 0x2c,
+	0xa7, 0x44, 0x99, 0xad,
+	0x59, 0x3d, 0x56, 0xd9,
+	0xf3, 0x25, 0x3c, 0x06,
+	0x2a, 0xdc, 0x1f, 0xfc,
+};
+
+static __u32  __attribute__((always_inline))
+rte_softrss_be(const __u32 *input_tuple, const uint8_t *rss_key,
+		__u8 input_len)
+{
+	__u32 i, j, hash = 0;
+#pragma unroll
+	for (j = 0; j < input_len; j++) {
+#pragma unroll
+		for (i = 0; i < 32; i++) {
+			if (input_tuple[j] & (1 << (31 - i))) {
+				hash ^= ((const __u32 *)def_rss_key)[j] << i |
+				(__u32)((uint64_t)
+				(((const __u32 *)def_rss_key)[j + 1])
+					>> (32 - i));
+			}
+		}
+	}
+	return hash;
+}
+
+static int __attribute__((always_inline))
+rss_l3_l4(struct __sk_buff *skb)
+{
+	void *data_end = (void *)(long)skb->data_end;
+	void *data = (void *)(long)skb->data;
+	__u16 proto = (__u16)skb->protocol;
+	__u32 key_idx = 0xdeadbeef;
+	__u32 hash;
+	struct rss_key *rsskey;
+	__u64 off = ETH_HLEN;
+	int j;
+	__u8 *key = 0;
+	__u32 len;
+	__u32 queue = 0;
+
+	rsskey = map_lookup_elem(&map_keys, &key_idx);
+	if (!rsskey) {
+		printt("hash(): rss key is not configured\n");
+		return TC_ACT_OK;
+	}
+	key = (__u8 *)rsskey->key;
+
+	/* Get correct proto for 802.1ad */
+	if (skb->vlan_present && skb->vlan_proto == htons(ETH_P_8021AD)) {
+		if (data + ETH_ALEN * 2 + sizeof(struct vlan_hdr) +
+		    sizeof(proto) > data_end)
+			return TC_ACT_OK;
+		proto = *(__u16 *)(data + ETH_ALEN * 2 +
+				   sizeof(struct vlan_hdr));
+		off += sizeof(struct vlan_hdr);
+	}
+
+	if (proto == htons(ETH_P_IP)) {
+		if (data + off + sizeof(struct iphdr) + sizeof(__u32)
+			> data_end)
+			return TC_ACT_OK;
+
+		__u8 *src_dst_addr = data + off + offsetof(struct iphdr, saddr);
+		__u8 *src_dst_port = data + off + sizeof(struct iphdr);
+		struct ipv4_l3_l4_tuple v4_tuple = {
+			.src_addr = IPv4(*(src_dst_addr + 0),
+					*(src_dst_addr + 1),
+					*(src_dst_addr + 2),
+					*(src_dst_addr + 3)),
+			.dst_addr = IPv4(*(src_dst_addr + 4),
+					*(src_dst_addr + 5),
+					*(src_dst_addr + 6),
+					*(src_dst_addr + 7)),
+			.sport = PORT(*(src_dst_port + 0),
+					*(src_dst_port + 1)),
+			.dport = PORT(*(src_dst_port + 2),
+					*(src_dst_port + 3)),
+		};
+		__u8 input_len = sizeof(v4_tuple) / sizeof(__u32);
+		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV4_L3))
+			input_len--;
+		hash = rte_softrss_be((__u32 *)&v4_tuple, key, 3);
+	} else if (proto == htons(ETH_P_IPV6)) {
+		if (data + off + sizeof(struct ipv6hdr) +
+					sizeof(__u32) > data_end)
+			return TC_ACT_OK;
+		__u8 *src_dst_addr = data + off +
+					offsetof(struct ipv6hdr, saddr);
+		__u8 *src_dst_port = data + off +
+					sizeof(struct ipv6hdr);
+		struct ipv6_l3_l4_tuple v6_tuple;
+		for (j = 0; j < 4; j++)
+			*((uint32_t *)&v6_tuple.src_addr + j) =
+				__builtin_bswap32(*((uint32_t *)
+						src_dst_addr + j));
+		for (j = 0; j < 4; j++)
+			*((uint32_t *)&v6_tuple.dst_addr + j) =
+				__builtin_bswap32(*((uint32_t *)
+						src_dst_addr + 4 + j));
+		v6_tuple.sport = PORT(*(src_dst_port + 0),
+			      *(src_dst_port + 1));
+		v6_tuple.dport = PORT(*(src_dst_port + 2),
+			      *(src_dst_port + 3));
+
+		__u8 input_len = sizeof(v6_tuple) / sizeof(__u32);
+		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV6_L3))
+			input_len--;
+		hash = rte_softrss_be((__u32 *)&v6_tuple, key, 9);
+	} else {
+		return TC_ACT_PIPE;
+	}
+
+	queue = rsskey->queues[(hash % rsskey->nb_queues) &
+				       (TAP_MAX_QUEUES - 1)];
+	skb->cb[1] = QUEUE_OFFSET + queue;
+	/* printt(">>>>> rss_l3_l4 hash=0x%x queue=%u\n", hash, queue); */
+
+	return TC_ACT_RECLASSIFY;
+}
+
+#define RSS(L)						\
+	__section(#L) int				\
+		L ## _hash(struct __sk_buff *skb)	\
+	{						\
+		return rss_ ## L (skb);			\
+	}
+
+RSS(l3_l4)
+
+BPF_LICENSE("Dual BSD/GPL");
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v4 4/5] net/tap: add eBPF API
  2018-01-11 17:45     ` [dpdk-dev] [PATCH v4 0/5] " Ophir Munk
                         ` (2 preceding siblings ...)
  2018-01-11 17:45       ` [dpdk-dev] [PATCH v4 3/5] net/tap: add eBPF program file Ophir Munk
@ 2018-01-11 17:45       ` Ophir Munk
  2018-01-11 17:45       ` [dpdk-dev] [PATCH v4 5/5] net/tap: implement TAP RSS using eBPF Ophir Munk
  2018-01-18 13:38       ` [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter Ophir Munk
  5 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-11 17:45 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

This commit include BPF API to be used by TAP.

tap_flow_bpf_cls_q() - download to kernel BPF program that classifies
packets to their matching queues
tap_flow_bpf_calc_l3_l4_hash() - download to kernel BPF program that
calculates per packet layer 3 and layer 4 RSS hash
tap_flow_bpf_rss_map_create() - create BPF RSS map for storing RSS
parameters per RSS rule
tap_flow_bpf_update_rss_elem() - update BPF map entry with RSS rule
parameters

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 drivers/net/tap/Makefile      |   6 ++
 drivers/net/tap/tap_bpf.h     | 112 +++++++++++++++++++++++++
 drivers/net/tap/tap_bpf_api.c | 190 ++++++++++++++++++++++++++++++++++++++++++
 drivers/net/tap/tap_flow.h    |   6 ++
 4 files changed, 314 insertions(+)
 create mode 100644 drivers/net/tap/tap_bpf.h
 create mode 100644 drivers/net/tap/tap_bpf_api.c

diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index fbf84e1..fad8a94 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -35,6 +35,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += rte_eth_tap.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_flow.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_netlink.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_tcmsgs.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_bpf_api.c
 
 include $(RTE_SDK)/mk/rte.lib.mk
 
@@ -61,6 +62,11 @@ tap_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
 		linux/pkt_cls.h \
 		enum TCA_FLOWER_KEY_VLAN_PRIO \
 		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_BPF_PROG_LOAD \
+		linux/bpf.h \
+		enum BPF_PROG_LOAD \
+		$(AUTOCONF_OUTPUT)
 
 # Create tap_autoconf.h or update it in case it differs from the new one.
 
diff --git a/drivers/net/tap/tap_bpf.h b/drivers/net/tap/tap_bpf.h
new file mode 100644
index 0000000..30eefb3
--- /dev/null
+++ b/drivers/net/tap/tap_bpf.h
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#ifndef __TAP_BPF_H__
+#define __TAP_BPF_H__
+
+#include <tap_autoconf.h>
+
+#ifdef HAVE_BPF_PROG_LOAD
+#include <linux/bpf.h>
+#else
+/* BPF_MAP_UPDATE_ELEM command flags */
+#define	BPF_ANY	0 /* create a new element or update an existing */
+
+/* BPF architecture instruction struct */
+struct bpf_insn {
+	__u8	code;
+	__u8	dst_reg:4;
+	__u8	src_reg:4;
+	__s16	off;
+	__s32	imm; /* immediate value */
+};
+
+/* BPF program types */
+enum bpf_prog_type {
+	BPF_PROG_TYPE_UNSPEC,
+	BPF_PROG_TYPE_SOCKET_FILTER,
+	BPF_PROG_TYPE_KPROBE,
+	BPF_PROG_TYPE_SCHED_CLS,
+	BPF_PROG_TYPE_SCHED_ACT,
+};
+
+/* BPF commands types */
+enum bpf_cmd {
+	BPF_MAP_CREATE,
+	BPF_MAP_LOOKUP_ELEM,
+	BPF_MAP_UPDATE_ELEM,
+	BPF_MAP_DELETE_ELEM,
+	BPF_MAP_GET_NEXT_KEY,
+	BPF_PROG_LOAD,
+};
+
+/* BPF maps types */
+enum bpf_map_type {
+	BPF_MAP_TYPE_UNSPEC,
+	BPF_MAP_TYPE_HASH,
+};
+
+/* union of anonymous structs used with TAP BPF commands */
+union bpf_attr {
+	/* BPF_MAP_CREATE command */
+	struct {
+		__u32	map_type;
+		__u32	key_size;
+		__u32	value_size;
+		__u32	max_entries;
+		__u32	map_flags;
+		__u32	inner_map_fd;
+	};
+
+	/* BPF_MAP_UPDATE_ELEM, BPF_MAP_DELETE_ELEM commands */
+	struct {
+		__u32		map_fd;
+		__aligned_u64	key;
+		union {
+			__aligned_u64 value;
+			__aligned_u64 next_key;
+		};
+		__u64		flags;
+	};
+
+	/* BPF_PROG_LOAD command */
+	struct {
+		__u32		prog_type;
+		__u32		insn_cnt;
+		__aligned_u64	insns;
+		__aligned_u64	license;
+		__u32		log_level;
+		__u32		log_size;
+		__aligned_u64	log_buf;
+		__u32		kern_version;
+		__u32		prog_flags;
+	};
+} __attribute__((aligned(8)));
+#endif
+
+#ifndef __NR_bpf
+# if defined(__i386__)
+#  define __NR_bpf 357
+# elif defined(__x86_64__)
+#  define __NR_bpf 321
+# elif defined(__aarch64__)
+#  define __NR_bpf 280
+# elif defined(__sparc__)
+#  define __NR_bpf 349
+# elif defined(__s390__)
+#  define __NR_bpf 351
+# else
+#  error __NR_bpf not defined
+# endif
+#endif
+
+enum {
+	BPF_MAP_ID_KEY,
+	BPF_MAP_ID_SIMPLE,
+};
+
+static int bpf_load(enum bpf_prog_type type, const struct bpf_insn *insns,
+		size_t insns_cnt, const char *license);
+
+#endif /* __TAP_BPF_H__ */
diff --git a/drivers/net/tap/tap_bpf_api.c b/drivers/net/tap/tap_bpf_api.c
new file mode 100644
index 0000000..109a681
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_api.c
@@ -0,0 +1,190 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/queue.h>
+
+#include <rte_malloc.h>
+#include <rte_eth_tap.h>
+#include <tap_flow.h>
+#include <tap_autoconf.h>
+#include <tap_tcmsgs.h>
+#include <tap_bpf.h>
+#include <tap_bpf_insns.h>
+
+/**
+ * Load BPF program (section cls_q) into the kernel and return a bpf fd
+ *
+ * @param queue_idx
+ *   Queue index matching packet cb
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int tap_flow_bpf_cls_q(__u32 queue_idx)
+{
+	cls_q_insns[1].imm = queue_idx;
+
+	return bpf_load(BPF_PROG_TYPE_SCHED_CLS,
+		(struct bpf_insn *)cls_q_insns,
+		RTE_DIM(cls_q_insns),
+		"Dual BSD/GPL");
+}
+
+/**
+ * Load BPF program (section l3_l4) into the kernel and return a bpf fd.
+ *
+ * @param[in] key_idx
+ *   RSS MAP key index
+ *
+ * @param[in] map_fd
+ *   BPF RSS map file descriptor
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd)
+{
+	l3_l4_hash_insns[4].imm = key_idx;
+	l3_l4_hash_insns[9].imm = map_fd;
+
+	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+		(struct bpf_insn *)l3_l4_hash_insns,
+		RTE_DIM(l3_l4_hash_insns),
+		"Dual BSD/GPL");
+}
+
+/**
+ * Helper function to convert a pointer to unsigned 64 bits
+ *
+ * @param[in] ptr
+ *   pointer to address
+ *
+ * @return
+ *   64 bit unsigned long type of pointer address
+ */
+static inline __u64 ptr_to_u64(const void *ptr)
+{
+	return (__u64)(unsigned long)ptr;
+}
+
+/**
+ * Call BPF system call
+ *
+ * @param[in] cmd
+ *   BPF command for program loading, map creation, map entry update, etc
+ *
+ * @param[in] attr
+ *   System call attributes relevant to system call command
+ *
+ * @param[in] size
+ *   size of attr parameter
+ *
+ * @return
+ *   -1 if BPF system call failed, 0 otherwise
+ */
+static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
+			unsigned int size)
+{
+	return syscall(__NR_bpf, cmd, attr, size);
+}
+
+/**
+ * Load BPF instructions to kernel
+ *
+ * @param[in] type
+ *   BPF program type: classifieir or action
+ *
+ * @param[in] insns
+ *   Array of BPF instructions (equivalent to BPF instructions)
+ *
+ * @param[in] insns_cnt
+ *   Number of BPF instructions (size of array)
+ *
+ * @param[in] lincense
+ *   License string that must be acknowledged by the kernel
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded, fd (file descriptor) otherwise
+ */
+static int bpf_load(enum bpf_prog_type type,
+		  const struct bpf_insn *insns,
+		  size_t insns_cnt,
+		  const char *license)
+{
+	union bpf_attr attr = {};
+
+	bzero(&attr, sizeof(attr));
+	attr.prog_type = type;
+	attr.insn_cnt = (__u32)insns_cnt;
+	attr.insns = ptr_to_u64(insns);
+	attr.license = ptr_to_u64(license);
+	attr.log_buf = ptr_to_u64(NULL);
+	attr.log_level = 0;
+	attr.kern_version = 0;
+
+	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
+}
+
+/**
+ * Create BPF map for RSS rules
+ *
+ * @param[in] key_size
+ *   map RSS key size
+ *
+ * @param[in] value_size
+ *   Map RSS value size
+ *
+ * @param[in] max_entries
+ *   Map max number of RSS entries (limit on max RSS rules)
+ *
+ * @return
+ *   -1 if BPF map couldn't be created, map fd otherwise
+ */
+int tap_flow_bpf_rss_map_create(unsigned int key_size,
+		unsigned int value_size,
+		unsigned int max_entries)
+{
+	union bpf_attr attr = {};
+
+	bzero(&attr, sizeof(attr));
+	attr.map_type    = BPF_MAP_TYPE_HASH;
+	attr.key_size    = key_size;
+	attr.value_size  = value_size;
+	attr.max_entries = max_entries;
+
+	return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
+}
+
+/**
+ * Update RSS entry in BPF map
+ *
+ * @param[in] fd
+ *   RSS map fd
+ *
+ * @param[in] key
+ *   Pointer to RSS key whose entry is updated
+ *
+ * @param[in] value
+ *   Pointer to RSS new updated value
+ *
+ * @return
+ *   -1 if RSS entry failed to be updated, 0 otherwise
+ */
+int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value)
+{
+	union bpf_attr attr = {};
+
+	bzero(&attr, sizeof(attr));
+
+	attr.map_type = BPF_MAP_TYPE_HASH;
+	attr.map_fd = fd;
+	attr.key = ptr_to_u64(key);
+	attr.value = ptr_to_u64(value);
+	attr.flags = BPF_ANY;
+
+	return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
+}
diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h
index 9e332b0..894c959 100644
--- a/drivers/net/tap/tap_flow.h
+++ b/drivers/net/tap/tap_flow.h
@@ -80,4 +80,10 @@ int tap_flow_implicit_destroy(struct pmd_internals *pmd,
 int tap_flow_implicit_flush(struct pmd_internals *pmd,
 			    struct rte_flow_error *error);
 
+int tap_flow_bpf_cls_q(__u32 queue_idx);
+int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd);
+int tap_flow_bpf_rss_map_create(unsigned int key_size, unsigned int value_size,
+			unsigned int max_entries);
+int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value);
+
 #endif /* _TAP_FLOW_H_ */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v4 5/5] net/tap: implement TAP RSS using eBPF
  2018-01-11 17:45     ` [dpdk-dev] [PATCH v4 0/5] " Ophir Munk
                         ` (3 preceding siblings ...)
  2018-01-11 17:45       ` [dpdk-dev] [PATCH v4 4/5] net/tap: add eBPF API Ophir Munk
@ 2018-01-11 17:45       ` Ophir Munk
  2018-01-18 13:38       ` [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter Ophir Munk
  5 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-11 17:45 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

TAP PMD is required to support RSS queue mapping based on rte_flow API. An
example usage for this requirement is failsafe transparent switching from a
PCI device to TAP device while keep redirecting packets to the same RSS
queues on both devices.

TAP RSS implementation is based on eBPF programs sent to Linux kernel
through BPF system calls and using netlink messages to reference the
programs as part of traffic control commands.

TC uses eBPF programs as classifiers and actions.
eBPF classification: packets marked with an RSS queue will be directed
to this queue using TC with "skbedit" action.
BPF classifiers are downloaded to the kernel once on TAP creation for
each TAP Rx queue.

eBPF action: calculate the Toeplitz RSS hash based on L3 addresses and
L4 ports. Mark the packet with the RSS queue according the resulting
RSS hash, then reclassify the packet.
BPF actions are downloaded to the kernel for each new RSS rule.

TAP eBPF requires Linux version 4.9 configured with BPF. TAP PMD will
successfully compile on systems with old or non-BPF configured kernels but
RSS rules creation on TAP devices will not be successful

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 drivers/net/tap/Makefile      |  20 ++
 drivers/net/tap/rte_eth_tap.h |   5 +
 drivers/net/tap/tap_flow.c    | 450 ++++++++++++++++++++++++++++++++++++++++--
 drivers/net/tap/tap_flow.h    |   7 +
 drivers/net/tap/tap_rss.h     |  34 ++++
 drivers/net/tap/tap_tcmsgs.h  |   4 +
 6 files changed, 502 insertions(+), 18 deletions(-)
 create mode 100644 drivers/net/tap/tap_rss.h

diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index fad8a94..e23c3a2 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -63,6 +63,26 @@ tap_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
 		enum TCA_FLOWER_KEY_VLAN_PRIO \
 		$(AUTOCONF_OUTPUT)
 	$Q sh -- '$<' '$@' \
+		HAVE_TC_BPF \
+		linux/pkt_cls.h \
+		enum TCA_BPF_UNSPEC \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_TC_BPF_FD \
+		linux/pkt_cls.h \
+		enum TCA_BPF_FD \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_TC_ACT_BPF \
+		linux/tc_act/tc_bpf.h \
+		enum TCA_ACT_BPF_UNSPEC \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_TC_ACT_BPF_FD \
+		linux/tc_act/tc_bpf.h \
+		enum TCA_ACT_BPF_FD \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
 		HAVE_BPF_PROG_LOAD \
 		linux/bpf.h \
 		enum BPF_PROG_LOAD \
diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
index 202b3cd..c185473 100644
--- a/drivers/net/tap/rte_eth_tap.h
+++ b/drivers/net/tap/rte_eth_tap.h
@@ -92,6 +92,11 @@ struct pmd_internals {
 	int flow_isolate;                 /* 1 if flow isolation is enabled */
 	int flower_support;               /* 1 if kernel supports, else 0 */
 	int flower_vlan_support;          /* 1 if kernel supports, else 0 */
+	int rss_enabled;                  /* 1 if RSS is enabled, else 0 */
+	/* implicit rules set when RSS is enabled */
+	int map_fd;                       /* BPF RSS map fd */
+	int bpf_fd[RTE_PMD_TAP_MAX_QUEUES];/* List of bpf fds per queue */
+	LIST_HEAD(tap_rss_flows, rte_flow) rss_flows;
 	LIST_HEAD(tap_flows, rte_flow) flows;        /* rte_flow rules */
 	/* implicit rte_flow rules set when a remote device is active */
 	LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows;
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index d2a69a7..6aa53a7 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -35,6 +35,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/queue.h>
+#include <sys/resource.h>
 
 #include <rte_byteorder.h>
 #include <rte_jhash.h>
@@ -43,6 +44,7 @@
 #include <tap_flow.h>
 #include <tap_autoconf.h>
 #include <tap_tcmsgs.h>
+#include <tap_rss.h>
 
 #ifndef HAVE_TC_FLOWER
 /*
@@ -82,12 +84,79 @@ enum {
 	TCA_FLOWER_KEY_VLAN_ETH_TYPE,   /* be16 */
 };
 #endif
+/*
+ * For kernels < 4.2 BPF related enums may not be defined.
+ * Runtime checks will be carried out to gracefully report on TC messages that
+ * are rejected by the kernel. Rejection reasons may be due to:
+ * 1. enum is not defined
+ * 2. enum is defined but kernel is not configured to support BPF system calls,
+ *    BPF classifications or BPF actions.
+ */
+#ifndef HAVE_TC_BPF
+enum {
+	TCA_BPF_UNSPEC,
+	TCA_BPF_ACT,
+	TCA_BPF_POLICE,
+	TCA_BPF_CLASSID,
+	TCA_BPF_OPS_LEN,
+	TCA_BPF_OPS,
+};
+#endif
+#ifndef HAVE_TC_BPF_FD
+enum {
+	TCA_BPF_FD = TCA_BPF_OPS + 1,
+	TCA_BPF_NAME,
+};
+#endif
+#ifndef HAVE_TC_ACT_BPF
+#define tc_gen \
+	__u32                 index; \
+	__u32                 capab; \
+	int                   action; \
+	int                   refcnt; \
+	int                   bindcnt
+
+struct tc_act_bpf {
+	tc_gen;
+};
+
+enum {
+	TCA_ACT_BPF_UNSPEC,
+	TCA_ACT_BPF_TM,
+	TCA_ACT_BPF_PARMS,
+	TCA_ACT_BPF_OPS_LEN,
+	TCA_ACT_BPF_OPS,
+};
+
+#endif
+#ifndef HAVE_TC_ACT_BPF_FD
+enum {
+	TCA_ACT_BPF_FD = TCA_ACT_BPF_OPS + 1,
+	TCA_ACT_BPF_NAME,
+};
+#endif
+
+/* RSS key management */
+enum bpf_rss_key_e {
+	KEY_CMD_GET = 1,
+	KEY_CMD_RELEASE,
+	KEY_CMD_INIT,
+	KEY_CMD_DEINIT,
+};
+
+enum key_status_e {
+	KEY_STAT_UNSPEC,
+	KEY_STAT_USED,
+	KEY_STAT_AVAILABLE,
+};
 
 #define ISOLATE_HANDLE 1
 
 struct rte_flow {
 	LIST_ENTRY(rte_flow) next; /* Pointer to the next rte_flow structure */
 	struct rte_flow *remote_flow; /* associated remote flow */
+	int bpf_fd[SEC_MAX]; /* list of bfs fds per ELF section */
+	uint32_t key_idx; /* RSS rule key index into BPF map */
 	struct nlmsg msg;
 };
 
@@ -115,6 +184,11 @@ struct action_data {
 			struct tc_skbedit skbedit;
 			uint16_t queue;
 		} skbedit;
+		struct bpf {
+			struct tc_act_bpf bpf;
+			int bpf_fd;
+			const char *annotation;
+		} bpf;
 	};
 };
 
@@ -148,6 +222,14 @@ tap_flow_isolate(struct rte_eth_dev *dev,
 		 int set,
 		 struct rte_flow_error *error);
 
+static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx);
+static int rss_enable(struct pmd_internals *pmd,
+			const struct rte_flow_attr *attr,
+			struct rte_flow_error *error);
+static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
+			const struct rte_flow_action_rss *rss,
+			struct rte_flow_error *error);
+
 static const struct rte_flow_ops tap_flow_ops = {
 	.validate = tap_flow_validate,
 	.create = tap_flow_create,
@@ -877,6 +959,14 @@ add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
 			   &adata->skbedit.skbedit);
 		tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING,
 			     adata->skbedit.queue);
+	} else if (strcmp("bpf", adata->id) == 0) {
+		tap_nlattr_add32(&msg->nh, TCA_ACT_BPF_FD, adata->bpf.bpf_fd);
+		tap_nlattr_add(&msg->nh, TCA_ACT_BPF_NAME,
+			   strlen(adata->bpf.annotation) + 1,
+			   adata->bpf.annotation);
+		tap_nlattr_add(&msg->nh, TCA_ACT_BPF_PARMS,
+			   sizeof(adata->bpf.bpf),
+			   &adata->bpf.bpf);
 	} else {
 		return -1;
 	}
@@ -979,7 +1069,8 @@ priv_flow_process(struct pmd_internals *pmd,
 		return -rte_errno;
 	} else if (flow) {
 		uint16_t group = attr->group << GROUP_SHIFT;
-		uint16_t prio = group | (attr->priority + PRIORITY_OFFSET);
+		uint16_t prio = group | (attr->priority +
+				RSS_PRIORITY_OFFSET + PRIORITY_OFFSET);
 		flow->msg.t.tcm_info = TC_H_MAKE(prio << 16,
 						 flow->msg.t.tcm_info);
 	}
@@ -1134,7 +1225,6 @@ priv_flow_process(struct pmd_internals *pmd,
 					TCA_FLOWER_ACT);
 			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
-			/* Fake RSS support. */
 			const struct rte_flow_action_rss *rss =
 				(const struct rte_flow_action_rss *)
 				actions->conf;
@@ -1142,23 +1232,13 @@ priv_flow_process(struct pmd_internals *pmd,
 			if (action++)
 				goto exit_action_not_supported;
 
-			if (!rss || rss->num < 1 ||
-			    (rss->queue[0] > pmd->dev->data->nb_rx_queues - 1))
-				goto exit_action_not_supported;
-			if (flow) {
-				struct action_data adata = {
-					.id = "skbedit",
-					.skbedit = {
-						.skbedit = {
-							.action = TC_ACT_PIPE,
-						},
-						.queue = rss->queue[0],
-					},
-				};
-
-				err = add_actions(flow, 1, &adata,
-					TCA_FLOWER_ACT);
+			if (!pmd->rss_enabled) {
+				err = rss_enable(pmd, attr, error);
+				if (err)
+					goto exit_action_not_supported;
 			}
+			if (flow && rss)
+				err = rss_add_actions(flow, pmd, rss, error);
 		} else {
 			goto exit_action_not_supported;
 		}
@@ -1370,6 +1450,7 @@ tap_flow_destroy_pmd(struct pmd_internals *pmd,
 		     struct rte_flow_error *error)
 {
 	struct rte_flow *remote_flow = flow->remote_flow;
+	int i;
 	int ret = 0;
 
 	LIST_REMOVE(flow, next);
@@ -1395,6 +1476,23 @@ tap_flow_destroy_pmd(struct pmd_internals *pmd,
 			"couldn't receive kernel ack to our request");
 		goto end;
 	}
+	/* Close opened BPF file descriptors of this flow */
+	for (i = 0; i < SEC_MAX; i++)
+		if (flow->bpf_fd[i] != 0) {
+			close(flow->bpf_fd[i]);
+			flow->bpf_fd[i] = 0;
+		}
+
+	/* Release map key for this RSS rule */
+	ret = bpf_rss_key(KEY_CMD_RELEASE, &flow->key_idx);
+	if (ret < 0) {
+		rte_flow_error_set(
+			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Failed to release BPF RSS key");
+
+		goto end;
+	}
+
 	if (remote_flow) {
 		remote_flow->msg.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
 		remote_flow->msg.nh.nlmsg_type = RTM_DELTFILTER;
@@ -1679,6 +1777,322 @@ tap_flow_implicit_flush(struct pmd_internals *pmd, struct rte_flow_error *error)
 	return 0;
 }
 
+#define MAX_RSS_KEYS 256
+#define SEC_NAME_CLS_Q "cls_q"
+
+const char *sec_name[SEC_MAX] = {
+	[SEC_L3_L4] = "l3_l4",
+};
+
+/**
+ * Enable RSS on tap: create TC rules for queuing.
+ *
+ * @param[in, out] pmd
+ *   Pointer to private structure.
+ *
+ * @param[in] attr
+ *   Pointer to rte_flow to get flow group
+ *
+ * @param[out] error
+ *   Pointer to error reporting if not NULL.
+ *
+ * @return 0 on success, negative value on failure.
+ */
+static int rss_enable(struct pmd_internals *pmd,
+			const struct rte_flow_attr *attr,
+			struct rte_flow_error *error)
+{
+	struct rte_flow *rss_flow = NULL;
+	struct nlmsg *msg = NULL;
+	/* 4096 is the maximum number of instructions for a BPF program */
+	char annotation[64];
+	int i;
+	int err = 0;
+
+	/* unlimit locked memory */
+	struct rlimit memlock_limit = {
+		.rlim_cur = RLIM_INFINITY,
+		.rlim_max = RLIM_INFINITY,
+	};
+	setrlimit(RLIMIT_MEMLOCK, &memlock_limit);
+
+	 /* Get a new map key for a new RSS rule */
+	err = bpf_rss_key(KEY_CMD_INIT, NULL);
+	if (err < 0) {
+		rte_flow_error_set(
+			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Failed to initialize BPF RSS keys");
+
+		return -1;
+	}
+
+	/*
+	 *  Create BPF RSS MAP
+	 */
+	pmd->map_fd = tap_flow_bpf_rss_map_create(sizeof(__u32), /* key size */
+				sizeof(struct rss_key),
+				MAX_RSS_KEYS);
+	if (pmd->map_fd < 0) {
+		RTE_LOG(ERR, PMD,
+			"Failed to create BPF map (%d): %s\n",
+				errno, strerror(errno));
+		rte_flow_error_set(
+			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Kernel too old or not configured "
+			"to support BPF maps");
+
+		return -ENOTSUP;
+	}
+
+	/*
+	 * Add a rule per queue to match reclassified packets and direct them to
+	 * the correct queue.
+	 */
+	for (i = 0; i < pmd->dev->data->nb_rx_queues; i++) {
+		pmd->bpf_fd[i] = tap_flow_bpf_cls_q(i);
+		if (pmd->bpf_fd[i] < 0) {
+			RTE_LOG(ERR, PMD,
+				"Failed to load BPF section %s for queue %d",
+				SEC_NAME_CLS_Q, i);
+			rte_flow_error_set(
+				error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
+				NULL,
+				"Kernel too old or not configured "
+				"to support BPF programs loading");
+
+			return -ENOTSUP;
+		}
+
+		rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
+		if (!rss_flow) {
+			RTE_LOG(ERR, PMD,
+				"Cannot allocate memory for rte_flow");
+			return -1;
+		}
+		msg = &rss_flow->msg;
+		tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER, NLM_F_REQUEST |
+			    NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE);
+		msg->t.tcm_info = TC_H_MAKE(0, htons(ETH_P_ALL));
+		tap_flow_set_handle(rss_flow);
+		uint16_t group = attr->group << GROUP_SHIFT;
+		uint16_t prio = group | (i + PRIORITY_OFFSET);
+		msg->t.tcm_info = TC_H_MAKE(prio << 16, msg->t.tcm_info);
+		msg->t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
+
+		tap_nlattr_add(&msg->nh, TCA_KIND, sizeof("bpf"), "bpf");
+		if (tap_nlattr_nested_start(msg, TCA_OPTIONS) < 0)
+			return -1;
+		tap_nlattr_add32(&msg->nh, TCA_BPF_FD, pmd->bpf_fd[i]);
+		snprintf(annotation, sizeof(annotation), "[%s%d]",
+			SEC_NAME_CLS_Q, i);
+		tap_nlattr_add(&msg->nh, TCA_BPF_NAME, strlen(annotation) + 1,
+			   annotation);
+		/* Actions */
+		{
+			struct action_data adata = {
+				.id = "skbedit",
+				.skbedit = {
+					.skbedit = {
+						.action = TC_ACT_PIPE,
+					},
+					.queue = i,
+				},
+			};
+			if (add_actions(rss_flow, 1, &adata, TCA_BPF_ACT) < 0)
+				return -1;
+		}
+		tap_nlattr_nested_finish(msg); /* nested TCA_OPTIONS */
+
+		/* Netlink message is now ready to be sent */
+		if (tap_nl_send(pmd->nlsk_fd, &msg->nh) < 0)
+			return -1;
+		err = tap_nl_recv_ack(pmd->nlsk_fd);
+		if (err < 0) {
+			RTE_LOG(ERR, PMD,
+				"Kernel refused TC filter rule creation (%d): %s\n",
+				errno, strerror(errno));
+			return err;
+		}
+		LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
+	}
+
+	pmd->rss_enabled = 1;
+	return err;
+}
+
+/**
+ * Manage bpf RSS keys repository with operations: init, get, release
+ *
+ * @param[in] cmd
+ *   Command on RSS keys: init, get, release
+ *
+ * @param[in, out] key_idx
+ *   Pointer to RSS Key index (out for get command, in for release command)
+ *
+ * @return -1 if couldn't get, release or init the RSS keys, 0 otherwise.
+ */
+static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx)
+{
+	__u32 i;
+	int err = -1;
+	static __u32 num_used_keys;
+	static __u32 rss_keys[MAX_RSS_KEYS] = {KEY_STAT_UNSPEC};
+	static __u32 rss_keys_initialized;
+
+	switch (cmd) {
+	case KEY_CMD_GET:
+		if (!rss_keys_initialized)
+			break;
+
+		if (num_used_keys == RTE_DIM(rss_keys))
+			break;
+
+		*key_idx = num_used_keys % RTE_DIM(rss_keys);
+		while (rss_keys[*key_idx] == KEY_STAT_USED)
+			*key_idx = (*key_idx + 1) % RTE_DIM(rss_keys);
+
+		rss_keys[*key_idx] = KEY_STAT_USED;
+		num_used_keys++;
+		err = 0;
+	break;
+
+	case KEY_CMD_RELEASE:
+		if (!rss_keys_initialized) {
+			err = 0;
+			break;
+		}
+
+		if (rss_keys[*key_idx] == KEY_STAT_USED) {
+			rss_keys[*key_idx] = KEY_STAT_AVAILABLE;
+			num_used_keys--;
+			err = 0;
+		}
+	break;
+
+	case KEY_CMD_INIT:
+		for (i = 0; i < RTE_DIM(rss_keys); i++)
+			rss_keys[i] = KEY_STAT_AVAILABLE;
+
+		rss_keys_initialized = 1;
+		num_used_keys = 0;
+		err = 0;
+	break;
+
+	case KEY_CMD_DEINIT:
+		for (i = 0; i < RTE_DIM(rss_keys); i++)
+			rss_keys[i] = KEY_STAT_UNSPEC;
+
+		rss_keys_initialized = 0;
+		num_used_keys = 0;
+		err = 0;
+	break;
+
+	default:
+		break;
+	}
+
+	return err;
+}
+
+/**
+ * Add RSS hash calculations and queue selection
+ *
+ * @param[in, out] pmd
+ *   Pointer to internal structure. Used to set/get RSS map fd
+ *
+ * @param[in] rss
+ *   Pointer to RSS flow actions
+ *
+ * @param[out] error
+ *   Pointer to error reporting if not NULL.
+ *
+ * @return 0 on success, negative value on failure
+ */
+static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
+			   const struct rte_flow_action_rss *rss,
+			   struct rte_flow_error *error)
+{
+	/* 4096 is the maximum number of instructions for a BPF program */
+	int i;
+	int err;
+	struct rss_key rss_entry = { .hash_fields = 0,
+				     .key_size = 0 };
+
+	/* Get a new map key for a new RSS rule */
+	err = bpf_rss_key(KEY_CMD_GET, &flow->key_idx);
+	if (err < 0) {
+		rte_flow_error_set(
+			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Failed to get BPF RSS key");
+
+		return -1;
+	}
+
+	/* Update RSS map entry with queues */
+	rss_entry.nb_queues = rss->num;
+	for (i = 0; i < rss->num; i++)
+		rss_entry.queues[i] = rss->queue[i];
+	rss_entry.hash_fields =
+		(1 << HASH_FIELD_IPV4_L3_L4) | (1 << HASH_FIELD_IPV6_L3_L4);
+
+	/* Add this RSS entry to map */
+	err = tap_flow_bpf_update_rss_elem(pmd->map_fd,
+				&flow->key_idx, &rss_entry);
+
+	if (err) {
+		RTE_LOG(ERR, PMD,
+			"Failed to update BPF map entry #%u (%d): %s\n",
+			flow->key_idx, errno, strerror(errno));
+		rte_flow_error_set(
+			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Kernel too old or not configured "
+			"to support BPF maps updates");
+
+		return -ENOTSUP;
+	}
+
+
+	/*
+	 * Load bpf rules to calculate hash for this key_idx
+	 */
+
+	flow->bpf_fd[SEC_L3_L4] =
+		tap_flow_bpf_calc_l3_l4_hash(flow->key_idx, pmd->map_fd);
+	if (flow->bpf_fd[SEC_L3_L4] < 0) {
+		RTE_LOG(ERR, PMD,
+			"Failed to load BPF section %s (%d): %s\n",
+				sec_name[SEC_L3_L4], errno, strerror(errno));
+		rte_flow_error_set(
+			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Kernel too old or not configured "
+			"to support BPF program loading");
+
+		return -ENOTSUP;
+	}
+
+	/* Actions */
+	{
+		struct action_data adata[] = {
+			{
+				.id = "bpf",
+				.bpf = {
+					.bpf_fd = flow->bpf_fd[SEC_L3_L4],
+					.annotation = sec_name[SEC_L3_L4],
+					.bpf = {
+						.action = TC_ACT_PIPE,
+					},
+				},
+			},
+		};
+
+		if (add_actions(flow, RTE_DIM(adata), adata,
+			TCA_FLOWER_ACT) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
 /**
  * Manage filter operations.
  *
diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h
index 894c959..daaf00b 100644
--- a/drivers/net/tap/tap_flow.h
+++ b/drivers/net/tap/tap_flow.h
@@ -37,6 +37,7 @@
 #include <rte_flow.h>
 #include <rte_flow_driver.h>
 #include <rte_eth_tap.h>
+#include <tap_autoconf.h>
 
 /**
  * In TC, priority 0 means we require the kernel to allocate one for us.
@@ -49,6 +50,7 @@
 #define GROUP_MASK (0xf)
 #define GROUP_SHIFT 12
 #define MAX_GROUP GROUP_MASK
+#define RSS_PRIORITY_OFFSET RTE_PMD_TAP_MAX_QUEUES
 
 /**
  * These index are actually in reversed order: their priority is processed
@@ -67,6 +69,11 @@ enum implicit_rule_index {
 	TAP_REMOTE_MAX_IDX,
 };
 
+enum bpf_fd_idx {
+	SEC_L3_L4,
+	SEC_MAX,
+};
+
 int tap_dev_filter_ctrl(struct rte_eth_dev *dev,
 			enum rte_filter_type filter_type,
 			enum rte_filter_op filter_op,
diff --git a/drivers/net/tap/tap_rss.h b/drivers/net/tap/tap_rss.h
new file mode 100644
index 0000000..3bb0d14
--- /dev/null
+++ b/drivers/net/tap/tap_rss.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#ifndef _TAP_RSS_H_
+#define _TAP_RSS_H_
+
+#ifndef TAP_MAX_QUEUES
+#define TAP_MAX_QUEUES 16
+#endif
+
+/* hashed fields for RSS */
+enum hash_field {
+	HASH_FIELD_IPV4_L3,	/* IPv4 src/dst addr */
+	HASH_FIELD_IPV4_L3_L4,	/* IPv4 src/dst addr + L4 src/dst ports */
+	HASH_FIELD_IPV6_L3,	/* IPv6 src/dst addr */
+	HASH_FIELD_IPV6_L3_L4,	/* IPv6 src/dst addr + L4 src/dst ports */
+	HASH_FIELD_L2_SRC,	/* Ethernet src addr */
+	HASH_FIELD_L2_DST,	/* Ethernet dst addr */
+	HASH_FIELD_L3_SRC,	/* L3 src addr */
+	HASH_FIELD_L3_DST,	/* L3 dst addr */
+	HASH_FIELD_L4_SRC,	/* TCP/UDP src ports */
+	HASH_FIELD_L4_DST,	/* TCP/UDP dst ports */
+};
+
+struct rss_key {
+	 __u8 key[128];
+	__u32 hash_fields;
+	__u32 key_size;
+	__u32 queues[TAP_MAX_QUEUES];
+	__u32 nb_queues;
+} __attribute__((packed));
+
+#endif /* _TAP_RSS_H_ */
diff --git a/drivers/net/tap/tap_tcmsgs.h b/drivers/net/tap/tap_tcmsgs.h
index 7895957..07c5074 100644
--- a/drivers/net/tap/tap_tcmsgs.h
+++ b/drivers/net/tap/tap_tcmsgs.h
@@ -34,6 +34,7 @@
 #ifndef _TAP_TCMSGS_H_
 #define _TAP_TCMSGS_H_
 
+#include <tap_autoconf.h>
 #include <linux/if_ether.h>
 #include <linux/rtnetlink.h>
 #include <linux/pkt_sched.h>
@@ -41,6 +42,9 @@
 #include <linux/tc_act/tc_mirred.h>
 #include <linux/tc_act/tc_gact.h>
 #include <linux/tc_act/tc_skbedit.h>
+#ifdef HAVE_TC_ACT_BPF
+#include <linux/tc_act/tc_bpf.h>
+#endif
 #include <inttypes.h>
 
 #include <rte_ether.h>
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter
  2018-01-11 17:45     ` [dpdk-dev] [PATCH v4 0/5] " Ophir Munk
                         ` (4 preceding siblings ...)
  2018-01-11 17:45       ` [dpdk-dev] [PATCH v4 5/5] net/tap: implement TAP RSS using eBPF Ophir Munk
@ 2018-01-18 13:38       ` Ophir Munk
  2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 1/6] net/tap: support actions for different classifiers Ophir Munk
                           ` (7 more replies)
  5 siblings, 8 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-18 13:38 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

The patches of TAP RSS eBPF follow the RFC on this issue
https://dpdk.org/dev/patchwork/patch/31781/

v5 changes with respect to v4
=============================
Update TAP document guide with RSS

v4 changes with respect to v3
=============================
* Code updates based on review comments
* New commits organization (2-->5) based on review comments
  1. net/tap: support actions for different classifiers (preparations for BPF. 
     No BPF code yet)
  2. net/tap: add eBPF bytes code (BPF bytes code in a separate file)
  3. net/tap: add eBPF program file (Program source code of bytes code)
  4. net/tap: add eBPF API (BPF API to be used by TAP)
  5. net/tap: implement TAP RSS using eBPF

v3 changes with respect to v2
=============================
* Add support for IPv6 RSS in BPF program
* Bug fixes
* Updated compatibility to kernel versions:
  eBPF requires Linux version 4.9 configured with BPF
* New license header (SPDX) for newly added files

v2 changes with respect to v1
=============================
* v2 has new commits organization (3 --> 2)
* BPF program was revised. It is successfully tested on
  IPv4 L3 L4 layers (compatible to mlx4 device)
* Licensing: no comments received for using "Dual BSD/GPL"
  string during BPF program loading to the kernel.
  (v1 and v2 are using the same license strings)
  Any comments are welcome.
* Compatibility to kernel versions:
  eBPF requires Linux version 4.2 configured with BPF. TAP PMD will
  successfully compile on systems with old or non-BPF configured kernels.
  During compilation time the required Linux headers are searched for.
  If they are not present missing definitions are locally added
  (tap_autoconf.h).
  If the kernel cannot support a BPF operation - at runtime it will
  gracefully reject the netlink message (with BPF) sent to it.

Ophir Munk (6):
  net/tap: support actions for different classifiers
  net/tap: add eBPF bytes code
  net/tap: add eBPF program file
  net/tap: add eBPF API
  net/tap: implement TAP RSS using eBPF
  doc: detail new tap RSS feature in guides

 doc/guides/nics/tap.rst           |   60 ++
 drivers/net/tap/Makefile          |   34 +
 drivers/net/tap/rte_eth_tap.h     |    9 +-
 drivers/net/tap/tap_bpf.h         |  112 +++
 drivers/net/tap/tap_bpf_api.c     |  190 +++++
 drivers/net/tap/tap_bpf_insns.h   | 1693 +++++++++++++++++++++++++++++++++++++
 drivers/net/tap/tap_bpf_program.c |  221 +++++
 drivers/net/tap/tap_flow.c        |  648 +++++++++++---
 drivers/net/tap/tap_flow.h        |   13 +
 drivers/net/tap/tap_rss.h         |   34 +
 drivers/net/tap/tap_tcmsgs.h      |    4 +
 11 files changed, 2922 insertions(+), 96 deletions(-)
 create mode 100644 drivers/net/tap/tap_bpf.h
 create mode 100644 drivers/net/tap/tap_bpf_api.c
 create mode 100644 drivers/net/tap/tap_bpf_insns.h
 create mode 100644 drivers/net/tap/tap_bpf_program.c
 create mode 100644 drivers/net/tap/tap_rss.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v5 1/6] net/tap: support actions for different classifiers
  2018-01-18 13:38       ` [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter Ophir Munk
@ 2018-01-18 13:38         ` Ophir Munk
  2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 2/6] net/tap: add eBPF bytes code Ophir Munk
                           ` (6 subsequent siblings)
  7 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-18 13:38 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

Add a generic TC actions handling for TC actions: "mirred",
"gact", "skbedit". This will be useful when introducing
BPF actions, as it uses TCA_BPF_ACT instead of TCA_FLOWER_ACT

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 drivers/net/tap/Makefile      |   8 ++
 drivers/net/tap/rte_eth_tap.h |   4 +-
 drivers/net/tap/tap_flow.c    | 224 +++++++++++++++++++++++++-----------------
 3 files changed, 145 insertions(+), 91 deletions(-)

diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index fd4195f..fbf84e1 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -12,6 +12,12 @@ EXPORT_MAP := rte_pmd_tap_version.map
 
 LIBABIVER := 1
 
+#
+# TAP_MAX_QUEUES must be a power of 2
+#
+ifeq ($(TAP_MAX_QUEUES),)
+	TAP_MAX_QUEUES = 16
+endif
 CFLAGS += -O3
 CFLAGS += -I$(SRCDIR)
 CFLAGS += -I.
@@ -20,6 +26,8 @@ LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
 LDLIBS += -lrte_bus_vdev
 
+CFLAGS += -DTAP_MAX_QUEUES=$(TAP_MAX_QUEUES)
+
 #
 # all source are stored in SRCS-y
 #
diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
index 829f32f..202b3cd 100644
--- a/drivers/net/tap/rte_eth_tap.h
+++ b/drivers/net/tap/rte_eth_tap.h
@@ -45,7 +45,7 @@
 #include <rte_ether.h>
 
 #ifdef IFF_MULTI_QUEUE
-#define RTE_PMD_TAP_MAX_QUEUES	16
+#define RTE_PMD_TAP_MAX_QUEUES	TAP_MAX_QUEUES
 #else
 #define RTE_PMD_TAP_MAX_QUEUES	1
 #endif
@@ -90,6 +90,8 @@ struct pmd_internals {
 	int ioctl_sock;                   /* socket for ioctl calls */
 	int nlsk_fd;                      /* Netlink socket fd */
 	int flow_isolate;                 /* 1 if flow isolation is enabled */
+	int flower_support;               /* 1 if kernel supports, else 0 */
+	int flower_vlan_support;          /* 1 if kernel supports, else 0 */
 	LIST_HEAD(tap_flows, rte_flow) flows;        /* rte_flow rules */
 	/* implicit rte_flow rules set when a remote device is active */
 	LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows;
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index 90b2654..d2a69a7 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -33,6 +33,7 @@
 
 #include <errno.h>
 #include <string.h>
+#include <unistd.h>
 #include <sys/queue.h>
 
 #include <rte_byteorder.h>
@@ -104,6 +105,19 @@ struct remote_rule {
 	int mirred;
 };
 
+struct action_data {
+	char id[16];
+
+	union {
+		struct tc_gact gact;
+		struct tc_mirred mirred;
+		struct skbedit {
+			struct tc_skbedit skbedit;
+			uint16_t queue;
+		} skbedit;
+	};
+};
+
 static int tap_flow_create_eth(const struct rte_flow_item *item, void *data);
 static int tap_flow_create_vlan(const struct rte_flow_item *item, void *data);
 static int tap_flow_create_ipv4(const struct rte_flow_item *item, void *data);
@@ -819,111 +833,89 @@ tap_flow_item_validate(const struct rte_flow_item *item,
 }
 
 /**
- * Transform a DROP/PASSTHRU action item in the provided flow for TC.
+ * Configure the kernel with a TC action and its configured parameters
+ * Handled actions: "gact", "mirred", "skbedit", "bpf"
  *
- * @param[in, out] flow
- *   Flow to be filled.
- * @param[in] action
- *   Appropriate action to be set in the TCA_GACT_PARMS structure.
+ * @param[in] flow
+ *   Pointer to rte flow containing the netlink message
  *
- * @return
- *   0 if checks are alright, -1 otherwise.
- */
-static int
-add_action_gact(struct rte_flow *flow, int action)
-{
-	struct nlmsg *msg = &flow->msg;
-	size_t act_index = 1;
-	struct tc_gact p = {
-		.action = action
-	};
-
-	if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
-		return -1;
-	if (tap_nlattr_nested_start(msg, act_index++) < 0)
-		return -1;
-	tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("gact"), "gact");
-	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
-		return -1;
-	tap_nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(p), &p);
-	tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
-	tap_nlattr_nested_finish(msg); /* nested act_index */
-	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
-	return 0;
-}
-
-/**
- * Transform a MIRRED action item in the provided flow for TC.
+ * @param[in, out] act_index
+ *   Pointer to action sequence number in the TC command
  *
- * @param[in, out] flow
- *   Flow to be filled.
- * @param[in] ifindex
- *   Netdevice ifindex, where to mirror/redirect packet to.
- * @param[in] action_type
- *   Either TCA_EGRESS_REDIR for redirection or TCA_EGRESS_MIRROR for mirroring.
+ * @param[in] adata
+ *  Pointer to struct holding the action parameters
  *
  * @return
- *   0 if checks are alright, -1 otherwise.
+ *   -1 on failure, 0 on success
  */
 static int
-add_action_mirred(struct rte_flow *flow, uint16_t ifindex, uint16_t action_type)
+add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
 {
 	struct nlmsg *msg = &flow->msg;
-	size_t act_index = 1;
-	struct tc_mirred p = {
-		.eaction = action_type,
-		.ifindex = ifindex,
-	};
 
-	if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
-		return -1;
-	if (tap_nlattr_nested_start(msg, act_index++) < 0)
+	if (tap_nlattr_nested_start(msg, (*act_index)++) < 0)
 		return -1;
-	tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("mirred"), "mirred");
+
+	tap_nlattr_add(&msg->nh, TCA_ACT_KIND,
+				strlen(adata->id) + 1, adata->id);
 	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
 		return -1;
-	if (action_type == TCA_EGRESS_MIRROR)
-		p.action = TC_ACT_PIPE;
-	else /* REDIRECT */
-		p.action = TC_ACT_STOLEN;
-	tap_nlattr_add(&msg->nh, TCA_MIRRED_PARMS, sizeof(p), &p);
+	if (strcmp("gact", adata->id) == 0) {
+		tap_nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(adata->gact),
+			   &adata->gact);
+	} else if (strcmp("mirred", adata->id) == 0) {
+		if (adata->mirred.eaction == TCA_EGRESS_MIRROR)
+			adata->mirred.action = TC_ACT_PIPE;
+		else /* REDIRECT */
+			adata->mirred.action = TC_ACT_STOLEN;
+		tap_nlattr_add(&msg->nh, TCA_MIRRED_PARMS,
+			   sizeof(adata->mirred),
+			   &adata->mirred);
+	} else if (strcmp("skbedit", adata->id) == 0) {
+		tap_nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS,
+			   sizeof(adata->skbedit.skbedit),
+			   &adata->skbedit.skbedit);
+		tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING,
+			     adata->skbedit.queue);
+	} else {
+		return -1;
+	}
 	tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
 	tap_nlattr_nested_finish(msg); /* nested act_index */
-	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
 	return 0;
 }
 
 /**
- * Transform a QUEUE action item in the provided flow for TC.
+ * Helper function to send a serie of TC actions to the kernel
  *
- * @param[in, out] flow
- *   Flow to be filled.
- * @param[in] queue
- *   Queue id to use.
+ * @param[in] flow
+ *   Pointer to rte flow containing the netlink message
+ *
+ * @param[in] nb_actions
+ *   Number of actions in an array of action structs
+ *
+ * @param[in] data
+ *   Pointer to an array of action structs
+ *
+ * @param[in] classifier_actions
+ *   The classifier on behave of which the actions are configured
  *
  * @return
- *   0 if checks are alright, -1 otherwise.
+ *   -1 on failure, 0 on success
  */
 static int
-add_action_skbedit(struct rte_flow *flow, uint16_t queue)
+add_actions(struct rte_flow *flow, int nb_actions, struct action_data *data,
+	    int classifier_action)
 {
 	struct nlmsg *msg = &flow->msg;
 	size_t act_index = 1;
-	struct tc_skbedit p = {
-		.action = TC_ACT_PIPE
-	};
+	int i;
 
-	if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
-		return -1;
-	if (tap_nlattr_nested_start(msg, act_index++) < 0)
+	if (tap_nlattr_nested_start(msg, classifier_action) < 0)
 		return -1;
-	tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("skbedit"), "skbedit");
-	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
-		return -1;
-	tap_nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS, sizeof(p), &p);
-	tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING, queue);
-	tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
-	tap_nlattr_nested_finish(msg); /* nested act_index */
+	for (i = 0; i < nb_actions; i++)
+		if (add_action(flow, &act_index, data + i) < 0)
+			return -1;
 	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
 	return 0;
 }
@@ -1056,7 +1048,12 @@ priv_flow_process(struct pmd_internals *pmd,
 		}
 	}
 	if (mirred && flow) {
-		uint16_t if_index = pmd->if_index;
+		struct action_data adata = {
+			.id = "mirred",
+			.mirred = {
+				.eaction = mirred,
+			},
+		};
 
 		/*
 		 * If attr->egress && mirred, then this is a special
@@ -1064,9 +1061,13 @@ priv_flow_process(struct pmd_internals *pmd,
 		 * redirect packets coming from the DPDK App, out
 		 * through the remote netdevice.
 		 */
-		if (attr->egress)
-			if_index = pmd->remote_if_index;
-		if (add_action_mirred(flow, if_index, mirred) < 0)
+		adata.mirred.ifindex = attr->ingress ? pmd->if_index :
+			pmd->remote_if_index;
+		if (mirred == TCA_EGRESS_MIRROR)
+			adata.mirred.action = TC_ACT_PIPE;
+		else
+			adata.mirred.action = TC_ACT_STOLEN;
+		if (add_actions(flow, 1, &adata, TCA_FLOWER_ACT) < 0)
 			goto exit_action_not_supported;
 		else
 			goto end;
@@ -1080,14 +1081,33 @@ priv_flow_process(struct pmd_internals *pmd,
 			if (action)
 				goto exit_action_not_supported;
 			action = 1;
-			if (flow)
-				err = add_action_gact(flow, TC_ACT_SHOT);
+			if (flow) {
+				struct action_data adata = {
+					.id = "gact",
+					.gact = {
+						.action = TC_ACT_SHOT,
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+						  TCA_FLOWER_ACT);
+			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_PASSTHRU) {
 			if (action)
 				goto exit_action_not_supported;
 			action = 1;
-			if (flow)
-				err = add_action_gact(flow, TC_ACT_UNSPEC);
+			if (flow) {
+				struct action_data adata = {
+					.id = "gact",
+					.gact = {
+						/* continue */
+						.action = TC_ACT_UNSPEC,
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+						  TCA_FLOWER_ACT);
+			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
 			const struct rte_flow_action_queue *queue =
 				(const struct rte_flow_action_queue *)
@@ -1099,22 +1119,46 @@ priv_flow_process(struct pmd_internals *pmd,
 			if (!queue ||
 			    (queue->index > pmd->dev->data->nb_rx_queues - 1))
 				goto exit_action_not_supported;
-			if (flow)
-				err = add_action_skbedit(flow, queue->index);
+			if (flow) {
+				struct action_data adata = {
+					.id = "skbedit",
+					.skbedit = {
+						.skbedit = {
+							.action = TC_ACT_PIPE,
+						},
+						.queue = queue->index,
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+					TCA_FLOWER_ACT);
+			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
 			/* Fake RSS support. */
 			const struct rte_flow_action_rss *rss =
 				(const struct rte_flow_action_rss *)
 				actions->conf;
 
-			if (action)
+			if (action++)
 				goto exit_action_not_supported;
-			action = 1;
+
 			if (!rss || rss->num < 1 ||
 			    (rss->queue[0] > pmd->dev->data->nb_rx_queues - 1))
 				goto exit_action_not_supported;
-			if (flow)
-				err = add_action_skbedit(flow, rss->queue[0]);
+			if (flow) {
+				struct action_data adata = {
+					.id = "skbedit",
+					.skbedit = {
+						.skbedit = {
+							.action = TC_ACT_PIPE,
+						},
+						.queue = rss->queue[0],
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+					TCA_FLOWER_ACT);
+			}
 		} else {
 			goto exit_action_not_supported;
 		}
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v5 2/6] net/tap: add eBPF bytes code
  2018-01-18 13:38       ` [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter Ophir Munk
  2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 1/6] net/tap: support actions for different classifiers Ophir Munk
@ 2018-01-18 13:38         ` Ophir Munk
  2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 3/6] net/tap: add eBPF program file Ophir Munk
                           ` (5 subsequent siblings)
  7 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-18 13:38 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

File tap_bpf_insns.h was added with eBPF bytes code.
The bytes code is in the format of C array of struct bpf_insn
It was generated from C source file by external tools.
1. The C file was compiled via LLVM into an object file in ELF
format as:
 clang -O2 -emit-llvm -c tap_bpf_program.c -o - | llc -march=bpf
 -filetype=obj -o <tap_bpf_program.o>

clang version must be 3.7 and above
The C functions are under different ELF sections and are considered
different BPF programs that can be downloaded to the kernel

2. Using an external tool the ELF sections are parsed and the C array
of struct bpf_insn is generated. Each C array (corresponding to BPF
bytes code) is downloaded to the kernel using BPF systm call.
The C program and the external tool source files will be added in
separate commits.

In this commit the bytes code is not part of DPDK compilation

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 drivers/net/tap/tap_bpf_insns.h | 1693 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 1693 insertions(+)
 create mode 100644 drivers/net/tap/tap_bpf_insns.h

diff --git a/drivers/net/tap/tap_bpf_insns.h b/drivers/net/tap/tap_bpf_insns.h
new file mode 100644
index 0000000..c406f78
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_insns.h
@@ -0,0 +1,1693 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#include <tap_bpf.h>
+
+/* bpf_insn array matching cls_q section. See tap_bpf_program.c file */
+struct bpf_insn cls_q_insns[] = {
+	{0x61,    1,    1,       52, 0x00000000},
+	{0x18,    2,    0,        0, 0xdeadbeef},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0x63,   10,    2,       -4, 0x00000000},
+	{0x61,    2,   10,       -4, 0x00000000},
+	{0x07,    2,    0,        0, 0x00000001},
+	{0x67,    2,    0,        0, 0x00000020},
+	{0x77,    2,    0,        0, 0x00000020},
+	{0xb7,    0,    0,        0, 0xffffffff},
+	{0x1d,    1,    2,        1, 0x00000000},
+	{0xb7,    0,    0,        0, 0x00000000},
+	{0x95,    0,    0,        0, 0x00000000},
+};
+
+/* bpf_insn array matching l3_l4 section. see tap_bpf_program.c file */
+struct bpf_insn l3_l4_hash_insns[] = {
+	{0xbf,    7,    1,        0, 0x00000000},
+	{0x61,    8,    7,       16, 0x00000000},
+	{0x61,    6,    7,       76, 0x00000000},
+	{0x61,    9,    7,       80, 0x00000000},
+	{0x18,    1,    0,        0, 0xdeadbeef},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0x63,   10,    1,       -4, 0x00000000},
+	{0xbf,    2,   10,        0, 0x00000000},
+	{0x07,    2,    0,        0, 0xfffffffc},
+	{0x18,    1,    1,        0, 0x0000cafe},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0x85,    0,    0,        0, 0x00000001},
+	{0x55,    0,    0,       21, 0x00000000},
+	{0xb7,    1,    0,        0, 0x00000a64},
+	{0x6b,   10,    1,      -16, 0x00000000},
+	{0x18,    1,    0,        0, 0x69666e6f},
+	{0x00,    0,    0,        0, 0x65727567},
+	{0x7b,   10,    1,      -24, 0x00000000},
+	{0x18,    1,    0,        0, 0x6e207369},
+	{0x00,    0,    0,        0, 0x6320746f},
+	{0x7b,   10,    1,      -32, 0x00000000},
+	{0x18,    1,    0,        0, 0x20737372},
+	{0x00,    0,    0,        0, 0x2079656b},
+	{0x7b,   10,    1,      -40, 0x00000000},
+	{0x18,    1,    0,        0, 0x68736168},
+	{0x00,    0,    0,        0, 0x203a2928},
+	{0x7b,   10,    1,      -48, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0x73,   10,    7,      -14, 0x00000000},
+	{0xbf,    1,   10,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0xffffffd0},
+	{0xb7,    2,    0,        0, 0x00000023},
+	{0x85,    0,    0,        0, 0x00000006},
+	{0x05,    0,    0,     1632, 0x00000000},
+	{0xb7,    1,    0,        0, 0x0000000e},
+	{0x61,    2,    7,       20, 0x00000000},
+	{0x15,    2,    0,       10, 0x00000000},
+	{0x61,    2,    7,       28, 0x00000000},
+	{0x55,    2,    0,        8, 0x0000a888},
+	{0xbf,    2,    7,        0, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0xbf,    1,    6,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0x00000012},
+	{0x2d,    1,    9,     1622, 0x00000000},
+	{0xb7,    1,    0,        0, 0x00000012},
+	{0x69,    8,    6,       16, 0x00000000},
+	{0xbf,    7,    2,        0, 0x00000000},
+	{0x7b,   10,    7,      -56, 0x00000000},
+	{0x57,    8,    0,        0, 0x0000ffff},
+	{0x15,    8,    0,      409, 0x0000dd86},
+	{0xb7,    7,    0,        0, 0x00000003},
+	{0x55,    8,    0,     1614, 0x00000008},
+	{0x0f,    6,    1,        0, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0xbf,    1,    6,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0x00000018},
+	{0x2d,    1,    9,     1609, 0x00000000},
+	{0x71,    3,    6,       12, 0x00000000},
+	{0xbf,    1,    3,        0, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000038},
+	{0xc7,    1,    0,        0, 0x00000020},
+	{0x77,    1,    0,        0, 0x0000001f},
+	{0x57,    1,    0,        0, 0x2cc681d1},
+	{0x67,    3,    0,        0, 0x00000018},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x40000000},
+	{0xb7,    2,    0,        0, 0x00000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x598d03a2},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x20000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb31a0745},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x10000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x66340e8a},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x08000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcc681d15},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x04000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x98d03a2b},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x02000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x31a07456},
+	{0x57,    3,    0,        0, 0x01000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6340e8ad},
+	{0x71,    3,    6,       13, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000010},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00800000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc681d15b},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00400000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d03a2b7},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00200000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1a07456f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00100000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x340e8ade},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00080000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x681d15bd},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00040000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd03a2b7b},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00020000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa07456f6},
+	{0x57,    3,    0,        0, 0x00010000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x40e8aded},
+	{0x71,    3,    6,       14, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00008000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x81d15bdb},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00004000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x03a2b7b7},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00002000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x07456f6f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00001000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0e8adedf},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000800},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1d15bdbf},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000400},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3a2b7b7e},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000200},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7456f6fd},
+	{0x57,    3,    0,        0, 0x00000100},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe8adedfa},
+	{0x71,    3,    6,       15, 0x00000000},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000080},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd15bdbf4},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000040},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa2b7b7e9},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000020},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x456f6fd3},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000010},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8adedfa7},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000008},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x15bdbf4f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000004},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2b7b7e9e},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000002},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x56f6fd3d},
+	{0x57,    3,    0,        0, 0x00000001},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xadedfa7b},
+	{0x71,    4,    6,       16, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000038},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0xb7,    3,    0,        0, 0xffffffff},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5bdbf4f7},
+	{0x67,    4,    0,        0, 0x00000018},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb7b7e9ef},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6f6fd3df},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdedfa7bf},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbdbf4f7f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7b7e9eff},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf6fd3dff},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xedfa7bfe},
+	{0x71,    4,    6,       17, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000010},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdbf4f7fc},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb7e9eff9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6fd3dff2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdfa7bfe5},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbf4f7fca},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7e9eff94},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfd3dff28},
+	{0x57,    4,    0,        0, 0x00010000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfa7bfe51},
+	{0x71,    4,    6,       18, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000008},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf4f7fca2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe9eff945},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd3dff28a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa7bfe514},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4f7fca28},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9eff9450},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3dff28a0},
+	{0x57,    4,    0,        0, 0x00000100},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7bfe5141},
+	{0x71,    4,    6,       19, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf7fca283},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xeff94506},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdff28a0c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbfe51418},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7fca2831},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff945063},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff28a0c6},
+	{0x57,    4,    0,        0, 0x00000001},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfe51418c},
+	{0x71,    4,    6,       20, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000008},
+	{0x71,    5,    6,       21, 0x00000000},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000030},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfca28319},
+	{0x67,    4,    0,        0, 0x00000010},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x40000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf9450633},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x20000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf28a0c67},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x10000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe51418ce},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x08000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xca28319d},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x04000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9450633b},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x02000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28a0c676},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x01000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x51418ced},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00800000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa28319db},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00400000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x450633b6},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00200000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8a0c676c},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00100000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1418ced8},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00080000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28319db1},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00040000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x50633b63},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00020000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa0c676c6},
+	{0x57,    4,    0,        0, 0x00010000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x418ced8d},
+	{0x71,    3,    6,       22, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00008000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8319db1a},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00004000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0633b634},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00002000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0c676c68},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00001000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x18ced8d1},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000800},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x319db1a3},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000400},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x633b6347},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000200},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc676c68f},
+	{0x57,    3,    0,        0, 0x00000100},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8ced8d1f},
+	{0x71,    3,    6,       23, 0x00000000},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000080},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x19db1a3e},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000040},
+	{0x79,    5,   10,      -56, 0x00000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x33b6347d},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000020},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x676c68fa},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000010},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xced8d1f4},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000008},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9db1a3e9},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000004},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3b6347d2},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000002},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x76c68fa5},
+	{0x57,    3,    0,        0, 0x00000001},
+	{0x1d,    3,    2,     1177, 0x00000000},
+	{0xa7,    1,    0,        0, 0xed8d1f4a},
+	{0x05,    0,    0,     1175, 0x00000000},
+	{0x0f,    6,    1,        0, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0xbf,    1,    6,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0x0000002c},
+	{0x2d,    1,    9,     1202, 0x00000000},
+	{0x61,    4,    6,        8, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000038},
+	{0xc7,    1,    0,        0, 0x00000020},
+	{0x77,    1,    0,        0, 0x0000001f},
+	{0x57,    1,    0,        0, 0x2cc681d1},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000040},
+	{0xb7,    2,    0,        0, 0x00000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x598d03a2},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000020},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb31a0745},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000010},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x66340e8a},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000008},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcc681d15},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000004},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x98d03a2b},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000002},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x31a07456},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000001},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6340e8ad},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00008000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc681d15b},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00004000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d03a2b7},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00002000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1a07456f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00001000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x340e8ade},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000800},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x681d15bd},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000400},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd03a2b7b},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000200},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa07456f6},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000100},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x40e8aded},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00800000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x81d15bdb},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00400000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x03a2b7b7},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00200000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x07456f6f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00100000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0e8adedf},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00080000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1d15bdbf},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00040000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3a2b7b7e},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00020000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7456f6fd},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00010000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe8adedfa},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0xb7,    3,    0,        0, 0xffffffff},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd15bdbf4},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa2b7b7e9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x456f6fd3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8adedfa7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x15bdbf4f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2b7b7e9e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x56f6fd3d},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xadedfa7b},
+	{0x61,    4,    6,       12, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5bdbf4f7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb7b7e9ef},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6f6fd3df},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdedfa7bf},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbdbf4f7f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7b7e9eff},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf6fd3dff},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xedfa7bfe},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdbf4f7fc},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb7e9eff9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6fd3dff2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdfa7bfe5},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbf4f7fca},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7e9eff94},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfd3dff28},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfa7bfe51},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf4f7fca2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe9eff945},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd3dff28a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa7bfe514},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4f7fca28},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9eff9450},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3dff28a0},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7bfe5141},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf7fca283},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xeff94506},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdff28a0c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbfe51418},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7fca2831},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff945063},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff28a0c6},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfe51418c},
+	{0x61,    4,    6,       16, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfca28319},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf9450633},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf28a0c67},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe51418ce},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xca28319d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9450633b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28a0c676},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x51418ced},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa28319db},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x450633b6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8a0c676c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1418ced8},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28319db1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x50633b63},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa0c676c6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x418ced8d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8319db1a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0633b634},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0c676c68},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x18ced8d1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x319db1a3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x633b6347},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc676c68f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8ced8d1f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x19db1a3e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x33b6347d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x676c68fa},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xced8d1f4},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9db1a3e9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3b6347d2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x76c68fa5},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xed8d1f4a},
+	{0x61,    4,    6,       20, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdb1a3e94},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb6347d28},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6c68fa51},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd8d1f4a3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb1a3e946},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6347d28d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc68fa51a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d1f4a35},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1a3e946b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x347d28d7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x68fa51ae},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd1f4a35c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa3e946b9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x47d28d73},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8fa51ae7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1f4a35cf},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3e946b9e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7d28d73c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfa51ae78},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf4a35cf1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe946b9e3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd28d73c7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa51ae78e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4a35cf1c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x946b9e38},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28d73c71},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x51ae78e3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa35cf1c6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x46b9e38d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d73c71b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1ae78e36},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x35cf1c6c},
+	{0x61,    4,    6,       24, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6b9e38d9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd73c71b2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xae78e364},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5cf1c6c9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb9e38d92},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x73c71b25},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe78e364b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcf1c6c96},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9e38d92c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3c71b259},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x78e364b2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf1c6c964},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe38d92c9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc71b2593},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8e364b27},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1c6c964e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x38d92c9c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x71b25938},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe364b270},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc6c964e0},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d92c9c0},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1b259380},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x364b2700},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6c964e01},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd92c9c03},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb2593807},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x64b2700f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc964e01e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x92c9c03d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2593807a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4b2700f4},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x964e01e8},
+	{0x61,    4,    6,       28, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2c9c03d1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x593807a3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb2700f46},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x64e01e8d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc9c03d1a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x93807a35},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2700f46b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4e01e8d6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9c03d1ad},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3807a35b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x700f46b6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe01e8d6c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc03d1ad9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x807a35b3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x00f46b66},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x01e8d6cc},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x03d1ad99},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x07a35b32},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0f46b665},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1e8d6cca},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3d1ad994},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7a35b328},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf46b6651},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe8d6cca2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd1ad9944},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa35b3289},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x46b66512},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d6cca25},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1ad9944a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x35b32894},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6b665129},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd6cca253},
+	{0x61,    4,    6,       32, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xad9944a7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5b32894f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb665129f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6cca253e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd9944a7d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb32894fb},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x665129f6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcca253ec},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9944a7d9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x32894fb2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x65129f65},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xca253eca},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x944a7d95},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2894fb2a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5129f655},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa253ecab},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x44a7d956},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x894fb2ac},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x129f6558},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x253ecab1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4a7d9563},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x94fb2ac7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x29f6558f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x53ecab1e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa7d9563d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4fb2ac7a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9f6558f5},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3ecab1ea},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7d9563d5},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfb2ac7ab},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf6558f56},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xecab1eac},
+	{0x61,    4,    6,       36, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd9563d59},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb2ac7ab2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6558f564},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcab1eac8},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9563d590},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2ac7ab20},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x558f5641},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xab1eac83},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x563d5906},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xac7ab20c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x58f56418},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb1eac831},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x63d59063},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc7ab20c7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8f56418f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1eac831e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3d59063c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7ab20c78},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf56418f0},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xeac831e1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd59063c2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xab20c784},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x56418f09},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xac831e12},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x59063c25},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb20c784b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6418f097},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc831e12f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9063c25f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x20c784be},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x418f097c},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x831e12f9},
+	{0x71,    4,    6,       40, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000008},
+	{0x71,    5,    6,       41, 0x00000000},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000030},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x063c25f3},
+	{0x67,    4,    0,        0, 0x00000010},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x40000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0c784be7},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x20000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x18f097cf},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x10000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x31e12f9f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x08000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x63c25f3f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x04000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc784be7f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x02000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8f097cff},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x01000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1e12f9fe},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00800000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3c25f3fc},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00400000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x784be7f8},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00200000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf097cff0},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00100000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe12f9fe0},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00080000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc25f3fc1},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00040000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x84be7f83},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00020000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x097cff07},
+	{0x57,    4,    0,        0, 0x00010000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x12f9fe0f},
+	{0x71,    3,    6,       42, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00008000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x25f3fc1f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00004000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4be7f83f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00002000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x97cff07f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00001000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2f9fe0fe},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000800},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5f3fc1fd},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000400},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbe7f83fb},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000200},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7cff07f7},
+	{0x57,    3,    0,        0, 0x00000100},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf9fe0fee},
+	{0x71,    3,    6,       43, 0x00000000},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000080},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf3fc1fdc},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000040},
+	{0x79,    5,   10,      -56, 0x00000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe7f83fb8},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000020},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcff07f70},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000010},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9fe0fee1},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000008},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3fc1fdc2},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000004},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7f83fb85},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000002},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff07f70a},
+	{0x57,    3,    0,        0, 0x00000001},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfe0fee15},
+	{0x71,    2,    0,      201, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000008},
+	{0x71,    3,    0,      200, 0x00000000},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0x71,    3,    0,      203, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0x71,    4,    0,      202, 0x00000000},
+	{0x4f,    3,    4,        0, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000010},
+	{0x4f,    3,    2,        0, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000020},
+	{0x77,    1,    0,        0, 0x00000020},
+	{0xbf,    2,    1,        0, 0x00000000},
+	{0x3f,    2,    3,        0, 0x00000000},
+	{0x2f,    2,    3,        0, 0x00000000},
+	{0x1f,    1,    2,        0, 0x00000000},
+	{0x57,    1,    0,        0, 0x0000000f},
+	{0x67,    1,    0,        0, 0x00000002},
+	{0x0f,    0,    1,        0, 0x00000000},
+	{0x71,    1,    0,      137, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000008},
+	{0x71,    2,    0,      136, 0x00000000},
+	{0x4f,    1,    2,        0, 0x00000000},
+	{0x71,    2,    0,      138, 0x00000000},
+	{0x71,    3,    0,      139, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0x4f,    3,    2,        0, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000010},
+	{0x4f,    3,    1,        0, 0x00000000},
+	{0x07,    3,    0,        0, 0x00000001},
+	{0x63,    5,    3,       52, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000001},
+	{0xbf,    0,    7,        0, 0x00000000},
+	{0x95,    0,    0,        0, 0x00000000},
+};
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v5 3/6] net/tap: add eBPF program file
  2018-01-18 13:38       ` [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter Ophir Munk
  2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 1/6] net/tap: support actions for different classifiers Ophir Munk
  2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 2/6] net/tap: add eBPF bytes code Ophir Munk
@ 2018-01-18 13:38         ` Ophir Munk
  2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 4/6] net/tap: add eBPF API Ophir Munk
                           ` (4 subsequent siblings)
  7 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-18 13:38 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

File tap_bpf_program.c was added with two ELF sections
corresponding to two BPF programs and one BPF map.
It is the C source file used to generate the eBPF bytes code
(see "net/tap: add eBPF bytes code").

Section cls_q - BPF classifier to classify packets to their
corresponding queue after an RSS hash was calculated on the packet
and saved in skb->cb[1]
Section l3_l4 - BPF action to calculate RSS hash on packet layers 3
and 4
This file is not part of DPDK tree compilation.

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 drivers/net/tap/tap_bpf_program.c | 221 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 221 insertions(+)
 create mode 100644 drivers/net/tap/tap_bpf_program.c

diff --git a/drivers/net/tap/tap_bpf_program.c b/drivers/net/tap/tap_bpf_program.c
new file mode 100644
index 0000000..848c50b
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_program.c
@@ -0,0 +1,221 @@
+/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <asm/types.h>
+#include <linux/in.h>
+#include <linux/if.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/if_tunnel.h>
+#include <linux/filter.h>
+#include <linux/bpf.h>
+
+#include "tap_rss.h"
+
+/** Create IPv4 address */
+#define IPv4(a, b, c, d) ((__u32)(((a) & 0xff) << 24) | \
+		(((b) & 0xff) << 16) | \
+		(((c) & 0xff) << 8)  | \
+		((d) & 0xff))
+
+#define PORT(a, b) ((__u16)(((a) & 0xff) << 8) | \
+		((b) & 0xff))
+
+/*
+ * The queue number is offset by 1, to distinguish packets that have
+ * gone through this rule (skb->cb[1] != 0) from others.
+ */
+#define QUEUE_OFFSET		1
+#define PIN_GLOBAL_NS		2
+
+#define KEY_IDX			0
+#define BPF_MAP_ID_KEY	1
+
+struct vlan_hdr {
+	__be16 proto;
+	__be16 tci;
+};
+
+struct bpf_elf_map __attribute__((section("maps"), used))
+map_keys = {
+	.type           =       BPF_MAP_TYPE_HASH,
+	.id             =       BPF_MAP_ID_KEY,
+	.size_key       =       sizeof(__u32),
+	.size_value     =       sizeof(struct rss_key),
+	.max_elem       =       256,
+	.pinning        =       PIN_GLOBAL_NS,
+};
+
+__section("cls_q") int
+match_q(struct __sk_buff *skb)
+{
+	__u32 queue = skb->cb[1];
+	volatile __u32 q = 0xdeadbeef;
+	__u32 match_queue = QUEUE_OFFSET + q;
+
+	/* printt("match_q$i() queue = %d\n", queue); */
+
+	if (queue != match_queue)
+		return TC_ACT_OK;
+	return TC_ACT_UNSPEC;
+}
+
+
+struct ipv4_l3_l4_tuple {
+	__u32    src_addr;
+	__u32    dst_addr;
+	__u16    dport;
+	__u16    sport;
+} __attribute__((packed));
+
+struct ipv6_l3_l4_tuple {
+	__u8        src_addr[16];
+	__u8        dst_addr[16];
+	__u16       dport;
+	__u16       sport;
+} __attribute__((packed));
+
+static const __u8 def_rss_key[] = {
+	0xd1, 0x81, 0xc6, 0x2c,
+	0xf7, 0xf4, 0xdb, 0x5b,
+	0x19, 0x83, 0xa2, 0xfc,
+	0x94, 0x3e, 0x1a, 0xdb,
+	0xd9, 0x38, 0x9e, 0x6b,
+	0xd1, 0x03, 0x9c, 0x2c,
+	0xa7, 0x44, 0x99, 0xad,
+	0x59, 0x3d, 0x56, 0xd9,
+	0xf3, 0x25, 0x3c, 0x06,
+	0x2a, 0xdc, 0x1f, 0xfc,
+};
+
+static __u32  __attribute__((always_inline))
+rte_softrss_be(const __u32 *input_tuple, const uint8_t *rss_key,
+		__u8 input_len)
+{
+	__u32 i, j, hash = 0;
+#pragma unroll
+	for (j = 0; j < input_len; j++) {
+#pragma unroll
+		for (i = 0; i < 32; i++) {
+			if (input_tuple[j] & (1 << (31 - i))) {
+				hash ^= ((const __u32 *)def_rss_key)[j] << i |
+				(__u32)((uint64_t)
+				(((const __u32 *)def_rss_key)[j + 1])
+					>> (32 - i));
+			}
+		}
+	}
+	return hash;
+}
+
+static int __attribute__((always_inline))
+rss_l3_l4(struct __sk_buff *skb)
+{
+	void *data_end = (void *)(long)skb->data_end;
+	void *data = (void *)(long)skb->data;
+	__u16 proto = (__u16)skb->protocol;
+	__u32 key_idx = 0xdeadbeef;
+	__u32 hash;
+	struct rss_key *rsskey;
+	__u64 off = ETH_HLEN;
+	int j;
+	__u8 *key = 0;
+	__u32 len;
+	__u32 queue = 0;
+
+	rsskey = map_lookup_elem(&map_keys, &key_idx);
+	if (!rsskey) {
+		printt("hash(): rss key is not configured\n");
+		return TC_ACT_OK;
+	}
+	key = (__u8 *)rsskey->key;
+
+	/* Get correct proto for 802.1ad */
+	if (skb->vlan_present && skb->vlan_proto == htons(ETH_P_8021AD)) {
+		if (data + ETH_ALEN * 2 + sizeof(struct vlan_hdr) +
+		    sizeof(proto) > data_end)
+			return TC_ACT_OK;
+		proto = *(__u16 *)(data + ETH_ALEN * 2 +
+				   sizeof(struct vlan_hdr));
+		off += sizeof(struct vlan_hdr);
+	}
+
+	if (proto == htons(ETH_P_IP)) {
+		if (data + off + sizeof(struct iphdr) + sizeof(__u32)
+			> data_end)
+			return TC_ACT_OK;
+
+		__u8 *src_dst_addr = data + off + offsetof(struct iphdr, saddr);
+		__u8 *src_dst_port = data + off + sizeof(struct iphdr);
+		struct ipv4_l3_l4_tuple v4_tuple = {
+			.src_addr = IPv4(*(src_dst_addr + 0),
+					*(src_dst_addr + 1),
+					*(src_dst_addr + 2),
+					*(src_dst_addr + 3)),
+			.dst_addr = IPv4(*(src_dst_addr + 4),
+					*(src_dst_addr + 5),
+					*(src_dst_addr + 6),
+					*(src_dst_addr + 7)),
+			.sport = PORT(*(src_dst_port + 0),
+					*(src_dst_port + 1)),
+			.dport = PORT(*(src_dst_port + 2),
+					*(src_dst_port + 3)),
+		};
+		__u8 input_len = sizeof(v4_tuple) / sizeof(__u32);
+		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV4_L3))
+			input_len--;
+		hash = rte_softrss_be((__u32 *)&v4_tuple, key, 3);
+	} else if (proto == htons(ETH_P_IPV6)) {
+		if (data + off + sizeof(struct ipv6hdr) +
+					sizeof(__u32) > data_end)
+			return TC_ACT_OK;
+		__u8 *src_dst_addr = data + off +
+					offsetof(struct ipv6hdr, saddr);
+		__u8 *src_dst_port = data + off +
+					sizeof(struct ipv6hdr);
+		struct ipv6_l3_l4_tuple v6_tuple;
+		for (j = 0; j < 4; j++)
+			*((uint32_t *)&v6_tuple.src_addr + j) =
+				__builtin_bswap32(*((uint32_t *)
+						src_dst_addr + j));
+		for (j = 0; j < 4; j++)
+			*((uint32_t *)&v6_tuple.dst_addr + j) =
+				__builtin_bswap32(*((uint32_t *)
+						src_dst_addr + 4 + j));
+		v6_tuple.sport = PORT(*(src_dst_port + 0),
+			      *(src_dst_port + 1));
+		v6_tuple.dport = PORT(*(src_dst_port + 2),
+			      *(src_dst_port + 3));
+
+		__u8 input_len = sizeof(v6_tuple) / sizeof(__u32);
+		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV6_L3))
+			input_len--;
+		hash = rte_softrss_be((__u32 *)&v6_tuple, key, 9);
+	} else {
+		return TC_ACT_PIPE;
+	}
+
+	queue = rsskey->queues[(hash % rsskey->nb_queues) &
+				       (TAP_MAX_QUEUES - 1)];
+	skb->cb[1] = QUEUE_OFFSET + queue;
+	/* printt(">>>>> rss_l3_l4 hash=0x%x queue=%u\n", hash, queue); */
+
+	return TC_ACT_RECLASSIFY;
+}
+
+#define RSS(L)						\
+	__section(#L) int				\
+		L ## _hash(struct __sk_buff *skb)	\
+	{						\
+		return rss_ ## L (skb);			\
+	}
+
+RSS(l3_l4)
+
+BPF_LICENSE("Dual BSD/GPL");
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v5 4/6] net/tap: add eBPF API
  2018-01-18 13:38       ` [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter Ophir Munk
                           ` (2 preceding siblings ...)
  2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 3/6] net/tap: add eBPF program file Ophir Munk
@ 2018-01-18 13:38         ` Ophir Munk
  2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 5/6] net/tap: implement TAP RSS using eBPF Ophir Munk
                           ` (3 subsequent siblings)
  7 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-18 13:38 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

This commit include BPF API to be used by TAP.

tap_flow_bpf_cls_q() - download to kernel BPF program that classifies
packets to their matching queues
tap_flow_bpf_calc_l3_l4_hash() - download to kernel BPF program that
calculates per packet layer 3 and layer 4 RSS hash
tap_flow_bpf_rss_map_create() - create BPF RSS map for storing RSS
parameters per RSS rule
tap_flow_bpf_update_rss_elem() - update BPF map entry with RSS rule
parameters

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 drivers/net/tap/Makefile      |   6 ++
 drivers/net/tap/tap_bpf.h     | 112 +++++++++++++++++++++++++
 drivers/net/tap/tap_bpf_api.c | 190 ++++++++++++++++++++++++++++++++++++++++++
 drivers/net/tap/tap_flow.h    |   6 ++
 4 files changed, 314 insertions(+)
 create mode 100644 drivers/net/tap/tap_bpf.h
 create mode 100644 drivers/net/tap/tap_bpf_api.c

diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index fbf84e1..fad8a94 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -35,6 +35,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += rte_eth_tap.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_flow.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_netlink.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_tcmsgs.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_bpf_api.c
 
 include $(RTE_SDK)/mk/rte.lib.mk
 
@@ -61,6 +62,11 @@ tap_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
 		linux/pkt_cls.h \
 		enum TCA_FLOWER_KEY_VLAN_PRIO \
 		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_BPF_PROG_LOAD \
+		linux/bpf.h \
+		enum BPF_PROG_LOAD \
+		$(AUTOCONF_OUTPUT)
 
 # Create tap_autoconf.h or update it in case it differs from the new one.
 
diff --git a/drivers/net/tap/tap_bpf.h b/drivers/net/tap/tap_bpf.h
new file mode 100644
index 0000000..30eefb3
--- /dev/null
+++ b/drivers/net/tap/tap_bpf.h
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#ifndef __TAP_BPF_H__
+#define __TAP_BPF_H__
+
+#include <tap_autoconf.h>
+
+#ifdef HAVE_BPF_PROG_LOAD
+#include <linux/bpf.h>
+#else
+/* BPF_MAP_UPDATE_ELEM command flags */
+#define	BPF_ANY	0 /* create a new element or update an existing */
+
+/* BPF architecture instruction struct */
+struct bpf_insn {
+	__u8	code;
+	__u8	dst_reg:4;
+	__u8	src_reg:4;
+	__s16	off;
+	__s32	imm; /* immediate value */
+};
+
+/* BPF program types */
+enum bpf_prog_type {
+	BPF_PROG_TYPE_UNSPEC,
+	BPF_PROG_TYPE_SOCKET_FILTER,
+	BPF_PROG_TYPE_KPROBE,
+	BPF_PROG_TYPE_SCHED_CLS,
+	BPF_PROG_TYPE_SCHED_ACT,
+};
+
+/* BPF commands types */
+enum bpf_cmd {
+	BPF_MAP_CREATE,
+	BPF_MAP_LOOKUP_ELEM,
+	BPF_MAP_UPDATE_ELEM,
+	BPF_MAP_DELETE_ELEM,
+	BPF_MAP_GET_NEXT_KEY,
+	BPF_PROG_LOAD,
+};
+
+/* BPF maps types */
+enum bpf_map_type {
+	BPF_MAP_TYPE_UNSPEC,
+	BPF_MAP_TYPE_HASH,
+};
+
+/* union of anonymous structs used with TAP BPF commands */
+union bpf_attr {
+	/* BPF_MAP_CREATE command */
+	struct {
+		__u32	map_type;
+		__u32	key_size;
+		__u32	value_size;
+		__u32	max_entries;
+		__u32	map_flags;
+		__u32	inner_map_fd;
+	};
+
+	/* BPF_MAP_UPDATE_ELEM, BPF_MAP_DELETE_ELEM commands */
+	struct {
+		__u32		map_fd;
+		__aligned_u64	key;
+		union {
+			__aligned_u64 value;
+			__aligned_u64 next_key;
+		};
+		__u64		flags;
+	};
+
+	/* BPF_PROG_LOAD command */
+	struct {
+		__u32		prog_type;
+		__u32		insn_cnt;
+		__aligned_u64	insns;
+		__aligned_u64	license;
+		__u32		log_level;
+		__u32		log_size;
+		__aligned_u64	log_buf;
+		__u32		kern_version;
+		__u32		prog_flags;
+	};
+} __attribute__((aligned(8)));
+#endif
+
+#ifndef __NR_bpf
+# if defined(__i386__)
+#  define __NR_bpf 357
+# elif defined(__x86_64__)
+#  define __NR_bpf 321
+# elif defined(__aarch64__)
+#  define __NR_bpf 280
+# elif defined(__sparc__)
+#  define __NR_bpf 349
+# elif defined(__s390__)
+#  define __NR_bpf 351
+# else
+#  error __NR_bpf not defined
+# endif
+#endif
+
+enum {
+	BPF_MAP_ID_KEY,
+	BPF_MAP_ID_SIMPLE,
+};
+
+static int bpf_load(enum bpf_prog_type type, const struct bpf_insn *insns,
+		size_t insns_cnt, const char *license);
+
+#endif /* __TAP_BPF_H__ */
diff --git a/drivers/net/tap/tap_bpf_api.c b/drivers/net/tap/tap_bpf_api.c
new file mode 100644
index 0000000..109a681
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_api.c
@@ -0,0 +1,190 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/queue.h>
+
+#include <rte_malloc.h>
+#include <rte_eth_tap.h>
+#include <tap_flow.h>
+#include <tap_autoconf.h>
+#include <tap_tcmsgs.h>
+#include <tap_bpf.h>
+#include <tap_bpf_insns.h>
+
+/**
+ * Load BPF program (section cls_q) into the kernel and return a bpf fd
+ *
+ * @param queue_idx
+ *   Queue index matching packet cb
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int tap_flow_bpf_cls_q(__u32 queue_idx)
+{
+	cls_q_insns[1].imm = queue_idx;
+
+	return bpf_load(BPF_PROG_TYPE_SCHED_CLS,
+		(struct bpf_insn *)cls_q_insns,
+		RTE_DIM(cls_q_insns),
+		"Dual BSD/GPL");
+}
+
+/**
+ * Load BPF program (section l3_l4) into the kernel and return a bpf fd.
+ *
+ * @param[in] key_idx
+ *   RSS MAP key index
+ *
+ * @param[in] map_fd
+ *   BPF RSS map file descriptor
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd)
+{
+	l3_l4_hash_insns[4].imm = key_idx;
+	l3_l4_hash_insns[9].imm = map_fd;
+
+	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+		(struct bpf_insn *)l3_l4_hash_insns,
+		RTE_DIM(l3_l4_hash_insns),
+		"Dual BSD/GPL");
+}
+
+/**
+ * Helper function to convert a pointer to unsigned 64 bits
+ *
+ * @param[in] ptr
+ *   pointer to address
+ *
+ * @return
+ *   64 bit unsigned long type of pointer address
+ */
+static inline __u64 ptr_to_u64(const void *ptr)
+{
+	return (__u64)(unsigned long)ptr;
+}
+
+/**
+ * Call BPF system call
+ *
+ * @param[in] cmd
+ *   BPF command for program loading, map creation, map entry update, etc
+ *
+ * @param[in] attr
+ *   System call attributes relevant to system call command
+ *
+ * @param[in] size
+ *   size of attr parameter
+ *
+ * @return
+ *   -1 if BPF system call failed, 0 otherwise
+ */
+static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
+			unsigned int size)
+{
+	return syscall(__NR_bpf, cmd, attr, size);
+}
+
+/**
+ * Load BPF instructions to kernel
+ *
+ * @param[in] type
+ *   BPF program type: classifieir or action
+ *
+ * @param[in] insns
+ *   Array of BPF instructions (equivalent to BPF instructions)
+ *
+ * @param[in] insns_cnt
+ *   Number of BPF instructions (size of array)
+ *
+ * @param[in] lincense
+ *   License string that must be acknowledged by the kernel
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded, fd (file descriptor) otherwise
+ */
+static int bpf_load(enum bpf_prog_type type,
+		  const struct bpf_insn *insns,
+		  size_t insns_cnt,
+		  const char *license)
+{
+	union bpf_attr attr = {};
+
+	bzero(&attr, sizeof(attr));
+	attr.prog_type = type;
+	attr.insn_cnt = (__u32)insns_cnt;
+	attr.insns = ptr_to_u64(insns);
+	attr.license = ptr_to_u64(license);
+	attr.log_buf = ptr_to_u64(NULL);
+	attr.log_level = 0;
+	attr.kern_version = 0;
+
+	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
+}
+
+/**
+ * Create BPF map for RSS rules
+ *
+ * @param[in] key_size
+ *   map RSS key size
+ *
+ * @param[in] value_size
+ *   Map RSS value size
+ *
+ * @param[in] max_entries
+ *   Map max number of RSS entries (limit on max RSS rules)
+ *
+ * @return
+ *   -1 if BPF map couldn't be created, map fd otherwise
+ */
+int tap_flow_bpf_rss_map_create(unsigned int key_size,
+		unsigned int value_size,
+		unsigned int max_entries)
+{
+	union bpf_attr attr = {};
+
+	bzero(&attr, sizeof(attr));
+	attr.map_type    = BPF_MAP_TYPE_HASH;
+	attr.key_size    = key_size;
+	attr.value_size  = value_size;
+	attr.max_entries = max_entries;
+
+	return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
+}
+
+/**
+ * Update RSS entry in BPF map
+ *
+ * @param[in] fd
+ *   RSS map fd
+ *
+ * @param[in] key
+ *   Pointer to RSS key whose entry is updated
+ *
+ * @param[in] value
+ *   Pointer to RSS new updated value
+ *
+ * @return
+ *   -1 if RSS entry failed to be updated, 0 otherwise
+ */
+int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value)
+{
+	union bpf_attr attr = {};
+
+	bzero(&attr, sizeof(attr));
+
+	attr.map_type = BPF_MAP_TYPE_HASH;
+	attr.map_fd = fd;
+	attr.key = ptr_to_u64(key);
+	attr.value = ptr_to_u64(value);
+	attr.flags = BPF_ANY;
+
+	return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
+}
diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h
index 9e332b0..894c959 100644
--- a/drivers/net/tap/tap_flow.h
+++ b/drivers/net/tap/tap_flow.h
@@ -80,4 +80,10 @@ int tap_flow_implicit_destroy(struct pmd_internals *pmd,
 int tap_flow_implicit_flush(struct pmd_internals *pmd,
 			    struct rte_flow_error *error);
 
+int tap_flow_bpf_cls_q(__u32 queue_idx);
+int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd);
+int tap_flow_bpf_rss_map_create(unsigned int key_size, unsigned int value_size,
+			unsigned int max_entries);
+int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value);
+
 #endif /* _TAP_FLOW_H_ */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v5 5/6] net/tap: implement TAP RSS using eBPF
  2018-01-18 13:38       ` [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter Ophir Munk
                           ` (3 preceding siblings ...)
  2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 4/6] net/tap: add eBPF API Ophir Munk
@ 2018-01-18 13:38         ` Ophir Munk
  2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 6/6] doc: detail new tap RSS feature in guides Ophir Munk
                           ` (2 subsequent siblings)
  7 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-18 13:38 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

TAP PMD is required to support RSS queue mapping based on rte_flow API. An
example usage for this requirement is failsafe transparent switching from a
PCI device to TAP device while keep redirecting packets to the same RSS
queues on both devices.

TAP RSS implementation is based on eBPF programs sent to Linux kernel
through BPF system calls and using netlink messages to reference the
programs as part of traffic control commands.

TC uses eBPF programs as classifiers and actions.
eBPF classification: packets marked with an RSS queue will be directed
to this queue using TC with "skbedit" action.
BPF classifiers are downloaded to the kernel once on TAP creation for
each TAP Rx queue.

eBPF action: calculate the Toeplitz RSS hash based on L3 addresses and
L4 ports. Mark the packet with the RSS queue according the resulting
RSS hash, then reclassify the packet.
BPF actions are downloaded to the kernel for each new RSS rule.

TAP eBPF requires Linux version 4.9 configured with BPF. TAP PMD will
successfully compile on systems with old or non-BPF configured kernels but
RSS rules creation on TAP devices will not be successful

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 drivers/net/tap/Makefile      |  20 ++
 drivers/net/tap/rte_eth_tap.h |   5 +
 drivers/net/tap/tap_flow.c    | 450 ++++++++++++++++++++++++++++++++++++++++--
 drivers/net/tap/tap_flow.h    |   7 +
 drivers/net/tap/tap_rss.h     |  34 ++++
 drivers/net/tap/tap_tcmsgs.h  |   4 +
 6 files changed, 502 insertions(+), 18 deletions(-)
 create mode 100644 drivers/net/tap/tap_rss.h

diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index fad8a94..e23c3a2 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -63,6 +63,26 @@ tap_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
 		enum TCA_FLOWER_KEY_VLAN_PRIO \
 		$(AUTOCONF_OUTPUT)
 	$Q sh -- '$<' '$@' \
+		HAVE_TC_BPF \
+		linux/pkt_cls.h \
+		enum TCA_BPF_UNSPEC \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_TC_BPF_FD \
+		linux/pkt_cls.h \
+		enum TCA_BPF_FD \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_TC_ACT_BPF \
+		linux/tc_act/tc_bpf.h \
+		enum TCA_ACT_BPF_UNSPEC \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_TC_ACT_BPF_FD \
+		linux/tc_act/tc_bpf.h \
+		enum TCA_ACT_BPF_FD \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
 		HAVE_BPF_PROG_LOAD \
 		linux/bpf.h \
 		enum BPF_PROG_LOAD \
diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
index 202b3cd..c185473 100644
--- a/drivers/net/tap/rte_eth_tap.h
+++ b/drivers/net/tap/rte_eth_tap.h
@@ -92,6 +92,11 @@ struct pmd_internals {
 	int flow_isolate;                 /* 1 if flow isolation is enabled */
 	int flower_support;               /* 1 if kernel supports, else 0 */
 	int flower_vlan_support;          /* 1 if kernel supports, else 0 */
+	int rss_enabled;                  /* 1 if RSS is enabled, else 0 */
+	/* implicit rules set when RSS is enabled */
+	int map_fd;                       /* BPF RSS map fd */
+	int bpf_fd[RTE_PMD_TAP_MAX_QUEUES];/* List of bpf fds per queue */
+	LIST_HEAD(tap_rss_flows, rte_flow) rss_flows;
 	LIST_HEAD(tap_flows, rte_flow) flows;        /* rte_flow rules */
 	/* implicit rte_flow rules set when a remote device is active */
 	LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows;
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index d2a69a7..6aa53a7 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -35,6 +35,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/queue.h>
+#include <sys/resource.h>
 
 #include <rte_byteorder.h>
 #include <rte_jhash.h>
@@ -43,6 +44,7 @@
 #include <tap_flow.h>
 #include <tap_autoconf.h>
 #include <tap_tcmsgs.h>
+#include <tap_rss.h>
 
 #ifndef HAVE_TC_FLOWER
 /*
@@ -82,12 +84,79 @@ enum {
 	TCA_FLOWER_KEY_VLAN_ETH_TYPE,   /* be16 */
 };
 #endif
+/*
+ * For kernels < 4.2 BPF related enums may not be defined.
+ * Runtime checks will be carried out to gracefully report on TC messages that
+ * are rejected by the kernel. Rejection reasons may be due to:
+ * 1. enum is not defined
+ * 2. enum is defined but kernel is not configured to support BPF system calls,
+ *    BPF classifications or BPF actions.
+ */
+#ifndef HAVE_TC_BPF
+enum {
+	TCA_BPF_UNSPEC,
+	TCA_BPF_ACT,
+	TCA_BPF_POLICE,
+	TCA_BPF_CLASSID,
+	TCA_BPF_OPS_LEN,
+	TCA_BPF_OPS,
+};
+#endif
+#ifndef HAVE_TC_BPF_FD
+enum {
+	TCA_BPF_FD = TCA_BPF_OPS + 1,
+	TCA_BPF_NAME,
+};
+#endif
+#ifndef HAVE_TC_ACT_BPF
+#define tc_gen \
+	__u32                 index; \
+	__u32                 capab; \
+	int                   action; \
+	int                   refcnt; \
+	int                   bindcnt
+
+struct tc_act_bpf {
+	tc_gen;
+};
+
+enum {
+	TCA_ACT_BPF_UNSPEC,
+	TCA_ACT_BPF_TM,
+	TCA_ACT_BPF_PARMS,
+	TCA_ACT_BPF_OPS_LEN,
+	TCA_ACT_BPF_OPS,
+};
+
+#endif
+#ifndef HAVE_TC_ACT_BPF_FD
+enum {
+	TCA_ACT_BPF_FD = TCA_ACT_BPF_OPS + 1,
+	TCA_ACT_BPF_NAME,
+};
+#endif
+
+/* RSS key management */
+enum bpf_rss_key_e {
+	KEY_CMD_GET = 1,
+	KEY_CMD_RELEASE,
+	KEY_CMD_INIT,
+	KEY_CMD_DEINIT,
+};
+
+enum key_status_e {
+	KEY_STAT_UNSPEC,
+	KEY_STAT_USED,
+	KEY_STAT_AVAILABLE,
+};
 
 #define ISOLATE_HANDLE 1
 
 struct rte_flow {
 	LIST_ENTRY(rte_flow) next; /* Pointer to the next rte_flow structure */
 	struct rte_flow *remote_flow; /* associated remote flow */
+	int bpf_fd[SEC_MAX]; /* list of bfs fds per ELF section */
+	uint32_t key_idx; /* RSS rule key index into BPF map */
 	struct nlmsg msg;
 };
 
@@ -115,6 +184,11 @@ struct action_data {
 			struct tc_skbedit skbedit;
 			uint16_t queue;
 		} skbedit;
+		struct bpf {
+			struct tc_act_bpf bpf;
+			int bpf_fd;
+			const char *annotation;
+		} bpf;
 	};
 };
 
@@ -148,6 +222,14 @@ tap_flow_isolate(struct rte_eth_dev *dev,
 		 int set,
 		 struct rte_flow_error *error);
 
+static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx);
+static int rss_enable(struct pmd_internals *pmd,
+			const struct rte_flow_attr *attr,
+			struct rte_flow_error *error);
+static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
+			const struct rte_flow_action_rss *rss,
+			struct rte_flow_error *error);
+
 static const struct rte_flow_ops tap_flow_ops = {
 	.validate = tap_flow_validate,
 	.create = tap_flow_create,
@@ -877,6 +959,14 @@ add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
 			   &adata->skbedit.skbedit);
 		tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING,
 			     adata->skbedit.queue);
+	} else if (strcmp("bpf", adata->id) == 0) {
+		tap_nlattr_add32(&msg->nh, TCA_ACT_BPF_FD, adata->bpf.bpf_fd);
+		tap_nlattr_add(&msg->nh, TCA_ACT_BPF_NAME,
+			   strlen(adata->bpf.annotation) + 1,
+			   adata->bpf.annotation);
+		tap_nlattr_add(&msg->nh, TCA_ACT_BPF_PARMS,
+			   sizeof(adata->bpf.bpf),
+			   &adata->bpf.bpf);
 	} else {
 		return -1;
 	}
@@ -979,7 +1069,8 @@ priv_flow_process(struct pmd_internals *pmd,
 		return -rte_errno;
 	} else if (flow) {
 		uint16_t group = attr->group << GROUP_SHIFT;
-		uint16_t prio = group | (attr->priority + PRIORITY_OFFSET);
+		uint16_t prio = group | (attr->priority +
+				RSS_PRIORITY_OFFSET + PRIORITY_OFFSET);
 		flow->msg.t.tcm_info = TC_H_MAKE(prio << 16,
 						 flow->msg.t.tcm_info);
 	}
@@ -1134,7 +1225,6 @@ priv_flow_process(struct pmd_internals *pmd,
 					TCA_FLOWER_ACT);
 			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
-			/* Fake RSS support. */
 			const struct rte_flow_action_rss *rss =
 				(const struct rte_flow_action_rss *)
 				actions->conf;
@@ -1142,23 +1232,13 @@ priv_flow_process(struct pmd_internals *pmd,
 			if (action++)
 				goto exit_action_not_supported;
 
-			if (!rss || rss->num < 1 ||
-			    (rss->queue[0] > pmd->dev->data->nb_rx_queues - 1))
-				goto exit_action_not_supported;
-			if (flow) {
-				struct action_data adata = {
-					.id = "skbedit",
-					.skbedit = {
-						.skbedit = {
-							.action = TC_ACT_PIPE,
-						},
-						.queue = rss->queue[0],
-					},
-				};
-
-				err = add_actions(flow, 1, &adata,
-					TCA_FLOWER_ACT);
+			if (!pmd->rss_enabled) {
+				err = rss_enable(pmd, attr, error);
+				if (err)
+					goto exit_action_not_supported;
 			}
+			if (flow && rss)
+				err = rss_add_actions(flow, pmd, rss, error);
 		} else {
 			goto exit_action_not_supported;
 		}
@@ -1370,6 +1450,7 @@ tap_flow_destroy_pmd(struct pmd_internals *pmd,
 		     struct rte_flow_error *error)
 {
 	struct rte_flow *remote_flow = flow->remote_flow;
+	int i;
 	int ret = 0;
 
 	LIST_REMOVE(flow, next);
@@ -1395,6 +1476,23 @@ tap_flow_destroy_pmd(struct pmd_internals *pmd,
 			"couldn't receive kernel ack to our request");
 		goto end;
 	}
+	/* Close opened BPF file descriptors of this flow */
+	for (i = 0; i < SEC_MAX; i++)
+		if (flow->bpf_fd[i] != 0) {
+			close(flow->bpf_fd[i]);
+			flow->bpf_fd[i] = 0;
+		}
+
+	/* Release map key for this RSS rule */
+	ret = bpf_rss_key(KEY_CMD_RELEASE, &flow->key_idx);
+	if (ret < 0) {
+		rte_flow_error_set(
+			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Failed to release BPF RSS key");
+
+		goto end;
+	}
+
 	if (remote_flow) {
 		remote_flow->msg.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
 		remote_flow->msg.nh.nlmsg_type = RTM_DELTFILTER;
@@ -1679,6 +1777,322 @@ tap_flow_implicit_flush(struct pmd_internals *pmd, struct rte_flow_error *error)
 	return 0;
 }
 
+#define MAX_RSS_KEYS 256
+#define SEC_NAME_CLS_Q "cls_q"
+
+const char *sec_name[SEC_MAX] = {
+	[SEC_L3_L4] = "l3_l4",
+};
+
+/**
+ * Enable RSS on tap: create TC rules for queuing.
+ *
+ * @param[in, out] pmd
+ *   Pointer to private structure.
+ *
+ * @param[in] attr
+ *   Pointer to rte_flow to get flow group
+ *
+ * @param[out] error
+ *   Pointer to error reporting if not NULL.
+ *
+ * @return 0 on success, negative value on failure.
+ */
+static int rss_enable(struct pmd_internals *pmd,
+			const struct rte_flow_attr *attr,
+			struct rte_flow_error *error)
+{
+	struct rte_flow *rss_flow = NULL;
+	struct nlmsg *msg = NULL;
+	/* 4096 is the maximum number of instructions for a BPF program */
+	char annotation[64];
+	int i;
+	int err = 0;
+
+	/* unlimit locked memory */
+	struct rlimit memlock_limit = {
+		.rlim_cur = RLIM_INFINITY,
+		.rlim_max = RLIM_INFINITY,
+	};
+	setrlimit(RLIMIT_MEMLOCK, &memlock_limit);
+
+	 /* Get a new map key for a new RSS rule */
+	err = bpf_rss_key(KEY_CMD_INIT, NULL);
+	if (err < 0) {
+		rte_flow_error_set(
+			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Failed to initialize BPF RSS keys");
+
+		return -1;
+	}
+
+	/*
+	 *  Create BPF RSS MAP
+	 */
+	pmd->map_fd = tap_flow_bpf_rss_map_create(sizeof(__u32), /* key size */
+				sizeof(struct rss_key),
+				MAX_RSS_KEYS);
+	if (pmd->map_fd < 0) {
+		RTE_LOG(ERR, PMD,
+			"Failed to create BPF map (%d): %s\n",
+				errno, strerror(errno));
+		rte_flow_error_set(
+			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Kernel too old or not configured "
+			"to support BPF maps");
+
+		return -ENOTSUP;
+	}
+
+	/*
+	 * Add a rule per queue to match reclassified packets and direct them to
+	 * the correct queue.
+	 */
+	for (i = 0; i < pmd->dev->data->nb_rx_queues; i++) {
+		pmd->bpf_fd[i] = tap_flow_bpf_cls_q(i);
+		if (pmd->bpf_fd[i] < 0) {
+			RTE_LOG(ERR, PMD,
+				"Failed to load BPF section %s for queue %d",
+				SEC_NAME_CLS_Q, i);
+			rte_flow_error_set(
+				error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
+				NULL,
+				"Kernel too old or not configured "
+				"to support BPF programs loading");
+
+			return -ENOTSUP;
+		}
+
+		rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
+		if (!rss_flow) {
+			RTE_LOG(ERR, PMD,
+				"Cannot allocate memory for rte_flow");
+			return -1;
+		}
+		msg = &rss_flow->msg;
+		tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER, NLM_F_REQUEST |
+			    NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE);
+		msg->t.tcm_info = TC_H_MAKE(0, htons(ETH_P_ALL));
+		tap_flow_set_handle(rss_flow);
+		uint16_t group = attr->group << GROUP_SHIFT;
+		uint16_t prio = group | (i + PRIORITY_OFFSET);
+		msg->t.tcm_info = TC_H_MAKE(prio << 16, msg->t.tcm_info);
+		msg->t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
+
+		tap_nlattr_add(&msg->nh, TCA_KIND, sizeof("bpf"), "bpf");
+		if (tap_nlattr_nested_start(msg, TCA_OPTIONS) < 0)
+			return -1;
+		tap_nlattr_add32(&msg->nh, TCA_BPF_FD, pmd->bpf_fd[i]);
+		snprintf(annotation, sizeof(annotation), "[%s%d]",
+			SEC_NAME_CLS_Q, i);
+		tap_nlattr_add(&msg->nh, TCA_BPF_NAME, strlen(annotation) + 1,
+			   annotation);
+		/* Actions */
+		{
+			struct action_data adata = {
+				.id = "skbedit",
+				.skbedit = {
+					.skbedit = {
+						.action = TC_ACT_PIPE,
+					},
+					.queue = i,
+				},
+			};
+			if (add_actions(rss_flow, 1, &adata, TCA_BPF_ACT) < 0)
+				return -1;
+		}
+		tap_nlattr_nested_finish(msg); /* nested TCA_OPTIONS */
+
+		/* Netlink message is now ready to be sent */
+		if (tap_nl_send(pmd->nlsk_fd, &msg->nh) < 0)
+			return -1;
+		err = tap_nl_recv_ack(pmd->nlsk_fd);
+		if (err < 0) {
+			RTE_LOG(ERR, PMD,
+				"Kernel refused TC filter rule creation (%d): %s\n",
+				errno, strerror(errno));
+			return err;
+		}
+		LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
+	}
+
+	pmd->rss_enabled = 1;
+	return err;
+}
+
+/**
+ * Manage bpf RSS keys repository with operations: init, get, release
+ *
+ * @param[in] cmd
+ *   Command on RSS keys: init, get, release
+ *
+ * @param[in, out] key_idx
+ *   Pointer to RSS Key index (out for get command, in for release command)
+ *
+ * @return -1 if couldn't get, release or init the RSS keys, 0 otherwise.
+ */
+static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx)
+{
+	__u32 i;
+	int err = -1;
+	static __u32 num_used_keys;
+	static __u32 rss_keys[MAX_RSS_KEYS] = {KEY_STAT_UNSPEC};
+	static __u32 rss_keys_initialized;
+
+	switch (cmd) {
+	case KEY_CMD_GET:
+		if (!rss_keys_initialized)
+			break;
+
+		if (num_used_keys == RTE_DIM(rss_keys))
+			break;
+
+		*key_idx = num_used_keys % RTE_DIM(rss_keys);
+		while (rss_keys[*key_idx] == KEY_STAT_USED)
+			*key_idx = (*key_idx + 1) % RTE_DIM(rss_keys);
+
+		rss_keys[*key_idx] = KEY_STAT_USED;
+		num_used_keys++;
+		err = 0;
+	break;
+
+	case KEY_CMD_RELEASE:
+		if (!rss_keys_initialized) {
+			err = 0;
+			break;
+		}
+
+		if (rss_keys[*key_idx] == KEY_STAT_USED) {
+			rss_keys[*key_idx] = KEY_STAT_AVAILABLE;
+			num_used_keys--;
+			err = 0;
+		}
+	break;
+
+	case KEY_CMD_INIT:
+		for (i = 0; i < RTE_DIM(rss_keys); i++)
+			rss_keys[i] = KEY_STAT_AVAILABLE;
+
+		rss_keys_initialized = 1;
+		num_used_keys = 0;
+		err = 0;
+	break;
+
+	case KEY_CMD_DEINIT:
+		for (i = 0; i < RTE_DIM(rss_keys); i++)
+			rss_keys[i] = KEY_STAT_UNSPEC;
+
+		rss_keys_initialized = 0;
+		num_used_keys = 0;
+		err = 0;
+	break;
+
+	default:
+		break;
+	}
+
+	return err;
+}
+
+/**
+ * Add RSS hash calculations and queue selection
+ *
+ * @param[in, out] pmd
+ *   Pointer to internal structure. Used to set/get RSS map fd
+ *
+ * @param[in] rss
+ *   Pointer to RSS flow actions
+ *
+ * @param[out] error
+ *   Pointer to error reporting if not NULL.
+ *
+ * @return 0 on success, negative value on failure
+ */
+static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
+			   const struct rte_flow_action_rss *rss,
+			   struct rte_flow_error *error)
+{
+	/* 4096 is the maximum number of instructions for a BPF program */
+	int i;
+	int err;
+	struct rss_key rss_entry = { .hash_fields = 0,
+				     .key_size = 0 };
+
+	/* Get a new map key for a new RSS rule */
+	err = bpf_rss_key(KEY_CMD_GET, &flow->key_idx);
+	if (err < 0) {
+		rte_flow_error_set(
+			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Failed to get BPF RSS key");
+
+		return -1;
+	}
+
+	/* Update RSS map entry with queues */
+	rss_entry.nb_queues = rss->num;
+	for (i = 0; i < rss->num; i++)
+		rss_entry.queues[i] = rss->queue[i];
+	rss_entry.hash_fields =
+		(1 << HASH_FIELD_IPV4_L3_L4) | (1 << HASH_FIELD_IPV6_L3_L4);
+
+	/* Add this RSS entry to map */
+	err = tap_flow_bpf_update_rss_elem(pmd->map_fd,
+				&flow->key_idx, &rss_entry);
+
+	if (err) {
+		RTE_LOG(ERR, PMD,
+			"Failed to update BPF map entry #%u (%d): %s\n",
+			flow->key_idx, errno, strerror(errno));
+		rte_flow_error_set(
+			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Kernel too old or not configured "
+			"to support BPF maps updates");
+
+		return -ENOTSUP;
+	}
+
+
+	/*
+	 * Load bpf rules to calculate hash for this key_idx
+	 */
+
+	flow->bpf_fd[SEC_L3_L4] =
+		tap_flow_bpf_calc_l3_l4_hash(flow->key_idx, pmd->map_fd);
+	if (flow->bpf_fd[SEC_L3_L4] < 0) {
+		RTE_LOG(ERR, PMD,
+			"Failed to load BPF section %s (%d): %s\n",
+				sec_name[SEC_L3_L4], errno, strerror(errno));
+		rte_flow_error_set(
+			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Kernel too old or not configured "
+			"to support BPF program loading");
+
+		return -ENOTSUP;
+	}
+
+	/* Actions */
+	{
+		struct action_data adata[] = {
+			{
+				.id = "bpf",
+				.bpf = {
+					.bpf_fd = flow->bpf_fd[SEC_L3_L4],
+					.annotation = sec_name[SEC_L3_L4],
+					.bpf = {
+						.action = TC_ACT_PIPE,
+					},
+				},
+			},
+		};
+
+		if (add_actions(flow, RTE_DIM(adata), adata,
+			TCA_FLOWER_ACT) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
 /**
  * Manage filter operations.
  *
diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h
index 894c959..daaf00b 100644
--- a/drivers/net/tap/tap_flow.h
+++ b/drivers/net/tap/tap_flow.h
@@ -37,6 +37,7 @@
 #include <rte_flow.h>
 #include <rte_flow_driver.h>
 #include <rte_eth_tap.h>
+#include <tap_autoconf.h>
 
 /**
  * In TC, priority 0 means we require the kernel to allocate one for us.
@@ -49,6 +50,7 @@
 #define GROUP_MASK (0xf)
 #define GROUP_SHIFT 12
 #define MAX_GROUP GROUP_MASK
+#define RSS_PRIORITY_OFFSET RTE_PMD_TAP_MAX_QUEUES
 
 /**
  * These index are actually in reversed order: their priority is processed
@@ -67,6 +69,11 @@ enum implicit_rule_index {
 	TAP_REMOTE_MAX_IDX,
 };
 
+enum bpf_fd_idx {
+	SEC_L3_L4,
+	SEC_MAX,
+};
+
 int tap_dev_filter_ctrl(struct rte_eth_dev *dev,
 			enum rte_filter_type filter_type,
 			enum rte_filter_op filter_op,
diff --git a/drivers/net/tap/tap_rss.h b/drivers/net/tap/tap_rss.h
new file mode 100644
index 0000000..3bb0d14
--- /dev/null
+++ b/drivers/net/tap/tap_rss.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#ifndef _TAP_RSS_H_
+#define _TAP_RSS_H_
+
+#ifndef TAP_MAX_QUEUES
+#define TAP_MAX_QUEUES 16
+#endif
+
+/* hashed fields for RSS */
+enum hash_field {
+	HASH_FIELD_IPV4_L3,	/* IPv4 src/dst addr */
+	HASH_FIELD_IPV4_L3_L4,	/* IPv4 src/dst addr + L4 src/dst ports */
+	HASH_FIELD_IPV6_L3,	/* IPv6 src/dst addr */
+	HASH_FIELD_IPV6_L3_L4,	/* IPv6 src/dst addr + L4 src/dst ports */
+	HASH_FIELD_L2_SRC,	/* Ethernet src addr */
+	HASH_FIELD_L2_DST,	/* Ethernet dst addr */
+	HASH_FIELD_L3_SRC,	/* L3 src addr */
+	HASH_FIELD_L3_DST,	/* L3 dst addr */
+	HASH_FIELD_L4_SRC,	/* TCP/UDP src ports */
+	HASH_FIELD_L4_DST,	/* TCP/UDP dst ports */
+};
+
+struct rss_key {
+	 __u8 key[128];
+	__u32 hash_fields;
+	__u32 key_size;
+	__u32 queues[TAP_MAX_QUEUES];
+	__u32 nb_queues;
+} __attribute__((packed));
+
+#endif /* _TAP_RSS_H_ */
diff --git a/drivers/net/tap/tap_tcmsgs.h b/drivers/net/tap/tap_tcmsgs.h
index 7895957..07c5074 100644
--- a/drivers/net/tap/tap_tcmsgs.h
+++ b/drivers/net/tap/tap_tcmsgs.h
@@ -34,6 +34,7 @@
 #ifndef _TAP_TCMSGS_H_
 #define _TAP_TCMSGS_H_
 
+#include <tap_autoconf.h>
 #include <linux/if_ether.h>
 #include <linux/rtnetlink.h>
 #include <linux/pkt_sched.h>
@@ -41,6 +42,9 @@
 #include <linux/tc_act/tc_mirred.h>
 #include <linux/tc_act/tc_gact.h>
 #include <linux/tc_act/tc_skbedit.h>
+#ifdef HAVE_TC_ACT_BPF
+#include <linux/tc_act/tc_bpf.h>
+#endif
 #include <inttypes.h>
 
 #include <rte_ether.h>
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v5 6/6] doc: detail new tap RSS feature in guides
  2018-01-18 13:38       ` [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter Ophir Munk
                           ` (4 preceding siblings ...)
  2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 5/6] net/tap: implement TAP RSS using eBPF Ophir Munk
@ 2018-01-18 13:38         ` Ophir Munk
  2018-01-19  6:48         ` [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter Pascal Mazon
  2018-01-20 21:11         ` [dpdk-dev] [PATCH v6 " Ophir Munk
  7 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-18 13:38 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 doc/guides/nics/tap.rst | 60 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/doc/guides/nics/tap.rst b/doc/guides/nics/tap.rst
index 04086b1..dc6f834 100644
--- a/doc/guides/nics/tap.rst
+++ b/doc/guides/nics/tap.rst
@@ -132,6 +132,7 @@ Supported actions:
 - DROP
 - QUEUE
 - PASSTHRU
+- RSS
 
 It is generally not possible to provide a "last" item. However, if the "last"
 item, once masked, is identical to the masked spec, then it is supported.
@@ -161,6 +162,11 @@ Drop UDP packets in vlan 3::
    testpmd> flow create 0 priority 3 ingress pattern eth / vlan vid is 3 / \
             ipv4 proto is 17 / end actions drop / end
 
+Distribute IPv4 TCP packets using RSS to a given MAC address over queues 0-3::
+
+   testpmd> flow create 0 priority 4 ingress pattern eth dst is 0a:0b:0c:0d:0e:0f \
+            / ipv4 / tcp / end actions rss queues 0 1 2 3 end / end
+
 Example
 -------
 
@@ -213,3 +219,57 @@ traffic is being looped back. You can use ``set all size XXX`` to change the
 size of the packets after you stop the traffic. Use pktgen ``help``
 command to see a list of all commands. You can also use the ``-f`` option to
 load commands at startup in command line or Lua script in pktgen.
+
+RSS specifics
+-------------
+Packet distribution in TAP is done by the kernel which has a default
+distribution. This feature is adding RSS distribution based on eBPF code.
+The default eBPF code calculates RSS hash based on Toeplitz algorithm for
+a fixed RSS key. It is calculated on fixed packet offsets. For IPv4 and IPv6 it
+is calculated over src/dst addresses (8 or 32 bytes for IPv4 or IPv6
+respectively) and src/dst TCP/UDP ports (4 bytes).
+
+The RSS algorithm is written in file ``tap_bpf_program.c`` which
+does not take part in TAP PMD compilation. Instead this file is compiled
+in advance to eBPF object file. The eBPF object file is then parsed and
+translated into eBPF byte code in the format of C arrays of eBPF
+instructions. The C array of eBPF instructions is part of TAP PMD tree and
+is taking part in TAP PMD compilation. At run time the C arrays are uploaded to
+the kernel via BPF system calls and the RSS hash is calculated by the
+kernel.
+
+It is possible to support different RSS hash algorithms by updating file
+``tap_bpf_program.c``  In order to add a new RSS hash algorithm follow these
+steps:
+
+1. Write the new RSS implementation in file ``tap_bpf_program.c``
+
+BPF programs which are uploaded to the kernel correspond to
+C functions under different ELF sections.
+
+2. Install ``LLVM`` library and ``clang`` compiler versions 3.7 and above
+
+3. Compile ``tap_bpf_program.c`` via ``LLVM`` into an object file::
+
+    clang -O2 -emit-llvm -c tap_bpf_program.c -o - | llc -march=bpf \
+    -filetype=obj -o <tap_bpf_program.o>
+
+
+4. Use a tool that receives two parameters: an eBPF object file and a section
+name, and prints out the section as a C array of eBPF instructions.
+Embed the C array in your TAP PMD tree.
+
+The C arrays are uploaded to the kernel using BPF system calls.
+
+``tc`` (traffic control) is a well known user space utility program used to
+configure the Linux kernel packet scheduler. It is usually packaged as
+part of the ``iproute2`` package.
+Since commit 11c39b5e9 ("tc: add eBPF support to f_bpf") ``tc`` can be used
+to uploads eBPF code to the kernel and can be patched in order to print the
+C arrays of eBPF instructions just before calling the BPF system call.
+Please refer to ``iproute2`` package file ``lib/bpf.c`` function
+``bpf_prog_load()``.
+
+An example utility for eBPF instruction generation in the format of C arrays will
+be added in next releases
+
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter
  2018-01-18 13:38       ` [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter Ophir Munk
                           ` (5 preceding siblings ...)
  2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 6/6] doc: detail new tap RSS feature in guides Ophir Munk
@ 2018-01-19  6:48         ` Pascal Mazon
  2018-01-20 16:15           ` Ferruh Yigit
  2018-01-20 21:11         ` [dpdk-dev] [PATCH v6 " Ophir Munk
  7 siblings, 1 reply; 42+ messages in thread
From: Pascal Mazon @ 2018-01-19  6:48 UTC (permalink / raw)
  To: Ophir Munk, dev; +Cc: Thomas Monjalon, Olga Shern

Hi,

It seems more logical to me to introduce tap_program (patch 3) before
its compiled version (patch 2).
Source code is indeed written down before compiling it.

The doc section is a good addition.
I'll be happy to see the upcoming utility for turning eBPF bytecode to C
arrays.
I'd have liked to see automation code (in a not-executed Makefile target
typically) for generating the bytecode.
I'm being told it should happen in the upcoming series along with the
aforementioned utility.

Otherwise code looks good enough (I couldn't see everything for lack of
time), considering that later patches are expected in next release.

Acked-by: Pascal Mazon <pascal.mazon@6wind.com>

Best regards,
Pascal

On 18/01/2018 14:38, Ophir Munk wrote:
> The patches of TAP RSS eBPF follow the RFC on this issue
> https://dpdk.org/dev/patchwork/patch/31781/
>
> v5 changes with respect to v4
> =============================
> Update TAP document guide with RSS
>
> v4 changes with respect to v3
> =============================
> * Code updates based on review comments
> * New commits organization (2-->5) based on review comments
>   1. net/tap: support actions for different classifiers (preparations for BPF. 
>      No BPF code yet)
>   2. net/tap: add eBPF bytes code (BPF bytes code in a separate file)
>   3. net/tap: add eBPF program file (Program source code of bytes code)
>   4. net/tap: add eBPF API (BPF API to be used by TAP)
>   5. net/tap: implement TAP RSS using eBPF
>
> v3 changes with respect to v2
> =============================
> * Add support for IPv6 RSS in BPF program
> * Bug fixes
> * Updated compatibility to kernel versions:
>   eBPF requires Linux version 4.9 configured with BPF
> * New license header (SPDX) for newly added files
>
> v2 changes with respect to v1
> =============================
> * v2 has new commits organization (3 --> 2)
> * BPF program was revised. It is successfully tested on
>   IPv4 L3 L4 layers (compatible to mlx4 device)
> * Licensing: no comments received for using "Dual BSD/GPL"
>   string during BPF program loading to the kernel.
>   (v1 and v2 are using the same license strings)
>   Any comments are welcome.
> * Compatibility to kernel versions:
>   eBPF requires Linux version 4.2 configured with BPF. TAP PMD will
>   successfully compile on systems with old or non-BPF configured kernels.
>   During compilation time the required Linux headers are searched for.
>   If they are not present missing definitions are locally added
>   (tap_autoconf.h).
>   If the kernel cannot support a BPF operation - at runtime it will
>   gracefully reject the netlink message (with BPF) sent to it.
>
> Ophir Munk (6):
>   net/tap: support actions for different classifiers
>   net/tap: add eBPF bytes code
>   net/tap: add eBPF program file
>   net/tap: add eBPF API
>   net/tap: implement TAP RSS using eBPF
>   doc: detail new tap RSS feature in guides
>
>  doc/guides/nics/tap.rst           |   60 ++
>  drivers/net/tap/Makefile          |   34 +
>  drivers/net/tap/rte_eth_tap.h     |    9 +-
>  drivers/net/tap/tap_bpf.h         |  112 +++
>  drivers/net/tap/tap_bpf_api.c     |  190 +++++
>  drivers/net/tap/tap_bpf_insns.h   | 1693 +++++++++++++++++++++++++++++++++++++
>  drivers/net/tap/tap_bpf_program.c |  221 +++++
>  drivers/net/tap/tap_flow.c        |  648 +++++++++++---
>  drivers/net/tap/tap_flow.h        |   13 +
>  drivers/net/tap/tap_rss.h         |   34 +
>  drivers/net/tap/tap_tcmsgs.h      |    4 +
>  11 files changed, 2922 insertions(+), 96 deletions(-)
>  create mode 100644 drivers/net/tap/tap_bpf.h
>  create mode 100644 drivers/net/tap/tap_bpf_api.c
>  create mode 100644 drivers/net/tap/tap_bpf_insns.h
>  create mode 100644 drivers/net/tap/tap_bpf_program.c
>  create mode 100644 drivers/net/tap/tap_rss.h
>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter
  2018-01-19  6:48         ` [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter Pascal Mazon
@ 2018-01-20 16:15           ` Ferruh Yigit
  2018-01-20 21:25             ` Ophir Munk
  0 siblings, 1 reply; 42+ messages in thread
From: Ferruh Yigit @ 2018-01-20 16:15 UTC (permalink / raw)
  To: Pascal Mazon, Ophir Munk, dev; +Cc: Thomas Monjalon, Olga Shern

On 1/19/2018 6:48 AM, Pascal Mazon wrote:
> Hi,
> 
> It seems more logical to me to introduce tap_program (patch 3) before
> its compiled version (patch 2).
> Source code is indeed written down before compiling it.
> 
> The doc section is a good addition.
> I'll be happy to see the upcoming utility for turning eBPF bytecode to C
> arrays.
> I'd have liked to see automation code (in a not-executed Makefile target
> typically) for generating the bytecode.
> I'm being told it should happen in the upcoming series along with the
> aforementioned utility.
> 
> Otherwise code looks good enough (I couldn't see everything for lack of
> time), considering that later patches are expected in next release.
> 
> Acked-by: Pascal Mazon <pascal.mazon@6wind.com>
> 
> Best regards,
> Pascal
> 
> On 18/01/2018 14:38, Ophir Munk wrote:
>> The patches of TAP RSS eBPF follow the RFC on this issue
>> https://dpdk.org/dev/patchwork/patch/31781/
>>
>> v5 changes with respect to v4
>> =============================
>> Update TAP document guide with RSS
>>
>> v4 changes with respect to v3
>> =============================
>> * Code updates based on review comments
>> * New commits organization (2-->5) based on review comments
>>   1. net/tap: support actions for different classifiers (preparations for BPF. 
>>      No BPF code yet)
>>   2. net/tap: add eBPF bytes code (BPF bytes code in a separate file)
>>   3. net/tap: add eBPF program file (Program source code of bytes code)
>>   4. net/tap: add eBPF API (BPF API to be used by TAP)
>>   5. net/tap: implement TAP RSS using eBPF
>>
>> v3 changes with respect to v2
>> =============================
>> * Add support for IPv6 RSS in BPF program
>> * Bug fixes
>> * Updated compatibility to kernel versions:
>>   eBPF requires Linux version 4.9 configured with BPF
>> * New license header (SPDX) for newly added files
>>
>> v2 changes with respect to v1
>> =============================
>> * v2 has new commits organization (3 --> 2)
>> * BPF program was revised. It is successfully tested on
>>   IPv4 L3 L4 layers (compatible to mlx4 device)
>> * Licensing: no comments received for using "Dual BSD/GPL"
>>   string during BPF program loading to the kernel.
>>   (v1 and v2 are using the same license strings)
>>   Any comments are welcome.
>> * Compatibility to kernel versions:
>>   eBPF requires Linux version 4.2 configured with BPF. TAP PMD will
>>   successfully compile on systems with old or non-BPF configured kernels.
>>   During compilation time the required Linux headers are searched for.
>>   If they are not present missing definitions are locally added
>>   (tap_autoconf.h).
>>   If the kernel cannot support a BPF operation - at runtime it will
>>   gracefully reject the netlink message (with BPF) sent to it.
>>
>> Ophir Munk (6):
>>   net/tap: support actions for different classifiers
>>   net/tap: add eBPF bytes code
>>   net/tap: add eBPF program file
>>   net/tap: add eBPF API
>>   net/tap: implement TAP RSS using eBPF
>>   doc: detail new tap RSS feature in guides

Series applied to dpdk-next-net/master, thanks.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v6 0/6] TAP RSS eBPF cover letter
  2018-01-18 13:38       ` [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter Ophir Munk
                           ` (6 preceding siblings ...)
  2018-01-19  6:48         ` [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter Pascal Mazon
@ 2018-01-20 21:11         ` Ophir Munk
  2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 1/6] net/tap: support actions for different classifiers Ophir Munk
                             ` (6 more replies)
  7 siblings, 7 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-20 21:11 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

The patches of TAP RSS eBPF follow the RFC on this issue
https://dpdk.org/dev/patchwork/patch/31781/

v6 changes with respect to v5
=============================
1. Reorder thes following commits (source file commit before byte code commit)
  net/tap: add eBPF program file
  net/tap: add eBPF bytes code
2. Add acknowledgment to commits 

v5 changes with respect to v4
=============================
Update TAP document guide with RSS

v4 changes with respect to v3
=============================
* Code updates based on review comments
* New commits organization (2-->5) based on review comments
  1. net/tap: support actions for different classifiers (preparations for BPF. 
     No BPF code yet)
  2. net/tap: add eBPF bytes code (BPF bytes code in a separate file)
  3. net/tap: add eBPF program file (Program source code of bytes code)
  4. net/tap: add eBPF API (BPF API to be used by TAP)
  5. net/tap: implement TAP RSS using eBPF

v3 changes with respect to v2
=============================
* Add support for IPv6 RSS in BPF program
* Bug fixes
* Updated compatibility to kernel versions:
  eBPF requires Linux version 4.9 configured with BPF
* New license header (SPDX) for newly added files

v2 changes with respect to v1
=============================
* v2 has new commits organization (3 --> 2)
* BPF program was revised. It is successfully tested on
  IPv4 L3 L4 layers (compatible to mlx4 device)
* Licensing: no comments received for using "Dual BSD/GPL"
  string during BPF program loading to the kernel.
  (v1 and v2 are using the same license strings)
  Any comments are welcome.
* Compatibility to kernel versions:
  eBPF requires Linux version 4.2 configured with BPF. TAP PMD will
  successfully compile on systems with old or non-BPF configured kernels.
  During compilation time the required Linux headers are searched for.
  If they are not present missing definitions are locally added
  (tap_autoconf.h).
  If the kernel cannot support a BPF operation - at runtime it will
  gracefully reject the netlink message (with BPF) sent to it.
Ophir Munk (6):
  net/tap: support actions for different classifiers
  net/tap: add eBPF program file
  net/tap: add eBPF bytes code
  net/tap: add eBPF API
  net/tap: implement TAP RSS using eBPF
  doc: detail new tap RSS feature in guides

 doc/guides/nics/tap.rst           |   60 ++
 drivers/net/tap/Makefile          |   34 +
 drivers/net/tap/rte_eth_tap.h     |    9 +-
 drivers/net/tap/tap_bpf.h         |  112 +++
 drivers/net/tap/tap_bpf_api.c     |  190 +++++
 drivers/net/tap/tap_bpf_insns.h   | 1693 +++++++++++++++++++++++++++++++++++++
 drivers/net/tap/tap_bpf_program.c |  221 +++++
 drivers/net/tap/tap_flow.c        |  648 +++++++++++---
 drivers/net/tap/tap_flow.h        |   13 +
 drivers/net/tap/tap_rss.h         |   34 +
 drivers/net/tap/tap_tcmsgs.h      |    4 +
 11 files changed, 2922 insertions(+), 96 deletions(-)
 create mode 100644 drivers/net/tap/tap_bpf.h
 create mode 100644 drivers/net/tap/tap_bpf_api.c
 create mode 100644 drivers/net/tap/tap_bpf_insns.h
 create mode 100644 drivers/net/tap/tap_bpf_program.c
 create mode 100644 drivers/net/tap/tap_rss.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v6 1/6] net/tap: support actions for different classifiers
  2018-01-20 21:11         ` [dpdk-dev] [PATCH v6 " Ophir Munk
@ 2018-01-20 21:11           ` Ophir Munk
  2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 2/6] net/tap: add eBPF program file Ophir Munk
                             ` (5 subsequent siblings)
  6 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-20 21:11 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

Add a generic TC actions handling for TC actions: "mirred",
"gact", "skbedit". This will be useful when introducing
BPF actions, as it uses TCA_BPF_ACT instead of TCA_FLOWER_ACT

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
Acked-by: Pascal Mazon <pascal.mazon@6wind.com>
---
 drivers/net/tap/Makefile      |   8 ++
 drivers/net/tap/rte_eth_tap.h |   4 +-
 drivers/net/tap/tap_flow.c    | 224 +++++++++++++++++++++++++-----------------
 3 files changed, 145 insertions(+), 91 deletions(-)

diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index fd4195f..fbf84e1 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -12,6 +12,12 @@ EXPORT_MAP := rte_pmd_tap_version.map
 
 LIBABIVER := 1
 
+#
+# TAP_MAX_QUEUES must be a power of 2
+#
+ifeq ($(TAP_MAX_QUEUES),)
+	TAP_MAX_QUEUES = 16
+endif
 CFLAGS += -O3
 CFLAGS += -I$(SRCDIR)
 CFLAGS += -I.
@@ -20,6 +26,8 @@ LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
 LDLIBS += -lrte_bus_vdev
 
+CFLAGS += -DTAP_MAX_QUEUES=$(TAP_MAX_QUEUES)
+
 #
 # all source are stored in SRCS-y
 #
diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
index 829f32f..202b3cd 100644
--- a/drivers/net/tap/rte_eth_tap.h
+++ b/drivers/net/tap/rte_eth_tap.h
@@ -45,7 +45,7 @@
 #include <rte_ether.h>
 
 #ifdef IFF_MULTI_QUEUE
-#define RTE_PMD_TAP_MAX_QUEUES	16
+#define RTE_PMD_TAP_MAX_QUEUES	TAP_MAX_QUEUES
 #else
 #define RTE_PMD_TAP_MAX_QUEUES	1
 #endif
@@ -90,6 +90,8 @@ struct pmd_internals {
 	int ioctl_sock;                   /* socket for ioctl calls */
 	int nlsk_fd;                      /* Netlink socket fd */
 	int flow_isolate;                 /* 1 if flow isolation is enabled */
+	int flower_support;               /* 1 if kernel supports, else 0 */
+	int flower_vlan_support;          /* 1 if kernel supports, else 0 */
 	LIST_HEAD(tap_flows, rte_flow) flows;        /* rte_flow rules */
 	/* implicit rte_flow rules set when a remote device is active */
 	LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows;
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index 90b2654..d2a69a7 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -33,6 +33,7 @@
 
 #include <errno.h>
 #include <string.h>
+#include <unistd.h>
 #include <sys/queue.h>
 
 #include <rte_byteorder.h>
@@ -104,6 +105,19 @@ struct remote_rule {
 	int mirred;
 };
 
+struct action_data {
+	char id[16];
+
+	union {
+		struct tc_gact gact;
+		struct tc_mirred mirred;
+		struct skbedit {
+			struct tc_skbedit skbedit;
+			uint16_t queue;
+		} skbedit;
+	};
+};
+
 static int tap_flow_create_eth(const struct rte_flow_item *item, void *data);
 static int tap_flow_create_vlan(const struct rte_flow_item *item, void *data);
 static int tap_flow_create_ipv4(const struct rte_flow_item *item, void *data);
@@ -819,111 +833,89 @@ tap_flow_item_validate(const struct rte_flow_item *item,
 }
 
 /**
- * Transform a DROP/PASSTHRU action item in the provided flow for TC.
+ * Configure the kernel with a TC action and its configured parameters
+ * Handled actions: "gact", "mirred", "skbedit", "bpf"
  *
- * @param[in, out] flow
- *   Flow to be filled.
- * @param[in] action
- *   Appropriate action to be set in the TCA_GACT_PARMS structure.
+ * @param[in] flow
+ *   Pointer to rte flow containing the netlink message
  *
- * @return
- *   0 if checks are alright, -1 otherwise.
- */
-static int
-add_action_gact(struct rte_flow *flow, int action)
-{
-	struct nlmsg *msg = &flow->msg;
-	size_t act_index = 1;
-	struct tc_gact p = {
-		.action = action
-	};
-
-	if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
-		return -1;
-	if (tap_nlattr_nested_start(msg, act_index++) < 0)
-		return -1;
-	tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("gact"), "gact");
-	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
-		return -1;
-	tap_nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(p), &p);
-	tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
-	tap_nlattr_nested_finish(msg); /* nested act_index */
-	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
-	return 0;
-}
-
-/**
- * Transform a MIRRED action item in the provided flow for TC.
+ * @param[in, out] act_index
+ *   Pointer to action sequence number in the TC command
  *
- * @param[in, out] flow
- *   Flow to be filled.
- * @param[in] ifindex
- *   Netdevice ifindex, where to mirror/redirect packet to.
- * @param[in] action_type
- *   Either TCA_EGRESS_REDIR for redirection or TCA_EGRESS_MIRROR for mirroring.
+ * @param[in] adata
+ *  Pointer to struct holding the action parameters
  *
  * @return
- *   0 if checks are alright, -1 otherwise.
+ *   -1 on failure, 0 on success
  */
 static int
-add_action_mirred(struct rte_flow *flow, uint16_t ifindex, uint16_t action_type)
+add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
 {
 	struct nlmsg *msg = &flow->msg;
-	size_t act_index = 1;
-	struct tc_mirred p = {
-		.eaction = action_type,
-		.ifindex = ifindex,
-	};
 
-	if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
-		return -1;
-	if (tap_nlattr_nested_start(msg, act_index++) < 0)
+	if (tap_nlattr_nested_start(msg, (*act_index)++) < 0)
 		return -1;
-	tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("mirred"), "mirred");
+
+	tap_nlattr_add(&msg->nh, TCA_ACT_KIND,
+				strlen(adata->id) + 1, adata->id);
 	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
 		return -1;
-	if (action_type == TCA_EGRESS_MIRROR)
-		p.action = TC_ACT_PIPE;
-	else /* REDIRECT */
-		p.action = TC_ACT_STOLEN;
-	tap_nlattr_add(&msg->nh, TCA_MIRRED_PARMS, sizeof(p), &p);
+	if (strcmp("gact", adata->id) == 0) {
+		tap_nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(adata->gact),
+			   &adata->gact);
+	} else if (strcmp("mirred", adata->id) == 0) {
+		if (adata->mirred.eaction == TCA_EGRESS_MIRROR)
+			adata->mirred.action = TC_ACT_PIPE;
+		else /* REDIRECT */
+			adata->mirred.action = TC_ACT_STOLEN;
+		tap_nlattr_add(&msg->nh, TCA_MIRRED_PARMS,
+			   sizeof(adata->mirred),
+			   &adata->mirred);
+	} else if (strcmp("skbedit", adata->id) == 0) {
+		tap_nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS,
+			   sizeof(adata->skbedit.skbedit),
+			   &adata->skbedit.skbedit);
+		tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING,
+			     adata->skbedit.queue);
+	} else {
+		return -1;
+	}
 	tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
 	tap_nlattr_nested_finish(msg); /* nested act_index */
-	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
 	return 0;
 }
 
 /**
- * Transform a QUEUE action item in the provided flow for TC.
+ * Helper function to send a serie of TC actions to the kernel
  *
- * @param[in, out] flow
- *   Flow to be filled.
- * @param[in] queue
- *   Queue id to use.
+ * @param[in] flow
+ *   Pointer to rte flow containing the netlink message
+ *
+ * @param[in] nb_actions
+ *   Number of actions in an array of action structs
+ *
+ * @param[in] data
+ *   Pointer to an array of action structs
+ *
+ * @param[in] classifier_actions
+ *   The classifier on behave of which the actions are configured
  *
  * @return
- *   0 if checks are alright, -1 otherwise.
+ *   -1 on failure, 0 on success
  */
 static int
-add_action_skbedit(struct rte_flow *flow, uint16_t queue)
+add_actions(struct rte_flow *flow, int nb_actions, struct action_data *data,
+	    int classifier_action)
 {
 	struct nlmsg *msg = &flow->msg;
 	size_t act_index = 1;
-	struct tc_skbedit p = {
-		.action = TC_ACT_PIPE
-	};
+	int i;
 
-	if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
-		return -1;
-	if (tap_nlattr_nested_start(msg, act_index++) < 0)
+	if (tap_nlattr_nested_start(msg, classifier_action) < 0)
 		return -1;
-	tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("skbedit"), "skbedit");
-	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
-		return -1;
-	tap_nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS, sizeof(p), &p);
-	tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING, queue);
-	tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
-	tap_nlattr_nested_finish(msg); /* nested act_index */
+	for (i = 0; i < nb_actions; i++)
+		if (add_action(flow, &act_index, data + i) < 0)
+			return -1;
 	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
 	return 0;
 }
@@ -1056,7 +1048,12 @@ priv_flow_process(struct pmd_internals *pmd,
 		}
 	}
 	if (mirred && flow) {
-		uint16_t if_index = pmd->if_index;
+		struct action_data adata = {
+			.id = "mirred",
+			.mirred = {
+				.eaction = mirred,
+			},
+		};
 
 		/*
 		 * If attr->egress && mirred, then this is a special
@@ -1064,9 +1061,13 @@ priv_flow_process(struct pmd_internals *pmd,
 		 * redirect packets coming from the DPDK App, out
 		 * through the remote netdevice.
 		 */
-		if (attr->egress)
-			if_index = pmd->remote_if_index;
-		if (add_action_mirred(flow, if_index, mirred) < 0)
+		adata.mirred.ifindex = attr->ingress ? pmd->if_index :
+			pmd->remote_if_index;
+		if (mirred == TCA_EGRESS_MIRROR)
+			adata.mirred.action = TC_ACT_PIPE;
+		else
+			adata.mirred.action = TC_ACT_STOLEN;
+		if (add_actions(flow, 1, &adata, TCA_FLOWER_ACT) < 0)
 			goto exit_action_not_supported;
 		else
 			goto end;
@@ -1080,14 +1081,33 @@ priv_flow_process(struct pmd_internals *pmd,
 			if (action)
 				goto exit_action_not_supported;
 			action = 1;
-			if (flow)
-				err = add_action_gact(flow, TC_ACT_SHOT);
+			if (flow) {
+				struct action_data adata = {
+					.id = "gact",
+					.gact = {
+						.action = TC_ACT_SHOT,
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+						  TCA_FLOWER_ACT);
+			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_PASSTHRU) {
 			if (action)
 				goto exit_action_not_supported;
 			action = 1;
-			if (flow)
-				err = add_action_gact(flow, TC_ACT_UNSPEC);
+			if (flow) {
+				struct action_data adata = {
+					.id = "gact",
+					.gact = {
+						/* continue */
+						.action = TC_ACT_UNSPEC,
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+						  TCA_FLOWER_ACT);
+			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
 			const struct rte_flow_action_queue *queue =
 				(const struct rte_flow_action_queue *)
@@ -1099,22 +1119,46 @@ priv_flow_process(struct pmd_internals *pmd,
 			if (!queue ||
 			    (queue->index > pmd->dev->data->nb_rx_queues - 1))
 				goto exit_action_not_supported;
-			if (flow)
-				err = add_action_skbedit(flow, queue->index);
+			if (flow) {
+				struct action_data adata = {
+					.id = "skbedit",
+					.skbedit = {
+						.skbedit = {
+							.action = TC_ACT_PIPE,
+						},
+						.queue = queue->index,
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+					TCA_FLOWER_ACT);
+			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
 			/* Fake RSS support. */
 			const struct rte_flow_action_rss *rss =
 				(const struct rte_flow_action_rss *)
 				actions->conf;
 
-			if (action)
+			if (action++)
 				goto exit_action_not_supported;
-			action = 1;
+
 			if (!rss || rss->num < 1 ||
 			    (rss->queue[0] > pmd->dev->data->nb_rx_queues - 1))
 				goto exit_action_not_supported;
-			if (flow)
-				err = add_action_skbedit(flow, rss->queue[0]);
+			if (flow) {
+				struct action_data adata = {
+					.id = "skbedit",
+					.skbedit = {
+						.skbedit = {
+							.action = TC_ACT_PIPE,
+						},
+						.queue = rss->queue[0],
+					},
+				};
+
+				err = add_actions(flow, 1, &adata,
+					TCA_FLOWER_ACT);
+			}
 		} else {
 			goto exit_action_not_supported;
 		}
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v6 2/6] net/tap: add eBPF program file
  2018-01-20 21:11         ` [dpdk-dev] [PATCH v6 " Ophir Munk
  2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 1/6] net/tap: support actions for different classifiers Ophir Munk
@ 2018-01-20 21:11           ` Ophir Munk
  2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 3/6] net/tap: add eBPF bytes code Ophir Munk
                             ` (4 subsequent siblings)
  6 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-20 21:11 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

File tap_bpf_program.c was added with two ELF sections
corresponding to two BPF programs and one BPF map.

Section cls_q - BPF classifier to classify packets to their
corresponding queue after an RSS hash was calculated on the packet
and saved in skb->cb[1]
Section l3_l4 - BPF action to calculate RSS hash on packet
layers 3 and 4
This file is not part of DPDK tree compilation.

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
Acked-by: Pascal Mazon <pascal.mazon@6wind.com>
---
 drivers/net/tap/tap_bpf_program.c | 221 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 221 insertions(+)
 create mode 100644 drivers/net/tap/tap_bpf_program.c

diff --git a/drivers/net/tap/tap_bpf_program.c b/drivers/net/tap/tap_bpf_program.c
new file mode 100644
index 0000000..848c50b
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_program.c
@@ -0,0 +1,221 @@
+/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <asm/types.h>
+#include <linux/in.h>
+#include <linux/if.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/if_tunnel.h>
+#include <linux/filter.h>
+#include <linux/bpf.h>
+
+#include "tap_rss.h"
+
+/** Create IPv4 address */
+#define IPv4(a, b, c, d) ((__u32)(((a) & 0xff) << 24) | \
+		(((b) & 0xff) << 16) | \
+		(((c) & 0xff) << 8)  | \
+		((d) & 0xff))
+
+#define PORT(a, b) ((__u16)(((a) & 0xff) << 8) | \
+		((b) & 0xff))
+
+/*
+ * The queue number is offset by 1, to distinguish packets that have
+ * gone through this rule (skb->cb[1] != 0) from others.
+ */
+#define QUEUE_OFFSET		1
+#define PIN_GLOBAL_NS		2
+
+#define KEY_IDX			0
+#define BPF_MAP_ID_KEY	1
+
+struct vlan_hdr {
+	__be16 proto;
+	__be16 tci;
+};
+
+struct bpf_elf_map __attribute__((section("maps"), used))
+map_keys = {
+	.type           =       BPF_MAP_TYPE_HASH,
+	.id             =       BPF_MAP_ID_KEY,
+	.size_key       =       sizeof(__u32),
+	.size_value     =       sizeof(struct rss_key),
+	.max_elem       =       256,
+	.pinning        =       PIN_GLOBAL_NS,
+};
+
+__section("cls_q") int
+match_q(struct __sk_buff *skb)
+{
+	__u32 queue = skb->cb[1];
+	volatile __u32 q = 0xdeadbeef;
+	__u32 match_queue = QUEUE_OFFSET + q;
+
+	/* printt("match_q$i() queue = %d\n", queue); */
+
+	if (queue != match_queue)
+		return TC_ACT_OK;
+	return TC_ACT_UNSPEC;
+}
+
+
+struct ipv4_l3_l4_tuple {
+	__u32    src_addr;
+	__u32    dst_addr;
+	__u16    dport;
+	__u16    sport;
+} __attribute__((packed));
+
+struct ipv6_l3_l4_tuple {
+	__u8        src_addr[16];
+	__u8        dst_addr[16];
+	__u16       dport;
+	__u16       sport;
+} __attribute__((packed));
+
+static const __u8 def_rss_key[] = {
+	0xd1, 0x81, 0xc6, 0x2c,
+	0xf7, 0xf4, 0xdb, 0x5b,
+	0x19, 0x83, 0xa2, 0xfc,
+	0x94, 0x3e, 0x1a, 0xdb,
+	0xd9, 0x38, 0x9e, 0x6b,
+	0xd1, 0x03, 0x9c, 0x2c,
+	0xa7, 0x44, 0x99, 0xad,
+	0x59, 0x3d, 0x56, 0xd9,
+	0xf3, 0x25, 0x3c, 0x06,
+	0x2a, 0xdc, 0x1f, 0xfc,
+};
+
+static __u32  __attribute__((always_inline))
+rte_softrss_be(const __u32 *input_tuple, const uint8_t *rss_key,
+		__u8 input_len)
+{
+	__u32 i, j, hash = 0;
+#pragma unroll
+	for (j = 0; j < input_len; j++) {
+#pragma unroll
+		for (i = 0; i < 32; i++) {
+			if (input_tuple[j] & (1 << (31 - i))) {
+				hash ^= ((const __u32 *)def_rss_key)[j] << i |
+				(__u32)((uint64_t)
+				(((const __u32 *)def_rss_key)[j + 1])
+					>> (32 - i));
+			}
+		}
+	}
+	return hash;
+}
+
+static int __attribute__((always_inline))
+rss_l3_l4(struct __sk_buff *skb)
+{
+	void *data_end = (void *)(long)skb->data_end;
+	void *data = (void *)(long)skb->data;
+	__u16 proto = (__u16)skb->protocol;
+	__u32 key_idx = 0xdeadbeef;
+	__u32 hash;
+	struct rss_key *rsskey;
+	__u64 off = ETH_HLEN;
+	int j;
+	__u8 *key = 0;
+	__u32 len;
+	__u32 queue = 0;
+
+	rsskey = map_lookup_elem(&map_keys, &key_idx);
+	if (!rsskey) {
+		printt("hash(): rss key is not configured\n");
+		return TC_ACT_OK;
+	}
+	key = (__u8 *)rsskey->key;
+
+	/* Get correct proto for 802.1ad */
+	if (skb->vlan_present && skb->vlan_proto == htons(ETH_P_8021AD)) {
+		if (data + ETH_ALEN * 2 + sizeof(struct vlan_hdr) +
+		    sizeof(proto) > data_end)
+			return TC_ACT_OK;
+		proto = *(__u16 *)(data + ETH_ALEN * 2 +
+				   sizeof(struct vlan_hdr));
+		off += sizeof(struct vlan_hdr);
+	}
+
+	if (proto == htons(ETH_P_IP)) {
+		if (data + off + sizeof(struct iphdr) + sizeof(__u32)
+			> data_end)
+			return TC_ACT_OK;
+
+		__u8 *src_dst_addr = data + off + offsetof(struct iphdr, saddr);
+		__u8 *src_dst_port = data + off + sizeof(struct iphdr);
+		struct ipv4_l3_l4_tuple v4_tuple = {
+			.src_addr = IPv4(*(src_dst_addr + 0),
+					*(src_dst_addr + 1),
+					*(src_dst_addr + 2),
+					*(src_dst_addr + 3)),
+			.dst_addr = IPv4(*(src_dst_addr + 4),
+					*(src_dst_addr + 5),
+					*(src_dst_addr + 6),
+					*(src_dst_addr + 7)),
+			.sport = PORT(*(src_dst_port + 0),
+					*(src_dst_port + 1)),
+			.dport = PORT(*(src_dst_port + 2),
+					*(src_dst_port + 3)),
+		};
+		__u8 input_len = sizeof(v4_tuple) / sizeof(__u32);
+		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV4_L3))
+			input_len--;
+		hash = rte_softrss_be((__u32 *)&v4_tuple, key, 3);
+	} else if (proto == htons(ETH_P_IPV6)) {
+		if (data + off + sizeof(struct ipv6hdr) +
+					sizeof(__u32) > data_end)
+			return TC_ACT_OK;
+		__u8 *src_dst_addr = data + off +
+					offsetof(struct ipv6hdr, saddr);
+		__u8 *src_dst_port = data + off +
+					sizeof(struct ipv6hdr);
+		struct ipv6_l3_l4_tuple v6_tuple;
+		for (j = 0; j < 4; j++)
+			*((uint32_t *)&v6_tuple.src_addr + j) =
+				__builtin_bswap32(*((uint32_t *)
+						src_dst_addr + j));
+		for (j = 0; j < 4; j++)
+			*((uint32_t *)&v6_tuple.dst_addr + j) =
+				__builtin_bswap32(*((uint32_t *)
+						src_dst_addr + 4 + j));
+		v6_tuple.sport = PORT(*(src_dst_port + 0),
+			      *(src_dst_port + 1));
+		v6_tuple.dport = PORT(*(src_dst_port + 2),
+			      *(src_dst_port + 3));
+
+		__u8 input_len = sizeof(v6_tuple) / sizeof(__u32);
+		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV6_L3))
+			input_len--;
+		hash = rte_softrss_be((__u32 *)&v6_tuple, key, 9);
+	} else {
+		return TC_ACT_PIPE;
+	}
+
+	queue = rsskey->queues[(hash % rsskey->nb_queues) &
+				       (TAP_MAX_QUEUES - 1)];
+	skb->cb[1] = QUEUE_OFFSET + queue;
+	/* printt(">>>>> rss_l3_l4 hash=0x%x queue=%u\n", hash, queue); */
+
+	return TC_ACT_RECLASSIFY;
+}
+
+#define RSS(L)						\
+	__section(#L) int				\
+		L ## _hash(struct __sk_buff *skb)	\
+	{						\
+		return rss_ ## L (skb);			\
+	}
+
+RSS(l3_l4)
+
+BPF_LICENSE("Dual BSD/GPL");
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v6 3/6] net/tap: add eBPF bytes code
  2018-01-20 21:11         ` [dpdk-dev] [PATCH v6 " Ophir Munk
  2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 1/6] net/tap: support actions for different classifiers Ophir Munk
  2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 2/6] net/tap: add eBPF program file Ophir Munk
@ 2018-01-20 21:11           ` Ophir Munk
  2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 4/6] net/tap: add eBPF API Ophir Munk
                             ` (3 subsequent siblings)
  6 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-20 21:11 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

File tap_bpf_insns.h was added. It includes  eBPF bytes code
which corresponds to source file tap_bpf_program.c
(see "net/tap: add eBPF program file").
The bytes code is in the format of C arrays of struct bpf_insn and
was generated from the C file tap_bpf_program.c
1. The C file was compiled via LLVM into an object file in ELF
format as:
   clang -O2 -emit-llvm -c tap_bpf_program.c -o - | llc -march=bpf \
   -filetype=obj -o <tap_bpf_program.o>

clang version must be 3.7 and above
The C functions are under different ELF sections and are considered
different BPF programs to be downloaded to the kernel

2. Using an external tool the ELF sections are parsed and the C arrays
of struct bpf_insn are generated. Each C array (corresponding to a
different function under an ELF section) is downloaded to the kernel
using an BPF systm call. The external tool that generates the C arrays
will be added in separate commits.

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
Acked-by: Pascal Mazon <pascal.mazon@6wind.com>
---
 drivers/net/tap/tap_bpf_insns.h | 1693 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 1693 insertions(+)
 create mode 100644 drivers/net/tap/tap_bpf_insns.h

diff --git a/drivers/net/tap/tap_bpf_insns.h b/drivers/net/tap/tap_bpf_insns.h
new file mode 100644
index 0000000..c406f78
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_insns.h
@@ -0,0 +1,1693 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#include <tap_bpf.h>
+
+/* bpf_insn array matching cls_q section. See tap_bpf_program.c file */
+struct bpf_insn cls_q_insns[] = {
+	{0x61,    1,    1,       52, 0x00000000},
+	{0x18,    2,    0,        0, 0xdeadbeef},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0x63,   10,    2,       -4, 0x00000000},
+	{0x61,    2,   10,       -4, 0x00000000},
+	{0x07,    2,    0,        0, 0x00000001},
+	{0x67,    2,    0,        0, 0x00000020},
+	{0x77,    2,    0,        0, 0x00000020},
+	{0xb7,    0,    0,        0, 0xffffffff},
+	{0x1d,    1,    2,        1, 0x00000000},
+	{0xb7,    0,    0,        0, 0x00000000},
+	{0x95,    0,    0,        0, 0x00000000},
+};
+
+/* bpf_insn array matching l3_l4 section. see tap_bpf_program.c file */
+struct bpf_insn l3_l4_hash_insns[] = {
+	{0xbf,    7,    1,        0, 0x00000000},
+	{0x61,    8,    7,       16, 0x00000000},
+	{0x61,    6,    7,       76, 0x00000000},
+	{0x61,    9,    7,       80, 0x00000000},
+	{0x18,    1,    0,        0, 0xdeadbeef},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0x63,   10,    1,       -4, 0x00000000},
+	{0xbf,    2,   10,        0, 0x00000000},
+	{0x07,    2,    0,        0, 0xfffffffc},
+	{0x18,    1,    1,        0, 0x0000cafe},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0x85,    0,    0,        0, 0x00000001},
+	{0x55,    0,    0,       21, 0x00000000},
+	{0xb7,    1,    0,        0, 0x00000a64},
+	{0x6b,   10,    1,      -16, 0x00000000},
+	{0x18,    1,    0,        0, 0x69666e6f},
+	{0x00,    0,    0,        0, 0x65727567},
+	{0x7b,   10,    1,      -24, 0x00000000},
+	{0x18,    1,    0,        0, 0x6e207369},
+	{0x00,    0,    0,        0, 0x6320746f},
+	{0x7b,   10,    1,      -32, 0x00000000},
+	{0x18,    1,    0,        0, 0x20737372},
+	{0x00,    0,    0,        0, 0x2079656b},
+	{0x7b,   10,    1,      -40, 0x00000000},
+	{0x18,    1,    0,        0, 0x68736168},
+	{0x00,    0,    0,        0, 0x203a2928},
+	{0x7b,   10,    1,      -48, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0x73,   10,    7,      -14, 0x00000000},
+	{0xbf,    1,   10,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0xffffffd0},
+	{0xb7,    2,    0,        0, 0x00000023},
+	{0x85,    0,    0,        0, 0x00000006},
+	{0x05,    0,    0,     1632, 0x00000000},
+	{0xb7,    1,    0,        0, 0x0000000e},
+	{0x61,    2,    7,       20, 0x00000000},
+	{0x15,    2,    0,       10, 0x00000000},
+	{0x61,    2,    7,       28, 0x00000000},
+	{0x55,    2,    0,        8, 0x0000a888},
+	{0xbf,    2,    7,        0, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0xbf,    1,    6,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0x00000012},
+	{0x2d,    1,    9,     1622, 0x00000000},
+	{0xb7,    1,    0,        0, 0x00000012},
+	{0x69,    8,    6,       16, 0x00000000},
+	{0xbf,    7,    2,        0, 0x00000000},
+	{0x7b,   10,    7,      -56, 0x00000000},
+	{0x57,    8,    0,        0, 0x0000ffff},
+	{0x15,    8,    0,      409, 0x0000dd86},
+	{0xb7,    7,    0,        0, 0x00000003},
+	{0x55,    8,    0,     1614, 0x00000008},
+	{0x0f,    6,    1,        0, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0xbf,    1,    6,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0x00000018},
+	{0x2d,    1,    9,     1609, 0x00000000},
+	{0x71,    3,    6,       12, 0x00000000},
+	{0xbf,    1,    3,        0, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000038},
+	{0xc7,    1,    0,        0, 0x00000020},
+	{0x77,    1,    0,        0, 0x0000001f},
+	{0x57,    1,    0,        0, 0x2cc681d1},
+	{0x67,    3,    0,        0, 0x00000018},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x40000000},
+	{0xb7,    2,    0,        0, 0x00000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x598d03a2},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x20000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb31a0745},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x10000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x66340e8a},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x08000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcc681d15},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x04000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x98d03a2b},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x02000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x31a07456},
+	{0x57,    3,    0,        0, 0x01000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6340e8ad},
+	{0x71,    3,    6,       13, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000010},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00800000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc681d15b},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00400000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d03a2b7},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00200000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1a07456f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00100000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x340e8ade},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00080000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x681d15bd},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00040000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd03a2b7b},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00020000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa07456f6},
+	{0x57,    3,    0,        0, 0x00010000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x40e8aded},
+	{0x71,    3,    6,       14, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00008000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x81d15bdb},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00004000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x03a2b7b7},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00002000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x07456f6f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00001000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0e8adedf},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000800},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1d15bdbf},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000400},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3a2b7b7e},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000200},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7456f6fd},
+	{0x57,    3,    0,        0, 0x00000100},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe8adedfa},
+	{0x71,    3,    6,       15, 0x00000000},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000080},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd15bdbf4},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000040},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa2b7b7e9},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000020},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x456f6fd3},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000010},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8adedfa7},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000008},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x15bdbf4f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000004},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2b7b7e9e},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000002},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x56f6fd3d},
+	{0x57,    3,    0,        0, 0x00000001},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xadedfa7b},
+	{0x71,    4,    6,       16, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000038},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0xb7,    3,    0,        0, 0xffffffff},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5bdbf4f7},
+	{0x67,    4,    0,        0, 0x00000018},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb7b7e9ef},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6f6fd3df},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdedfa7bf},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbdbf4f7f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7b7e9eff},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf6fd3dff},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xedfa7bfe},
+	{0x71,    4,    6,       17, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000010},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdbf4f7fc},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb7e9eff9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6fd3dff2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdfa7bfe5},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbf4f7fca},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7e9eff94},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfd3dff28},
+	{0x57,    4,    0,        0, 0x00010000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfa7bfe51},
+	{0x71,    4,    6,       18, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000008},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf4f7fca2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe9eff945},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd3dff28a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa7bfe514},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4f7fca28},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9eff9450},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3dff28a0},
+	{0x57,    4,    0,        0, 0x00000100},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7bfe5141},
+	{0x71,    4,    6,       19, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf7fca283},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xeff94506},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdff28a0c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbfe51418},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7fca2831},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff945063},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff28a0c6},
+	{0x57,    4,    0,        0, 0x00000001},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfe51418c},
+	{0x71,    4,    6,       20, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000008},
+	{0x71,    5,    6,       21, 0x00000000},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000030},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfca28319},
+	{0x67,    4,    0,        0, 0x00000010},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x40000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf9450633},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x20000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf28a0c67},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x10000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe51418ce},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x08000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xca28319d},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x04000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9450633b},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x02000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28a0c676},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x01000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x51418ced},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00800000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa28319db},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00400000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x450633b6},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00200000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8a0c676c},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00100000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1418ced8},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00080000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28319db1},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00040000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x50633b63},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00020000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa0c676c6},
+	{0x57,    4,    0,        0, 0x00010000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x418ced8d},
+	{0x71,    3,    6,       22, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00008000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8319db1a},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00004000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0633b634},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00002000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0c676c68},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00001000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x18ced8d1},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000800},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x319db1a3},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000400},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x633b6347},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000200},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc676c68f},
+	{0x57,    3,    0,        0, 0x00000100},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8ced8d1f},
+	{0x71,    3,    6,       23, 0x00000000},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000080},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x19db1a3e},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000040},
+	{0x79,    5,   10,      -56, 0x00000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x33b6347d},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000020},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x676c68fa},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000010},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xced8d1f4},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000008},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9db1a3e9},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000004},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3b6347d2},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000002},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x76c68fa5},
+	{0x57,    3,    0,        0, 0x00000001},
+	{0x1d,    3,    2,     1177, 0x00000000},
+	{0xa7,    1,    0,        0, 0xed8d1f4a},
+	{0x05,    0,    0,     1175, 0x00000000},
+	{0x0f,    6,    1,        0, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000000},
+	{0xbf,    1,    6,        0, 0x00000000},
+	{0x07,    1,    0,        0, 0x0000002c},
+	{0x2d,    1,    9,     1202, 0x00000000},
+	{0x61,    4,    6,        8, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000038},
+	{0xc7,    1,    0,        0, 0x00000020},
+	{0x77,    1,    0,        0, 0x0000001f},
+	{0x57,    1,    0,        0, 0x2cc681d1},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000040},
+	{0xb7,    2,    0,        0, 0x00000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x598d03a2},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000020},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb31a0745},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000010},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x66340e8a},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000008},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcc681d15},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000004},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x98d03a2b},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000002},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x31a07456},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000001},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6340e8ad},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00008000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc681d15b},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00004000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d03a2b7},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00002000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1a07456f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00001000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x340e8ade},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000800},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x681d15bd},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000400},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd03a2b7b},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000200},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa07456f6},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000100},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x40e8aded},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00800000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x81d15bdb},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00400000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x03a2b7b7},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00200000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x07456f6f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00100000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0e8adedf},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00080000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1d15bdbf},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00040000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3a2b7b7e},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00020000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7456f6fd},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00010000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe8adedfa},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0xb7,    3,    0,        0, 0xffffffff},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd15bdbf4},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa2b7b7e9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x456f6fd3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8adedfa7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x15bdbf4f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2b7b7e9e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x56f6fd3d},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xadedfa7b},
+	{0x61,    4,    6,       12, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5bdbf4f7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb7b7e9ef},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6f6fd3df},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdedfa7bf},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbdbf4f7f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7b7e9eff},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf6fd3dff},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xedfa7bfe},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdbf4f7fc},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb7e9eff9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6fd3dff2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdfa7bfe5},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbf4f7fca},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7e9eff94},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfd3dff28},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfa7bfe51},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf4f7fca2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe9eff945},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd3dff28a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa7bfe514},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4f7fca28},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9eff9450},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3dff28a0},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7bfe5141},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf7fca283},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xeff94506},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdff28a0c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbfe51418},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7fca2831},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff945063},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff28a0c6},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfe51418c},
+	{0x61,    4,    6,       16, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfca28319},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf9450633},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf28a0c67},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe51418ce},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xca28319d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9450633b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28a0c676},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x51418ced},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa28319db},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x450633b6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8a0c676c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1418ced8},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28319db1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x50633b63},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa0c676c6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x418ced8d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8319db1a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0633b634},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0c676c68},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x18ced8d1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x319db1a3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x633b6347},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc676c68f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8ced8d1f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x19db1a3e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x33b6347d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x676c68fa},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xced8d1f4},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9db1a3e9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3b6347d2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x76c68fa5},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xed8d1f4a},
+	{0x61,    4,    6,       20, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xdb1a3e94},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb6347d28},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6c68fa51},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd8d1f4a3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb1a3e946},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6347d28d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc68fa51a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d1f4a35},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1a3e946b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x347d28d7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x68fa51ae},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd1f4a35c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa3e946b9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x47d28d73},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8fa51ae7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1f4a35cf},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3e946b9e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7d28d73c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfa51ae78},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf4a35cf1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe946b9e3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd28d73c7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa51ae78e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4a35cf1c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x946b9e38},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x28d73c71},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x51ae78e3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa35cf1c6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x46b9e38d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d73c71b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1ae78e36},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x35cf1c6c},
+	{0x61,    4,    6,       24, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6b9e38d9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd73c71b2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xae78e364},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5cf1c6c9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb9e38d92},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x73c71b25},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe78e364b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcf1c6c96},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9e38d92c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3c71b259},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x78e364b2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf1c6c964},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe38d92c9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc71b2593},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8e364b27},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1c6c964e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x38d92c9c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x71b25938},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe364b270},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc6c964e0},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d92c9c0},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1b259380},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x364b2700},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6c964e01},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd92c9c03},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb2593807},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x64b2700f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc964e01e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x92c9c03d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2593807a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4b2700f4},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x964e01e8},
+	{0x61,    4,    6,       28, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2c9c03d1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x593807a3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb2700f46},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x64e01e8d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc9c03d1a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x93807a35},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2700f46b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4e01e8d6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9c03d1ad},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3807a35b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x700f46b6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe01e8d6c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc03d1ad9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x807a35b3},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x00f46b66},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x01e8d6cc},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x03d1ad99},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x07a35b32},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0f46b665},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1e8d6cca},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3d1ad994},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7a35b328},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf46b6651},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe8d6cca2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd1ad9944},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa35b3289},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x46b66512},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8d6cca25},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1ad9944a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x35b32894},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6b665129},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd6cca253},
+	{0x61,    4,    6,       32, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xad9944a7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5b32894f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb665129f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6cca253e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd9944a7d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb32894fb},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x665129f6},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcca253ec},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9944a7d9},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x32894fb2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x65129f65},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xca253eca},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x944a7d95},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2894fb2a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5129f655},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa253ecab},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x44a7d956},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x894fb2ac},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x129f6558},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x253ecab1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4a7d9563},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x94fb2ac7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x29f6558f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x53ecab1e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xa7d9563d},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4fb2ac7a},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9f6558f5},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3ecab1ea},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7d9563d5},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfb2ac7ab},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf6558f56},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xecab1eac},
+	{0x61,    4,    6,       36, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd9563d59},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb2ac7ab2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6558f564},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcab1eac8},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9563d590},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2ac7ab20},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x558f5641},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xab1eac83},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x563d5906},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xac7ab20c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x58f56418},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb1eac831},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x63d59063},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc7ab20c7},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8f56418f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1eac831e},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3d59063c},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7ab20c78},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf56418f0},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xeac831e1},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xd59063c2},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xab20c784},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x56418f09},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xac831e12},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x59063c25},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xb20c784b},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x6418f097},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc831e12f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9063c25f},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x20c784be},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x1d,    5,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x418f097c},
+	{0x57,    4,    0,        0, 0x01000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x831e12f9},
+	{0x71,    4,    6,       40, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000008},
+	{0x71,    5,    6,       41, 0x00000000},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    4,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000030},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x6d,    5,    3,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x063c25f3},
+	{0x67,    4,    0,        0, 0x00000010},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x40000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x0c784be7},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x20000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x18f097cf},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x10000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x31e12f9f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x08000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x63c25f3f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x04000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc784be7f},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x02000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x8f097cff},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x01000000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x1e12f9fe},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00800000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3c25f3fc},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00400000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x784be7f8},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00200000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf097cff0},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00100000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe12f9fe0},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00080000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xc25f3fc1},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00040000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x84be7f83},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00020000},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x097cff07},
+	{0x57,    4,    0,        0, 0x00010000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x12f9fe0f},
+	{0x71,    3,    6,       42, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00008000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x25f3fc1f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00004000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x4be7f83f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00002000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x97cff07f},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00001000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x2f9fe0fe},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000800},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x5f3fc1fd},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000400},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xbe7f83fb},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000200},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7cff07f7},
+	{0x57,    3,    0,        0, 0x00000100},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf9fe0fee},
+	{0x71,    3,    6,       43, 0x00000000},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000080},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xf3fc1fdc},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000040},
+	{0x79,    5,   10,      -56, 0x00000000},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xe7f83fb8},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000020},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xcff07f70},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000010},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x9fe0fee1},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000008},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x3fc1fdc2},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000004},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0x7f83fb85},
+	{0xbf,    4,    3,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000002},
+	{0x1d,    4,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xff07f70a},
+	{0x57,    3,    0,        0, 0x00000001},
+	{0x1d,    3,    2,        1, 0x00000000},
+	{0xa7,    1,    0,        0, 0xfe0fee15},
+	{0x71,    2,    0,      201, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000008},
+	{0x71,    3,    0,      200, 0x00000000},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0x71,    3,    0,      203, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0x71,    4,    0,      202, 0x00000000},
+	{0x4f,    3,    4,        0, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000010},
+	{0x4f,    3,    2,        0, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000020},
+	{0x77,    1,    0,        0, 0x00000020},
+	{0xbf,    2,    1,        0, 0x00000000},
+	{0x3f,    2,    3,        0, 0x00000000},
+	{0x2f,    2,    3,        0, 0x00000000},
+	{0x1f,    1,    2,        0, 0x00000000},
+	{0x57,    1,    0,        0, 0x0000000f},
+	{0x67,    1,    0,        0, 0x00000002},
+	{0x0f,    0,    1,        0, 0x00000000},
+	{0x71,    1,    0,      137, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000008},
+	{0x71,    2,    0,      136, 0x00000000},
+	{0x4f,    1,    2,        0, 0x00000000},
+	{0x71,    2,    0,      138, 0x00000000},
+	{0x71,    3,    0,      139, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000008},
+	{0x4f,    3,    2,        0, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000010},
+	{0x4f,    3,    1,        0, 0x00000000},
+	{0x07,    3,    0,        0, 0x00000001},
+	{0x63,    5,    3,       52, 0x00000000},
+	{0xb7,    7,    0,        0, 0x00000001},
+	{0xbf,    0,    7,        0, 0x00000000},
+	{0x95,    0,    0,        0, 0x00000000},
+};
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v6 4/6] net/tap: add eBPF API
  2018-01-20 21:11         ` [dpdk-dev] [PATCH v6 " Ophir Munk
                             ` (2 preceding siblings ...)
  2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 3/6] net/tap: add eBPF bytes code Ophir Munk
@ 2018-01-20 21:11           ` Ophir Munk
  2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 5/6] net/tap: implement TAP RSS using eBPF Ophir Munk
                             ` (2 subsequent siblings)
  6 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-20 21:11 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

This commit include BPF API to be used by TAP.

tap_flow_bpf_cls_q() - download to kernel BPF program that classifies
packets to their matching queues
tap_flow_bpf_calc_l3_l4_hash() - download to kernel BPF program that
calculates per packet layer 3 and layer 4 RSS hash
tap_flow_bpf_rss_map_create() - create BPF RSS map for storing RSS
parameters per RSS rule
tap_flow_bpf_update_rss_elem() - update BPF map entry with RSS rule
parameters

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
Acked-by: Pascal Mazon <pascal.mazon@6wind.com>
---
 drivers/net/tap/Makefile      |   6 ++
 drivers/net/tap/tap_bpf.h     | 112 +++++++++++++++++++++++++
 drivers/net/tap/tap_bpf_api.c | 190 ++++++++++++++++++++++++++++++++++++++++++
 drivers/net/tap/tap_flow.h    |   6 ++
 4 files changed, 314 insertions(+)
 create mode 100644 drivers/net/tap/tap_bpf.h
 create mode 100644 drivers/net/tap/tap_bpf_api.c

diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index fbf84e1..fad8a94 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -35,6 +35,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += rte_eth_tap.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_flow.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_netlink.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_tcmsgs.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_bpf_api.c
 
 include $(RTE_SDK)/mk/rte.lib.mk
 
@@ -61,6 +62,11 @@ tap_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
 		linux/pkt_cls.h \
 		enum TCA_FLOWER_KEY_VLAN_PRIO \
 		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_BPF_PROG_LOAD \
+		linux/bpf.h \
+		enum BPF_PROG_LOAD \
+		$(AUTOCONF_OUTPUT)
 
 # Create tap_autoconf.h or update it in case it differs from the new one.
 
diff --git a/drivers/net/tap/tap_bpf.h b/drivers/net/tap/tap_bpf.h
new file mode 100644
index 0000000..30eefb3
--- /dev/null
+++ b/drivers/net/tap/tap_bpf.h
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#ifndef __TAP_BPF_H__
+#define __TAP_BPF_H__
+
+#include <tap_autoconf.h>
+
+#ifdef HAVE_BPF_PROG_LOAD
+#include <linux/bpf.h>
+#else
+/* BPF_MAP_UPDATE_ELEM command flags */
+#define	BPF_ANY	0 /* create a new element or update an existing */
+
+/* BPF architecture instruction struct */
+struct bpf_insn {
+	__u8	code;
+	__u8	dst_reg:4;
+	__u8	src_reg:4;
+	__s16	off;
+	__s32	imm; /* immediate value */
+};
+
+/* BPF program types */
+enum bpf_prog_type {
+	BPF_PROG_TYPE_UNSPEC,
+	BPF_PROG_TYPE_SOCKET_FILTER,
+	BPF_PROG_TYPE_KPROBE,
+	BPF_PROG_TYPE_SCHED_CLS,
+	BPF_PROG_TYPE_SCHED_ACT,
+};
+
+/* BPF commands types */
+enum bpf_cmd {
+	BPF_MAP_CREATE,
+	BPF_MAP_LOOKUP_ELEM,
+	BPF_MAP_UPDATE_ELEM,
+	BPF_MAP_DELETE_ELEM,
+	BPF_MAP_GET_NEXT_KEY,
+	BPF_PROG_LOAD,
+};
+
+/* BPF maps types */
+enum bpf_map_type {
+	BPF_MAP_TYPE_UNSPEC,
+	BPF_MAP_TYPE_HASH,
+};
+
+/* union of anonymous structs used with TAP BPF commands */
+union bpf_attr {
+	/* BPF_MAP_CREATE command */
+	struct {
+		__u32	map_type;
+		__u32	key_size;
+		__u32	value_size;
+		__u32	max_entries;
+		__u32	map_flags;
+		__u32	inner_map_fd;
+	};
+
+	/* BPF_MAP_UPDATE_ELEM, BPF_MAP_DELETE_ELEM commands */
+	struct {
+		__u32		map_fd;
+		__aligned_u64	key;
+		union {
+			__aligned_u64 value;
+			__aligned_u64 next_key;
+		};
+		__u64		flags;
+	};
+
+	/* BPF_PROG_LOAD command */
+	struct {
+		__u32		prog_type;
+		__u32		insn_cnt;
+		__aligned_u64	insns;
+		__aligned_u64	license;
+		__u32		log_level;
+		__u32		log_size;
+		__aligned_u64	log_buf;
+		__u32		kern_version;
+		__u32		prog_flags;
+	};
+} __attribute__((aligned(8)));
+#endif
+
+#ifndef __NR_bpf
+# if defined(__i386__)
+#  define __NR_bpf 357
+# elif defined(__x86_64__)
+#  define __NR_bpf 321
+# elif defined(__aarch64__)
+#  define __NR_bpf 280
+# elif defined(__sparc__)
+#  define __NR_bpf 349
+# elif defined(__s390__)
+#  define __NR_bpf 351
+# else
+#  error __NR_bpf not defined
+# endif
+#endif
+
+enum {
+	BPF_MAP_ID_KEY,
+	BPF_MAP_ID_SIMPLE,
+};
+
+static int bpf_load(enum bpf_prog_type type, const struct bpf_insn *insns,
+		size_t insns_cnt, const char *license);
+
+#endif /* __TAP_BPF_H__ */
diff --git a/drivers/net/tap/tap_bpf_api.c b/drivers/net/tap/tap_bpf_api.c
new file mode 100644
index 0000000..109a681
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_api.c
@@ -0,0 +1,190 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/queue.h>
+
+#include <rte_malloc.h>
+#include <rte_eth_tap.h>
+#include <tap_flow.h>
+#include <tap_autoconf.h>
+#include <tap_tcmsgs.h>
+#include <tap_bpf.h>
+#include <tap_bpf_insns.h>
+
+/**
+ * Load BPF program (section cls_q) into the kernel and return a bpf fd
+ *
+ * @param queue_idx
+ *   Queue index matching packet cb
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int tap_flow_bpf_cls_q(__u32 queue_idx)
+{
+	cls_q_insns[1].imm = queue_idx;
+
+	return bpf_load(BPF_PROG_TYPE_SCHED_CLS,
+		(struct bpf_insn *)cls_q_insns,
+		RTE_DIM(cls_q_insns),
+		"Dual BSD/GPL");
+}
+
+/**
+ * Load BPF program (section l3_l4) into the kernel and return a bpf fd.
+ *
+ * @param[in] key_idx
+ *   RSS MAP key index
+ *
+ * @param[in] map_fd
+ *   BPF RSS map file descriptor
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd)
+{
+	l3_l4_hash_insns[4].imm = key_idx;
+	l3_l4_hash_insns[9].imm = map_fd;
+
+	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+		(struct bpf_insn *)l3_l4_hash_insns,
+		RTE_DIM(l3_l4_hash_insns),
+		"Dual BSD/GPL");
+}
+
+/**
+ * Helper function to convert a pointer to unsigned 64 bits
+ *
+ * @param[in] ptr
+ *   pointer to address
+ *
+ * @return
+ *   64 bit unsigned long type of pointer address
+ */
+static inline __u64 ptr_to_u64(const void *ptr)
+{
+	return (__u64)(unsigned long)ptr;
+}
+
+/**
+ * Call BPF system call
+ *
+ * @param[in] cmd
+ *   BPF command for program loading, map creation, map entry update, etc
+ *
+ * @param[in] attr
+ *   System call attributes relevant to system call command
+ *
+ * @param[in] size
+ *   size of attr parameter
+ *
+ * @return
+ *   -1 if BPF system call failed, 0 otherwise
+ */
+static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
+			unsigned int size)
+{
+	return syscall(__NR_bpf, cmd, attr, size);
+}
+
+/**
+ * Load BPF instructions to kernel
+ *
+ * @param[in] type
+ *   BPF program type: classifieir or action
+ *
+ * @param[in] insns
+ *   Array of BPF instructions (equivalent to BPF instructions)
+ *
+ * @param[in] insns_cnt
+ *   Number of BPF instructions (size of array)
+ *
+ * @param[in] lincense
+ *   License string that must be acknowledged by the kernel
+ *
+ * @return
+ *   -1 if the BPF program couldn't be loaded, fd (file descriptor) otherwise
+ */
+static int bpf_load(enum bpf_prog_type type,
+		  const struct bpf_insn *insns,
+		  size_t insns_cnt,
+		  const char *license)
+{
+	union bpf_attr attr = {};
+
+	bzero(&attr, sizeof(attr));
+	attr.prog_type = type;
+	attr.insn_cnt = (__u32)insns_cnt;
+	attr.insns = ptr_to_u64(insns);
+	attr.license = ptr_to_u64(license);
+	attr.log_buf = ptr_to_u64(NULL);
+	attr.log_level = 0;
+	attr.kern_version = 0;
+
+	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
+}
+
+/**
+ * Create BPF map for RSS rules
+ *
+ * @param[in] key_size
+ *   map RSS key size
+ *
+ * @param[in] value_size
+ *   Map RSS value size
+ *
+ * @param[in] max_entries
+ *   Map max number of RSS entries (limit on max RSS rules)
+ *
+ * @return
+ *   -1 if BPF map couldn't be created, map fd otherwise
+ */
+int tap_flow_bpf_rss_map_create(unsigned int key_size,
+		unsigned int value_size,
+		unsigned int max_entries)
+{
+	union bpf_attr attr = {};
+
+	bzero(&attr, sizeof(attr));
+	attr.map_type    = BPF_MAP_TYPE_HASH;
+	attr.key_size    = key_size;
+	attr.value_size  = value_size;
+	attr.max_entries = max_entries;
+
+	return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
+}
+
+/**
+ * Update RSS entry in BPF map
+ *
+ * @param[in] fd
+ *   RSS map fd
+ *
+ * @param[in] key
+ *   Pointer to RSS key whose entry is updated
+ *
+ * @param[in] value
+ *   Pointer to RSS new updated value
+ *
+ * @return
+ *   -1 if RSS entry failed to be updated, 0 otherwise
+ */
+int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value)
+{
+	union bpf_attr attr = {};
+
+	bzero(&attr, sizeof(attr));
+
+	attr.map_type = BPF_MAP_TYPE_HASH;
+	attr.map_fd = fd;
+	attr.key = ptr_to_u64(key);
+	attr.value = ptr_to_u64(value);
+	attr.flags = BPF_ANY;
+
+	return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
+}
diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h
index 9e332b0..894c959 100644
--- a/drivers/net/tap/tap_flow.h
+++ b/drivers/net/tap/tap_flow.h
@@ -80,4 +80,10 @@ int tap_flow_implicit_destroy(struct pmd_internals *pmd,
 int tap_flow_implicit_flush(struct pmd_internals *pmd,
 			    struct rte_flow_error *error);
 
+int tap_flow_bpf_cls_q(__u32 queue_idx);
+int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd);
+int tap_flow_bpf_rss_map_create(unsigned int key_size, unsigned int value_size,
+			unsigned int max_entries);
+int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value);
+
 #endif /* _TAP_FLOW_H_ */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v6 5/6] net/tap: implement TAP RSS using eBPF
  2018-01-20 21:11         ` [dpdk-dev] [PATCH v6 " Ophir Munk
                             ` (3 preceding siblings ...)
  2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 4/6] net/tap: add eBPF API Ophir Munk
@ 2018-01-20 21:11           ` Ophir Munk
  2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 6/6] doc: detail new tap RSS feature in guides Ophir Munk
  2018-01-21 14:50           ` [dpdk-dev] [PATCH v6 0/6] TAP RSS eBPF cover letter Ferruh Yigit
  6 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-20 21:11 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

TAP PMD is required to support RSS queue mapping based on rte_flow API. An
example usage for this requirement is failsafe transparent switching from a
PCI device to TAP device while keep redirecting packets to the same RSS
queues on both devices.

TAP RSS implementation is based on eBPF programs sent to Linux kernel
through BPF system calls and using netlink messages to reference the
programs as part of traffic control commands.

TC uses eBPF programs as classifiers and actions.
eBPF classification: packets marked with an RSS queue will be directed
to this queue using TC with "skbedit" action.
BPF classifiers are downloaded to the kernel once on TAP creation for
each TAP Rx queue.

eBPF action: calculate the Toeplitz RSS hash based on L3 addresses and
L4 ports. Mark the packet with the RSS queue according the resulting
RSS hash, then reclassify the packet.
BPF actions are downloaded to the kernel for each new RSS rule.

TAP eBPF requires Linux version 4.9 configured with BPF. TAP PMD will
successfully compile on systems with old or non-BPF configured kernels but
RSS rules creation on TAP devices will not be successful

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
Acked-by: Pascal Mazon <pascal.mazon@6wind.com>
---
 drivers/net/tap/Makefile      |  20 ++
 drivers/net/tap/rte_eth_tap.h |   5 +
 drivers/net/tap/tap_flow.c    | 450 ++++++++++++++++++++++++++++++++++++++++--
 drivers/net/tap/tap_flow.h    |   7 +
 drivers/net/tap/tap_rss.h     |  34 ++++
 drivers/net/tap/tap_tcmsgs.h  |   4 +
 6 files changed, 502 insertions(+), 18 deletions(-)
 create mode 100644 drivers/net/tap/tap_rss.h

diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index fad8a94..e23c3a2 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -63,6 +63,26 @@ tap_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
 		enum TCA_FLOWER_KEY_VLAN_PRIO \
 		$(AUTOCONF_OUTPUT)
 	$Q sh -- '$<' '$@' \
+		HAVE_TC_BPF \
+		linux/pkt_cls.h \
+		enum TCA_BPF_UNSPEC \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_TC_BPF_FD \
+		linux/pkt_cls.h \
+		enum TCA_BPF_FD \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_TC_ACT_BPF \
+		linux/tc_act/tc_bpf.h \
+		enum TCA_ACT_BPF_UNSPEC \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_TC_ACT_BPF_FD \
+		linux/tc_act/tc_bpf.h \
+		enum TCA_ACT_BPF_FD \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
 		HAVE_BPF_PROG_LOAD \
 		linux/bpf.h \
 		enum BPF_PROG_LOAD \
diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
index 202b3cd..c185473 100644
--- a/drivers/net/tap/rte_eth_tap.h
+++ b/drivers/net/tap/rte_eth_tap.h
@@ -92,6 +92,11 @@ struct pmd_internals {
 	int flow_isolate;                 /* 1 if flow isolation is enabled */
 	int flower_support;               /* 1 if kernel supports, else 0 */
 	int flower_vlan_support;          /* 1 if kernel supports, else 0 */
+	int rss_enabled;                  /* 1 if RSS is enabled, else 0 */
+	/* implicit rules set when RSS is enabled */
+	int map_fd;                       /* BPF RSS map fd */
+	int bpf_fd[RTE_PMD_TAP_MAX_QUEUES];/* List of bpf fds per queue */
+	LIST_HEAD(tap_rss_flows, rte_flow) rss_flows;
 	LIST_HEAD(tap_flows, rte_flow) flows;        /* rte_flow rules */
 	/* implicit rte_flow rules set when a remote device is active */
 	LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows;
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index d2a69a7..6aa53a7 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -35,6 +35,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/queue.h>
+#include <sys/resource.h>
 
 #include <rte_byteorder.h>
 #include <rte_jhash.h>
@@ -43,6 +44,7 @@
 #include <tap_flow.h>
 #include <tap_autoconf.h>
 #include <tap_tcmsgs.h>
+#include <tap_rss.h>
 
 #ifndef HAVE_TC_FLOWER
 /*
@@ -82,12 +84,79 @@ enum {
 	TCA_FLOWER_KEY_VLAN_ETH_TYPE,   /* be16 */
 };
 #endif
+/*
+ * For kernels < 4.2 BPF related enums may not be defined.
+ * Runtime checks will be carried out to gracefully report on TC messages that
+ * are rejected by the kernel. Rejection reasons may be due to:
+ * 1. enum is not defined
+ * 2. enum is defined but kernel is not configured to support BPF system calls,
+ *    BPF classifications or BPF actions.
+ */
+#ifndef HAVE_TC_BPF
+enum {
+	TCA_BPF_UNSPEC,
+	TCA_BPF_ACT,
+	TCA_BPF_POLICE,
+	TCA_BPF_CLASSID,
+	TCA_BPF_OPS_LEN,
+	TCA_BPF_OPS,
+};
+#endif
+#ifndef HAVE_TC_BPF_FD
+enum {
+	TCA_BPF_FD = TCA_BPF_OPS + 1,
+	TCA_BPF_NAME,
+};
+#endif
+#ifndef HAVE_TC_ACT_BPF
+#define tc_gen \
+	__u32                 index; \
+	__u32                 capab; \
+	int                   action; \
+	int                   refcnt; \
+	int                   bindcnt
+
+struct tc_act_bpf {
+	tc_gen;
+};
+
+enum {
+	TCA_ACT_BPF_UNSPEC,
+	TCA_ACT_BPF_TM,
+	TCA_ACT_BPF_PARMS,
+	TCA_ACT_BPF_OPS_LEN,
+	TCA_ACT_BPF_OPS,
+};
+
+#endif
+#ifndef HAVE_TC_ACT_BPF_FD
+enum {
+	TCA_ACT_BPF_FD = TCA_ACT_BPF_OPS + 1,
+	TCA_ACT_BPF_NAME,
+};
+#endif
+
+/* RSS key management */
+enum bpf_rss_key_e {
+	KEY_CMD_GET = 1,
+	KEY_CMD_RELEASE,
+	KEY_CMD_INIT,
+	KEY_CMD_DEINIT,
+};
+
+enum key_status_e {
+	KEY_STAT_UNSPEC,
+	KEY_STAT_USED,
+	KEY_STAT_AVAILABLE,
+};
 
 #define ISOLATE_HANDLE 1
 
 struct rte_flow {
 	LIST_ENTRY(rte_flow) next; /* Pointer to the next rte_flow structure */
 	struct rte_flow *remote_flow; /* associated remote flow */
+	int bpf_fd[SEC_MAX]; /* list of bfs fds per ELF section */
+	uint32_t key_idx; /* RSS rule key index into BPF map */
 	struct nlmsg msg;
 };
 
@@ -115,6 +184,11 @@ struct action_data {
 			struct tc_skbedit skbedit;
 			uint16_t queue;
 		} skbedit;
+		struct bpf {
+			struct tc_act_bpf bpf;
+			int bpf_fd;
+			const char *annotation;
+		} bpf;
 	};
 };
 
@@ -148,6 +222,14 @@ tap_flow_isolate(struct rte_eth_dev *dev,
 		 int set,
 		 struct rte_flow_error *error);
 
+static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx);
+static int rss_enable(struct pmd_internals *pmd,
+			const struct rte_flow_attr *attr,
+			struct rte_flow_error *error);
+static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
+			const struct rte_flow_action_rss *rss,
+			struct rte_flow_error *error);
+
 static const struct rte_flow_ops tap_flow_ops = {
 	.validate = tap_flow_validate,
 	.create = tap_flow_create,
@@ -877,6 +959,14 @@ add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
 			   &adata->skbedit.skbedit);
 		tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING,
 			     adata->skbedit.queue);
+	} else if (strcmp("bpf", adata->id) == 0) {
+		tap_nlattr_add32(&msg->nh, TCA_ACT_BPF_FD, adata->bpf.bpf_fd);
+		tap_nlattr_add(&msg->nh, TCA_ACT_BPF_NAME,
+			   strlen(adata->bpf.annotation) + 1,
+			   adata->bpf.annotation);
+		tap_nlattr_add(&msg->nh, TCA_ACT_BPF_PARMS,
+			   sizeof(adata->bpf.bpf),
+			   &adata->bpf.bpf);
 	} else {
 		return -1;
 	}
@@ -979,7 +1069,8 @@ priv_flow_process(struct pmd_internals *pmd,
 		return -rte_errno;
 	} else if (flow) {
 		uint16_t group = attr->group << GROUP_SHIFT;
-		uint16_t prio = group | (attr->priority + PRIORITY_OFFSET);
+		uint16_t prio = group | (attr->priority +
+				RSS_PRIORITY_OFFSET + PRIORITY_OFFSET);
 		flow->msg.t.tcm_info = TC_H_MAKE(prio << 16,
 						 flow->msg.t.tcm_info);
 	}
@@ -1134,7 +1225,6 @@ priv_flow_process(struct pmd_internals *pmd,
 					TCA_FLOWER_ACT);
 			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
-			/* Fake RSS support. */
 			const struct rte_flow_action_rss *rss =
 				(const struct rte_flow_action_rss *)
 				actions->conf;
@@ -1142,23 +1232,13 @@ priv_flow_process(struct pmd_internals *pmd,
 			if (action++)
 				goto exit_action_not_supported;
 
-			if (!rss || rss->num < 1 ||
-			    (rss->queue[0] > pmd->dev->data->nb_rx_queues - 1))
-				goto exit_action_not_supported;
-			if (flow) {
-				struct action_data adata = {
-					.id = "skbedit",
-					.skbedit = {
-						.skbedit = {
-							.action = TC_ACT_PIPE,
-						},
-						.queue = rss->queue[0],
-					},
-				};
-
-				err = add_actions(flow, 1, &adata,
-					TCA_FLOWER_ACT);
+			if (!pmd->rss_enabled) {
+				err = rss_enable(pmd, attr, error);
+				if (err)
+					goto exit_action_not_supported;
 			}
+			if (flow && rss)
+				err = rss_add_actions(flow, pmd, rss, error);
 		} else {
 			goto exit_action_not_supported;
 		}
@@ -1370,6 +1450,7 @@ tap_flow_destroy_pmd(struct pmd_internals *pmd,
 		     struct rte_flow_error *error)
 {
 	struct rte_flow *remote_flow = flow->remote_flow;
+	int i;
 	int ret = 0;
 
 	LIST_REMOVE(flow, next);
@@ -1395,6 +1476,23 @@ tap_flow_destroy_pmd(struct pmd_internals *pmd,
 			"couldn't receive kernel ack to our request");
 		goto end;
 	}
+	/* Close opened BPF file descriptors of this flow */
+	for (i = 0; i < SEC_MAX; i++)
+		if (flow->bpf_fd[i] != 0) {
+			close(flow->bpf_fd[i]);
+			flow->bpf_fd[i] = 0;
+		}
+
+	/* Release map key for this RSS rule */
+	ret = bpf_rss_key(KEY_CMD_RELEASE, &flow->key_idx);
+	if (ret < 0) {
+		rte_flow_error_set(
+			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Failed to release BPF RSS key");
+
+		goto end;
+	}
+
 	if (remote_flow) {
 		remote_flow->msg.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
 		remote_flow->msg.nh.nlmsg_type = RTM_DELTFILTER;
@@ -1679,6 +1777,322 @@ tap_flow_implicit_flush(struct pmd_internals *pmd, struct rte_flow_error *error)
 	return 0;
 }
 
+#define MAX_RSS_KEYS 256
+#define SEC_NAME_CLS_Q "cls_q"
+
+const char *sec_name[SEC_MAX] = {
+	[SEC_L3_L4] = "l3_l4",
+};
+
+/**
+ * Enable RSS on tap: create TC rules for queuing.
+ *
+ * @param[in, out] pmd
+ *   Pointer to private structure.
+ *
+ * @param[in] attr
+ *   Pointer to rte_flow to get flow group
+ *
+ * @param[out] error
+ *   Pointer to error reporting if not NULL.
+ *
+ * @return 0 on success, negative value on failure.
+ */
+static int rss_enable(struct pmd_internals *pmd,
+			const struct rte_flow_attr *attr,
+			struct rte_flow_error *error)
+{
+	struct rte_flow *rss_flow = NULL;
+	struct nlmsg *msg = NULL;
+	/* 4096 is the maximum number of instructions for a BPF program */
+	char annotation[64];
+	int i;
+	int err = 0;
+
+	/* unlimit locked memory */
+	struct rlimit memlock_limit = {
+		.rlim_cur = RLIM_INFINITY,
+		.rlim_max = RLIM_INFINITY,
+	};
+	setrlimit(RLIMIT_MEMLOCK, &memlock_limit);
+
+	 /* Get a new map key for a new RSS rule */
+	err = bpf_rss_key(KEY_CMD_INIT, NULL);
+	if (err < 0) {
+		rte_flow_error_set(
+			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Failed to initialize BPF RSS keys");
+
+		return -1;
+	}
+
+	/*
+	 *  Create BPF RSS MAP
+	 */
+	pmd->map_fd = tap_flow_bpf_rss_map_create(sizeof(__u32), /* key size */
+				sizeof(struct rss_key),
+				MAX_RSS_KEYS);
+	if (pmd->map_fd < 0) {
+		RTE_LOG(ERR, PMD,
+			"Failed to create BPF map (%d): %s\n",
+				errno, strerror(errno));
+		rte_flow_error_set(
+			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Kernel too old or not configured "
+			"to support BPF maps");
+
+		return -ENOTSUP;
+	}
+
+	/*
+	 * Add a rule per queue to match reclassified packets and direct them to
+	 * the correct queue.
+	 */
+	for (i = 0; i < pmd->dev->data->nb_rx_queues; i++) {
+		pmd->bpf_fd[i] = tap_flow_bpf_cls_q(i);
+		if (pmd->bpf_fd[i] < 0) {
+			RTE_LOG(ERR, PMD,
+				"Failed to load BPF section %s for queue %d",
+				SEC_NAME_CLS_Q, i);
+			rte_flow_error_set(
+				error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
+				NULL,
+				"Kernel too old or not configured "
+				"to support BPF programs loading");
+
+			return -ENOTSUP;
+		}
+
+		rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
+		if (!rss_flow) {
+			RTE_LOG(ERR, PMD,
+				"Cannot allocate memory for rte_flow");
+			return -1;
+		}
+		msg = &rss_flow->msg;
+		tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER, NLM_F_REQUEST |
+			    NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE);
+		msg->t.tcm_info = TC_H_MAKE(0, htons(ETH_P_ALL));
+		tap_flow_set_handle(rss_flow);
+		uint16_t group = attr->group << GROUP_SHIFT;
+		uint16_t prio = group | (i + PRIORITY_OFFSET);
+		msg->t.tcm_info = TC_H_MAKE(prio << 16, msg->t.tcm_info);
+		msg->t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
+
+		tap_nlattr_add(&msg->nh, TCA_KIND, sizeof("bpf"), "bpf");
+		if (tap_nlattr_nested_start(msg, TCA_OPTIONS) < 0)
+			return -1;
+		tap_nlattr_add32(&msg->nh, TCA_BPF_FD, pmd->bpf_fd[i]);
+		snprintf(annotation, sizeof(annotation), "[%s%d]",
+			SEC_NAME_CLS_Q, i);
+		tap_nlattr_add(&msg->nh, TCA_BPF_NAME, strlen(annotation) + 1,
+			   annotation);
+		/* Actions */
+		{
+			struct action_data adata = {
+				.id = "skbedit",
+				.skbedit = {
+					.skbedit = {
+						.action = TC_ACT_PIPE,
+					},
+					.queue = i,
+				},
+			};
+			if (add_actions(rss_flow, 1, &adata, TCA_BPF_ACT) < 0)
+				return -1;
+		}
+		tap_nlattr_nested_finish(msg); /* nested TCA_OPTIONS */
+
+		/* Netlink message is now ready to be sent */
+		if (tap_nl_send(pmd->nlsk_fd, &msg->nh) < 0)
+			return -1;
+		err = tap_nl_recv_ack(pmd->nlsk_fd);
+		if (err < 0) {
+			RTE_LOG(ERR, PMD,
+				"Kernel refused TC filter rule creation (%d): %s\n",
+				errno, strerror(errno));
+			return err;
+		}
+		LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
+	}
+
+	pmd->rss_enabled = 1;
+	return err;
+}
+
+/**
+ * Manage bpf RSS keys repository with operations: init, get, release
+ *
+ * @param[in] cmd
+ *   Command on RSS keys: init, get, release
+ *
+ * @param[in, out] key_idx
+ *   Pointer to RSS Key index (out for get command, in for release command)
+ *
+ * @return -1 if couldn't get, release or init the RSS keys, 0 otherwise.
+ */
+static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx)
+{
+	__u32 i;
+	int err = -1;
+	static __u32 num_used_keys;
+	static __u32 rss_keys[MAX_RSS_KEYS] = {KEY_STAT_UNSPEC};
+	static __u32 rss_keys_initialized;
+
+	switch (cmd) {
+	case KEY_CMD_GET:
+		if (!rss_keys_initialized)
+			break;
+
+		if (num_used_keys == RTE_DIM(rss_keys))
+			break;
+
+		*key_idx = num_used_keys % RTE_DIM(rss_keys);
+		while (rss_keys[*key_idx] == KEY_STAT_USED)
+			*key_idx = (*key_idx + 1) % RTE_DIM(rss_keys);
+
+		rss_keys[*key_idx] = KEY_STAT_USED;
+		num_used_keys++;
+		err = 0;
+	break;
+
+	case KEY_CMD_RELEASE:
+		if (!rss_keys_initialized) {
+			err = 0;
+			break;
+		}
+
+		if (rss_keys[*key_idx] == KEY_STAT_USED) {
+			rss_keys[*key_idx] = KEY_STAT_AVAILABLE;
+			num_used_keys--;
+			err = 0;
+		}
+	break;
+
+	case KEY_CMD_INIT:
+		for (i = 0; i < RTE_DIM(rss_keys); i++)
+			rss_keys[i] = KEY_STAT_AVAILABLE;
+
+		rss_keys_initialized = 1;
+		num_used_keys = 0;
+		err = 0;
+	break;
+
+	case KEY_CMD_DEINIT:
+		for (i = 0; i < RTE_DIM(rss_keys); i++)
+			rss_keys[i] = KEY_STAT_UNSPEC;
+
+		rss_keys_initialized = 0;
+		num_used_keys = 0;
+		err = 0;
+	break;
+
+	default:
+		break;
+	}
+
+	return err;
+}
+
+/**
+ * Add RSS hash calculations and queue selection
+ *
+ * @param[in, out] pmd
+ *   Pointer to internal structure. Used to set/get RSS map fd
+ *
+ * @param[in] rss
+ *   Pointer to RSS flow actions
+ *
+ * @param[out] error
+ *   Pointer to error reporting if not NULL.
+ *
+ * @return 0 on success, negative value on failure
+ */
+static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
+			   const struct rte_flow_action_rss *rss,
+			   struct rte_flow_error *error)
+{
+	/* 4096 is the maximum number of instructions for a BPF program */
+	int i;
+	int err;
+	struct rss_key rss_entry = { .hash_fields = 0,
+				     .key_size = 0 };
+
+	/* Get a new map key for a new RSS rule */
+	err = bpf_rss_key(KEY_CMD_GET, &flow->key_idx);
+	if (err < 0) {
+		rte_flow_error_set(
+			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Failed to get BPF RSS key");
+
+		return -1;
+	}
+
+	/* Update RSS map entry with queues */
+	rss_entry.nb_queues = rss->num;
+	for (i = 0; i < rss->num; i++)
+		rss_entry.queues[i] = rss->queue[i];
+	rss_entry.hash_fields =
+		(1 << HASH_FIELD_IPV4_L3_L4) | (1 << HASH_FIELD_IPV6_L3_L4);
+
+	/* Add this RSS entry to map */
+	err = tap_flow_bpf_update_rss_elem(pmd->map_fd,
+				&flow->key_idx, &rss_entry);
+
+	if (err) {
+		RTE_LOG(ERR, PMD,
+			"Failed to update BPF map entry #%u (%d): %s\n",
+			flow->key_idx, errno, strerror(errno));
+		rte_flow_error_set(
+			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Kernel too old or not configured "
+			"to support BPF maps updates");
+
+		return -ENOTSUP;
+	}
+
+
+	/*
+	 * Load bpf rules to calculate hash for this key_idx
+	 */
+
+	flow->bpf_fd[SEC_L3_L4] =
+		tap_flow_bpf_calc_l3_l4_hash(flow->key_idx, pmd->map_fd);
+	if (flow->bpf_fd[SEC_L3_L4] < 0) {
+		RTE_LOG(ERR, PMD,
+			"Failed to load BPF section %s (%d): %s\n",
+				sec_name[SEC_L3_L4], errno, strerror(errno));
+		rte_flow_error_set(
+			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"Kernel too old or not configured "
+			"to support BPF program loading");
+
+		return -ENOTSUP;
+	}
+
+	/* Actions */
+	{
+		struct action_data adata[] = {
+			{
+				.id = "bpf",
+				.bpf = {
+					.bpf_fd = flow->bpf_fd[SEC_L3_L4],
+					.annotation = sec_name[SEC_L3_L4],
+					.bpf = {
+						.action = TC_ACT_PIPE,
+					},
+				},
+			},
+		};
+
+		if (add_actions(flow, RTE_DIM(adata), adata,
+			TCA_FLOWER_ACT) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
 /**
  * Manage filter operations.
  *
diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h
index 894c959..daaf00b 100644
--- a/drivers/net/tap/tap_flow.h
+++ b/drivers/net/tap/tap_flow.h
@@ -37,6 +37,7 @@
 #include <rte_flow.h>
 #include <rte_flow_driver.h>
 #include <rte_eth_tap.h>
+#include <tap_autoconf.h>
 
 /**
  * In TC, priority 0 means we require the kernel to allocate one for us.
@@ -49,6 +50,7 @@
 #define GROUP_MASK (0xf)
 #define GROUP_SHIFT 12
 #define MAX_GROUP GROUP_MASK
+#define RSS_PRIORITY_OFFSET RTE_PMD_TAP_MAX_QUEUES
 
 /**
  * These index are actually in reversed order: their priority is processed
@@ -67,6 +69,11 @@ enum implicit_rule_index {
 	TAP_REMOTE_MAX_IDX,
 };
 
+enum bpf_fd_idx {
+	SEC_L3_L4,
+	SEC_MAX,
+};
+
 int tap_dev_filter_ctrl(struct rte_eth_dev *dev,
 			enum rte_filter_type filter_type,
 			enum rte_filter_op filter_op,
diff --git a/drivers/net/tap/tap_rss.h b/drivers/net/tap/tap_rss.h
new file mode 100644
index 0000000..3bb0d14
--- /dev/null
+++ b/drivers/net/tap/tap_rss.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 Mellanox Technologies, Ltd.
+ */
+
+#ifndef _TAP_RSS_H_
+#define _TAP_RSS_H_
+
+#ifndef TAP_MAX_QUEUES
+#define TAP_MAX_QUEUES 16
+#endif
+
+/* hashed fields for RSS */
+enum hash_field {
+	HASH_FIELD_IPV4_L3,	/* IPv4 src/dst addr */
+	HASH_FIELD_IPV4_L3_L4,	/* IPv4 src/dst addr + L4 src/dst ports */
+	HASH_FIELD_IPV6_L3,	/* IPv6 src/dst addr */
+	HASH_FIELD_IPV6_L3_L4,	/* IPv6 src/dst addr + L4 src/dst ports */
+	HASH_FIELD_L2_SRC,	/* Ethernet src addr */
+	HASH_FIELD_L2_DST,	/* Ethernet dst addr */
+	HASH_FIELD_L3_SRC,	/* L3 src addr */
+	HASH_FIELD_L3_DST,	/* L3 dst addr */
+	HASH_FIELD_L4_SRC,	/* TCP/UDP src ports */
+	HASH_FIELD_L4_DST,	/* TCP/UDP dst ports */
+};
+
+struct rss_key {
+	 __u8 key[128];
+	__u32 hash_fields;
+	__u32 key_size;
+	__u32 queues[TAP_MAX_QUEUES];
+	__u32 nb_queues;
+} __attribute__((packed));
+
+#endif /* _TAP_RSS_H_ */
diff --git a/drivers/net/tap/tap_tcmsgs.h b/drivers/net/tap/tap_tcmsgs.h
index 7895957..07c5074 100644
--- a/drivers/net/tap/tap_tcmsgs.h
+++ b/drivers/net/tap/tap_tcmsgs.h
@@ -34,6 +34,7 @@
 #ifndef _TAP_TCMSGS_H_
 #define _TAP_TCMSGS_H_
 
+#include <tap_autoconf.h>
 #include <linux/if_ether.h>
 #include <linux/rtnetlink.h>
 #include <linux/pkt_sched.h>
@@ -41,6 +42,9 @@
 #include <linux/tc_act/tc_mirred.h>
 #include <linux/tc_act/tc_gact.h>
 #include <linux/tc_act/tc_skbedit.h>
+#ifdef HAVE_TC_ACT_BPF
+#include <linux/tc_act/tc_bpf.h>
+#endif
 #include <inttypes.h>
 
 #include <rte_ether.h>
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v6 6/6] doc: detail new tap RSS feature in guides
  2018-01-20 21:11         ` [dpdk-dev] [PATCH v6 " Ophir Munk
                             ` (4 preceding siblings ...)
  2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 5/6] net/tap: implement TAP RSS using eBPF Ophir Munk
@ 2018-01-20 21:11           ` Ophir Munk
  2018-01-21 14:50           ` [dpdk-dev] [PATCH v6 0/6] TAP RSS eBPF cover letter Ferruh Yigit
  6 siblings, 0 replies; 42+ messages in thread
From: Ophir Munk @ 2018-01-20 21:11 UTC (permalink / raw)
  To: dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern, Ophir Munk

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
Acked-by: Pascal Mazon <pascal.mazon@6wind.com>
---
 doc/guides/nics/tap.rst | 60 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/doc/guides/nics/tap.rst b/doc/guides/nics/tap.rst
index 04086b1..dc6f834 100644
--- a/doc/guides/nics/tap.rst
+++ b/doc/guides/nics/tap.rst
@@ -132,6 +132,7 @@ Supported actions:
 - DROP
 - QUEUE
 - PASSTHRU
+- RSS
 
 It is generally not possible to provide a "last" item. However, if the "last"
 item, once masked, is identical to the masked spec, then it is supported.
@@ -161,6 +162,11 @@ Drop UDP packets in vlan 3::
    testpmd> flow create 0 priority 3 ingress pattern eth / vlan vid is 3 / \
             ipv4 proto is 17 / end actions drop / end
 
+Distribute IPv4 TCP packets using RSS to a given MAC address over queues 0-3::
+
+   testpmd> flow create 0 priority 4 ingress pattern eth dst is 0a:0b:0c:0d:0e:0f \
+            / ipv4 / tcp / end actions rss queues 0 1 2 3 end / end
+
 Example
 -------
 
@@ -213,3 +219,57 @@ traffic is being looped back. You can use ``set all size XXX`` to change the
 size of the packets after you stop the traffic. Use pktgen ``help``
 command to see a list of all commands. You can also use the ``-f`` option to
 load commands at startup in command line or Lua script in pktgen.
+
+RSS specifics
+-------------
+Packet distribution in TAP is done by the kernel which has a default
+distribution. This feature is adding RSS distribution based on eBPF code.
+The default eBPF code calculates RSS hash based on Toeplitz algorithm for
+a fixed RSS key. It is calculated on fixed packet offsets. For IPv4 and IPv6 it
+is calculated over src/dst addresses (8 or 32 bytes for IPv4 or IPv6
+respectively) and src/dst TCP/UDP ports (4 bytes).
+
+The RSS algorithm is written in file ``tap_bpf_program.c`` which
+does not take part in TAP PMD compilation. Instead this file is compiled
+in advance to eBPF object file. The eBPF object file is then parsed and
+translated into eBPF byte code in the format of C arrays of eBPF
+instructions. The C array of eBPF instructions is part of TAP PMD tree and
+is taking part in TAP PMD compilation. At run time the C arrays are uploaded to
+the kernel via BPF system calls and the RSS hash is calculated by the
+kernel.
+
+It is possible to support different RSS hash algorithms by updating file
+``tap_bpf_program.c``  In order to add a new RSS hash algorithm follow these
+steps:
+
+1. Write the new RSS implementation in file ``tap_bpf_program.c``
+
+BPF programs which are uploaded to the kernel correspond to
+C functions under different ELF sections.
+
+2. Install ``LLVM`` library and ``clang`` compiler versions 3.7 and above
+
+3. Compile ``tap_bpf_program.c`` via ``LLVM`` into an object file::
+
+    clang -O2 -emit-llvm -c tap_bpf_program.c -o - | llc -march=bpf \
+    -filetype=obj -o <tap_bpf_program.o>
+
+
+4. Use a tool that receives two parameters: an eBPF object file and a section
+name, and prints out the section as a C array of eBPF instructions.
+Embed the C array in your TAP PMD tree.
+
+The C arrays are uploaded to the kernel using BPF system calls.
+
+``tc`` (traffic control) is a well known user space utility program used to
+configure the Linux kernel packet scheduler. It is usually packaged as
+part of the ``iproute2`` package.
+Since commit 11c39b5e9 ("tc: add eBPF support to f_bpf") ``tc`` can be used
+to uploads eBPF code to the kernel and can be patched in order to print the
+C arrays of eBPF instructions just before calling the BPF system call.
+Please refer to ``iproute2`` package file ``lib/bpf.c`` function
+``bpf_prog_load()``.
+
+An example utility for eBPF instruction generation in the format of C arrays will
+be added in next releases
+
-- 
2.7.4

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter
  2018-01-20 16:15           ` Ferruh Yigit
@ 2018-01-20 21:25             ` Ophir Munk
  2018-01-21 14:20               ` Ferruh Yigit
  0 siblings, 1 reply; 42+ messages in thread
From: Ophir Munk @ 2018-01-20 21:25 UTC (permalink / raw)
  To: Ferruh Yigit, Pascal Mazon, dev; +Cc: Thomas Monjalon, Olga Shern

Hi Ferruh,
Thanks for applying v5 patches while changing the order of commits and adding "Acked-by: ..."

I have sent v6 which does the same but also updates the commit messages of the switched commits to reflect more accurately the new order. 

Please let know if you are going to leave v5 as is or replace it with v6.

Regards,
Ophir

> -----Original Message-----
> From: Ferruh Yigit [mailto:ferruh.yigit@intel.com]
> Sent: Saturday, January 20, 2018 6:16 PM
> To: Pascal Mazon <pascal.mazon@6wind.com>; Ophir Munk
> <ophirmu@mellanox.com>; dev@dpdk.org
> Cc: Thomas Monjalon <thomas@monjalon.net>; Olga Shern
> <olgas@mellanox.com>
> Subject: Re: [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter
> 
> On 1/19/2018 6:48 AM, Pascal Mazon wrote:
> > Hi,
> >
> > It seems more logical to me to introduce tap_program (patch 3) before
> > its compiled version (patch 2).
> > Source code is indeed written down before compiling it.
> >
> > The doc section is a good addition.
> > I'll be happy to see the upcoming utility for turning eBPF bytecode to
> > C arrays.
> > I'd have liked to see automation code (in a not-executed Makefile
> > target
> > typically) for generating the bytecode.
> > I'm being told it should happen in the upcoming series along with the
> > aforementioned utility.
> >
> > Otherwise code looks good enough (I couldn't see everything for lack
> > of time), considering that later patches are expected in next release.
> >
> > Acked-by: Pascal Mazon <pascal.mazon@6wind.com>
> >
> > Best regards,
> > Pascal
> >
> > On 18/01/2018 14:38, Ophir Munk wrote:
> >> The patches of TAP RSS eBPF follow the RFC on this issue
> >>
> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdp
> >>
> dk.org%2Fdev%2Fpatchwork%2Fpatch%2F31781%2F&data=02%7C01%7Cop
> hirmu%40
> >>
> mellanox.com%7Ccd9b412a6c1d428fe52308d56021141b%7Ca652971c7d2e
> 4d9ba6a
> >>
> 4d149256f461b%7C0%7C0%7C636520617565078480&sdata=7AuH4FxyKlZR
> %2Fwy6%2
> >> B3hEnW3UQIWmGonkq%2FtAxPdEG2w%3D&reserved=0
> >>
> >> v5 changes with respect to v4
> >> =============================
> >> Update TAP document guide with RSS
> >>
> >> v4 changes with respect to v3
> >> =============================
> >> * Code updates based on review comments
> >> * New commits organization (2-->5) based on review comments
> >>   1. net/tap: support actions for different classifiers (preparations for BPF.
> >>      No BPF code yet)
> >>   2. net/tap: add eBPF bytes code (BPF bytes code in a separate file)
> >>   3. net/tap: add eBPF program file (Program source code of bytes code)
> >>   4. net/tap: add eBPF API (BPF API to be used by TAP)
> >>   5. net/tap: implement TAP RSS using eBPF
> >>
> >> v3 changes with respect to v2
> >> =============================
> >> * Add support for IPv6 RSS in BPF program
> >> * Bug fixes
> >> * Updated compatibility to kernel versions:
> >>   eBPF requires Linux version 4.9 configured with BPF
> >> * New license header (SPDX) for newly added files
> >>
> >> v2 changes with respect to v1
> >> =============================
> >> * v2 has new commits organization (3 --> 2)
> >> * BPF program was revised. It is successfully tested on
> >>   IPv4 L3 L4 layers (compatible to mlx4 device)
> >> * Licensing: no comments received for using "Dual BSD/GPL"
> >>   string during BPF program loading to the kernel.
> >>   (v1 and v2 are using the same license strings)
> >>   Any comments are welcome.
> >> * Compatibility to kernel versions:
> >>   eBPF requires Linux version 4.2 configured with BPF. TAP PMD will
> >>   successfully compile on systems with old or non-BPF configured kernels.
> >>   During compilation time the required Linux headers are searched for.
> >>   If they are not present missing definitions are locally added
> >>   (tap_autoconf.h).
> >>   If the kernel cannot support a BPF operation - at runtime it will
> >>   gracefully reject the netlink message (with BPF) sent to it.
> >>
> >> Ophir Munk (6):
> >>   net/tap: support actions for different classifiers
> >>   net/tap: add eBPF bytes code
> >>   net/tap: add eBPF program file
> >>   net/tap: add eBPF API
> >>   net/tap: implement TAP RSS using eBPF
> >>   doc: detail new tap RSS feature in guides
> 
> Series applied to dpdk-next-net/master, thanks.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter
  2018-01-20 21:25             ` Ophir Munk
@ 2018-01-21 14:20               ` Ferruh Yigit
  0 siblings, 0 replies; 42+ messages in thread
From: Ferruh Yigit @ 2018-01-21 14:20 UTC (permalink / raw)
  To: Ophir Munk, Pascal Mazon, dev; +Cc: Thomas Monjalon, Olga Shern

On 1/20/2018 9:25 PM, Ophir Munk wrote:
> Hi Ferruh,
> Thanks for applying v5 patches while changing the order of commits and adding "Acked-by: ..."
> 
> I have sent v6 which does the same but also updates the commit messages of the switched commits to reflect more accurately the new order. 
> 
> Please let know if you are going to leave v5 as is or replace it with v6.

I will drop existing ones and get your v6.

> 
> Regards,
> Ophir
> 
>> -----Original Message-----
>> From: Ferruh Yigit [mailto:ferruh.yigit@intel.com]
>> Sent: Saturday, January 20, 2018 6:16 PM
>> To: Pascal Mazon <pascal.mazon@6wind.com>; Ophir Munk
>> <ophirmu@mellanox.com>; dev@dpdk.org
>> Cc: Thomas Monjalon <thomas@monjalon.net>; Olga Shern
>> <olgas@mellanox.com>
>> Subject: Re: [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter
>>
>> On 1/19/2018 6:48 AM, Pascal Mazon wrote:
>>> Hi,
>>>
>>> It seems more logical to me to introduce tap_program (patch 3) before
>>> its compiled version (patch 2).
>>> Source code is indeed written down before compiling it.
>>>
>>> The doc section is a good addition.
>>> I'll be happy to see the upcoming utility for turning eBPF bytecode to
>>> C arrays.
>>> I'd have liked to see automation code (in a not-executed Makefile
>>> target
>>> typically) for generating the bytecode.
>>> I'm being told it should happen in the upcoming series along with the
>>> aforementioned utility.
>>>
>>> Otherwise code looks good enough (I couldn't see everything for lack
>>> of time), considering that later patches are expected in next release.
>>>
>>> Acked-by: Pascal Mazon <pascal.mazon@6wind.com>
>>>
>>> Best regards,
>>> Pascal
>>>
>>> On 18/01/2018 14:38, Ophir Munk wrote:
>>>> The patches of TAP RSS eBPF follow the RFC on this issue
>>>>
>> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdp
>>>>
>> dk.org%2Fdev%2Fpatchwork%2Fpatch%2F31781%2F&data=02%7C01%7Cop
>> hirmu%40
>>>>
>> mellanox.com%7Ccd9b412a6c1d428fe52308d56021141b%7Ca652971c7d2e
>> 4d9ba6a
>>>>
>> 4d149256f461b%7C0%7C0%7C636520617565078480&sdata=7AuH4FxyKlZR
>> %2Fwy6%2
>>>> B3hEnW3UQIWmGonkq%2FtAxPdEG2w%3D&reserved=0
>>>>
>>>> v5 changes with respect to v4
>>>> =============================
>>>> Update TAP document guide with RSS
>>>>
>>>> v4 changes with respect to v3
>>>> =============================
>>>> * Code updates based on review comments
>>>> * New commits organization (2-->5) based on review comments
>>>>   1. net/tap: support actions for different classifiers (preparations for BPF.
>>>>      No BPF code yet)
>>>>   2. net/tap: add eBPF bytes code (BPF bytes code in a separate file)
>>>>   3. net/tap: add eBPF program file (Program source code of bytes code)
>>>>   4. net/tap: add eBPF API (BPF API to be used by TAP)
>>>>   5. net/tap: implement TAP RSS using eBPF
>>>>
>>>> v3 changes with respect to v2
>>>> =============================
>>>> * Add support for IPv6 RSS in BPF program
>>>> * Bug fixes
>>>> * Updated compatibility to kernel versions:
>>>>   eBPF requires Linux version 4.9 configured with BPF
>>>> * New license header (SPDX) for newly added files
>>>>
>>>> v2 changes with respect to v1
>>>> =============================
>>>> * v2 has new commits organization (3 --> 2)
>>>> * BPF program was revised. It is successfully tested on
>>>>   IPv4 L3 L4 layers (compatible to mlx4 device)
>>>> * Licensing: no comments received for using "Dual BSD/GPL"
>>>>   string during BPF program loading to the kernel.
>>>>   (v1 and v2 are using the same license strings)
>>>>   Any comments are welcome.
>>>> * Compatibility to kernel versions:
>>>>   eBPF requires Linux version 4.2 configured with BPF. TAP PMD will
>>>>   successfully compile on systems with old or non-BPF configured kernels.
>>>>   During compilation time the required Linux headers are searched for.
>>>>   If they are not present missing definitions are locally added
>>>>   (tap_autoconf.h).
>>>>   If the kernel cannot support a BPF operation - at runtime it will
>>>>   gracefully reject the netlink message (with BPF) sent to it.
>>>>
>>>> Ophir Munk (6):
>>>>   net/tap: support actions for different classifiers
>>>>   net/tap: add eBPF bytes code
>>>>   net/tap: add eBPF program file
>>>>   net/tap: add eBPF API
>>>>   net/tap: implement TAP RSS using eBPF
>>>>   doc: detail new tap RSS feature in guides
>>
>> Series applied to dpdk-next-net/master, thanks.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v6 0/6] TAP RSS eBPF cover letter
  2018-01-20 21:11         ` [dpdk-dev] [PATCH v6 " Ophir Munk
                             ` (5 preceding siblings ...)
  2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 6/6] doc: detail new tap RSS feature in guides Ophir Munk
@ 2018-01-21 14:50           ` Ferruh Yigit
  6 siblings, 0 replies; 42+ messages in thread
From: Ferruh Yigit @ 2018-01-21 14:50 UTC (permalink / raw)
  To: Ophir Munk, dev, Pascal Mazon; +Cc: Thomas Monjalon, Olga Shern

On 1/20/2018 9:11 PM, Ophir Munk wrote:
> The patches of TAP RSS eBPF follow the RFC on this issue
> https://dpdk.org/dev/patchwork/patch/31781/
> 
> v6 changes with respect to v5
> =============================
> 1. Reorder thes following commits (source file commit before byte code commit)
>   net/tap: add eBPF program file
>   net/tap: add eBPF bytes code
> 2. Add acknowledgment to commits 
> 
> v5 changes with respect to v4
> =============================
> Update TAP document guide with RSS
> 
> v4 changes with respect to v3
> =============================
> * Code updates based on review comments
> * New commits organization (2-->5) based on review comments
>   1. net/tap: support actions for different classifiers (preparations for BPF. 
>      No BPF code yet)
>   2. net/tap: add eBPF bytes code (BPF bytes code in a separate file)
>   3. net/tap: add eBPF program file (Program source code of bytes code)
>   4. net/tap: add eBPF API (BPF API to be used by TAP)
>   5. net/tap: implement TAP RSS using eBPF
> 
> v3 changes with respect to v2
> =============================
> * Add support for IPv6 RSS in BPF program
> * Bug fixes
> * Updated compatibility to kernel versions:
>   eBPF requires Linux version 4.9 configured with BPF
> * New license header (SPDX) for newly added files
> 
> v2 changes with respect to v1
> =============================
> * v2 has new commits organization (3 --> 2)
> * BPF program was revised. It is successfully tested on
>   IPv4 L3 L4 layers (compatible to mlx4 device)
> * Licensing: no comments received for using "Dual BSD/GPL"
>   string during BPF program loading to the kernel.
>   (v1 and v2 are using the same license strings)
>   Any comments are welcome.
> * Compatibility to kernel versions:
>   eBPF requires Linux version 4.2 configured with BPF. TAP PMD will
>   successfully compile on systems with old or non-BPF configured kernels.
>   During compilation time the required Linux headers are searched for.
>   If they are not present missing definitions are locally added
>   (tap_autoconf.h).
>   If the kernel cannot support a BPF operation - at runtime it will
>   gracefully reject the netlink message (with BPF) sent to it.
> Ophir Munk (6):
>   net/tap: support actions for different classifiers
>   net/tap: add eBPF program file
>   net/tap: add eBPF bytes code
>   net/tap: add eBPF API
>   net/tap: implement TAP RSS using eBPF
>   doc: detail new tap RSS feature in guides

Series applied to dpdk-next-net/master, thanks.

^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2018-01-21 14:50 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-17 12:21 [dpdk-dev] [PATCH v1 0/3] TAP RSS eBPF cover letter Ophir Munk
2017-12-17 12:21 ` [dpdk-dev] [PATCH v1 1/3] net/tap: add BPF sections for TAP device Ophir Munk
2017-12-17 12:21 ` [dpdk-dev] [PATCH v1 2/3] net/tap: add eBPF instructions Ophir Munk
2017-12-17 12:21 ` [dpdk-dev] [PATCH v1 3/3] net/tap: add eBPF classifiers map and actions Ophir Munk
2017-12-28 10:09 ` [dpdk-dev] [PATCH v2 0/2] TAP RSS eBPF cover letter Ophir Munk
2017-12-28 10:09   ` [dpdk-dev] [PATCH v2 1/2] net/tap: add eBPF instructions to TAP device Ophir Munk
2017-12-28 10:09   ` [dpdk-dev] [PATCH v2 2/2] net/tap: implement RSS with eBPF classifier and action Ophir Munk
2018-01-10  7:06   ` [dpdk-dev] [PATCH v3 0/2] TAP RSS eBPF cover letter Ophir Munk
2018-01-10  7:06     ` [dpdk-dev] [PATCH v3 1/2] net/tap: add eBPF instructions to TAP device Ophir Munk
2018-01-10  9:34       ` Pascal Mazon
2018-01-10 10:12         ` Ophir Munk
2018-01-10  7:06     ` [dpdk-dev] [PATCH v3 2/2] net/tap: implement RSS with eBPF classifier and action Ophir Munk
2018-01-10 10:19       ` Pascal Mazon
2018-01-11 17:20         ` Ophir Munk
2018-01-10 10:10     ` [dpdk-dev] [PATCH v3 0/2] TAP RSS eBPF cover letter Jason Wang
2018-01-10 15:34       ` Ophir Munk
2018-01-11  2:45         ` Jason Wang
2018-01-11 17:45     ` [dpdk-dev] [PATCH v4 0/5] " Ophir Munk
2018-01-11 17:45       ` [dpdk-dev] [PATCH v4 1/5] net/tap: support actions for different classifiers Ophir Munk
2018-01-11 17:45       ` [dpdk-dev] [PATCH v4 2/5] net/tap: add eBPF bytes code Ophir Munk
2018-01-11 17:45       ` [dpdk-dev] [PATCH v4 3/5] net/tap: add eBPF program file Ophir Munk
2018-01-11 17:45       ` [dpdk-dev] [PATCH v4 4/5] net/tap: add eBPF API Ophir Munk
2018-01-11 17:45       ` [dpdk-dev] [PATCH v4 5/5] net/tap: implement TAP RSS using eBPF Ophir Munk
2018-01-18 13:38       ` [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter Ophir Munk
2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 1/6] net/tap: support actions for different classifiers Ophir Munk
2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 2/6] net/tap: add eBPF bytes code Ophir Munk
2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 3/6] net/tap: add eBPF program file Ophir Munk
2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 4/6] net/tap: add eBPF API Ophir Munk
2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 5/6] net/tap: implement TAP RSS using eBPF Ophir Munk
2018-01-18 13:38         ` [dpdk-dev] [PATCH v5 6/6] doc: detail new tap RSS feature in guides Ophir Munk
2018-01-19  6:48         ` [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter Pascal Mazon
2018-01-20 16:15           ` Ferruh Yigit
2018-01-20 21:25             ` Ophir Munk
2018-01-21 14:20               ` Ferruh Yigit
2018-01-20 21:11         ` [dpdk-dev] [PATCH v6 " Ophir Munk
2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 1/6] net/tap: support actions for different classifiers Ophir Munk
2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 2/6] net/tap: add eBPF program file Ophir Munk
2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 3/6] net/tap: add eBPF bytes code Ophir Munk
2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 4/6] net/tap: add eBPF API Ophir Munk
2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 5/6] net/tap: implement TAP RSS using eBPF Ophir Munk
2018-01-20 21:11           ` [dpdk-dev] [PATCH v6 6/6] doc: detail new tap RSS feature in guides Ophir Munk
2018-01-21 14:50           ` [dpdk-dev] [PATCH v6 0/6] TAP RSS eBPF cover letter Ferruh Yigit

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).