]> git.proxmox.com Git - mirror_ovs.git/blame - utilities/ovs-pipegen.py
ofp-table: Always format the table number in table features.
[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
fa4058ab 21
c875bb94
EJ
22def flow_str(stage, match, action, priority=32768):
23 mtd_match = "metadata=%d" % stage
24 if match:
25 mtd_match += "," + match
26
27 return "priority=%d %s,actions=%s" % (priority, mtd_match, action)
28
29
30def resubmit(nxt):
31 return "load:%d->OXM_OF_METADATA[],resubmit(,0)" % nxt
32
33
34def rand_ip_mask():
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]))
38
39
40def rand_bool():
41 return bool(random.randint(0, 1))
42
43
44def 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]
47 mac = ":".join(mac)
48 return flow_str(stage, "dl_dst=%s" % mac, action)
49
50
51def l3(stage, action):
52 ip, mask = rand_ip_mask()
53 return flow_str(stage, "ip,ip_dst=%s/%d" % (ip, mask), action,
54 priority=mask)
55
56
57def l4(stage, action):
58 match = "tcp"
59
60 if rand_bool():
61 match += ",ip_src=%s/%d" % rand_ip_mask()
62
63 if rand_bool():
64 match += ",ip_dst=%s/%d" % rand_ip_mask()
65
66 src_dst = "tp_src" if rand_bool() else "tp_dst"
efae9437 67 match += ",%s=%d" % (src_dst, random.randint(1024, 2 ** 16 - 1))
c875bb94
EJ
68 return flow_str(stage, match, action)
69
70
71def pipeline(size):
72 pipeline = [l2, l3, l4, l2]
73
74 flows = []
fd405262 75 for stage in range(len(pipeline)):
c875bb94 76 action = resubmit(stage + 1)
fd405262 77 flows += [pipeline[stage](stage, action) for _ in range(size)]
c875bb94
EJ
78 flows.append(flow_str(stage, "", action, priority=1))
79
80 flows.append(flow_str(len(pipeline), "", "in_port"))
81
82 for f in flows:
fd405262 83 print(f)
c875bb94
EJ
84
85
86def main():
87 description = textwrap.dedent(
88 """
89 Generate a test OpenFlow pipeline.
90
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.
97
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.
102 """)
103
104 epilog = textwrap.dedent(
105 """
106 typical usage:
107 ovs-ofctl del-flows bridge \\
108 && %s | ovs-ofctl add-flows bridge - \\
109 && ovs-ofctl dump-flows bridge
110 """ % sys.argv[0])
111
112 parser = argparse.ArgumentParser(description=description, epilog=epilog,
fa4058ab 113 formatter_class=argparse.RawDescriptionHelpFormatter)
c875bb94
EJ
114 parser.add_argument("--size", dest="size", default=1000,
115 help="Size (rules) of each OpenFlow table.")
fa4058ab 116 args = parser.parse_args()
c875bb94
EJ
117
118 pipeline(int(args.size))
119
120
121if __name__ == "__main__":
122 main()