1 # vim: tabstop=4 shiftwidth=4 softtabstop=4
2 # -*- coding: utf-8 -*-
8 from linkpair.device import Device
9 from linkpair.port import Port
10 from linkpair.collect.agent.base_agent import BaseAgent
13 class OVSAgent(BaseAgent):
15 Open vSwitch Collector Agent
19 self.get_configuration()
21 def get_bridge_metadata(self, br):
24 br_meta["controller"] = ""
25 br_meta["manager"] = ""
27 res_mgr = self._runner.exec_cmd("ovs-vsctl get-manager")
29 br_meta["manager"] = self._u.str_join(
30 br_meta["manager"], mgr.strip(), ", ")
32 res_ctl = self._runner.exec_cmd("ovs-vsctl get-controller " + br)
34 br_meta["controller"] = self._u.str_join(
35 br_meta["controller"], ctl.strip(), ", ")
37 res_ofsw = self._runner.exec_cmd("ovs-ofctl show " + br)
38 for ofsw_spec in res_ofsw:
39 ofsw_spec = ofsw_spec.strip()
40 if self._u.d_push(re.search(r': dpid:(.*)', ofsw_spec)) is not None:
41 br_meta["dpid"] = self._u.d_pop().group(1).strip()
42 elif self._u.d_push(re.search(r'n_tables:(.*), n_buffers:(.*)', ofsw_spec)) is not None:
43 match = self._u.d_pop()
44 br_meta["tables"] = match.group(1).strip()
45 br_meta["buffers"] = match.group(2).strip()
46 elif self._u.d_push(re.search(r'capabilities:(.*)', ofsw_spec)) is not None:
47 br_meta["capabilities"] = self._u.d_pop().group(1).strip()
48 elif self._u.d_push(re.search(r'actions:(.*)', ofsw_spec)) is not None:
49 br_meta["actions"] = self._u.d_pop().group(1).strip()
53 def get_port_metadata(self, port_name, br_name=""):
55 exist_port = self._cu.get_port(port_name)
56 if exist_port != self._cu.PORT_NOT_FOUND:
57 port_meta = exist_port.metadata
59 res_ovsport = self._runner.exec_cmd("ovs-vsctl show")
60 for i in range(0, len(res_ovsport)):
61 port_start = res_ovsport[i].strip()
62 if self._u.d_push(re.search(r'Port "?%s"?' % port_name, port_start)) is not None:
63 for j in range(i + 1, len(res_ovsport)):
64 port_spec = res_ovsport[j].strip()
65 if self._u.d_push(re.search(r'tag: (.*)', port_spec)) is not None:
66 port_meta["tag"] = self._u.d_pop().group(1).strip()
67 elif self._u.d_push(re.search(r'type: (.*)', port_spec)) is not None:
68 port_meta["type"] = self._u.d_pop().group(1).strip()
69 elif self._u.d_push(re.search(r'options: {(.*)}', port_spec)) is not None:
70 port_options = self._u.d_pop().group(
72 for port_option in port_options:
73 (opt_name, opt_value) = port_option.split("=")
74 opt_name = opt_name.strip()
75 opt_value = opt_value.replace("\""," ")
76 opt_value = opt_value.strip()
77 port_meta[opt_name] = opt_value
78 if opt_name == "remote_ip":
79 res_iproute = self._runner.exec_cmd("ip route get " + opt_value)
80 for i in range(0, len(res_iproute)):
81 remote_route = res_iproute[i].strip()
82 if self._u.d_push(re.search(r'via (\S+) dev (\S+) src (\S+)', remote_route)) is not None:
83 match = self._u.d_pop()
84 port_meta["remote_routing_if_ipaddr"] = match.group(1).strip()
85 port_meta["remote_routing_if_dev"] = match.group(2).strip()
86 port_meta["remote_routing_src_ipaddr"] = match.group(3).strip()
87 elif self._u.d_push(re.search(r'cache mtu (\d+) advmss (\d+) hoplimit (\d+)', remote_route)) is not None:
88 match = self._u.d_pop()
89 port_meta["remote_peer_mtu"] = match.group(1).strip()
90 port_meta["remote_peer_mss"] = match.group(2).strip()
91 port_meta["remote_peer_hoplimit"] = match.group(3).strip()
93 elif self._u.d_push(re.search(r'Port "*', port_spec)) is not None:
97 res_ofctl = self._runner.exec_cmd("ovs-ofctl show " + br_name)
98 for i in range(0, len(res_ofctl)):
99 port_start = res_ofctl[i].strip()
100 if self._u.d_push(re.search(r'(\d+)\(%s\): addr:(.*)' % port_name, port_start)) is not None:
101 match = self._u.d_pop()
102 port_meta["port_no"] = match.group(1).strip()
103 port_meta["mac_addr"] = match.group(2).strip()
106 res_ofctl = self._runner.exec_cmd("ovs-ofctl dump-ports " + br_name)
107 if "port_no" in port_meta:
109 for i in range(0, len(res_ofctl)):
110 port_start = res_ofctl[i].strip()
112 re.search(r'port\s*%s:\s*rx pkts=(\d+), bytes=(\d+), drop=(\d+), errs=(\d+), frame=(\d+), over=(\d+), crc=(\d+)'
113 % port_meta["port_no"], port_start)) is not None:
114 match = self._u.d_pop()
115 port_meta["rx_pkts"] = match.group(1).strip()
116 port_meta["rx_bytes"] = match.group(2).strip()
117 port_meta["rx_drop"] = match.group(3).strip()
118 port_meta["rx_errs"] = match.group(4).strip()
119 port_meta["rx_frame"] = match.group(5).strip()
120 port_meta["rx_over"] = match.group(6).strip()
121 port_meta["rx_crc"] = match.group(7).strip()
124 re.search(r'\s*tx pkts=(\d+), bytes=(\d+), drop=(\d+), errs=(\d+), coll=(\d+)',
125 port_start)) is not None and found_port:
126 match = self._u.d_pop()
127 port_meta["tx_pkts"] = match.group(1).strip()
128 port_meta["tx_bytes"] = match.group(2).strip()
129 port_meta["tx_drop"] = match.group(3).strip()
130 port_meta["tx_errs"] = match.group(4).strip()
131 port_meta["tx_coll"] = match.group(5).strip()
136 def get_configuration(self):
140 result = self._runner.exec_cmd("ovs-vsctl list-br")
141 for br_src in result:
142 br_src = br_src.rstrip()
143 br_src_meta = self.get_bridge_metadata(br_src)
144 port_names = self._runner.exec_cmd(
145 "ovs-vsctl list-ports " + br_src)
146 for port_name in port_names:
147 port_name = port_name.rstrip()
148 port_meta = self.get_port_metadata(port_name, br_src)
150 self._port_to_br[port_name] = br_src
152 if self._cu.get_port_type(port_meta) == "patch":
153 patch_src = port_name
154 patch_dst = self._cu.get_port_peer(port_meta)
155 patch_peers[patch_src + ":" + patch_dst] = self.PEER_FOUND
157 if patch_dst + ":" + patch_src in patch_peers:
160 patch_src_meta = port_meta
161 result3 = self._runner.exec_cmd(
162 "ovs-vsctl port-to-br " + patch_dst)
163 if result3 is not None and len(result3) > 0:
164 br_dst = result3[0].rstrip()
165 br_dst_meta = self.get_bridge_metadata(br_dst)
166 patch_dst_meta = self.get_port_metadata(patch_dst, br_dst)
167 self._cu.add_linkpair(
168 Device(br_src, Device.BR_TYPE, br_src_meta),
169 Device(br_dst, Device.BR_TYPE, br_dst_meta),
170 Port(patch_src, Port.DEFAULT_TYPE, patch_src_meta),
171 Port(patch_dst, Port.DEFAULT_TYPE, patch_dst_meta),
172 self._formatter.PATCH_FORMAT)
174 patch_dst_meta = self.get_port_metadata(patch_dst, br_dst)
175 self._cu.add_linkpair(
176 Device(br_src, Device.BR_TYPE, br_src_meta),
177 Device("NOT CONNECTED", Device.NOT_CONNECTED_TYPE),
178 Port(patch_src, Port.DEFAULT_TYPE, patch_src_meta),
179 Port(patch_dst, Port.DEFAULT_TYPE, patch_dst_meta),
180 self._formatter.PATCH_FORMAT)
183 elif self._cu.get_port_veth_peer(port_name) != self._cu.PORT_PEER_UNSPECIFIED:
185 peer_dst = self._cu.get_port_veth_peer(port_name)
186 veth_peers[peer_src + ":" + peer_dst] = self.PEER_FOUND
188 if peer_dst + ":" + peer_src in veth_peers:
191 peer_src_meta = port_meta
192 result3 = self._runner.exec_cmd(
193 "ovs-vsctl port-to-br " + peer_dst)
194 if result3 is not None and len(result3) > 0:
195 br_dst = result3[0].rstrip()
196 br_dst_meta = self.get_bridge_metadata(br_dst)
197 peer_dst_meta = self.get_port_metadata(peer_dst, br_dst)
198 self._cu.add_linkpair(
199 Device(br_src, Device.BR_TYPE, br_src_meta),
200 Device(br_dst, Device.BR_TYPE, br_dst_meta),
201 Port(peer_src, Port.DEFAULT_TYPE, peer_src_meta),
202 Port(peer_dst, Port.DEFAULT_TYPE, peer_dst_meta),
203 self._formatter.VETH_FORMAT)
205 peer_dst_meta = self.get_port_metadata(peer_dst, br_dst)
206 self._cu.add_linkpair(
207 Device(br_src, Device.BR_TYPE, br_src_meta),
208 Device("NOT CONNECTED", Device.NOT_CONNECTED_TYPE),
209 Port(peer_src, Port.DEFAULT_TYPE, peer_src_meta),
210 Port(peer_dst, Port.DEFAULT_TYPE, peer_dst_meta),
211 self._formatter.VETH_FORMAT)
213 # none patch/veth port
215 # NOT Internal Bridge Port.
216 if self._cu.get_port_type(port_meta) != "internal":
219 if self._u.d_push(re.match(r'^eth\d+$', port_name)) \
220 or self._u.d_push(re.match(r'^em\d+$', port_name)) \
221 or self._u.d_push(re.match(r'^igb\d+$', port_name)) \
222 or self._u.d_push(re.match(r'^bond\d+$', port_name)):
223 self._cu.add_linkpair(
224 Device(br_src, Device.BR_TYPE, br_src_meta),
225 Device("Physical NW", Device.PHYNET_TYPE),
226 Port(port_name, Port.DEFAULT_TYPE, port_meta),
230 elif self._u.d_push(re.match(r'(vxlan\d+)', port_name)) \
231 or self._cu.get_port_type(port_meta) == "gre" \
232 or self._cu.get_port_type(port_meta) == "stt":
233 self._cu.add_linkpair(
234 Device(br_src, Device.BR_TYPE, br_src_meta),
235 Device("OS Routing", Device.OS_ROUTE_TYPE),
236 Port(port_name, Port.DEFAULT_TYPE, port_meta),
238 self._formatter.OS_ROUTING_FORMAT)
243 if self._cu.get_port_vlan_master_if(port_name) != self._cu.PORT_VLAN_UNSPECIFIED:
244 master_if = self._cu.get_port_vlan_master_if(port_name)
245 if master_if in self._port_to_br:
246 br_dst = self._port_to_br[master_if]
247 br_dst_obj = self._cu.get_device(br_dst)
249 port_src_meta = port_meta
251 #port_dst_obj = self._cu.get_port(master_if)
252 port_dst_meta = self.get_port_metadata(port_dst, br_dst)
253 self._cu.add_linkpair(
254 Device(br_src, Device.BR_TYPE, br_src_meta),
256 Port(port_src, Port.DEFAULT_TYPE, port_src_meta),
258 Port(port_dst, Port.DEFAULT_TYPE, port_dst_meta),
259 self._formatter.VLAN_DIST_FORMAT)
261 elif self._u.d_push(re.match(r'^eth\d+$', master_if)) \
262 or self._u.d_push(re.match(r'^em\d+$', master_if)) \
263 or self._u.d_push(re.match(r'^igb\d+$', master_if)) \
264 or self._u.d_push(re.match(r'^bond\d+$', master_if)):
265 self._cu.add_linkpair(
266 Device(br_src, Device.BR_TYPE, br_src_meta),
267 Device("Physical NW", Device.PHYNET_TYPE),
268 Port(port_name, Port.DEFAULT_TYPE, port_meta),
271 self._cu.add_linkpair(
272 Device(br_src, Device.BR_TYPE, br_src_meta),
273 Device("NOT CONNECTED", Device.NOT_CONNECTED_TYPE),
274 Port(port_name, Port.DEFAULT_TYPE, port_meta),
278 elif self._cu.get_port_type(port_meta) == "internal":
279 if port_name in self._iface_to_nss:
280 self._cu.add_linkpair(
281 Device(br_src, Device.BR_TYPE, br_src_meta),
282 Device(self._iface_to_nss[
283 port], Device.NAMESPACE_TYPE),
284 Port(port_name, Port.DEFAULT_TYPE, port_meta),
286 self._formatter.NAMESPACE_FORMAT)
288 self._cu.add_linkpair(
289 Device(br_src, Device.BR_TYPE, br_src_meta),
290 Device("INTERNAL", Device.OS_ROUTE_TYPE),
291 Port(port_name, Port.DEFAULT_TYPE, port_meta),
295 # self._port_to_br[port_name] = br_src