2 # Copyright (c) 2013, 2014, 2015 Nicira, Inc.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
22 def flow_str(stage
, match
, action
, priority
=32768):
23 mtd_match
= "metadata=%d" % stage
25 mtd_match
+= "," + match
27 return "priority=%d %s,actions=%s" % (priority
, mtd_match
, action
)
31 return "load:%d->OXM_OF_METADATA[],resubmit(,0)" % nxt
35 return ("%d.%d.%d.%d" % (random
.randint(0, 255), random
.randint(0, 255),
36 random
.randint(0, 255), random
.randint(0, 255)),
37 random
.choice([8, 16, 24, 32]))
41 return bool(random
.randint(0, 1))
44 def l2(stage
, action
):
45 mac
= ["%x" % random
.randint(0, 2 ** 8 - 1) for x
in range(6)]
46 mac
= [x
.zfill(2) for x
in mac
]
48 return flow_str(stage
, "dl_dst=%s" % mac
, action
)
51 def l3(stage
, action
):
52 ip
, mask
= rand_ip_mask()
53 return flow_str(stage
, "ip,ip_dst=%s/%d" % (ip
, mask
), action
,
57 def l4(stage
, action
):
61 match
+= ",ip_src=%s/%d" % rand_ip_mask()
64 match
+= ",ip_dst=%s/%d" % rand_ip_mask()
66 src_dst
= "tp_src" if rand_bool() else "tp_dst"
67 match
+= ",%s=%d" % (src_dst
, random
.randint(1024, 2 ** 16 - 1))
68 return flow_str(stage
, match
, action
)
72 pipeline
= [l2
, l3
, l4
, l2
]
75 for stage
in range(len(pipeline
)):
76 action
= resubmit(stage
+ 1)
77 flows
+= [pipeline
[stage
](stage
, action
) for _
in range(size
)]
78 flows
.append(flow_str(stage
, "", action
, priority
=1))
80 flows
.append(flow_str(len(pipeline
), "", "in_port"))
87 description
= textwrap
.dedent(
89 Generate a test OpenFlow pipeline.
91 Open vSwitch relies heavily on flow caching to get good performance for
92 packet processing. While on average, this produces good results,
93 performance is heavily depedent on the slow path OpenFlow tables, and
94 how they're translated into datapath megaflows. For this reason, when
95 doing performance testing it's important to run with "realistic"
96 OpenFlow tables to ensure results will stand up in the real world.
98 This script generates a simple OpenFlow pipeline intended to simulate
99 realistic network virtualization workloads. All traffic received is
100 run through a series of OpenFlow tables designed to simulate a logical
101 switch, router, and firewall, before forwarded back on the in_port.
104 epilog
= textwrap
.dedent(
107 ovs-ofctl del-flows bridge \\
108 && %s | ovs-ofctl add-flows bridge - \\
109 && ovs-ofctl dump-flows bridge
112 parser
= argparse
.ArgumentParser(description
=description
, epilog
=epilog
,
113 formatter_class
=argparse
.RawDescriptionHelpFormatter
)
114 parser
.add_argument("--size", dest
="size", default
=1000,
115 help="Size (rules) of each OpenFlow table.")
116 args
= parser
.parse_args()
118 pipeline(int(args
.size
))
121 if __name__
== "__main__":