]>
Commit | Line | Data |
---|---|---|
8521345b BP |
1 | #! /usr/bin/python |
2 | # | |
3 | # Copyright (c) 2009 Nicira Networks. | |
4 | # | |
5 | # Licensed under the Apache License, Version 2.0 (the "License"); | |
6 | # you may not use this file except in compliance with the License. | |
7 | # You may obtain a copy of the License at: | |
8 | # | |
9 | # http://www.apache.org/licenses/LICENSE-2.0 | |
10 | # | |
11 | # Unless required by applicable law or agreed to in writing, software | |
12 | # distributed under the License is distributed on an "AS IS" BASIS, | |
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | # See the License for the specific language governing permissions and | |
15 | # limitations under the License. | |
16 | ||
17 | import getopt | |
18 | import os | |
19 | import re | |
20 | import subprocess | |
21 | import sys | |
22 | ||
23 | argv0 = sys.argv[0] | |
24 | ||
bc391960 | 25 | BRCTL = "/usr/lib/openvswitch/xs-original/brctl" |
bd1b03cd | 26 | VSCTL = "/usr/bin/ovs-vsctl" |
bc391960 | 27 | OVSDB_SERVER = "unix:/var/run/openvswitch/db.sock" |
8521345b BP |
28 | |
29 | # Execute the real brctl program, passing the same arguments that were passed | |
30 | # to us. | |
31 | def delegate(): | |
32 | os.execl(BRCTL, BRCTL, *sys.argv[1:]) | |
33 | # execl should never return. We only arrive here if brctl failed to exec. | |
34 | sys.exit(1) | |
35 | ||
bd1b03cd JP |
36 | def call_vsctl(cmd, arg=""): |
37 | database = '--db=' + OVSDB_SERVER | |
38 | command = [VSCTL, database, cmd] | |
39 | if (arg): | |
40 | command.append(arg) | |
41 | return subprocess.Popen(command, stdout=subprocess.PIPE).communicate()[0].split() | |
8521345b | 42 | |
bd1b03cd JP |
43 | # Returns a list of all the bridges |
44 | def get_bridges(): | |
45 | return call_vsctl('list-br') | |
46 | ||
47 | # Returns a list of all ports on 'bridge' | |
48 | def get_bridge_ports(bridge): | |
49 | return call_vsctl('list-ports', bridge) | |
50 | ||
51 | # Returns a list of all interfaces on 'bridge' | |
52 | def get_bridge_ifaces(bridge): | |
53 | return call_vsctl('list-ifaces', bridge) | |
54 | ||
55 | # Returns the parent of 'bridge'. If 'bridge' does not have a parent, | |
56 | # 'bridge' is returned. | |
57 | def get_bridge_parent(bridge): | |
58 | return call_vsctl('br-to-parent', bridge) | |
8521345b BP |
59 | |
60 | # Returns the first line of the file named 'name', with the trailing new-line | |
61 | # (if any) stripped off. | |
62 | def read_first_line_of_file(name): | |
63 | file = None | |
64 | try: | |
65 | file = open(name, 'r') | |
66 | return file.readline().rstrip('\n') | |
67 | finally: | |
68 | if file != None: | |
69 | file.close() | |
70 | ||
71 | # Returns a bridge ID constructed from the MAC address of network device | |
72 | # 'netdev', in the format "8000.000102030405". | |
73 | def get_bridge_id(netdev): | |
74 | try: | |
75 | hwaddr = read_first_line_of_file("/sys/class/net/%s/address" % netdev) | |
76 | return "8000.%s" % (hwaddr.replace(":", "")) | |
77 | except: | |
78 | return "8000.002320ffffff" | |
79 | ||
80 | def cmd_show(): | |
81 | print "bridge name\tbridge id\t\tSTP enabled\tinterfaces" | |
8521345b BP |
82 | |
83 | # Find all the bridges. | |
bd1b03cd | 84 | bridges = get_bridges() |
8521345b BP |
85 | |
86 | # Find all the interfaces on each bridge. | |
bd1b03cd JP |
87 | for bridge in bridges: |
88 | bridge_ports = get_bridge_ports(bridge) | |
89 | parent = get_bridge_parent(bridge) | |
90 | if parent in bridge_ports: | |
91 | bridge_ports.remove(parent) | |
8521345b | 92 | bridge_ports.sort() |
bd1b03cd | 93 | bridge_id = get_bridge_id(bridge) |
8521345b BP |
94 | first_port = "" |
95 | if bridge_ports: | |
96 | first_port = bridge_ports[0] | |
bd1b03cd | 97 | print "%s\t\t%s\t%s\t\t%s" % (bridge, bridge_id, "no", first_port) |
8521345b BP |
98 | for port in bridge_ports[1:]: |
99 | print "\t\t\t\t\t\t\t%s" % port | |
100 | ||
101 | def main(): | |
102 | # Parse the command line. | |
103 | try: | |
104 | options, args = getopt.gnu_getopt(sys.argv[1:], | |
105 | "hV", ["help", "version"]) | |
106 | except getopt.GetoptError, msg: | |
107 | sys.stderr.write("%s: %s (use --help for help)\n" % (argv0, msg)) | |
108 | sys.exit(1) | |
109 | ||
110 | # Handle command-line options. | |
111 | for opt, optarg in options: | |
112 | if opt == "-h" or opt == "--help": | |
113 | delegate() | |
114 | elif opt == "-V" or opt == "--version": | |
115 | subprocess.call([BRCTL, "--version"]) | |
116 | print "Open vSwitch brctl wrapper" | |
117 | sys.exit(0) | |
118 | ||
119 | # Execute commands. Most commands are delegated to the brctl binary that | |
120 | # we are wrapping, but we implement the "show" command ourselves. | |
121 | if args and args[0] == "show": | |
122 | cmd_show() | |
123 | else: | |
124 | delegate() | |
125 | ||
126 | if __name__ == "__main__": | |
127 | main() |