aboutsummaryrefslogtreecommitdiffstats
path: root/examples/ip_pipeline/config
diff options
context:
space:
mode:
Diffstat (limited to 'examples/ip_pipeline/config')
-rw-r--r--examples/ip_pipeline/config/action.cfg68
-rw-r--r--examples/ip_pipeline/config/action.sh119
-rw-r--r--examples/ip_pipeline/config/action.txt8
-rw-r--r--examples/ip_pipeline/config/edge_router_downstream.cfg30
-rw-r--r--examples/ip_pipeline/config/edge_router_downstream.sh7
-rw-r--r--examples/ip_pipeline/config/edge_router_upstream.cfg36
-rw-r--r--examples/ip_pipeline/config/edge_router_upstream.sh37
-rw-r--r--examples/ip_pipeline/config/firewall.cfg68
-rw-r--r--examples/ip_pipeline/config/firewall.sh13
-rw-r--r--examples/ip_pipeline/config/firewall.txt9
-rw-r--r--examples/ip_pipeline/config/flow.cfg72
-rw-r--r--examples/ip_pipeline/config/flow.sh25
-rw-r--r--examples/ip_pipeline/config/flow.txt17
-rw-r--r--examples/ip_pipeline/config/kni.cfg67
-rw-r--r--examples/ip_pipeline/config/l2fwd.cfg5
-rw-r--r--examples/ip_pipeline/config/l3fwd.cfg9
-rw-r--r--examples/ip_pipeline/config/l3fwd.sh32
-rw-r--r--examples/ip_pipeline/config/l3fwd_arp.cfg70
-rw-r--r--examples/ip_pipeline/config/l3fwd_arp.sh43
-rw-r--r--examples/ip_pipeline/config/network_layers.cfg223
-rw-r--r--examples/ip_pipeline/config/network_layers.sh79
-rwxr-xr-xexamples/ip_pipeline/config/pipeline-to-core-mapping.py936
22 files changed, 1923 insertions, 50 deletions
diff --git a/examples/ip_pipeline/config/action.cfg b/examples/ip_pipeline/config/action.cfg
new file mode 100644
index 00000000..994ae94a
--- /dev/null
+++ b/examples/ip_pipeline/config/action.cfg
@@ -0,0 +1,68 @@
+; BSD LICENSE
+;
+; Copyright(c) 2016 Intel Corporation. All rights reserved.
+; All rights reserved.
+;
+; 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 Intel Corporation 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.
+
+; ________________
+; RXQ0.0 --->| |---> TXQ0.0
+; | |
+; RXQ1.0 --->| |---> TXQ1.0
+; | Flow |
+; RXQ2.0 --->| Actions |---> TXQ2.0
+; | |
+; RXQ3.0 --->| |---> TXQ3.0
+; |________________|
+;
+;
+; Input packet: Ethernet/IPv4
+;
+; Packet buffer layout:
+; # Field Name Offset (Bytes) Size (Bytes)
+; 0 Mbuf 0 128
+; 1 Headroom 128 128
+; 2 Ethernet header 256 14
+; 3 IPv4 header 270 20
+
+[EAL]
+log_level = 0
+
+[PIPELINE0]
+type = MASTER
+core = 0
+
+[PIPELINE1]
+type = FLOW_ACTIONS
+core = 1
+pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0
+pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0
+n_flows = 65536
+n_meters_per_flow = 4
+flow_id_offset = 286; ipdaddr
+ip_hdr_offset = 270
+color_offset = 128
diff --git a/examples/ip_pipeline/config/action.sh b/examples/ip_pipeline/config/action.sh
new file mode 100644
index 00000000..2986ae60
--- /dev/null
+++ b/examples/ip_pipeline/config/action.sh
@@ -0,0 +1,119 @@
+#
+# run ./config/action.sh
+#
+
+p 1 action flow 0 meter 0 trtcm 1250000000 1250000000 1000000 1000000
+p 1 action flow 0 policer 0 g G y Y r R
+p 1 action flow 0 meter 1 trtcm 1250000000 1250000000 1000000 1000000
+p 1 action flow 0 policer 1 g G y Y r R
+p 1 action flow 0 meter 2 trtcm 1250000000 1250000000 1000000 1000000
+p 1 action flow 0 policer 2 g G y Y r R
+p 1 action flow 0 meter 3 trtcm 1250000000 1250000000 1000000 1000000
+p 1 action flow 0 policer 3 g G y Y r R
+p 1 action flow 0 port 0
+
+p 1 action flow 1 meter 0 trtcm 1250000000 1250000000 1000000 1000000
+p 1 action flow 1 policer 0 g G y Y r R
+p 1 action flow 1 meter 1 trtcm 1250000000 1250000000 1000000 1000000
+p 1 action flow 1 policer 1 g G y Y r R
+p 1 action flow 1 meter 2 trtcm 1250000000 1250000000 1000000 1000000
+p 1 action flow 1 policer 2 g G y Y r R
+p 1 action flow 1 meter 3 trtcm 1250000000 1250000000 1000000 1000000
+p 1 action flow 1 policer 3 g G y Y r R
+p 1 action flow 1 port 1
+
+p 1 action flow 2 meter 0 trtcm 1250000000 1250000000 1000000 1000000
+p 1 action flow 2 policer 0 g G y Y r R
+p 1 action flow 2 meter 1 trtcm 1250000000 1250000000 1000000 1000000
+p 1 action flow 2 policer 1 g G y Y r R
+p 1 action flow 2 meter 2 trtcm 1250000000 1250000000 1000000 1000000
+p 1 action flow 2 policer 2 g G y Y r R
+p 1 action flow 2 meter 3 trtcm 1250000000 1250000000 1000000 1000000
+p 1 action flow 2 policer 3 g G y Y r R
+p 1 action flow 2 port 2
+
+p 1 action flow 3 meter 0 trtcm 1250000000 1250000000 1000000 1000000
+p 1 action flow 3 policer 0 g G y Y r R
+p 1 action flow 3 meter 1 trtcm 1250000000 1250000000 1000000 1000000
+p 1 action flow 3 policer 1 g G y Y r R
+p 1 action flow 3 meter 2 trtcm 1250000000 1250000000 1000000 1000000
+p 1 action flow 3 policer 2 g G y Y r R
+p 1 action flow 3 meter 3 trtcm 1250000000 1250000000 1000000 1000000
+p 1 action flow 3 policer 3 g G y Y r R
+p 1 action flow 3 port 3
+
+#p 1 action flow bulk ./config/action.txt
+
+#p 1 action flow ls
+
+p 1 action flow 0 stats
+p 1 action flow 1 stats
+p 1 action flow 2 stats
+p 1 action flow 3 stats
+
+p 1 action dscp 0 class 0 color G
+p 1 action dscp 1 class 1 color G
+p 1 action dscp 2 class 2 color G
+p 1 action dscp 3 class 3 color G
+p 1 action dscp 4 class 0 color G
+p 1 action dscp 5 class 1 color G
+p 1 action dscp 6 class 2 color G
+p 1 action dscp 7 class 3 color G
+p 1 action dscp 8 class 0 color G
+p 1 action dscp 9 class 1 color G
+p 1 action dscp 10 class 2 color G
+p 1 action dscp 11 class 3 color G
+p 1 action dscp 12 class 0 color G
+p 1 action dscp 13 class 1 color G
+p 1 action dscp 14 class 2 color G
+p 1 action dscp 15 class 3 color G
+p 1 action dscp 16 class 0 color G
+p 1 action dscp 17 class 1 color G
+p 1 action dscp 18 class 2 color G
+p 1 action dscp 19 class 3 color G
+p 1 action dscp 20 class 0 color G
+p 1 action dscp 21 class 1 color G
+p 1 action dscp 22 class 2 color G
+p 1 action dscp 23 class 3 color G
+p 1 action dscp 24 class 0 color G
+p 1 action dscp 25 class 1 color G
+p 1 action dscp 26 class 2 color G
+p 1 action dscp 27 class 3 color G
+p 1 action dscp 27 class 0 color G
+p 1 action dscp 29 class 1 color G
+p 1 action dscp 30 class 2 color G
+p 1 action dscp 31 class 3 color G
+p 1 action dscp 32 class 0 color G
+p 1 action dscp 33 class 1 color G
+p 1 action dscp 34 class 2 color G
+p 1 action dscp 35 class 3 color G
+p 1 action dscp 36 class 0 color G
+p 1 action dscp 37 class 1 color G
+p 1 action dscp 38 class 2 color G
+p 1 action dscp 39 class 3 color G
+p 1 action dscp 40 class 0 color G
+p 1 action dscp 41 class 1 color G
+p 1 action dscp 42 class 2 color G
+p 1 action dscp 43 class 3 color G
+p 1 action dscp 44 class 0 color G
+p 1 action dscp 45 class 1 color G
+p 1 action dscp 46 class 2 color G
+p 1 action dscp 47 class 3 color G
+p 1 action dscp 48 class 0 color G
+p 1 action dscp 49 class 1 color G
+p 1 action dscp 50 class 2 color G
+p 1 action dscp 51 class 3 color G
+p 1 action dscp 52 class 0 color G
+p 1 action dscp 53 class 1 color G
+p 1 action dscp 54 class 2 color G
+p 1 action dscp 55 class 3 color G
+p 1 action dscp 56 class 0 color G
+p 1 action dscp 57 class 1 color G
+p 1 action dscp 58 class 2 color G
+p 1 action dscp 59 class 3 color G
+p 1 action dscp 60 class 0 color G
+p 1 action dscp 61 class 1 color G
+p 1 action dscp 62 class 2 color G
+p 1 action dscp 63 class 3 color G
+
+p 1 action dscp ls
diff --git a/examples/ip_pipeline/config/action.txt b/examples/ip_pipeline/config/action.txt
new file mode 100644
index 00000000..f14207b9
--- /dev/null
+++ b/examples/ip_pipeline/config/action.txt
@@ -0,0 +1,8 @@
+#
+# p <pipelineid> action flow bulk ./config/action.txt
+#
+
+flow 0 meter 0 trtcm 1250000000 1250000000 1000000 1000000 policer 0 g G y Y r R meter 1 trtcm 1250000000 1250000000 1000000 1000000 policer 1 g G y Y r R meter 2 trtcm 1250000000 1250000000 1000000 1000000 policer 2 g G y Y r R meter 3 trtcm 1250000000 1250000000 1000000 1000000 policer 3 g G y Y r R port 0
+flow 1 meter 0 trtcm 1250000000 1250000000 1000000 1000000 policer 0 g G y Y r R meter 1 trtcm 1250000000 1250000000 1000000 1000000 policer 1 g G y Y r R meter 2 trtcm 1250000000 1250000000 1000000 1000000 policer 2 g G y Y r R meter 3 trtcm 1250000000 1250000000 1000000 1000000 policer 3 g G y Y r R port 1
+flow 2 meter 0 trtcm 1250000000 1250000000 1000000 1000000 policer 0 g G y Y r R meter 1 trtcm 1250000000 1250000000 1000000 1000000 policer 1 g G y Y r R meter 2 trtcm 1250000000 1250000000 1000000 1000000 policer 2 g G y Y r R meter 3 trtcm 1250000000 1250000000 1000000 1000000 policer 3 g G y Y r R port 2
+flow 3 meter 0 trtcm 1250000000 1250000000 1000000 1000000 policer 0 g G y Y r R meter 1 trtcm 1250000000 1250000000 1000000 1000000 policer 1 g G y Y r R meter 2 trtcm 1250000000 1250000000 1000000 1000000 policer 2 g G y Y r R meter 3 trtcm 1250000000 1250000000 1000000 1000000 policer 3 g G y Y r R port 3
diff --git a/examples/ip_pipeline/config/edge_router_downstream.cfg b/examples/ip_pipeline/config/edge_router_downstream.cfg
index 85bbab8f..c6b4e1f2 100644
--- a/examples/ip_pipeline/config/edge_router_downstream.cfg
+++ b/examples/ip_pipeline/config/edge_router_downstream.cfg
@@ -1,6 +1,6 @@
; BSD LICENSE
;
-; Copyright(c) 2015 Intel Corporation. All rights reserved.
+; Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
@@ -36,9 +36,9 @@
; network) contains the following functional blocks: Packet RX & Routing,
; Traffic management and Packet TX. The input packets are assumed to be
; IPv4, while the output packets are Q-in-Q IPv4.
-
+;
; A simple implementation for this functional pipeline is presented below.
-
+;
; Packet Rx & Traffic Management Packet Tx
; Routing (Pass-Through) (Pass-Through)
; _____________________ SWQ0 ______________________ SWQ4 _____________________
@@ -50,11 +50,23 @@
; | | SWQ3 | | SWQ7 | |
; RXQ3.0 --->| |----->| |----->| |---> TXQ3.0
; |_____________________| |______________________| |_____________________|
-; | _|_ ^ _|_ ^ _|_ ^ _|_ ^
-; | |___|||___|||___|||___||
-; +--> SINK0 |___|||___|||___|||___||
-; (route miss) |__| |__| |__| |__|
-; TM0 TM1 TM2 TM3
+; | | ^ | ^ | ^ | ^
+; | |__| |__| |__| |__|
+; +--> SINK0 TM0 TM1 TM2 TM3
+; (Default)
+;
+; Input packet: Ethernet/IPv4
+; Output packet: Ethernet/QinQ/IPv4
+;
+; Packet buffer layout:
+; # Field Name Offset (Bytes) Size (Bytes)
+; 0 Mbuf 0 128
+; 1 Headroom 128 128
+; 2 Ethernet header 256 14
+; 3 IPv4 header 270 20
+
+[EAL]
+log_level = 0
[PIPELINE0]
type = MASTER
@@ -67,7 +79,7 @@ pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0
pktq_out = SWQ0 SWQ1 SWQ2 SWQ3 SINK0
encap = ethernet_qinq
qinq_sched = test
-ip_hdr_offset = 270; mbuf (128) + headroom (128) + ethernet header (14) = 270
+ip_hdr_offset = 270
[PIPELINE2]
type = PASS-THROUGH
diff --git a/examples/ip_pipeline/config/edge_router_downstream.sh b/examples/ip_pipeline/config/edge_router_downstream.sh
index ce46beb5..67c3a0d1 100644
--- a/examples/ip_pipeline/config/edge_router_downstream.sh
+++ b/examples/ip_pipeline/config/edge_router_downstream.sh
@@ -1,3 +1,7 @@
+#
+# run ./config/edge_router_downstream.sh
+#
+
################################################################################
# Routing: Ether QinQ, ARP off
################################################################################
@@ -6,5 +10,4 @@ p 1 route add 0.0.0.0 10 port 0 ether a0:b0:c0:d0:e0:f0 qinq 256 257
p 1 route add 0.64.0.0 10 port 1 ether a1:b1:c1:d1:e1:f1 qinq 258 259
p 1 route add 0.128.0.0 10 port 2 ether a2:b2:c2:d2:e2:f2 qinq 260 261
p 1 route add 0.192.0.0 10 port 3 ether a3:b3:c3:d3:e3:f3 qinq 262 263
-
-p 1 route ls
+#p 1 route ls
diff --git a/examples/ip_pipeline/config/edge_router_upstream.cfg b/examples/ip_pipeline/config/edge_router_upstream.cfg
index a08c5cce..dea42b95 100644
--- a/examples/ip_pipeline/config/edge_router_upstream.cfg
+++ b/examples/ip_pipeline/config/edge_router_upstream.cfg
@@ -1,6 +1,6 @@
; BSD LICENSE
;
-; Copyright(c) 2015 Intel Corporation. All rights reserved.
+; Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
@@ -29,6 +29,7 @@
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
; An edge router typically sits between two networks such as the provider
; core network and the provider access network. A typical packet processing
; pipeline for the upstream traffic (i.e. traffic from access to core
@@ -36,10 +37,10 @@
; Flow classification, Metering, Routing and Packet TX. The input packets
; are assumed to be Q-in-Q IPv4, while the output packets are MPLS IPv4
; (with variable number of labels per route).
-
+;
; A simple implementation for this functional pipeline is presented below.
-
-; Packet Rx & Pass-Through Flow-Classification Flow-Actions Routing
+;
+; Packet RX & Pass-Through Flow Classification Flow Actions Routing
: Firewall
; __________ SWQ0 __________ SWQ4 __________ SWQ8 __________ SWQ12 __________
; RXQ0.0 --->| |------>| |------>| |------>| |------>| |------> TXQ0.0
@@ -51,8 +52,21 @@
; RXQ3.0 --->| |------>| |------>| |------>| |------>| |------> TXQ3.0
; |__________| |__________| |__________| |__________| |__________|
; | | |
-; +--> SINK0 (Default) +--> SINK1 (Default) +--> SINK2 (Route Miss)
+; +--> SINK0 (Default) +--> SINK1 (Default) +--> SINK2 (Default)
+;
+; Input packet: Ethernet/QinQ/IPv4
+; Output packet: Ethernet/MPLS/IPv4
+;
+; Packet buffer layout:
+; # Field Name Offset (Bytes) Size (Bytes)
+; 0 Mbuf 0 128
+; 1 Headroom 128 128
+; 2 Ethernet header 256 14
+; 3 QinQ header 270 8
+; 4 IPv4 header 278 20
+[EAL]
+log_level = 0
[PIPELINE0]
type = MASTER
@@ -72,10 +86,10 @@ core = 2
pktq_in = SWQ0 SWQ1 SWQ2 SWQ3
pktq_out = SWQ4 SWQ5 SWQ6 SWQ7
dma_size = 8
-dma_dst_offset = 128; mbuf (128)
-dma_src_offset = 268; mbuf (128) + headroom (128) + 1st ethertype offset (12) = 268
+dma_dst_offset = 128
+dma_src_offset = 268; 1st Ethertype offset
dma_src_mask = 00000FFF00000FFF; qinq
-dma_hash_offset = 136; dma_dst_offset + dma_size = 136
+dma_hash_offset = 136; dma_dst_offset + dma_size
[PIPELINE3]
type = FLOW_CLASSIFICATION
@@ -86,7 +100,7 @@ n_flows = 65536
key_size = 8; dma_size
key_offset = 128; dma_dst_offset
hash_offset = 136; dma_hash_offset
-flowid_offset = 192; mbuf (128) + 64
+flowid_offset = 192
[PIPELINE4]
type = FLOW_ACTIONS
@@ -96,7 +110,7 @@ pktq_out = SWQ12 SWQ13 SWQ14 SWQ15
n_flows = 65536
n_meters_per_flow = 1
flow_id_offset = 192; flowid_offset
-ip_hdr_offset = 278; mbuf (128) + headroom (128) + ethernet (14) + qinq (8) = 278
+ip_hdr_offset = 278
color_offset = 196; flowid_offset + sizeof(flow_id)
[PIPELINE5]
@@ -106,5 +120,5 @@ pktq_in = SWQ12 SWQ13 SWQ14 SWQ15
pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0 SINK2
encap = ethernet_mpls
mpls_color_mark = yes
-ip_hdr_offset = 278; mbuf (128) + headroom (128) + ethernet (14) + qinq (8) = 278
+ip_hdr_offset = 278
color_offset = 196; flowid_offset + sizeof(flow_id)
diff --git a/examples/ip_pipeline/config/edge_router_upstream.sh b/examples/ip_pipeline/config/edge_router_upstream.sh
index eeba600c..5d574c1a 100644
--- a/examples/ip_pipeline/config/edge_router_upstream.sh
+++ b/examples/ip_pipeline/config/edge_router_upstream.sh
@@ -1,24 +1,26 @@
-################################################
-# Firewall Rules:4 for 4 ports
-################################################
-p 1 firewall add ipv4 1 0.0.0.0 8 0.0.0.0 10 0 0 0 0 6 1 0
-p 1 firewall add ipv4 1 0.0.0.0 8 0.64.0.0 10 0 0 0 0 6 1 1
-p 1 firewall add ipv4 1 0.0.0.0 8 0.128.0.0 10 0 0 0 0 6 1 2
-p 1 firewall add ipv4 1 0.0.0.0 8 0.192.0.0 10 0 0 0 0 6 1 3
-p 1 firewall add default 4 #SINK0
+#
+# run ./config/edge_router_upstream.sh
+#
+################################################################################
+# Firewall
+################################################################################
+p 1 firewall add default 4 #SINK0
+p 1 firewall add bulk ./config/edge_router_upstream_firewall.txt
+#p 1 firewall ls
################################################################################
-# Flow classification
+# Flow Classification
################################################################################
p 3 flow add default 4 #SINK1
-p 3 flow add qinq all 65536 4
+p 3 flow add qinq bulk ./config/edge_router_upstream_flow.txt
+#p 3 flow ls
################################################################################
-# Flow Actions - Metering
+# Flow Actions - Metering and Policing
################################################################################
-p 4 flows 65536 meter 0 trtcm 1250000000 1250000000 100000000 100000000
-p 4 flows 65536 ports 4
+p 4 action flow bulk ./config/edge_router_upstream_action.txt
+#p 4 action flow ls
################################################################################
# Routing: Ether MPLS, ARP off
@@ -28,11 +30,4 @@ p 5 route add 0.0.0.0 10 port 0 ether a0:b0:c0:d0:e0:f0 mpls 0:1
p 5 route add 0.64.0.0 10 port 1 ether a1:b1:c1:d1:e1:f1 mpls 10:11
p 5 route add 0.128.0.0 10 port 2 ether a2:b2:c2:d2:e2:f2 mpls 20:21
p 5 route add 0.192.0.0 10 port 3 ether a3:b3:c3:d3:e3:f3 mpls 30:31
-
-################################################################################
-# List all configurations
-################################################################################
-p 1 firewall ls
-#p 3 flow ls
-#p 4 flow actions ls
-p 5 route ls
+#p 5 route ls
diff --git a/examples/ip_pipeline/config/firewall.cfg b/examples/ip_pipeline/config/firewall.cfg
new file mode 100644
index 00000000..2f5dd9f6
--- /dev/null
+++ b/examples/ip_pipeline/config/firewall.cfg
@@ -0,0 +1,68 @@
+; BSD LICENSE
+;
+; Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
+; All rights reserved.
+;
+; 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 Intel Corporation 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.
+
+; _______________
+; RXQ0.0 --->| |---> TXQ0.0
+; | |
+; RXQ1.0 --->| |---> TXQ1.0
+; | Firewall |
+; RXQ2.0 --->| |---> TXQ2.0
+; | |
+; RXQ3.0 --->| |---> TXQ3.0
+; |_______________|
+; |
+; +-----------> SINK0 (default rule)
+;
+; Input packet: Ethernet/IPv4
+;
+; Packet buffer layout:
+; # Field Name Offset (Bytes) Size (Bytes)
+; 0 Mbuf 0 128
+; 1 Headroom 128 128
+; 2 Ethernet header 256 14
+; 3 IPv4 header 270 20
+
+[EAL]
+log_level = 0
+
+[PIPELINE0]
+type = MASTER
+core = 0
+
+[PIPELINE1]
+type = FIREWALL
+core = 1
+pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0
+pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0 SINK0
+n_rules = 4096
+pkt_type = ipv4
+;pkt_type = vlan_ipv4
+;pkt_type = qinq_ipv4
diff --git a/examples/ip_pipeline/config/firewall.sh b/examples/ip_pipeline/config/firewall.sh
new file mode 100644
index 00000000..c83857ee
--- /dev/null
+++ b/examples/ip_pipeline/config/firewall.sh
@@ -0,0 +1,13 @@
+#
+# run ./config/firewall.sh
+#
+
+p 1 firewall add default 4 #SINK0
+p 1 firewall add priority 1 ipv4 0.0.0.0 0 100.0.0.0 10 0 65535 0 65535 6 0xF port 0
+p 1 firewall add priority 1 ipv4 0.0.0.0 0 100.64.0.0 10 0 65535 0 65535 6 0xF port 1
+p 1 firewall add priority 1 ipv4 0.0.0.0 0 100.128.0.0 10 0 65535 0 65535 6 0xF port 2
+p 1 firewall add priority 1 ipv4 0.0.0.0 0 100.192.0.0 10 0 65535 0 65535 6 0xF port 3
+
+#p 1 firewall add bulk ./config/firewall.txt
+
+p 1 firewall ls
diff --git a/examples/ip_pipeline/config/firewall.txt b/examples/ip_pipeline/config/firewall.txt
new file mode 100644
index 00000000..54cfffda
--- /dev/null
+++ b/examples/ip_pipeline/config/firewall.txt
@@ -0,0 +1,9 @@
+#
+# p <pipelineid> firewall add bulk ./config/firewall.txt
+# p <pipelineid> firewall del bulk ./config/firewall.txt
+#
+
+priority 1 ipv4 0.0.0.0 0 100.0.0.0 10 0 65535 0 65535 6 0xF port 0
+priority 1 ipv4 0.0.0.0 0 100.64.0.0 10 0 65535 0 65535 6 0xF port 1
+priority 1 ipv4 0.0.0.0 0 100.128.0.0 10 0 65535 0 65535 6 0xF port 2
+priority 1 ipv4 0.0.0.0 0 100.192.0.0 10 0 65535 0 65535 6 0xF port 3
diff --git a/examples/ip_pipeline/config/flow.cfg b/examples/ip_pipeline/config/flow.cfg
new file mode 100644
index 00000000..6895d393
--- /dev/null
+++ b/examples/ip_pipeline/config/flow.cfg
@@ -0,0 +1,72 @@
+; BSD LICENSE
+;
+; Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
+; All rights reserved.
+;
+; 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 Intel Corporation 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.
+
+; ________________
+; RXQ0.0 --->| |---> TXQ0.0
+; | |
+; RXQ1.0 --->| |---> TXQ1.0
+; | Flow |
+; RXQ2.0 --->| Classification |---> TXQ2.0
+; | |
+; RXQ3.0 --->| |---> TXQ3.0
+; |________________|
+; |
+; +-----------> SINK0 (flow lookup miss)
+;
+; Input packet: Ethernet/IPv4
+;
+; Packet buffer layout:
+; # Field Name Offset (Bytes) Size (Bytes)
+; 0 Mbuf 0 128
+; 1 Headroom 128 128
+; 2 Ethernet header 256 14
+; 3 QinQ/IPv4/IPv6 header 270 8/20/40
+
+[EAL]
+log_level = 0
+
+[PIPELINE0]
+type = MASTER
+core = 0
+
+[PIPELINE1]
+type = FLOW_CLASSIFICATION
+core = 1
+pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0
+pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0 SINK0
+n_flows = 65536
+;key_size = 8 ; QinQ key size
+;key_offset = 270 ; QinQ key offset
+;key_mask = 0000FFF00000FFF0 ; QinQ key mask
+key_size = 16 ; IPv4 5-tuple key size
+key_offset = 278 ; IPv4 5-tuple key offset
+key_mask = 00FF0000FFFFFFFFFFFFFFFFFFFFFFFF ; IPv4 5-tuple key mask
+flowid_offset = 128
diff --git a/examples/ip_pipeline/config/flow.sh b/examples/ip_pipeline/config/flow.sh
new file mode 100644
index 00000000..489c7079
--- /dev/null
+++ b/examples/ip_pipeline/config/flow.sh
@@ -0,0 +1,25 @@
+#
+# run ./config/flow.sh
+#
+
+################################################################################
+# Flow classification (QinQ)
+################################################################################
+#p 1 flow add default 4 #SINK0
+#p 1 flow add qinq 100 200 port 0 id 0
+#p 1 flow add qinq 101 201 port 1 id 1
+#p 1 flow add qinq 102 202 port 2 id 2
+#p 1 flow add qinq 103 203 port 3 id 3
+
+#p 1 flow add qinq bulk ./config/flow.txt
+
+################################################################################
+# Flow classification (IPv4 5-tuple)
+################################################################################
+p 1 flow add default 4 #SINK0
+p 1 flow add ipv4 100.0.0.10 200.0.0.10 100 200 6 port 0 id 0
+p 1 flow add ipv4 100.0.0.11 200.0.0.11 101 201 6 port 1 id 1
+p 1 flow add ipv4 100.0.0.12 200.0.0.12 102 202 6 port 2 id 2
+p 1 flow add ipv4 100.0.0.13 200.0.0.13 103 203 6 port 3 id 3
+
+#p 1 flow add ipv4 bulk ./config/flow.txt
diff --git a/examples/ip_pipeline/config/flow.txt b/examples/ip_pipeline/config/flow.txt
new file mode 100644
index 00000000..c1a141dd
--- /dev/null
+++ b/examples/ip_pipeline/config/flow.txt
@@ -0,0 +1,17 @@
+#
+# p <pipelineid> flow add qinq bulk ./config/flow.txt
+#
+
+#qinq 100 200 port 0 id 0
+#qinq 101 201 port 1 id 1
+#qinq 102 202 port 2 id 2
+#qinq 103 203 port 3 id 3
+
+#
+# p <pipelineid> flow add ipv4 bulk ./config/flow.txt
+#
+
+ipv4 100.0.0.10 200.0.0.10 100 200 6 port 0 id 0
+ipv4 100.0.0.11 200.0.0.11 101 201 6 port 1 id 1
+ipv4 100.0.0.12 200.0.0.12 102 202 6 port 2 id 2
+ipv4 100.0.0.13 200.0.0.13 103 203 6 port 3 id 3
diff --git a/examples/ip_pipeline/config/kni.cfg b/examples/ip_pipeline/config/kni.cfg
new file mode 100644
index 00000000..cea208b4
--- /dev/null
+++ b/examples/ip_pipeline/config/kni.cfg
@@ -0,0 +1,67 @@
+; BSD LICENSE
+;
+; Copyright(c) 2016 Intel Corporation.
+; All rights reserved.
+;
+; 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 Intel Corporation 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.
+;
+; ______________ ______________________
+; | | KNI0 | |
+; RXQ0.0 --->| |------->|--+ |
+; | | KNI1 | | br0 |
+; TXQ1.0 <---| |<-------|<-+ |
+; | Pass-through | | Linux Kernel |
+; | (P1) | | Network Stack |
+; | | KNI1 | |
+; RXQ1.0 --->| |------->|--+ |
+; | | KNI0 | | br0 |
+; TXQ0.0 <---| |<-------|<-+ |
+; |______________| |______________________|
+;
+; Insert Linux kernel KNI module:
+; [Linux]$ insmod rte_kni.ko
+;
+; Configure Linux kernel bridge between KNI0 and KNI1 interfaces:
+; [Linux]$ ifconfig KNI0 up
+; [Linux]$ ifconfig KNI1 up
+; [Linux]$ brctl addbr "br0"
+; [Linux]$ brctl addif br0 KNI0
+; [Linux]$ brctl addif br0 KNI1
+; [Linux]$ ifconfig br0 up
+
+[EAL]
+log_level = 0
+
+[PIPELINE0]
+type = MASTER
+core = 0
+
+[PIPELINE1]
+type = PASS-THROUGH
+core = 1
+pktq_in = RXQ0.0 KNI1 RXQ1.0 KNI0
+pktq_out = KNI0 TXQ1.0 KNI1 TXQ0.0
diff --git a/examples/ip_pipeline/config/l2fwd.cfg b/examples/ip_pipeline/config/l2fwd.cfg
index c743a143..a1df9e6a 100644
--- a/examples/ip_pipeline/config/l2fwd.cfg
+++ b/examples/ip_pipeline/config/l2fwd.cfg
@@ -1,6 +1,6 @@
; BSD LICENSE
;
-; Copyright(c) 2015 Intel Corporation. All rights reserved.
+; Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
@@ -44,6 +44,9 @@
; |________________|
;
+[EAL]
+log_level = 0
+
[PIPELINE0]
type = MASTER
core = 0
diff --git a/examples/ip_pipeline/config/l3fwd.cfg b/examples/ip_pipeline/config/l3fwd.cfg
index 5449dc32..02c8f36f 100644
--- a/examples/ip_pipeline/config/l3fwd.cfg
+++ b/examples/ip_pipeline/config/l3fwd.cfg
@@ -1,6 +1,6 @@
; BSD LICENSE
;
-; Copyright(c) 2015 Intel Corporation. All rights reserved.
+; Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
@@ -50,6 +50,9 @@
; 2 Ethernet header 256 14
; 3 IPv4 header 270 20
+[EAL]
+log_level = 0
+
[PIPELINE0]
type = MASTER
core = 0
@@ -59,5 +62,7 @@ type = ROUTING
core = 1
pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0
pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0 SINK0
-encap = ethernet; encap = ethernet / ethernet_qinq / ethernet_mpls
+encap = ethernet
+;encap = ethernet_qinq
+;encap = ethernet_mpls
ip_hdr_offset = 270
diff --git a/examples/ip_pipeline/config/l3fwd.sh b/examples/ip_pipeline/config/l3fwd.sh
index 27740103..47406aa4 100644
--- a/examples/ip_pipeline/config/l3fwd.sh
+++ b/examples/ip_pipeline/config/l3fwd.sh
@@ -1,9 +1,33 @@
+#
+# run ./config/l3fwd.sh
+#
+
################################################################################
# Routing: encap = ethernet, arp = off
################################################################################
p 1 route add default 4 #SINK0
-p 1 route add 0.0.0.0 10 port 0 ether a0:b0:c0:d0:e0:f0
-p 1 route add 0.64.0.0 10 port 1 ether a1:b1:c1:d1:e1:f1
-p 1 route add 0.128.0.0 10 port 2 ether a2:b2:c2:d2:e2:f2
-p 1 route add 0.192.0.0 10 port 3 ether a3:b3:c3:d3:e3:f3
+p 1 route add 100.0.0.0 10 port 0 ether a0:b0:c0:d0:e0:f0
+p 1 route add 100.64.0.0 10 port 1 ether a1:b1:c1:d1:e1:f1
+p 1 route add 100.128.0.0 10 port 2 ether a2:b2:c2:d2:e2:f2
+p 1 route add 100.192.0.0 10 port 3 ether a3:b3:c3:d3:e3:f3
p 1 route ls
+
+################################################################################
+# Routing: encap = ethernet_qinq, arp = off
+################################################################################
+#p 1 route add default 4 #SINK0
+#p 1 route add 100.0.0.0 10 port 0 ether a0:b0:c0:d0:e0:f0 qinq 1000 2000
+#p 1 route add 100.64.0.0 10 port 1 ether a1:b1:c1:d1:e1:f1 qinq 1001 2001
+#p 1 route add 100.128.0.0 10 port 2 ether a2:b2:c2:d2:e2:f2 qinq 1002 2002
+#p 1 route add 100.192.0.0 10 port 3 ether a3:b3:c3:d3:e3:f3 qinq 1003 2003
+#p 1 route ls
+
+################################################################################
+# Routing: encap = ethernet_mpls, arp = off
+################################################################################
+#p 1 route add default 4 #SINK0
+#p 1 route add 100.0.0.0 10 port 0 ether a0:b0:c0:d0:e0:f0 mpls 1000:2000
+#p 1 route add 100.64.0.0 10 port 1 ether a1:b1:c1:d1:e1:f1 mpls 1001:2001
+#p 1 route add 100.128.0.0 10 port 2 ether a2:b2:c2:d2:e2:f2 mpls 1002:2002
+#p 1 route add 100.192.0.0 10 port 3 ether a3:b3:c3:d3:e3:f3 mpls 1003:2003
+#p 1 route ls
diff --git a/examples/ip_pipeline/config/l3fwd_arp.cfg b/examples/ip_pipeline/config/l3fwd_arp.cfg
new file mode 100644
index 00000000..2c63c8fd
--- /dev/null
+++ b/examples/ip_pipeline/config/l3fwd_arp.cfg
@@ -0,0 +1,70 @@
+; BSD LICENSE
+;
+; Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
+; All rights reserved.
+;
+; 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 Intel Corporation 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.
+
+; _______________
+; RXQ0.0 --->| |---> TXQ0.0
+; | |
+; RXQ1.0 --->| |---> TXQ1.0
+; | Routing |
+; RXQ2.0 --->| |---> TXQ2.0
+; | |
+; RXQ3.0 --->| |---> TXQ3.0
+; |_______________|
+; |
+; +-----------> SINK0 (route miss)
+;
+; Input packet: Ethernet/IPv4
+;
+; Packet buffer layout:
+; # Field Name Offset (Bytes) Size (Bytes)
+; 0 Mbuf 0 128
+; 1 Headroom 128 128
+; 2 Ethernet header 256 14
+; 3 IPv4 header 270 20
+
+[EAL]
+log_level = 0
+
+[PIPELINE0]
+type = MASTER
+core = 0
+
+[PIPELINE1]
+type = ROUTING
+core = 1
+pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0
+pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0 SINK0
+encap = ethernet
+;encap = ethernet_qinq
+;encap = ethernet_mpls
+n_arp_entries = 1024
+ip_hdr_offset = 270
+arp_key_offset = 128
diff --git a/examples/ip_pipeline/config/l3fwd_arp.sh b/examples/ip_pipeline/config/l3fwd_arp.sh
new file mode 100644
index 00000000..20bea582
--- /dev/null
+++ b/examples/ip_pipeline/config/l3fwd_arp.sh
@@ -0,0 +1,43 @@
+#
+# run ./config/l3fwd_arp.sh
+#
+
+################################################################################
+# ARP
+################################################################################
+p 1 arp add default 4 #SINK0
+p 1 arp add 0 10.0.0.1 a0:b0:c0:d0:e0:f0
+p 1 arp add 1 11.0.0.1 a1:b1:c1:d1:e1:f1
+p 1 arp add 2 12.0.0.1 a2:b2:c2:d2:e2:f2
+p 1 arp add 3 13.0.0.1 a3:b3:c3:d3:e3:f3
+p 1 arp ls
+
+################################################################################
+# Routing: encap = ethernet, arp = on
+################################################################################
+p 1 route add default 4 #SINK0
+p 1 route add 100.0.0.0 10 port 0 ether 10.0.0.1
+p 1 route add 100.64.0.0 10 port 1 ether 11.0.0.1
+p 1 route add 100.128.0.0 10 port 2 ether 12.0.0.1
+p 1 route add 100.192.0.0 10 port 3 ether 13.0.0.1
+p 1 route ls
+
+################################################################################
+# Routing: encap = ethernet_qinq, arp = on
+################################################################################
+#p 1 route add default 4 #SINK0
+#p 1 route add 100.0.0.0 10 port 0 ether 10.0.0.1 qinq 1000 2000
+#p 1 route add 100.64.0.0 10 port 1 ether 11.0.0.1 qinq 1001 2001
+#p 1 route add 100.128.0.0 10 port 2 ether 12.0.0.1 qinq 1002 2002
+#p 1 route add 100.192.0.0 10 port 3 ether 13.0.0.1 qinq 1003 2003
+#p 1 route ls
+
+################################################################################
+# Routing: encap = ethernet_mpls, arp = on
+################################################################################
+#p 1 route add default 4 #SINK0
+#p 1 route add 100.0.0.0 10 port 0 ether 10.0.0.1 mpls 1000:2000
+#p 1 route add 100.64.0.0 10 port 1 ether 11.0.0.1 mpls 1001:2001
+#p 1 route add 100.128.0.0 10 port 2 ether 12.0.0.1 mpls 1002:2002
+#p 1 route add 100.192.0.0 10 port 3 ether 13.0.0.1 mpls 1003:2003
+#p 1 route ls
diff --git a/examples/ip_pipeline/config/network_layers.cfg b/examples/ip_pipeline/config/network_layers.cfg
new file mode 100644
index 00000000..8054d9fe
--- /dev/null
+++ b/examples/ip_pipeline/config/network_layers.cfg
@@ -0,0 +1,223 @@
+; BSD LICENSE
+;
+; Copyright(c) 2016 Intel Corporation. All rights reserved.
+; All rights reserved.
+;
+; 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 Intel Corporation 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.
+
+; The diagram below shows how additional protocol components can be plugged into
+; the IP layer implemented by the ip_pipeline application. Pick your favorite
+; open source components for dynamic ARP, ICMP, UDP or TCP termination, etc and
+; connect them through SWQs to the IP infrastructure.
+;
+; The input packets with local destination are sent to the UDP/TCP applications
+; while the input packets with remote destination are routed back to the
+; network. Additional features can easily be added to this setup:
+; * IP Reassembly: add SWQs with IP reassembly enabled (typically required for
+; the input traffic with local destination);
+; * IP Fragmentation: add SWQs with IP fragmentation enabled (typically
+; required to enforce the MTU for the routed output traffic);
+; * Traffic Metering: add Flow Action pipeline instances (e.g. for metering the
+; TCP connections or ICMP input traffic);
+; * Traffic Management: add TMs for the required output LINKs;
+; * Protocol encapsulations (QinQ, MPLS) for the output packets: part of the
+; routing pipeline configuration.
+;
+; _________ _________
+; | | | |
+; | UDP | | TCP |
+; | App | | App |
+; |_________| |_________|
+; ^ | ^ |
+; __|___V__ __|___V__
+; | | SWQ0 (UDP TX) | | SWQ1 (TCP TX)
+; | UDP |-------+ | TCP |------------+
+; | | | | | |
+; |_________| | |_________| |
+; ^ | ^ |
+; | SWQ2 | | SWQ3 |
+; | (UDP RX) | | (TCP RX) |
+; ____|____ | ____|____ |
+; | | | | | |
+; RXQ<0..3>.1 ------>|Firewall +--->| | +------>| Flow +--->| |
+; (UDP local dest) | (P2) | SINK0 | | | (P3) | SINK1 |
+; |_________| (Deny)| | |_________| (RST) |
+; RXQ<0..3>.2 -------------------------|-----+ |
+; (TCP local dest) | |
+; | +------------------------------+
+; | |
+; _V_____V_
+; | |
+; | Routing | TXQ<0..3>.0
+; RXQ<0..3>.0 ---------------------->| & ARP +----------------------------->
+; (IP remote dest) | (P1) |
+; |_________|
+; | ^ |
+; SWQ4 +-------------+ | | SWQ5 (ARP miss)
+; (Route miss) | | +------------+
+; | +-------------+ |
+; ___V__|__ SWQ6 ____V____
+; | | (ICMP TX) | | TXQ<0..3>.1
+; RXQ<0..3>.3 ------>| ICMP | +------>| Dyn ARP +------------->
+; (IP local dest) | | | | |
+; |_________| | |_________|
+; RXQ<0..3>.4 -------------------------------+
+; (ARP)
+;
+; This configuration file implements the diagram presented below, where the
+; dynamic ARP, ICMP, UDP and TCP components have been stubbed out and replaced
+; with loop-back and packet drop devices.
+;
+; _________ _________
+; | | SWQ0 (UDP TX) | | SWQ1 (TCP TX)
+; |Loobpack |-------+ |Loopback |------------+
+; | (P4) | | | (P5) | |
+; |_________| | |_________| |
+; ^ | ^ |
+; | SWQ2 | | SWQ3 |
+; | (UDP RX) | | (TCP RX) |
+; ____|____ | ____|____ |
+; | | | | | |
+; RXQ<0..3>.1 ------>|Firewall +--->| | +------>| Flow +--->| |
+; (UDP local dest) | (P2) | SINK0 | | | (P3) | SINK1 |
+; |_________| (Deny)| | |_________| (RST) |
+; RXQ<0..3>.2 -------------------------|-----+ |
+; (TCP local dest) | |
+; | +------------------------------+
+; | |
+; _V_____V_
+; | |
+; | Routing | TXQ<0..3>.0
+; RXQ<0..3>.0 ---------------------->| & ARP +----------------------------->
+; (IP remote dest) | (P1) |
+; |_________|
+; | |
+; SINK2 |<---+ +--->| SINK3
+; (Route miss) (ARP miss)
+;
+; _________ _________
+; | | | |
+; RXQ<0..3>.3 ------>| Drop +--->| SINK<4..7> +------>| Drop +--->| SINK<8..11>
+; (IP local dest) | (P6) | (IP local dest) | | (P7) | (ARP)
+; |_________| | |_________|
+; RXQ<0..3>.4 ------------------------------------+
+; (ARP)
+;
+;
+; Input packet: Ethernet/IPv4 or Ethernet/ARP
+; Output packet: Ethernet/IPv4 or Ethernet/ARP
+;
+; Packet buffer layout (for input IPv4 packets):
+; # Field Name Offset (Bytes) Size (Bytes)
+; 0 Mbuf 0 128
+; 1 Headroom 128 128
+; 2 Ethernet header 256 14
+; 3 IPv4 header 270 20
+; 4 ICMP/UDP/TCP header 290 8/8/20
+
+[EAL]
+log_level = 0
+
+[LINK0]
+udp_local_q = 1
+tcp_local_q = 2
+ip_local_q = 3
+arp_q = 4
+
+[LINK1]
+udp_local_q = 1
+tcp_local_q = 2
+ip_local_q = 3
+arp_q = 4
+
+[LINK2]
+udp_local_q = 1
+tcp_local_q = 2
+ip_local_q = 3
+arp_q = 4
+
+[LINK3]
+udp_local_q = 1
+tcp_local_q = 2
+ip_local_q = 3
+arp_q = 4
+
+[PIPELINE0]
+type = MASTER
+core = 0
+
+[PIPELINE1]
+type = ROUTING
+core = 1
+pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0 SWQ0 SWQ1
+pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0 SINK2 SINK3
+port_local_dest = 4 ; SINK2 (Drop)
+n_arp_entries = 1000
+ip_hdr_offset = 270
+arp_key_offset = 128
+
+[PIPELINE2]
+type = FIREWALL
+core = 1
+pktq_in = RXQ0.1 RXQ1.1 RXQ2.1 RXQ3.1
+pktq_out = SWQ2 SINK0
+n_rules = 4096
+
+[PIPELINE3]
+type = FLOW_CLASSIFICATION
+core = 1
+pktq_in = RXQ0.2 RXQ1.2 RXQ2.2 RXQ3.2
+pktq_out = SWQ3 SINK1
+n_flows = 65536
+key_size = 16 ; IPv4 5-tuple key size
+key_offset = 278 ; IPv4 5-tuple key offset
+key_mask = 00FF0000FFFFFFFFFFFFFFFFFFFFFFFF ; IPv4 5-tuple key mask
+flowid_offset = 128 ; Flow ID effectively acts as TCP socket ID
+
+[PIPELINE4]
+type = PASS-THROUGH ; Loop-back (UDP place-holder)
+core = 1
+pktq_in = SWQ2
+pktq_out = SWQ0
+
+[PIPELINE5]
+type = PASS-THROUGH ; Loop-back (TCP place-holder)
+core = 1
+pktq_in = SWQ3
+pktq_out = SWQ1
+
+[PIPELINE6]
+type = PASS-THROUGH ; Drop (ICMP place-holder)
+core = 1
+pktq_in = RXQ0.3 RXQ1.3 RXQ2.3 RXQ3.3
+pktq_out = SINK4 SINK5 SINK6 SINK7
+
+[PIPELINE7]
+type = PASS-THROUGH ; Drop (Dynamic ARP place-holder)
+core = 1
+pktq_in = RXQ0.4 RXQ1.4 RXQ2.4 RXQ3.4
+pktq_out = SINK8 SINK9 SINK10 SINK11
diff --git a/examples/ip_pipeline/config/network_layers.sh b/examples/ip_pipeline/config/network_layers.sh
new file mode 100644
index 00000000..3b86bebd
--- /dev/null
+++ b/examples/ip_pipeline/config/network_layers.sh
@@ -0,0 +1,79 @@
+#
+# run ./config/network_layers.sh
+#
+
+################################################################################
+# Link configuration
+################################################################################
+# Routes added implicitly when links are brought UP:
+# IP Prefix = 10.0.0.1/16 => (Port 0, Local)
+# IP Prefix = 10.0.0.1/32 => (Port 4, Local)
+# IP Prefix = 10.1.0.1/16 => (Port 1, Local)
+# IP Prefix = 10.1.0.1/32 => (Port 4, Local)
+# IP Prefix = 10.2.0.1/16 => (Port 2, Local)
+# IP Prefix = 10.2.0.1/32 => (Port 4, Local)
+# IP Prefix = 10.3.0.1/16 => (Port 3, Local)
+# IP Prefix = 10.3.0.1/32 => (Port 4, Local)
+link 0 down
+link 1 down
+link 2 down
+link 3 down
+link 0 config 10.0.0.1 16
+link 1 config 10.1.0.1 16
+link 2 config 10.2.0.1 16
+link 3 config 10.3.0.1 16
+link 0 up
+link 1 up
+link 2 up
+link 3 up
+#link ls
+
+################################################################################
+# Static ARP
+################################################################################
+p 1 arp add default 5 #SINK3
+p 1 arp add 0 10.0.0.2 a0:b0:c0:d0:e0:f0
+p 1 arp add 1 10.1.0.2 a1:b1:c1:d1:e1:f1
+p 1 arp add 2 10.2.0.2 a2:b2:c2:d2:e2:f2
+p 1 arp add 3 10.3.0.2 a3:b3:c3:d3:e3:f3
+#p 1 arp ls
+
+################################################################################
+# Routes
+################################################################################
+p 1 route add default 4 #SINK2
+p 1 route add 100.0.0.0 16 port 0 ether 10.0.0.2
+p 1 route add 100.1.0.0 16 port 1 ether 10.1.0.2
+p 1 route add 100.2.0.0 16 port 2 ether 10.2.0.2
+p 1 route add 100.3.0.0 16 port 3 ether 10.3.0.2
+#p 1 route ls
+
+################################################################################
+# Local destination UDP traffic
+################################################################################
+# Prio = Lowest: [SA = ANY, DA = ANY, SP = ANY, DP = ANY, PROTO = ANY] => Drop
+# Prio = 1 (High): [SA = ANY, DA = 10.0.0.1, SP = ANY, DP = 1000, PROTO = UDP] => Allow
+# Prio = 1 (High): [SA = ANY, DA = 10.1.0.1, SP = ANY, DP = 1001, PROTO = UDP] => Allow
+# Prio = 1 (High): [SA = ANY, DA = 10.2.0.1, SP = ANY, DP = 1002, PROTO = UDP] => Allow
+# Prio = 1 (High): [SA = ANY, DA = 10.3.0.1, SP = ANY, DP = 1003, PROTO = UDP] => Allow
+p 1 firewall add default 1 #SINK0
+p 2 firewall add priority 1 ipv4 0.0.0.0 0 10.0.0.1 32 0 65535 1000 1000 17 0xF port 0
+p 2 firewall add priority 1 ipv4 0.0.0.0 0 10.1.0.1 32 0 65535 1001 1001 17 0xF port 0
+p 2 firewall add priority 1 ipv4 0.0.0.0 0 10.2.0.1 32 0 65535 1002 1002 17 0xF port 0
+p 2 firewall add priority 1 ipv4 0.0.0.0 0 10.3.0.1 32 0 65535 1003 1003 17 0xF port 0
+#p 2 firewall ls
+
+################################################################################
+# Local destination TCP traffic
+################################################################################
+# Unknown connection => Drop
+# TCP [SA = 100.0.0.10, DA = 10.0.0.1, SP = 1000, DP = 80] => socket ID = 0
+# TCP [SA = 100.1.0.10, DA = 10.1.0.1, SP = 1001, DP = 80] => socket ID = 1
+# TCP [SA = 100.2.0.10, DA = 10.2.0.1, SP = 1002, DP = 80] => socket ID = 2
+# TCP [SA = 100.3.0.10, DA = 10.3.0.1, SP = 1003, DP = 80] => socket ID = 3
+p 3 flow add default 1 #SINK1
+p 3 flow add ipv4 100.0.0.10 10.0.0.1 1000 80 6 port 1 id 0
+p 3 flow add ipv4 100.1.0.10 10.1.0.1 1001 80 6 port 1 id 1
+p 3 flow add ipv4 100.2.0.10 10.2.0.1 1002 80 6 port 1 id 2
+p 3 flow add ipv4 100.3.0.10 10.3.0.1 1003 80 6 port 1 id 3
+#p 3 flow ls
diff --git a/examples/ip_pipeline/config/pipeline-to-core-mapping.py b/examples/ip_pipeline/config/pipeline-to-core-mapping.py
new file mode 100755
index 00000000..37b131c6
--- /dev/null
+++ b/examples/ip_pipeline/config/pipeline-to-core-mapping.py
@@ -0,0 +1,936 @@
+#! /usr/bin/python2
+
+# BSD LICENSE
+#
+# Copyright(c) 2016 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# 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 Intel Corporation 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.
+
+#
+# This script maps the set of pipelines identified (MASTER pipelines are
+# ignored) from the input configuration file to the set of cores
+# provided as input argument and creates configuration files for each of
+# the mapping combinations.
+#
+
+from __future__ import print_function
+import sys
+import errno
+import os
+import re
+import array
+import itertools
+import re
+import argparse
+from collections import namedtuple
+
+# default values
+enable_stage0_traceout = 1
+enable_stage1_traceout = 1
+enable_stage2_traceout = 1
+
+enable_stage1_fileout = 1
+enable_stage2_fileout = 1
+
+Constants = namedtuple('Constants', ['MAX_CORES', 'MAX_PIPELINES'])
+constants = Constants(16, 64)
+
+# pattern for physical core
+pattern_phycore = '^(s|S)\d(c|C)[1-9][0-9]*$'
+reg_phycore = re.compile(pattern_phycore)
+
+
+def popcount(mask):
+ return bin(mask).count("1")
+
+
+def len2mask(length):
+ if (length == 0):
+ return 0
+
+ if (length > 64):
+ sys.exit('error: len2mask - length %i > 64. exiting' % length)
+
+ return int('1' * length, 2)
+
+
+def bitstring_write(n, n_bits):
+ tmpstr = ""
+ if (n_bits > 64):
+ return
+
+ i = n_bits - 1
+ while (i >= 0):
+ cond = (n & (1 << i))
+ if (cond):
+ print('1', end='')
+ tmpstr += '1'
+ else:
+ print('0', end='')
+ tmpstr += '0'
+ i -= 1
+ return tmpstr
+
+
+class Cores0:
+
+ def __init__(self):
+ self.n_pipelines = 0
+
+
+class Cores1:
+
+ def __init__(self):
+ self.pipelines = 0
+ self.n_pipelines = 0
+
+
+class Cores2:
+
+ def __init__(self):
+ self.pipelines = 0
+ self.n_pipelines = 0
+ self.counter = 0
+ self.counter_max = 0
+ self.bitpos = array.array(
+ "L", itertools.repeat(0, constants.MAX_PIPELINES))
+
+
+class Context0:
+
+ def __init__(self):
+ self.cores = [Cores0() for i in range(0, constants.MAX_CORES)]
+ self.n_cores = 0
+ self.n_pipelines = 0
+ self.n_pipelines0 = 0
+ self.pos = 0
+ self.file_comment = ""
+ self.ctx1 = None
+ self.ctx2 = None
+
+ def stage0_print(self):
+ print('printing Context0 obj')
+ print('c0.cores(n_pipelines) = [ ', end='')
+ for cores_count in range(0, constants.MAX_CORES):
+ print(self.cores[cores_count].n_pipelines, end=' ')
+ print(']')
+ print('c0.n_cores = %d' % self.n_cores)
+ print('c0.n_pipelines = %d' % self.n_pipelines)
+ print('c0.n_pipelines0 = %d' % self.n_pipelines0)
+ print('c0.pos = %d' % self.pos)
+ print('c0.file_comment = %s' % self.file_comment)
+ if (self.ctx1 is not None):
+ print('c0.ctx1 = ', end='')
+ print(repr(self.ctx1))
+ else:
+ print('c0.ctx1 = None')
+
+ if (self.ctx2 is not None):
+ print('c0.ctx2 = ', end='')
+ print(repr(self.ctx2))
+ else:
+ print('c0.ctx2 = None')
+
+ def stage0_init(self, num_cores, num_pipelines, ctx1, ctx2):
+ self.n_cores = num_cores
+ self.n_pipelines = num_pipelines
+ self.ctx1 = ctx1
+ self.ctx2 = ctx2
+
+ def stage0_process(self):
+ # stage0 init
+ self.cores[0].n_pipelines = self.n_pipelines
+ self.n_pipelines0 = 0
+ self.pos = 1
+
+ while True:
+ # go forward
+ while True:
+ if ((self.pos < self.n_cores) and (self.n_pipelines0 > 0)):
+ self.cores[self.pos].n_pipelines = min(
+ self.cores[self.pos - 1].n_pipelines,
+ self.n_pipelines0)
+ self.n_pipelines0 -= self.cores[self.pos].n_pipelines
+ self.pos += 1
+ else:
+ break
+
+ # check solution
+ if (self.n_pipelines0 == 0):
+ self.stage0_log()
+ self.ctx1.stage1_init(self, self.ctx2) # self is object c0
+ self.ctx1.stage1_process()
+
+ # go backward
+ while True:
+ if (self.pos == 0):
+ return
+
+ self.pos -= 1
+ if ((self.cores[self.pos].n_pipelines > 1) and
+ (self.pos != (self.n_cores - 1))):
+ break
+
+ self.n_pipelines0 += self.cores[self.pos].n_pipelines
+ self.cores[self.pos].n_pipelines = 0
+
+ # rearm
+ self.cores[self.pos].n_pipelines -= 1
+ self.n_pipelines0 += 1
+ self.pos += 1
+
+ def stage0_log(self):
+ tmp_file_comment = ""
+ if(enable_stage0_traceout != 1):
+ return
+
+ print('STAGE0: ', end='')
+ tmp_file_comment += 'STAGE0: '
+ for cores_count in range(0, self.n_cores):
+ print('C%d = %d\t'
+ % (cores_count,
+ self.cores[cores_count].n_pipelines), end='')
+ tmp_file_comment += "C{} = {}\t".format(
+ cores_count, self.cores[cores_count].n_pipelines)
+ # end for
+ print('')
+ self.ctx1.stage0_file_comment = tmp_file_comment
+ self.ctx2.stage0_file_comment = tmp_file_comment
+
+
+class Context1:
+ _fileTrace = None
+
+ def __init__(self):
+ self.cores = [Cores1() for i in range(constants.MAX_CORES)]
+ self.n_cores = 0
+ self.n_pipelines = 0
+ self.pos = 0
+ self.stage0_file_comment = ""
+ self.stage1_file_comment = ""
+
+ self.ctx2 = None
+ self.arr_pipelines2cores = []
+
+ def stage1_reset(self):
+ for i in range(constants.MAX_CORES):
+ self.cores[i].pipelines = 0
+ self.cores[i].n_pipelines = 0
+
+ self.n_cores = 0
+ self.n_pipelines = 0
+ self.pos = 0
+ self.ctx2 = None
+ # clear list
+ del self.arr_pipelines2cores[:]
+
+ def stage1_print(self):
+ print('printing Context1 obj')
+ print('ctx1.cores(pipelines,n_pipelines) = [ ', end='')
+ for cores_count in range(0, constants.MAX_CORES):
+ print('(%d,%d)' % (self.cores[cores_count].pipelines,
+ self.cores[cores_count].n_pipelines), end=' ')
+ print(']')
+ print('ctx1.n_cores = %d' % self.n_cores)
+ print('ctx1.n_pipelines = %d' % self.n_pipelines)
+ print('ctx1.pos = %d' % self.pos)
+ print('ctx1.stage0_file_comment = %s' % self.stage0_file_comment)
+ print('ctx1.stage1_file_comment = %s' % self.stage1_file_comment)
+ if (self.ctx2 is not None):
+ print('ctx1.ctx2 = ', end='')
+ print(self.ctx2)
+ else:
+ print('ctx1.ctx2 = None')
+
+ def stage1_init(self, c0, ctx2):
+ self.stage1_reset()
+ self.n_cores = 0
+ while (c0.cores[self.n_cores].n_pipelines > 0):
+ self.n_cores += 1
+
+ self.n_pipelines = c0.n_pipelines
+ self.ctx2 = ctx2
+
+ self.arr_pipelines2cores = [0] * self.n_pipelines
+
+ i = 0
+ while (i < self.n_cores):
+ self.cores[i].n_pipelines = c0.cores[i].n_pipelines
+ i += 1
+
+ def stage1_process(self):
+ pipelines_max = len2mask(self.n_pipelines)
+ while True:
+ pos = 0
+ overlap = 0
+
+ if (self.cores[self.pos].pipelines == pipelines_max):
+ if (self.pos == 0):
+ return
+
+ self.cores[self.pos].pipelines = 0
+ self.pos -= 1
+ continue
+
+ self.cores[self.pos].pipelines += 1
+ if (popcount(self.cores[self.pos].pipelines) !=
+ self.cores[self.pos].n_pipelines):
+ continue
+
+ overlap = 0
+ pos = 0
+ while (pos < self.pos):
+ if ((self.cores[self.pos].pipelines) &
+ (self.cores[pos].pipelines)):
+ overlap = 1
+ break
+ pos += 1
+
+ if (overlap):
+ continue
+
+ if ((self.pos > 0) and
+ ((self.cores[self.pos].n_pipelines) ==
+ (self.cores[self.pos - 1].n_pipelines)) and
+ ((self.cores[self.pos].pipelines) <
+ (self.cores[self.pos - 1].pipelines))):
+ continue
+
+ if (self.pos == self.n_cores - 1):
+ self.stage1_log()
+ self.ctx2.stage2_init(self)
+ self.ctx2.stage2_process()
+
+ if (self.pos == 0):
+ return
+
+ self.cores[self.pos].pipelines = 0
+ self.pos -= 1
+ continue
+
+ self.pos += 1
+
+ def stage1_log(self):
+ tmp_file_comment = ""
+ if(enable_stage1_traceout == 1):
+ print('STAGE1: ', end='')
+ tmp_file_comment += 'STAGE1: '
+ i = 0
+ while (i < self.n_cores):
+ print('C%d = [' % i, end='')
+ tmp_file_comment += "C{} = [".format(i)
+
+ j = self.n_pipelines - 1
+ while (j >= 0):
+ cond = ((self.cores[i].pipelines) & (1 << j))
+ if (cond):
+ print('1', end='')
+ tmp_file_comment += '1'
+ else:
+ print('0', end='')
+ tmp_file_comment += '0'
+ j -= 1
+
+ print(']\t', end='')
+ tmp_file_comment += ']\t'
+ i += 1
+
+ print('\n', end='')
+ self.stage1_file_comment = tmp_file_comment
+ self.ctx2.stage1_file_comment = tmp_file_comment
+
+ # check if file traceing is enabled
+ if(enable_stage1_fileout != 1):
+ return
+
+ # spit out the combination to file
+ self.stage1_process_file()
+
+ def stage1_updateCoresInBuf(self, nPipeline, sCore):
+ rePipeline = self._fileTrace.arr_pipelines[nPipeline]
+ rePipeline = rePipeline.replace("[", "\[").replace("]", "\]")
+ reCore = 'core\s*=\s*((\d*)|(((s|S)\d)?(c|C)[1-9][0-9]*)).*\n'
+ sSubs = 'core = ' + sCore + '\n'
+
+ reg_pipeline = re.compile(rePipeline)
+ search_match = reg_pipeline.search(self._fileTrace.in_buf)
+
+ if(search_match):
+ pos = search_match.start()
+ substr1 = self._fileTrace.in_buf[:pos]
+ substr2 = self._fileTrace.in_buf[pos:]
+ substr2 = re.sub(reCore, sSubs, substr2, 1)
+ self._fileTrace.in_buf = substr1 + substr2
+
+ def stage1_process_file(self):
+ outFileName = os.path.join(self._fileTrace.out_path,
+ self._fileTrace.prefix_outfile)
+ outFileName += "_{}CoReS".format(self.n_cores)
+
+ i = 0 # represents core number
+ while (i < self.n_cores):
+ j = self.n_pipelines - 1
+ pipeline_idx = 0
+ while(j >= 0):
+ cond = ((self.cores[i].pipelines) & (1 << j))
+ if (cond):
+ # update the pipelines array to match the core
+ # only in case of cond match
+ self.arr_pipelines2cores[
+ pipeline_idx] = fileTrace.in_physical_cores[i]
+
+ j -= 1
+ pipeline_idx += 1
+
+ i += 1
+
+ # update the in_buf as per the arr_pipelines2cores
+ for pipeline_idx in range(len(self.arr_pipelines2cores)):
+ outFileName += "_{}".format(self.arr_pipelines2cores[pipeline_idx])
+ self.stage1_updateCoresInBuf(
+ pipeline_idx, self.arr_pipelines2cores[pipeline_idx])
+
+ # by now the in_buf is all set to be written to file
+ outFileName += self._fileTrace.suffix_outfile
+ outputFile = open(outFileName, "w")
+
+ # write out the comments
+ strTruncated = ("", "(Truncated)")[self._fileTrace.ncores_truncated]
+ outputFile.write(
+ "; =============== Pipeline-to-Core Mapping ================\n"
+ "; Generated from file {}\n"
+ "; Input pipelines = {}\n"
+ "; Input cores = {}\n"
+ "; N_PIPELINES = {} N_CORES = {} {} hyper_thread = {}\n"
+ .format(
+ self._fileTrace.in_file_namepath,
+ fileTrace.arr_pipelines,
+ fileTrace.in_physical_cores,
+ self._fileTrace.n_pipelines,
+ self._fileTrace.n_cores,
+ strTruncated,
+ self._fileTrace.hyper_thread))
+
+ outputFile.write(
+ "; {stg0cmt}\n"
+ "; {stg1cmt}\n"
+ "; ========================================================\n"
+ "; \n"
+ .format(
+ stg0cmt=self.stage0_file_comment,
+ stg1cmt=self.stage1_file_comment))
+
+ # write buffer contents
+ outputFile.write(self._fileTrace.in_buf)
+ outputFile.flush()
+ outputFile.close()
+
+
+class Context2:
+ _fileTrace = None
+
+ def __init__(self):
+ self.cores = [Cores2() for i in range(constants.MAX_CORES)]
+ self.n_cores = 0
+ self.n_pipelines = 0
+ self.pos = 0
+ self.stage0_file_comment = ""
+ self.stage1_file_comment = ""
+ self.stage2_file_comment = ""
+
+ # each array entry is a pipeline mapped to core stored as string
+ # pipeline ranging from 1 to n, however stored in zero based array
+ self.arr2_pipelines2cores = []
+
+ def stage2_print(self):
+ print('printing Context2 obj')
+ print('ctx2.cores(pipelines, n_pipelines, counter, counter_max) =')
+ for cores_count in range(0, constants.MAX_CORES):
+ print('core[%d] = (%d,%d,%d,%d)' % (
+ cores_count,
+ self.cores[cores_count].pipelines,
+ self.cores[cores_count].n_pipelines,
+ self.cores[cores_count].counter,
+ self.cores[cores_count].counter_max))
+
+ print('ctx2.n_cores = %d' % self.n_cores, end='')
+ print('ctx2.n_pipelines = %d' % self.n_pipelines, end='')
+ print('ctx2.pos = %d' % self.pos)
+ print('ctx2.stage0_file_comment = %s' %
+ self.self.stage0_file_comment)
+ print('ctx2.stage1_file_comment = %s' %
+ self.self.stage1_file_comment)
+ print('ctx2.stage2_file_comment = %s' %
+ self.self.stage2_file_comment)
+
+ def stage2_reset(self):
+ for i in range(0, constants.MAX_CORES):
+ self.cores[i].pipelines = 0
+ self.cores[i].n_pipelines = 0
+ self.cores[i].counter = 0
+ self.cores[i].counter_max = 0
+
+ for idx in range(0, constants.MAX_PIPELINES):
+ self.cores[i].bitpos[idx] = 0
+
+ self.n_cores = 0
+ self.n_pipelines = 0
+ self.pos = 0
+ # clear list
+ del self.arr2_pipelines2cores[:]
+
+ def bitpos_load(self, coreidx):
+ i = j = 0
+ while (i < self.n_pipelines):
+ if ((self.cores[coreidx].pipelines) &
+ (1 << i)):
+ self.cores[coreidx].bitpos[j] = i
+ j += 1
+ i += 1
+ self.cores[coreidx].n_pipelines = j
+
+ def bitpos_apply(self, in_buf, pos, n_pos):
+ out = 0
+ for i in range(0, n_pos):
+ out |= (in_buf & (1 << i)) << (pos[i] - i)
+
+ return out
+
+ def stage2_init(self, ctx1):
+ self.stage2_reset()
+ self.n_cores = ctx1.n_cores
+ self.n_pipelines = ctx1.n_pipelines
+
+ self.arr2_pipelines2cores = [''] * self.n_pipelines
+
+ core_idx = 0
+ while (core_idx < self.n_cores):
+ self.cores[core_idx].pipelines = ctx1.cores[core_idx].pipelines
+
+ self.bitpos_load(core_idx)
+ core_idx += 1
+
+ def stage2_log(self):
+ tmp_file_comment = ""
+ if(enable_stage2_traceout == 1):
+ print('STAGE2: ', end='')
+ tmp_file_comment += 'STAGE2: '
+
+ for i in range(0, self.n_cores):
+ mask = len2mask(self.cores[i].n_pipelines)
+ pipelines_ht0 = self.bitpos_apply(
+ (~self.cores[i].counter) & mask,
+ self.cores[i].bitpos,
+ self.cores[i].n_pipelines)
+
+ pipelines_ht1 = self.bitpos_apply(
+ self.cores[i].counter,
+ self.cores[i].bitpos,
+ self.cores[i].n_pipelines)
+
+ print('C%dHT0 = [' % i, end='')
+ tmp_file_comment += "C{}HT0 = [".format(i)
+ tmp_file_comment += bitstring_write(
+ pipelines_ht0, self.n_pipelines)
+
+ print(']\tC%dHT1 = [' % i, end='')
+ tmp_file_comment += "]\tC{}HT1 = [".format(i)
+ tmp_file_comment += bitstring_write(
+ pipelines_ht1, self.n_pipelines)
+ print(']\t', end='')
+ tmp_file_comment += ']\t'
+
+ print('')
+ self.stage2_file_comment = tmp_file_comment
+
+ # check if file traceing is enabled
+ if(enable_stage2_fileout != 1):
+ return
+ # spit out the combination to file
+ self.stage2_process_file()
+
+ def stage2_updateCoresInBuf(self, nPipeline, sCore):
+ rePipeline = self._fileTrace.arr_pipelines[nPipeline]
+ rePipeline = rePipeline.replace("[", "\[").replace("]", "\]")
+ reCore = 'core\s*=\s*((\d*)|(((s|S)\d)?(c|C)[1-9][0-9]*)).*\n'
+ sSubs = 'core = ' + sCore + '\n'
+
+ reg_pipeline = re.compile(rePipeline)
+ search_match = reg_pipeline.search(self._fileTrace.in_buf)
+
+ if(search_match):
+ pos = search_match.start()
+ substr1 = self._fileTrace.in_buf[:pos]
+ substr2 = self._fileTrace.in_buf[pos:]
+ substr2 = re.sub(reCore, sSubs, substr2, 1)
+ self._fileTrace.in_buf = substr1 + substr2
+
+ def pipelines2cores(self, n, n_bits, nCore, bHT):
+ if (n_bits > 64):
+ return
+
+ i = n_bits - 1
+ pipeline_idx = 0
+ while (i >= 0):
+ cond = (n & (1 << i))
+ if (cond):
+ # update the pipelines array to match the core
+ # only in case of cond match
+ # PIPELINE0 and core 0 are reserved
+ if(bHT):
+ tmpCore = fileTrace.in_physical_cores[nCore] + 'h'
+ self.arr2_pipelines2cores[pipeline_idx] = tmpCore
+ else:
+ self.arr2_pipelines2cores[pipeline_idx] = \
+ fileTrace.in_physical_cores[nCore]
+
+ i -= 1
+ pipeline_idx += 1
+
+ def stage2_process_file(self):
+ outFileName = os.path.join(self._fileTrace.out_path,
+ self._fileTrace.prefix_outfile)
+ outFileName += "_{}CoReS".format(self.n_cores)
+
+ for i in range(0, self.n_cores):
+ mask = len2mask(self.cores[i].n_pipelines)
+ pipelines_ht0 = self.bitpos_apply((~self.cores[i].counter) & mask,
+ self.cores[i].bitpos,
+ self.cores[i].n_pipelines)
+
+ pipelines_ht1 = self.bitpos_apply(self.cores[i].counter,
+ self.cores[i].bitpos,
+ self.cores[i].n_pipelines)
+
+ # update pipelines to core mapping
+ self.pipelines2cores(pipelines_ht0, self.n_pipelines, i, False)
+ self.pipelines2cores(pipelines_ht1, self.n_pipelines, i, True)
+
+ # update the in_buf as per the arr_pipelines2cores
+ for pipeline_idx in range(len(self.arr2_pipelines2cores)):
+ outFileName += "_{}".format(
+ self.arr2_pipelines2cores[pipeline_idx])
+ self.stage2_updateCoresInBuf(
+ pipeline_idx, self.arr2_pipelines2cores[pipeline_idx])
+
+ # by now the in_buf is all set to be written to file
+ outFileName += self._fileTrace.suffix_outfile
+ outputFile = open(outFileName, "w")
+
+ # write the file comments
+ strTruncated = ("", "(Truncated)")[self._fileTrace.ncores_truncated]
+ outputFile.write(
+ "; =============== Pipeline-to-Core Mapping ================\n"
+ "; Generated from file {}\n"
+ "; Input pipelines = {}\n"
+ "; Input cores = {}\n"
+ "; N_PIPELINES = {} N_CORES = {} {} hyper_thread = {} \n"
+ .format(
+ self._fileTrace.in_file_namepath,
+ fileTrace.arr_pipelines,
+ fileTrace.in_physical_cores,
+ self._fileTrace.n_pipelines,
+ self._fileTrace.n_cores,
+ strTruncated,
+ self._fileTrace.hyper_thread))
+
+ outputFile.write(
+ "; {stg0cmt}\n"
+ "; {stg1cmt}\n"
+ "; {stg2cmt}\n"
+ "; ========================================================\n"
+ "; \n"
+ .format(
+ stg0cmt=self.stage0_file_comment,
+ stg1cmt=self.stage1_file_comment,
+ stg2cmt=self.stage2_file_comment))
+
+ # write the buffer contents
+ outputFile.write(self._fileTrace.in_buf)
+ outputFile.flush()
+ outputFile.close()
+
+ def stage2_process(self):
+ i = 0
+ while(i < self.n_cores):
+ self.cores[i].counter_max = len2mask(
+ self.cores[i].n_pipelines - 1)
+ i += 1
+
+ self.pos = self.n_cores - 1
+ while True:
+ if (self.pos == self.n_cores - 1):
+ self.stage2_log()
+
+ if (self.cores[self.pos].counter ==
+ self.cores[self.pos].counter_max):
+ if (self.pos == 0):
+ return
+
+ self.cores[self.pos].counter = 0
+ self.pos -= 1
+ continue
+
+ self.cores[self.pos].counter += 1
+ if(self.pos < self.n_cores - 1):
+ self.pos += 1
+
+
+class FileTrace:
+
+ def __init__(self, filenamepath):
+ self.in_file_namepath = os.path.abspath(filenamepath)
+ self.in_filename = os.path.basename(self.in_file_namepath)
+ self.in_path = os.path.dirname(self.in_file_namepath)
+
+ filenamesplit = self.in_filename.split('.')
+ self.prefix_outfile = filenamesplit[0]
+ self.suffix_outfile = ".cfg"
+
+ # output folder: in the same folder as input file
+ # create new folder in the name of input file
+ self.out_path = os.path.join(
+ os.path.abspath(os.path.dirname(__file__)),
+ self.prefix_outfile)
+
+ try:
+ os.makedirs(self.out_path)
+ except OSError as excep:
+ if excep.errno == errno.EEXIST and os.path.isdir(self.out_path):
+ pass
+ else:
+ raise
+
+ self.in_buf = None
+ self.arr_pipelines = [] # holds the positions of search
+
+ self.max_cores = 15
+ self.max_pipelines = 15
+
+ self.in_physical_cores = None
+ self.hyper_thread = None
+
+ # save the num of pipelines determined from input file
+ self.n_pipelines = 0
+ # save the num of cores input (or the truncated value)
+ self.n_cores = 0
+ self.ncores_truncated = False
+
+ def print_TraceFile(self):
+ print("self.in_file_namepath = ", self.in_file_namepath)
+ print("self.in_filename = ", self.in_filename)
+ print("self.in_path = ", self.in_path)
+ print("self.out_path = ", self.out_path)
+ print("self.prefix_outfile = ", self.prefix_outfile)
+ print("self.suffix_outfile = ", self.suffix_outfile)
+ print("self.in_buf = ", self.in_buf)
+ print("self.arr_pipelines =", self.arr_pipelines)
+ print("self.in_physical_cores", self.in_physical_cores)
+ print("self.hyper_thread", self.hyper_thread)
+
+
+def process(n_cores, n_pipelines, fileTrace):
+ '''process and map pipelines, cores.'''
+ if (n_cores == 0):
+ sys.exit('N_CORES is 0, exiting')
+
+ if (n_pipelines == 0):
+ sys.exit('N_PIPELINES is 0, exiting')
+
+ if (n_cores > n_pipelines):
+ print('\nToo many cores, truncating N_CORES to N_PIPELINES')
+ n_cores = n_pipelines
+ fileTrace.ncores_truncated = True
+
+ fileTrace.n_pipelines = n_pipelines
+ fileTrace.n_cores = n_cores
+
+ strTruncated = ("", "(Truncated)")[fileTrace.ncores_truncated]
+ print("N_PIPELINES = {}, N_CORES = {} {}"
+ .format(n_pipelines, n_cores, strTruncated))
+ print("---------------------------------------------------------------")
+
+ ctx0_inst = Context0()
+ ctx1_inst = Context1()
+ ctx2_inst = Context2()
+
+ # initialize the class variables
+ ctx1_inst._fileTrace = fileTrace
+ ctx2_inst._fileTrace = fileTrace
+
+ ctx0_inst.stage0_init(n_cores, n_pipelines, ctx1_inst, ctx2_inst)
+ ctx0_inst.stage0_process()
+
+
+def validate_core(core):
+ match = reg_phycore.match(core)
+ if(match):
+ return True
+ else:
+ return False
+
+
+def validate_phycores(phy_cores):
+ '''validate physical cores, check if unique.'''
+ # eat up whitespaces
+ phy_cores = phy_cores.strip().split(',')
+
+ # check if the core list is unique
+ if(len(phy_cores) != len(set(phy_cores))):
+ print('list of physical cores has duplicates')
+ return None
+
+ for core in phy_cores:
+ if not validate_core(core):
+ print('invalid physical core specified.')
+ return None
+ return phy_cores
+
+
+def scanconfigfile(fileTrace):
+ '''scan input file for pipelines, validate then process.'''
+ # open file
+ filetoscan = open(fileTrace.in_file_namepath, 'r')
+ fileTrace.in_buf = filetoscan.read()
+
+ # reset iterator on open file
+ filetoscan.seek(0)
+
+ # scan input file for pipelines
+ # master pipelines to be ignored
+ pattern_pipeline = r'\[PIPELINE\d*\]'
+ pattern_mastertype = r'type\s*=\s*MASTER'
+
+ pending_pipeline = False
+ for line in filetoscan:
+ match_pipeline = re.search(pattern_pipeline, line)
+ match_type = re.search('type\s*=', line)
+ match_mastertype = re.search(pattern_mastertype, line)
+
+ if(match_pipeline):
+ sPipeline = line[match_pipeline.start():match_pipeline.end()]
+ pending_pipeline = True
+ elif(match_type):
+ # found a type definition...
+ if(match_mastertype is None):
+ # and this is not a master pipeline...
+ if(pending_pipeline):
+ # add it to the list of pipelines to be mapped
+ fileTrace.arr_pipelines.append(sPipeline)
+ pending_pipeline = False
+ else:
+ # and this is a master pipeline...
+ # ignore the current and move on to next
+ sPipeline = ""
+ pending_pipeline = False
+ filetoscan.close()
+
+ # validate if pipelines are unique
+ if(len(fileTrace.arr_pipelines) != len(set(fileTrace.arr_pipelines))):
+ sys.exit('Error: duplicate pipelines in input file')
+
+ num_pipelines = len(fileTrace.arr_pipelines)
+ num_cores = len(fileTrace.in_physical_cores)
+
+ print("-------------------Pipeline-to-core mapping--------------------")
+ print("Input pipelines = {}\nInput cores = {}"
+ .format(fileTrace.arr_pipelines, fileTrace.in_physical_cores))
+
+ # input configuration file validations goes here
+ if (num_cores > fileTrace.max_cores):
+ sys.exit('Error: number of cores specified > max_cores (%d)' %
+ fileTrace.max_cores)
+
+ if (num_pipelines > fileTrace.max_pipelines):
+ sys.exit('Error: number of pipelines in input \
+ cfg file > max_pipelines (%d)' % fileTrace.max_pipelines)
+
+ # call process to generate pipeline-to-core mapping, trace and log
+ process(num_cores, num_pipelines, fileTrace)
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(description='mappipelines')
+
+ reqNamedGrp = parser.add_argument_group('required named args')
+ reqNamedGrp.add_argument(
+ '-i',
+ '--input-file',
+ type=argparse.FileType('r'),
+ help='Input config file',
+ required=True)
+
+ reqNamedGrp.add_argument(
+ '-pc',
+ '--physical-cores',
+ type=validate_phycores,
+ help='''Enter available CPU cores in
+ format:\"<core>,<core>,...\"
+ where each core format: \"s<SOCKETID>c<COREID>\"
+ where SOCKETID={0..9}, COREID={1-99}''',
+ required=True)
+
+ # add optional arguments
+ parser.add_argument(
+ '-ht',
+ '--hyper-thread',
+ help='enable/disable hyper threading. default is ON',
+ default='ON',
+ choices=['ON', 'OFF'])
+
+ parser.add_argument(
+ '-nO',
+ '--no-output-file',
+ help='''disable output config file generation.
+ Output file generation is enabled by default''',
+ action="store_true")
+
+ args = parser.parse_args()
+
+ if(args.physical_cores is None):
+ parser.error("invalid physical_cores specified")
+
+ # create object of FileTrace and initialise
+ fileTrace = FileTrace(args.input_file.name)
+ fileTrace.in_physical_cores = args.physical_cores
+ fileTrace.hyper_thread = args.hyper_thread
+
+ if(fileTrace.hyper_thread == 'OFF'):
+ print("!!!!disabling stage2 HT!!!!")
+ enable_stage2_traceout = 0
+ enable_stage2_fileout = 0
+ elif(fileTrace.hyper_thread == 'ON'):
+ print("!!!!HT enabled. disabling stage1 file generation.!!!!")
+ enable_stage1_fileout = 0
+
+ if(args.no_output_file is True):
+ print("!!!!disabling stage1 and stage2 fileout!!!!")
+ enable_stage1_fileout = 0
+ enable_stage2_fileout = 0
+
+ scanconfigfile(fileTrace)