]> git.proxmox.com Git - mirror_ovs.git/blame - utilities/ovs-pipegen.py
ovs-tcpdump: Do not import unused "select" module.
[mirror_ovs.git] / utilities / ovs-pipegen.py
CommitLineData
f6783a7a 1#! /usr/bin/env python
c875bb94
EJ
2# Copyright (c) 2013, 2014, 2015 Nicira, Inc.
3#
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:
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
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.
15
16import argparse
17import random
18import sys
19import textwrap
20
21def flow_str(stage, match, action, priority=32768):
22 mtd_match = "metadata=%d" % stage
23 if match:
24 mtd_match += "," + match
25
26 return "priority=%d %s,actions=%s" % (priority, mtd_match, action)
27
28
29def resubmit(nxt):
30 return "load:%d->OXM_OF_METADATA[],resubmit(,0)" % nxt
31
32
33def rand_ip_mask():
34 return ("%d.%d.%d.%d" % (random.randint(0, 255), random.randint(0, 255),
35 random.randint(0, 255), random.randint(0, 255)),
36 random.choice([8, 16, 24, 32]))
37
38
39def rand_bool():
40 return bool(random.randint(0, 1))
41
42
43def l2(stage, action):
44 mac = ["%x" % random.randint(0, 2 ** 8 - 1) for x in range(6)]
45 mac = [x.zfill(2) for x in mac]
46 mac = ":".join(mac)
47 return flow_str(stage, "dl_dst=%s" % mac, action)
48
49
50def l3(stage, action):
51 ip, mask = rand_ip_mask()
52 return flow_str(stage, "ip,ip_dst=%s/%d" % (ip, mask), action,
53 priority=mask)
54
55
56def l4(stage, action):
57 match = "tcp"
58
59 if rand_bool():
60 match += ",ip_src=%s/%d" % rand_ip_mask()
61
62 if rand_bool():
63 match += ",ip_dst=%s/%d" % rand_ip_mask()
64
65 src_dst = "tp_src" if rand_bool() else "tp_dst"
66 match += ",%s=%d" % (src_dst, random.randint(1024, 2**16 - 1))
67 return flow_str(stage, match, action)
68
69
70def pipeline(size):
71 pipeline = [l2, l3, l4, l2]
72
73 flows = []
74 for stage in xrange(len(pipeline)):
75 action = resubmit(stage + 1)
76 flows += [pipeline[stage](stage, action) for _ in xrange(size)]
77 flows.append(flow_str(stage, "", action, priority=1))
78
79 flows.append(flow_str(len(pipeline), "", "in_port"))
80
81 for f in flows:
82 print f
83
84
85def main():
86 description = textwrap.dedent(
87 """
88 Generate a test OpenFlow pipeline.
89
90 Open vSwitch relies heavily on flow caching to get good performance for
91 packet processing. While on average, this produces good results,
92 performance is heavily depedent on the slow path OpenFlow tables, and
93 how they're translated into datapath megaflows. For this reason, when
94 doing performance testing it's important to run with "realistic"
95 OpenFlow tables to ensure results will stand up in the real world.
96
97 This script generates a simple OpenFlow pipeline intended to simulate
98 realistic network virtualization workloads. All traffic received is
99 run through a series of OpenFlow tables designed to simulate a logical
100 switch, router, and firewall, before forwarded back on the in_port.
101 """)
102
103 epilog = textwrap.dedent(
104 """
105 typical usage:
106 ovs-ofctl del-flows bridge \\
107 && %s | ovs-ofctl add-flows bridge - \\
108 && ovs-ofctl dump-flows bridge
109 """ % sys.argv[0])
110
111 parser = argparse.ArgumentParser(description=description, epilog=epilog,
112 formatter_class=\
113 argparse.RawDescriptionHelpFormatter)
114 parser.add_argument("--size", dest="size", default=1000,
115 help="Size (rules) of each OpenFlow table.")
116 args=parser.parse_args()
117
118 pipeline(int(args.size))
119
120
121if __name__ == "__main__":
122 main()