summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAditya Prakash Vaja <wolverine.av@gmail.com>2018-11-20 12:45:38 -0800
committerAditya Vaja <wolverine.av@gmail.com>2018-11-20 22:36:44 +0000
commit8874df55bd9d40484901504dda6aebe980e0bd5a (patch)
tree1f2a494c448464b5d97f9b01af98adf578ad2a89
parent44fb55ffc89626f8c4b54f6cb1cac22bdaa9aa3a (diff)
OSP-257: cleanup redundant packages from queens and onwards
we had to split the networking-bigswitch package into multiple packages owing to the containerization of services in queens. we now install the packages based on requirement on a per container basis - instead of the previous approach of installing everything as part of networking-bigswitch. now that all the containers are working with new packages, we have to cleanup the networking-bigswitch and get rid of the packages that are redundant. Change-Id: I7e3cdde12ac5809fcbbd3d0a219f9d6198c44eed
Notes
Notes (review): Code-Review+2: Aditya Vaja <wolverine.av@gmail.com> Workflow+1: Aditya Vaja <wolverine.av@gmail.com> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Tue, 20 Nov 2018 23:17:52 +0000 Reviewed-on: https://review.openstack.org/619096 Project: openstack/networking-bigswitch Branch: refs/heads/master
-rw-r--r--networking_bigswitch/bsnlldp/__init__.py0
-rwxr-xr-xnetworking_bigswitch/bsnlldp/bsnlldp.py31
-rw-r--r--networking_bigswitch/bsnlldp/rhlib.py281
-rw-r--r--networking_bigswitch/bsnlldp/send_lldp.py716
-rw-r--r--networking_bigswitch/plugins/bigswitch/neutronclient/__init__.py0
-rw-r--r--networking_bigswitch/plugins/bigswitch/neutronclient/v2_0/__init__.py0
-rw-r--r--networking_bigswitch/plugins/bigswitch/neutronclient/v2_0/_bsn_plugin_client.py542
-rw-r--r--rhel/neutron-bsn-lldp.service14
-rw-r--r--rhel/python-networking-bigswitch.spec17
-rw-r--r--setup.cfg3
10 files changed, 0 insertions, 1604 deletions
diff --git a/networking_bigswitch/bsnlldp/__init__.py b/networking_bigswitch/bsnlldp/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/networking_bigswitch/bsnlldp/__init__.py
+++ /dev/null
diff --git a/networking_bigswitch/bsnlldp/bsnlldp.py b/networking_bigswitch/bsnlldp/bsnlldp.py
deleted file mode 100755
index e4e1535..0000000
--- a/networking_bigswitch/bsnlldp/bsnlldp.py
+++ /dev/null
@@ -1,31 +0,0 @@
1# Copyright 2014 Big Switch Networks, Inc.
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# 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, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
16import platform
17from rhlib import BCFMode
18from rhlib import get_bcf_mode
19from send_lldp import send_lldp
20
21
22def main():
23 platform_os = platform.linux_distribution()[0]
24 if "red hat" in platform_os.strip().lower():
25 if BCFMode.MODE_P_V == get_bcf_mode():
26 return
27 send_lldp()
28
29
30if __name__ == "__main__":
31 main()
diff --git a/networking_bigswitch/bsnlldp/rhlib.py b/networking_bigswitch/bsnlldp/rhlib.py
deleted file mode 100644
index e1d65fc..0000000
--- a/networking_bigswitch/bsnlldp/rhlib.py
+++ /dev/null
@@ -1,281 +0,0 @@
1# Copyright 2014 Big Switch Networks, Inc.
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# 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, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
16from enum import Enum
17import os
18from os_net_config import utils
19from oslo_serialization import jsonutils
20import re
21import syslog as LOG
22import time
23
24# constants for RHOSP
25NET_CONF_PATH = "/etc/os-net-config/config.json"
26HIERA_DIR_PATH = "/etc/puppet/hieradata"
27COMPUTE_FILE_PATH = "%s/compute.json" % HIERA_DIR_PATH
28SUPPORTED_BOND = ['ovs_bond', 'linux_bond']
29_SYS_CLASS_NET = '/sys/class/net'
30
31
32class BCFMode(Enum):
33 MODE_P_ONLY = 5
34 MODE_P_V = 6
35
36
37# monkey patch to identify phy nics
38def _is_active_nic(interface_name):
39 try:
40 if interface_name == 'lo':
41 return False
42
43 device_dir = _SYS_CLASS_NET + '/%s/device' % interface_name
44 has_device_dir = os.path.isdir(device_dir)
45
46 carrier = None
47 with open(_SYS_CLASS_NET + '/%s/carrier' % interface_name, 'r') as f:
48 carrier = int(f.read().rstrip())
49
50 address = None
51 with open(_SYS_CLASS_NET + '/%s/address' % interface_name, 'r') as f:
52 address = f.read().rstrip()
53
54 if has_device_dir and carrier == 1 and address:
55 return True
56 else:
57 return False
58 except IOError:
59 return False
60
61utils._is_active_nic = _is_active_nic
62
63
64def get_bcf_mode():
65 """Get bcf deployment mode.
66
67 :returns: UNKNOWN, MODE_P_ONLY or MODE_P_V.
68 """
69 while True:
70 if os.path.isdir(HIERA_DIR_PATH):
71 break
72 if not os.path.isfile(COMPUTE_FILE_PATH):
73 return BCFMode.MODE_P_ONLY
74
75 if not os.path.isfile(NET_CONF_PATH):
76 return BCFMode.MODE_P_ONLY
77 try:
78 json_data = open(NET_CONF_PATH).read()
79 data = jsonutils.loads(json_data)
80 except Exception:
81 return BCFMode.MODE_P_ONLY
82 network_config = data.get('network_config')
83 for config in network_config:
84 if config.get('type') == 'ivs_bridge':
85 return BCFMode.MODE_P_V
86
87 return BCFMode.MODE_P_ONLY
88
89
90def get_mac_str(network_interface):
91 with open("/sys/class/net/%s/address" % network_interface) as f:
92 return f.read().strip()
93
94
95def add_intf_to_map(intf_map, bridge_or_bond, config_type, intf_index,
96 lacp=False):
97 """Adds an interface to the interface map, after performing validation
98
99 interface_map has a specific structure. this method checks and inserts
100 keys if they're missing for the bridge or interface being added.
101
102 :param intf_map: interface map object to which the interface is added
103 :param bridge_or_bond: bridge or bond name to which the interface belongs
104 :param config_type: type of object - either bridge or bond
105 :param intf_index: name or index number of the interface
106 if interface is in nicX format, this will be a
107 numerical index, else name. both would be string.
108 :param lacp: boolean flag, specifying whether intf is part of some form of
109 link aggregation or no.
110 :return: intf_map after being updated
111 """
112 if bridge_or_bond not in intf_map:
113 intf_map[bridge_or_bond] = {}
114 if 'config_type' not in intf_map[bridge_or_bond]:
115 intf_map[bridge_or_bond]['config_type'] = config_type
116 if 'members' not in intf_map[bridge_or_bond]:
117 intf_map[bridge_or_bond]['members'] = []
118 if config_type == 'linux_bond' or lacp:
119 # for linux_bond config type, always True. Otherwise, depends on
120 # whether its a bond or individual interface in a bridge.
121 intf_map[bridge_or_bond]['lacp'] = True
122 else:
123 intf_map[bridge_or_bond]['lacp'] = False
124 intf_map[bridge_or_bond]['members'].append(intf_index)
125 return intf_map
126
127
128def _get_intf_index(nic_name):
129 """os-net-config can have interface name stored nicX, where X is a number
130
131 in this case, REAL interface name is not used. derive the index if it is in
132 nicX format.
133 otherwise, simply use the name.
134
135 :param nic_name:
136 :return: index or name. both in string format.
137 """
138 indexes = map(int, re.findall(r'\d+', nic_name))
139 if len(indexes) == 1 and nic_name.startswith("nic"):
140 intf_index = str(indexes[0] - 1)
141 else:
142 intf_index = str(nic_name)
143 return intf_index
144
145
146def get_network_interface_map():
147 """Get interface map for bonds and bridges relevant on this RHOSP node
148
149 :return: returns a mapping of network interfaces with its parent being a
150 bridge or bond. syntax:
151 {
152 'bridge_or_bond_name': {
153 'type': 'bond or bridge type',
154 'lacp': False (boolean, defaults to False),
155 'members': [ list of interfaces ]
156 }
157 }
158
159 sample output of a mix of bonds and bridges:
160
161 {
162 u 'bond_api': {
163 'type': 'linux_bond',,
164 'lacp': True,
165 'members': ['p1p1']
166 }, u 'br-link': {
167 'type': 'ovs_bridge',
168 'lacp': False,
169 'members': ['p1p2']
170 }, u 'br-ex': {
171 'type': 'ovs_bridge',
172 'lacp': True,
173 'members': ['p1p1', 'p1p2']
174 }
175 }
176 """
177 intf_map = {}
178 while True:
179 if not os.path.isfile(NET_CONF_PATH):
180 time.sleep(1)
181 continue
182 try:
183 json_data = open(NET_CONF_PATH).read()
184 data = jsonutils.loads(json_data)
185 except ValueError:
186 time.sleep(1)
187 continue
188 network_config = data.get('network_config')
189 for config in network_config:
190 config_type = config.get('type')
191 if config_type == 'ovs_bridge':
192 bridge_name = config.get('name').encode('ascii', 'ignore')
193 members = config.get('members')
194 for member in members:
195 # member can be a bond or single interface in case of
196 # ovs_bridge on DPDK controller
197 member_type = member.get('type')
198 if member_type == 'interface':
199 intf_index = _get_intf_index(
200 member.get('name').encode('ascii', 'ignore'))
201 add_intf_to_map(
202 intf_map=intf_map, bridge_or_bond=bridge_name,
203 config_type='ovs_bridge', intf_index=intf_index)
204 break
205 elif member_type in SUPPORTED_BOND:
206 nics = member.get('members')
207 for nic in nics:
208 if nic.get('type') != 'interface':
209 continue
210 intf_index = _get_intf_index(
211 nic.get('name').encode('ascii', 'ignore'))
212 add_intf_to_map(
213 intf_map=intf_map, bridge_or_bond=bridge_name,
214 config_type='ovs_bridge',
215 intf_index=intf_index, lacp=True)
216 break
217 else:
218 # either a vlan type interface or unsupported type
219 continue
220 elif config_type == 'linux_bond':
221 bond_name = config.get('name').encode('ascii', 'ignore')
222 members = config.get('members')
223 for nic in members:
224 if nic.get('type') != 'interface':
225 continue
226 intf_index = _get_intf_index(
227 nic.get('name').encode('ascii', 'ignore'))
228 add_intf_to_map(
229 intf_map=intf_map, bridge_or_bond=bond_name,
230 config_type='linux_bond', intf_index=intf_index)
231 elif config_type == 'ovs_user_bridge':
232 bridge_name = config.get('name').encode('ascii', 'ignore')
233 members = config.get('members')
234 for nic in members:
235 nic_type = nic.get('type')
236 if nic_type == 'ovs_dpdk_port':
237 intf_name = nic.get('name').encode('ascii', 'ignore')
238 add_intf_to_map(
239 intf_map=intf_map, bridge_or_bond=bridge_name,
240 config_type='ovs_user_bridge',
241 intf_index=intf_name)
242 break
243 elif nic_type == 'ovs_dpdk_bond':
244 bond_interfaces = nic.get('members')
245 for bond_intf in bond_interfaces:
246 if bond_intf.get('type') != 'ovs_dpdk_port':
247 LOG.syslog("DPDK ovs_dpdk_bond has NON "
248 "ovs_dpdk_port %s" %
249 bond_intf.get('name'))
250 continue
251 intf_name = (bond_intf.get('name')
252 .encode('ascii', 'ignore'))
253 add_intf_to_map(
254 intf_map=intf_map, bridge_or_bond=bridge_name,
255 config_type='ovs_user_bridge',
256 intf_index=intf_name, lacp=True)
257 else:
258 continue
259 break
260 # get active interfaces from os_net_config
261 active_intfs = utils.ordered_active_nics()
262 intf_len = len(active_intfs)
263 # use the intf_map and work out the chassisid
264 for br_or_bond in intf_map:
265 if intf_map[br_or_bond]['config_type'] == 'ovs_user_bridge':
266 # do not try to map interface name with kernel entries
267 # ovs_user_bridge is used for DPDK compute nodes, interfaces are
268 # owned by DPDK driver and not kernel network driver
269 continue
270 if 'members' in intf_map[br_or_bond]:
271 intfs = []
272 for index in intf_map[br_or_bond]['members']:
273 try:
274 idx = int(index)
275 if idx < intf_len:
276 intfs.append(active_intfs[idx])
277 except ValueError:
278 intfs.append(index)
279 intf_map[br_or_bond]['members'] = intfs
280 LOG.syslog("Network interface map is %s" % intf_map)
281 return intf_map
diff --git a/networking_bigswitch/bsnlldp/send_lldp.py b/networking_bigswitch/bsnlldp/send_lldp.py
deleted file mode 100644
index ffe083d..0000000
--- a/networking_bigswitch/bsnlldp/send_lldp.py
+++ /dev/null
@@ -1,716 +0,0 @@
1# Copyright 2014 Big Switch Networks, Inc.
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# 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, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
16import argparse
17import ctypes
18from ctypes import c_byte
19from ctypes import c_char_p
20from ctypes import c_uint
21from ctypes import c_uint16
22from ctypes import c_uint32
23from ctypes import c_ushort
24from ctypes import c_void_p
25from ctypes import cast
26from ctypes import get_errno
27from ctypes import pointer
28from ctypes import POINTER
29from ctypes import Structure
30from ctypes import Union
31import ctypes.util
32import os
33import os.path
34import platform
35import socket
36from socket import AF_INET
37from socket import AF_INET6
38from socket import inet_ntop
39import subprocess
40import syslog as LOG
41import time
42try:
43 from rhlib import get_network_interface_map
44except ImportError:
45 pass
46
47LLDP_DST_MAC = "01:80:c2:00:00:0e"
48SYSTEM_DESC_LACP = "5c:16:c7:00:00:04"
49SYSTEM_DESC_STATIC = "5c:16:c7:00:00:00"
50LLDP_ETHERTYPE = 0x88cc
51TTL = 120
52INTERVAL = 10
53CHASSIS_ID_LOCALLY_ASSIGNED = 7
54PORT_ID_INTERFACE_ALIAS = 1
55PCI_IDS_DIR = "/run/pci_ids"
56LLDP_START_STR = "lldp start"
57LLDP_STOP_STR = "lldp stop"
58X710_INTEL_DRIVER_STR = "i40e"
59X710_DEVICE_LIST = [0x1572, 0x1583]
60
61# read and save lldp status for different interfaces
62lldp_status = {}
63
64
65class struct_sockaddr(Structure):
66 _fields_ = [
67 ('sa_family', c_ushort),
68 ('sa_data', c_byte * 14)]
69
70
71class struct_sockaddr_in(Structure):
72 _fields_ = [
73 ('sin_family', c_ushort),
74 ('sin_port', c_uint16),
75 ('sin_addr', c_byte * 4)]
76
77
78class struct_sockaddr_in6(Structure):
79 _fields_ = [
80 ('sin6_family', c_ushort),
81 ('sin6_port', c_uint16),
82 ('sin6_flowinfo', c_uint32),
83 ('sin6_addr', c_byte * 16),
84 ('sin6_scope_id', c_uint32)]
85
86
87class union_ifa_ifu(Union):
88 _fields_ = [
89 ('ifu_broadaddr', POINTER(struct_sockaddr)),
90 ('ifu_dstaddr', POINTER(struct_sockaddr))]
91
92
93class struct_ifaddrs(Structure):
94 pass
95struct_ifaddrs._fields_ = [
96 ('ifa_next', POINTER(struct_ifaddrs)),
97 ('ifa_name', c_char_p),
98 ('ifa_flags', c_uint),
99 ('ifa_addr', POINTER(struct_sockaddr)),
100 ('ifa_netmask', POINTER(struct_sockaddr)),
101 ('ifa_ifu', union_ifa_ifu),
102 ('ifa_data', c_void_p)]
103
104libc = ctypes.CDLL(ctypes.util.find_library('c'))
105
106
107def ifap_iter(ifap):
108 ifa = ifap.contents
109 while True:
110 yield ifa
111 if not ifa.ifa_next:
112 break
113 ifa = ifa.ifa_next.contents
114
115
116def getfamaddr(sa):
117 family = sa.sa_family
118 addr = None
119 if family == AF_INET:
120 sa = cast(pointer(sa), POINTER(struct_sockaddr_in)).contents
121 addr = inet_ntop(family, sa.sin_addr)
122 elif family == AF_INET6:
123 sa = cast(pointer(sa), POINTER(struct_sockaddr_in6)).contents
124 addr = inet_ntop(family, sa.sin6_addr)
125 return family, addr
126
127
128class NetworkInterface(object):
129 def __init__(self, name):
130 self.name = name
131 self.index = libc.if_nametoindex(name)
132 self.addresses = {}
133
134 def __str__(self):
135 return "%s [index=%d, IPv4=%s, IPv6=%s]" % (
136 self.name, self.index,
137 self.addresses.get(AF_INET),
138 self.addresses.get(AF_INET6))
139
140
141def get_network_interfaces():
142 ifap = POINTER(struct_ifaddrs)()
143 result = libc.getifaddrs(pointer(ifap))
144 if result != 0:
145 raise OSError(get_errno())
146 del result
147 try:
148 retval = {}
149 for ifa in ifap_iter(ifap):
150 name = ifa.ifa_name
151 i = retval.get(name)
152 if not i:
153 i = retval[name] = NetworkInterface(name)
154 family, addr = getfamaddr(ifa.ifa_addr.contents)
155 if addr:
156 i.addresses[family] = addr
157 return retval.values()
158 finally:
159 libc.freeifaddrs(ifap)
160
161
162def parse_args():
163 parser = argparse.ArgumentParser()
164
165 # LLDP packet arguments
166 parser.add_argument("--network_interface")
167 parser.add_argument("--system-name")
168 parser.add_argument("--system-desc")
169
170 # Other arguments
171 parser.add_argument("-i", "--interval", type=int, default=0)
172 parser.add_argument("-d", "--daemonize",
173 action="store_true", default=False)
174 parser.add_argument("--sriov", action="store_true", default=False)
175
176 return parser.parse_args()
177
178
179def validate_num_bits_of_int(int_value, num_bits, name=None):
180 mask = pow(2, num_bits) - 1
181 if (int_value & mask) != int_value:
182 name = name if name else "The integer value"
183 msg = ("{name} must be {num_bits}-bit long. Given: {int_value} "
184 "({hex_value})".format(**{'name': name, 'num_bits': num_bits,
185 'int_value': int_value,
186 'hex_value': hex(int_value)}))
187 raise ValueError(msg)
188
189
190def raw_bytes_of_hex_str(hex_str):
191 return hex_str.decode("hex")
192
193
194def raw_bytes_of_mac_str(mac_str):
195 return raw_bytes_of_hex_str(mac_str.replace(":", ""))
196
197
198def raw_bytes_of_int(int_value, num_bytes, name=None):
199 validate_num_bits_of_int(int_value, num_bytes * 8, name)
200 template = "%0" + "%d" % (num_bytes * 2) + "x"
201 return raw_bytes_of_hex_str(template % int_value)
202
203
204def get_mac_str(network_interface):
205 """Attempts to get MAC addr from kernel /sys/class/net files.
206
207 Returns None if nic is not controlled by kernel network driver file is
208 missing.
209
210 :param network_interface:
211 :return:
212 """
213 try:
214 with open("/sys/class/net/%s/address" % network_interface) as f:
215 return f.read().strip()
216 except Exception as e:
217 LOG.syslog("Exception getting MAC address of interface %s: %s" %
218 (network_interface, e.message))
219 return None
220
221
222def execute_cmd(cmd):
223 """Execute a command on host and return output.
224
225 Returns None if there is an exception during execution.
226
227 :param cmd:
228 :return:
229 """
230 try:
231 output = subprocess.check_output(
232 cmd, stderr=subprocess.STDOUT, shell=True)
233 return output.strip().strip("\"")
234 except Exception as e:
235 msg = ("Error executing command %s: %s\n" % (cmd, e))
236 LOG.syslog(msg)
237 return None
238
239
240def get_intf_ofport_number(intf_name):
241 """Return OFPort Number of an interface from ovs-db's Interface table
242
243 :param intf_name:
244 :return:
245 """
246 cmd = ("ovs-vsctl get Interface %(intf_name)s ofport"
247 % {'intf_name': intf_name})
248 return execute_cmd(cmd)
249
250
251def get_dpdk_intf_mac_addr(intf_name):
252 """Returns MAC addr of an interface from ovs-db's Interface table
253
254 :param intf_name:
255 :return:
256 """
257 cmd = ("ovs-vsctl get Interface %(intf_name)s mac_in_use"
258 % {'intf_name': intf_name})
259 return execute_cmd(cmd)
260
261
262def get_fqdn_cli():
263 """Returns output of 'hostname -f'
264
265 In some cases, socket.getfqdn() does not return domain name. This is a more
266 robust way to get hostname with domain name.
267
268 :return:
269 """
270 cmd = "hostname -f"
271 return execute_cmd(cmd)
272
273
274def readfile(path):
275 with open(path) as f:
276 return f.read()
277
278
279def writefile(path, data):
280 with open(path, "w") as f:
281 f.write(data)
282
283
284def lldp_ethertype():
285 return raw_bytes_of_int(LLDP_ETHERTYPE, 2, "LLDP ethertype")
286
287
288def validate_tlv_type(type_):
289 validate_num_bits_of_int(type_, 7, "TLV type")
290
291
292def validate_tlv_length(length):
293 validate_num_bits_of_int(length, 9, "TLV length")
294
295
296def tlv_1st_2nd_bytes_of(type_, length):
297 validate_tlv_type(type_)
298 validate_tlv_length(length)
299 int_value = (type_ << (8 + 1)) | length
300 return raw_bytes_of_int(int_value, 2, "First 2 bytes of TLV")
301
302
303def tlv_of(type_, str_value):
304 return tlv_1st_2nd_bytes_of(type_, len(str_value)) + str_value
305
306
307def chassis_id_tlv_of(chassis_id, subtype=CHASSIS_ID_LOCALLY_ASSIGNED):
308 return tlv_of(
309 1, raw_bytes_of_int(subtype, 1, "Chassis ID subtype") + chassis_id)
310
311
312def port_id_tlv_of(port_id, subtype=PORT_ID_INTERFACE_ALIAS):
313 return tlv_of(2, raw_bytes_of_int(subtype, 1, "Port ID subtype") + port_id)
314
315
316def ttl_tlv_of(ttl_seconds):
317 return tlv_of(3, raw_bytes_of_int(ttl_seconds, 2, "TTL (seconds)"))
318
319
320def port_desc_tlv_of(port_desc):
321 return tlv_of(4, port_desc)
322
323
324def system_name_tlv_of(system_name):
325 return tlv_of(5, system_name)
326
327
328def system_desc_tlv_of(system_desc):
329 return tlv_of(6, system_desc)
330
331
332def end_tlv():
333 return tlv_of(0, "")
334
335
336def lldp_frame_of(chassis_id,
337 network_interface,
338 ttl,
339 system_name=None,
340 system_desc=None,
341 port_mac_str=None):
342 if not port_mac_str:
343 port_mac_str = get_mac_str(network_interface)
344 contents = [
345 # Ethernet header
346 raw_bytes_of_mac_str(LLDP_DST_MAC),
347 raw_bytes_of_mac_str(port_mac_str),
348 lldp_ethertype(),
349
350 # Required LLDP TLVs
351 chassis_id_tlv_of(chassis_id),
352 port_id_tlv_of(network_interface),
353 ttl_tlv_of(ttl),
354 port_desc_tlv_of(port_mac_str)]
355
356 # Optional LLDP TLVs
357 if system_name is not None:
358 contents.append(system_name_tlv_of(system_name))
359 if system_desc is not None:
360 contents.append(system_desc_tlv_of(system_desc))
361
362 # End TLV
363 contents.append(end_tlv())
364 return "".join(contents)
365
366
367def daemonize():
368 # Do not use this code for daemonizing elsewhere as this is
369 # a very simple version that is just good enough for here.
370 pid = os.fork()
371 if pid != 0:
372 # Exit from the parent process
373 os._exit(os.EX_OK)
374
375 os.setsid()
376
377 pid = os.fork()
378 if pid != 0:
379 # Exit from the 2nd parent process
380 os._exit(os.EX_OK)
381
382
383def list_a_minus_list_b(list_a, list_b):
384 """This method assumes input is two lists with unique elements aka sets.
385
386 It then returns all unique elements in list_a, not present in list_b.
387
388 :param list_a:
389 :param list_b:
390 :return: list of elements only in list_a OR an empty list
391 """
392 return list(set(list_a) - set(list_b))
393
394
395def find_pci_id(uplink):
396 if os.path.exists("/sys/bus/pci/devices/%s" % uplink):
397 return uplink
398
399 stash = os.path.join(PCI_IDS_DIR, uplink)
400 if os.path.exists(stash):
401 pci_id = readfile(stash)
402 return pci_id
403
404 if not os.path.exists("/sys/class/net/%s" % uplink):
405 msg = ("No such network device %s" % uplink)
406 raise RuntimeError(msg)
407
408 pci_id = os.path.basename(os.readlink("/sys/class/net/%s/device" % uplink))
409
410 if not os.path.exists(PCI_IDS_DIR):
411 os.mkdir(PCI_IDS_DIR)
412
413 writefile(stash, pci_id)
414 return pci_id
415
416
417def save_x710_intf_lldp_status(intf):
418 """This will read the LLDP status being sent for the interface, only if
419
420 it is an x710 network card.
421
422 If its status is already recorded, it returns True
423 If not, it will read and save and return True for x710 interfaces
424 For all other interfaces, it will return False
425
426 :param intf:
427 :return: (boolean, pci_id) True or False based on outcome. pci_id is None
428 if False. Actual pci_id otherwise
429 """
430 LOG.syslog("Read and save LLDP Tx status from device as needed")
431
432 uplink = intf.strip()
433 pci_id = find_pci_id(uplink)
434 LOG.syslog("Uplink %(uplink)s is PCI device %(pci_id)s" %
435 {"uplink": uplink, "pci_id": pci_id})
436
437 if uplink in lldp_status:
438 LOG.syslog("Uplink %s already has LLDP status saved as %s" %
439 (uplink, lldp_status[uplink]))
440 return (True, pci_id)
441
442 # check the card type, if x710, read lldp statusfrom nic
443 vendor = int(readfile("/sys/bus/pci/devices/%s/vendor" % pci_id), 16)
444 device = int(readfile("/sys/bus/pci/devices/%s/device" % pci_id), 16)
445
446 LOG.syslog("pci_id %s vendor %#04x device %#04x" %
447 (pci_id, vendor, device))
448
449 # check if X710 NIC, if yes, read lldp status
450 if (vendor == 0x8086 and device in X710_DEVICE_LIST):
451 # default assume status as lldp is stopped
452 lldp_status[uplink] = LLDP_STOP_STR
453 if os.path.exists("/sys/bus/pci/devices/%s/driver" % pci_id):
454 driver = os.path.basename(
455 os.readlink("/sys/bus/pci/devices/%s/driver" % pci_id))
456 if driver == X710_INTEL_DRIVER_STR:
457 status = readfile("/sys/kernel/debug/%s/%s/command" %
458 (driver, pci_id))
459 # update the status
460 if (status is LLDP_START_STR or status is LLDP_STOP_STR):
461 lldp_status[uplink] = status
462 LOG.syslog("LLDP status read for Uplink %s pci_id %s "
463 "vendor %#04x device %#04x" %
464 (uplink, pci_id, vendor, device))
465 return (True, pci_id)
466 else:
467 LOG.syslog("LLDP status not read for Uplink %s pci_id %s "
468 "vendor %#04x device %#04x as driver file "
469 "doesn't exist" % (uplink, pci_id, vendor, device))
470 return (False, None)
471
472
473def update_x710_lldp_status(pci_id, status):
474 """This method should only be called when interface has been identified as
475
476 x710 interface.
477
478 :param pci_id:
479 :param status:
480 :return: None
481 """
482 writefile("/sys/kernel/debug/%s/%s/command"
483 % (X710_INTEL_DRIVER_STR, pci_id),
484 status)
485
486
487def save_and_stop_x710_intf_lldp(intf):
488 """This checks if the interface is x710 interface, if yes, it will save
489
490 the status in a local variable and stop LLDP on that interface.
491
492 :param intf:
493 :return: True, if its x710 interface, False otherwise
494 """
495 is_x710, pci_id = save_x710_intf_lldp_status(intf)
496 if is_x710:
497 update_x710_lldp_status(pci_id, LLDP_STOP_STR)
498 return True
499 return False
500
501
502def save_and_restore_x710_intf_lldp(intf):
503 is_x710, pci_id = save_x710_intf_lldp_status(intf)
504 if is_x710:
505 update_x710_lldp_status(pci_id, lldp_status[intf.strip()])
506
507
508def send_pktout_via_ovs(bridge_name, intf_ofport_num, hex_pkt):
509 """Performs packet-out on OVS as described in ovs-ofctl manual [1]
510
511 Complete params and options given at [1].
512
513 [1] http://www.openvswitch.org/support/dist-docs/ovs-ofctl.8.txt
514
515 :param bridge_name: bridge name to which interface belongs
516 :param intf_ofport_num: OFPort number of the interface w.r.t the bridge
517 :param hex_pkt: packet to be sent out in hex format
518 :return:
519 """
520 cmd = ("ovs-ofctl packet-out %(bridge_name)s LOCAL %(intf_ofport_num)s "
521 "%(hex_pkt)s" % {'bridge_name': bridge_name,
522 'intf_ofport_num': intf_ofport_num,
523 'hex_pkt': hex_pkt})
524 return execute_cmd(cmd)
525
526
527def _generate_senders_frames(intfs, chassisid, args):
528 senders = []
529 frames = []
530 systemname = socket.getfqdn()
531 if args.system_name:
532 systemname = args.system_name
533 LOG.syslog("LLDP system-name is %s" % systemname)
534 systemdesc = SYSTEM_DESC_LACP
535 if args.system_desc:
536 systemdesc = args.system_desc
537 LOG.syslog("LLDP system-desc is %s" % systemdesc)
538 for intf in intfs:
539 interface = intf.strip()
540 frame = lldp_frame_of(chassis_id=chassisid,
541 network_interface=interface,
542 ttl=TTL,
543 system_name=systemname,
544 system_desc=systemdesc)
545 frames.append(frame)
546 s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW)
547 s.bind((interface, 0))
548 senders.append(s)
549 return senders, frames
550
551
552def _send_frames_kernel_socket(network_map, br_bond_name, args):
553 """Send LLDP frames on all interfaces for the br_bond_name specified.
554
555 :param network_map:
556 :param br_bond_name:
557 :param args:
558 :return:
559 """
560 LOG.syslog("LLDP generating frames for %s" % br_bond_name)
561 senders = []
562 frames = []
563
564 hostname_fqdn = get_fqdn_cli()
565 if not hostname_fqdn:
566 hostname_fqdn = socket.getfqdn()
567 systemname = hostname_fqdn + '_' + br_bond_name
568 LOG.syslog("LLDP system-name is %s" % systemname)
569 # default system-desc for compute node's DPDK interface is STATIC
570 systemdesc = SYSTEM_DESC_STATIC
571 if network_map[br_bond_name]['lacp']:
572 # if bonded nics, send LACP system-desc
573 systemdesc = SYSTEM_DESC_LACP
574 LOG.syslog("LLDP system-desc is %s" % systemdesc)
575 chassis_id = None
576
577 for member in network_map[br_bond_name]['members']:
578 intf_name = member
579 LOG.syslog("LLDP interface name is %s" % intf_name)
580 mac_addr = get_mac_str(intf_name)
581 if not mac_addr:
582 # skip this interface if unable to get mac_addr
583 LOG.syslog("LLDP unable to get mac_addr. Skip sending LLDP on "
584 "interface %s" % intf_name)
585 continue
586 LOG.syslog("LLDP interface mac is %s" % systemdesc)
587 if not chassis_id:
588 chassis_id = mac_addr
589 LOG.syslog("LLDP chassis-id is %s" % chassis_id)
590 frame = lldp_frame_of(
591 chassis_id=chassis_id, network_interface=intf_name, ttl=TTL,
592 system_name=systemname, system_desc=systemdesc,
593 port_mac_str=mac_addr)
594 frames.append(frame)
595 s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW)
596 s.bind((intf_name, 0))
597 senders.append(s)
598
599 # send frames
600 for idx, s in enumerate(senders):
601 try:
602 s.send(frames[idx])
603 except Exception:
604 continue
605
606
607def send_lldp_on_all_interfaces(args, network_map):
608 """Given a network_map of all bridges, bonds and their interfaces
609
610 respectively. Send LLDP packets on each interface accordingly.
611
612 :param args:
613 :param network_map:
614 :return:
615 """
616 for br_or_bond in network_map:
617 root_type = network_map[br_or_bond]['config_type']
618 if root_type == 'ovs_bridge':
619 # save state in case of x710 nic
620 for intf in network_map[br_or_bond]['members']:
621 save_and_stop_x710_intf_lldp(intf)
622 # send packet via kernel socket
623 _send_frames_kernel_socket(
624 network_map=network_map, br_bond_name=br_or_bond, args=args)
625 elif root_type == 'linux_bond':
626 # send packet via kernel socket
627 _send_frames_kernel_socket(
628 network_map=network_map, br_bond_name=br_or_bond, args=args)
629 elif root_type == 'ovs_user_bridge':
630 # send packet via OVS packet out
631 bridge_name = br_or_bond
632 LOG.syslog("LLDP generating frames for %s" % bridge_name)
633
634 chassis_id = "00:00:00:00:00:00"
635 intf_tuple_list = []
636 for member in network_map[br_or_bond]['members']:
637 intf_name = member
638 ofport_num = get_intf_ofport_number(intf_name=intf_name)
639 mac_addr = get_dpdk_intf_mac_addr(intf_name=intf_name)
640 LOG.syslog("LLDP DPDK interface name %s ofport_num %s "
641 "mac_addr %s" % (intf_name, ofport_num, mac_addr))
642 if (not ofport_num or not mac_addr):
643 LOG.syslog("LLDP either ofport_num or mac_addr missing. "
644 "Skip sending LLDP on interface %s" % intf_name)
645 continue
646 intf_tuple_list.append((intf_name, ofport_num, mac_addr))
647 if len(intf_tuple_list) != 0:
648 chassis_id = intf_tuple_list[0][2]
649 LOG.syslog("LLDP chassis-id is %s" % chassis_id)
650 hostname_fqdn = get_fqdn_cli()
651 systemname = hostname_fqdn + '_' + bridge_name
652 LOG.syslog("LLDP system-name is %s" % systemname)
653 # default system-desc for compute node's DPDK interface is STATIC
654 systemdesc = SYSTEM_DESC_STATIC
655 if network_map[bridge_name]['lacp']:
656 # if bonded nics, send LACP system-desc
657 systemdesc = SYSTEM_DESC_LACP
658 LOG.syslog("LLDP system-desc is %s" % systemdesc)
659 # generate ovs-ofctl packet-out command for each interface
660 for (intf_name, ofport_num, mac_addr) in intf_tuple_list:
661 raw_frame = lldp_frame_of(
662 chassis_id=chassis_id, network_interface=intf_name,
663 ttl=120, system_name=systemname, system_desc=systemdesc,
664 port_mac_str=mac_addr)
665 hex_pkt = raw_frame.encode('hex')
666 send_pktout_via_ovs(bridge_name=bridge_name,
667 intf_ofport_num=ofport_num,
668 hex_pkt=hex_pkt)
669
670
671def send_lldp_redhat(args):
672 interval = INTERVAL
673 if args.interval:
674 interval = args.interval
675 LOG.syslog("LLDP interval is %d" % interval)
676 while True:
677 network_map = get_network_interface_map()
678 send_lldp_on_all_interfaces(args, network_map)
679 time.sleep(interval)
680
681
682def send_lldp():
683 args = parse_args()
684 if args.daemonize:
685 daemonize()
686
687 intfs = []
688 platform_os = platform.linux_distribution()[0]
689 os_is_redhat = "red hat" in platform_os.strip().lower()
690
691 if os_is_redhat and not args.sriov:
692 send_lldp_redhat(args)
693
694 chassisid = "00:00:00:00:00:00"
695 if args.network_interface:
696 intfs = args.network_interface.split(',')
697
698 LOG.syslog("LLDP interfaces are %s" % ','.join(intfs))
699 LOG.syslog("LLDP chassisid is %s" % chassisid)
700
701 senders, frames = _generate_senders_frames(intfs, chassisid, args)
702 interval = INTERVAL
703 if args.interval:
704 interval = args.interval
705 LOG.syslog("LLDP interval is %d" % interval)
706 while True:
707 for idx, s in enumerate(senders):
708 try:
709 s.send(frames[idx])
710 except Exception:
711 continue
712 time.sleep(interval)
713
714
715if __name__ == "__main__":
716 send_lldp()
diff --git a/networking_bigswitch/plugins/bigswitch/neutronclient/__init__.py b/networking_bigswitch/plugins/bigswitch/neutronclient/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/networking_bigswitch/plugins/bigswitch/neutronclient/__init__.py
+++ /dev/null
diff --git a/networking_bigswitch/plugins/bigswitch/neutronclient/v2_0/__init__.py b/networking_bigswitch/plugins/bigswitch/neutronclient/v2_0/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/networking_bigswitch/plugins/bigswitch/neutronclient/v2_0/__init__.py
+++ /dev/null
diff --git a/networking_bigswitch/plugins/bigswitch/neutronclient/v2_0/_bsn_plugin_client.py b/networking_bigswitch/plugins/bigswitch/neutronclient/v2_0/_bsn_plugin_client.py
deleted file mode 100644
index ff94042..0000000
--- a/networking_bigswitch/plugins/bigswitch/neutronclient/v2_0/_bsn_plugin_client.py
+++ /dev/null
@@ -1,542 +0,0 @@
1# Copyright 2011 OpenStack Foundation.
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# 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, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15from networking_bigswitch.plugins.bigswitch.i18n import _
16from neutronclient.common import extension
17
18
19# network templates
20def _networktemplate_updatable_args(parser):
21 parser.add_argument(
22 'name',
23 help=_('Name of this network template.'))
24 parser.add_argument(
25 'body',
26 help=_('Body of this network template.'))
27
28
29def _networktemplate_updatable_args2body(parsed_args, body, client):
30 if parsed_args.name:
31 body['name'] = parsed_args.name
32 if parsed_args.body:
33 body['body'] = parsed_args.body
34
35
36class NetworkTemplate(extension.NeutronClientExtension):
37 resource = 'networktemplate'
38 resource_plural = '%ss' % resource
39 object_path = '/%s' % resource_plural
40 resource_path = '/%s/%%s' % resource_plural
41 versions = ['2.0']
42
43
44class NetworkTemplatesList(extension.ClientExtensionList, NetworkTemplate):
45 """List Network Templates"""
46
47 shell_command = 'network-templates-list'
48 list_columns = ['id', 'name', 'body']
49
50
51class NetworkTemplatesCreate(extension.ClientExtensionCreate, NetworkTemplate):
52 """Create a Network Template."""
53
54 shell_command = 'network-templates-create'
55 list_columns = ['id', 'name', 'body']
56
57 def add_known_arguments(self, parser):
58 _networktemplate_updatable_args(parser)
59
60 def args2body(self, parsed_args):
61 body = {}
62 client = self.get_client()
63 _networktemplate_updatable_args2body(parsed_args, body, client)
64 return {'networktemplate': body}
65
66
67class NetworkTemplatesUpdate(extension.ClientExtensionUpdate, NetworkTemplate):
68 """Update a network template."""
69
70 shell_command = 'network-templates-update'
71 list_columns = ['id', 'name', 'body']
72
73 def add_known_arguments(self, parser):
74 _networktemplate_updatable_args(parser)
75
76 def args2body(self, parsed_args):
77 body = {}
78 client = self.get_client()
79 _networktemplate_updatable_args2body(parsed_args, body, client)
80 return {'networktemplate': body}
81
82
83class NetworkTemplatesDelete(extension.ClientExtensionDelete, NetworkTemplate):
84 """Delete a network template."""
85
86 shell_command = 'network-templates-delete'
87
88
89class NetworkTemplatesShow(extension.ClientExtensionShow, NetworkTemplate):
90 """Show a network template."""
91
92 shell_command = 'network-templates-show'
93
94
95# network template assignment
96def _networktemplateassignment_updatable_args(parser):
97 parser.add_argument(
98 'template_id', metavar='template-id',
99 help=_('ID of the network template associated with this tenant.'))
100 parser.add_argument(
101 'stack_id', metavar='stack-id',
102 help=_('ID of the heat template associated with this tenant.'))
103
104
105def _networktemplateassignment_updatable_args2body(parsed_args, body, client):
106 if parsed_args.template_id:
107 body['template_id'] = parsed_args.template_id
108 if parsed_args.stack_id:
109 body['stack_id'] = parsed_args.stack_id
110
111
112class NetworkTemplateAssignment(extension.NeutronClientExtension):
113 resource = 'networktemplateassignment'
114 resource_plural = '%ss' % resource
115 object_path = '/%s' % resource_plural
116 resource_path = '/%s/%%s' % resource_plural
117 versions = ['2.0']
118
119
120class NetworkTemplateAssignmentsList(extension.ClientExtensionList,
121 NetworkTemplateAssignment):
122 """List Network Template Assignments"""
123
124 shell_command = 'network-template-assignments-list'
125 list_columns = ['tenant_id', 'template_id', 'stack_id']
126
127
128class NetworkTemplateAssignmentsCreate(extension.ClientExtensionCreate,
129 NetworkTemplateAssignment):
130 """Create a Network Template Assignment."""
131
132 shell_command = 'network-template-assignments-create'
133 list_columns = ['tenant_id', 'template_id', 'stack_id']
134
135 def add_known_arguments(self, parser):
136 _networktemplateassignment_updatable_args(parser)
137
138 def args2body(self, parsed_args):
139 body = {}
140 client = self.get_client()
141 _networktemplateassignment_updatable_args2body(parsed_args,
142 body,
143 client)
144 return {'networktemplateassignment': body}
145
146
147class NetworkTemplateAssignmentsUpdate(extension.ClientExtensionUpdate,
148 NetworkTemplateAssignment):
149 """Update a Network Template Assignment."""
150
151 allow_names = False
152 shell_command = 'network-template-assignments-update'
153 list_columns = ['tenant_id', 'template_id', 'stack_id']
154
155 def add_known_arguments(self, parser):
156 _networktemplateassignment_updatable_args(parser)
157
158 def args2body(self, parsed_args):
159 body = {}
160 client = self.get_client()
161 _networktemplateassignment_updatable_args2body(parsed_args,
162 body,
163 client)
164 return {'networktemplateassignment': body}
165
166
167class NetworkTemplateAssignmentsDelete(extension.ClientExtensionDelete,
168 NetworkTemplateAssignment):
169 """Delete a Network Template Assignment."""
170
171 shell_command = 'network-template-assignments-delete'
172
173
174class NetworkTemplateAssignmentsShow(extension.ClientExtensionShow,
175 NetworkTemplateAssignment):
176 """Show a Network Template Assignment."""
177
178 shell_command = 'network-template-assignments-show'
179
180
181# reachability tests
182def _reachabilitytest_updatable_args(parser):
183 parser.add_argument(
184 'name',
185 help=_('Name of this reachability test.'))
186 parser.add_argument(
187 'src_tenant_id', metavar='src-tenant-id',
188 help=_('Tenant ID of the src-ip.'))
189 parser.add_argument(
190 'src_tenant_name', metavar='src-tenant-name',
191 help=_('Tenant name of the src-ip.'))
192 parser.add_argument(
193 'src_segment_id', metavar='src-segment-id',
194 help=_('Network id of the src-ip.'))
195 parser.add_argument(
196 'src_segment_name', metavar='src-segment-name',
197 help=_('Network name of the src-ip.'))
198 parser.add_argument(
199 'src_ip', metavar='src-ip',
200 help=_('Source IP of the reachability test.'))
201 parser.add_argument(
202 'dst_ip', metavar='dst-ip',
203 help=_('Destination IP of the reachability test.'))
204 parser.add_argument(
205 'expected_result', metavar='expected-result',
206 help=_('Expected result of the test.'))
207
208
209def _reachabilitytest_runtest_args(parser):
210 parser.add_argument('name',
211 help=_('Name of this reachability test.'))
212
213
214def _reachabilitytest_updatable_args2body(parsed_args, body, client):
215 if parsed_args.name:
216 body['name'] = parsed_args.name
217 if parsed_args.src_tenant_id:
218 body['src_tenant_id'] = parsed_args.src_tenant_id
219 if parsed_args.src_tenant_name:
220 body['src_tenant_name'] = parsed_args.src_tenant_name
221 if parsed_args.src_segment_id:
222 body['src_segment_id'] = parsed_args.src_segment_id
223 if parsed_args.src_segment_name:
224 body['src_segment_name'] = parsed_args.src_segment_name
225 if parsed_args.src_ip:
226 body['src_ip'] = parsed_args.src_ip
227 if parsed_args.dst_ip:
228 body['dst_ip'] = parsed_args.dst_ip
229 if parsed_args.expected_result:
230 body['expected_result'] = parsed_args.expected_result
231
232
233class ReachabilityTest(extension.NeutronClientExtension):
234 resource = 'reachabilitytest'
235 resource_plural = '%ss' % resource
236 object_path = '/%s' % resource_plural
237 resource_path = '/%s/%%s' % resource_plural
238 versions = ['2.0']
239
240
241class ReachabilityTestsList(extension.ClientExtensionList, ReachabilityTest):
242 """List Reachability Tests."""
243
244 shell_command = 'reachability-tests-list'
245 list_columns = ['id', 'name', 'src_tenant_id', 'src_tenant_name',
246 'src_segment_id', 'src_segment_name',
247 'src_ip', 'dst_ip', 'expected_result']
248
249
250class ReachabilityTestsCreate(extension.ClientExtensionCreate,
251 ReachabilityTest):
252 """Create a Reachability Test."""
253
254 shell_command = 'reachability-tests-create'
255 list_columns = ['id', 'name', 'src_tenant_id', 'src_tenant_name',
256 'src_segment_id', 'src_segment_name',
257 'src_ip', 'dst_ip', 'expected_result']
258
259 def add_known_arguments(self, parser):
260 _reachabilitytest_updatable_args(parser)
261
262 def args2body(self, parsed_args):
263 body = {}
264 client = self.get_client()
265 _reachabilitytest_updatable_args2body(parsed_args, body, client)
266 return {'reachabilitytest': body}
267
268
269class ReachabilityTestsUpdate(extension.ClientExtensionUpdate,
270 ReachabilityTest):
271 """Update a Reachability Test."""
272
273 shell_command = 'reachability-tests-update'
274 list_columns = ['id', 'name', 'src_tenant_id', 'src_tenant_name',
275 'src_segment_id', 'src_segment_name',
276 'src_ip', 'dst_ip', 'expected_result']
277
278 def add_known_arguments(self, parser):
279 _reachabilitytest_updatable_args(parser)
280
281 def args2body(self, parsed_args):
282 body = {}
283 client = self.get_client()
284 _reachabilitytest_updatable_args2body(parsed_args, body, client)
285 return {'reachabilitytest': body}
286
287
288class ReachabilityTestsRun(extension.ClientExtensionUpdate,
289 ReachabilityTest):
290 """Run a Reachability Test."""
291
292 shell_command = 'reachability-tests-run'
293 list_columns = ['id', 'name', 'src_tenant_id', 'src_tenant_name',
294 'src_segment_id', 'src_segment_name',
295 'src_ip', 'dst_ip', 'expected_result', 'test_result',
296 'detail', 'logical_path', 'test_time']
297
298 def args2body(self, parsed_args):
299 body = {}
300 body['run_test'] = True
301 return {'reachabilitytest': body}
302
303
304class ReachabilityTestsDelete(extension.ClientExtensionDelete,
305 ReachabilityTest):
306 """Delete a Reachability Test."""
307
308 shell_command = 'reachability-tests-delete'
309
310
311class ReachabilityTestsShow(extension.ClientExtensionShow, ReachabilityTest):
312 """Show a Reachability Test."""
313
314 shell_command = 'reachability-tests-show'
315
316
317# reachability quick tests
318class ReachabilityQuickTest(extension.NeutronClientExtension):
319 resource = 'reachabilityquicktest'
320 resource_plural = '%ss' % resource
321 object_path = '/%s' % resource_plural
322 resource_path = '/%s/%%s' % resource_plural
323 versions = ['2.0']
324
325
326class ReachabilityQuickTestsList(extension.ClientExtensionList,
327 ReachabilityQuickTest):
328 """List Reachability Quick Tests."""
329
330 shell_command = 'reachability-quick-tests-list'
331 list_columns = ['id', 'name', 'src_tenant_id', 'src_tenant_name',
332 'src_segment_id', 'src_segment_name',
333 'src_ip', 'dst_ip', 'expected_result']
334
335
336class ReachabilityQuickTestsCreate(extension.ClientExtensionCreate,
337 ReachabilityQuickTest):
338 """Create a Reachability Quick Test."""
339
340 shell_command = 'reachability-quick-tests-create'
341 list_columns = ['id', 'name', 'src_tenant_id', 'src_tenant_name',
342 'src_segment_id', 'src_segment_name',
343 'src_ip', 'dst_ip', 'expected_result']
344
345 def add_known_arguments(self, parser):
346 _reachabilitytest_updatable_args(parser)
347
348 def args2body(self, parsed_args):
349 body = {}
350 client = self.get_client()
351 _reachabilitytest_updatable_args2body(parsed_args, body, client)
352 return {'reachabilityquicktest': body}
353
354
355class ReachabilityQuickTestsUpdate(extension.ClientExtensionUpdate,
356 ReachabilityQuickTest):
357 """Update a Reachability Quick Test."""
358
359 shell_command = 'reachability-quick-tests-update'
360 list_columns = ['id', 'name', 'src_tenant_id', 'src_tenant_name',
361 'src_segment_id', 'src_segment_name',
362 'src_ip', 'dst_ip', 'expected_result']
363
364 def add_known_arguments(self, parser):
365 _reachabilitytest_updatable_args(parser)
366
367 def args2body(self, parsed_args):
368 body = {}
369 client = self.get_client()
370 _reachabilitytest_updatable_args2body(parsed_args, body, client)
371 return {'reachabilityquicktest': body}
372
373
374class ReachabilityQuickTestsRun(extension.ClientExtensionUpdate,
375 ReachabilityQuickTest):
376 """Run a Reachability Quick Test."""
377
378 shell_command = 'reachability-quick-tests-run'
379 list_columns = ['id', 'name', 'src_tenant_id', 'src_tenant_name',
380 'src_segment_id', 'src_segment_name',
381 'src_ip', 'dst_ip', 'expected_result', 'test_result',
382 'detail', 'logical_path', 'test_time']
383
384 def args2body(self, parsed_args):
385 body = {}
386 body['run_test'] = True
387 return {'reachabilityquicktest': body}
388
389
390class ReachabilityQuickTestsDelete(extension.ClientExtensionDelete,
391 ReachabilityQuickTest):
392 """Delete a Reachability Quick Test."""
393
394 shell_command = 'reachability-quick-tests-delete'
395
396
397class ReachabilityQuickTestsShow(extension.ClientExtensionShow,
398 ReachabilityQuickTest):
399 """Show a Reachability Quick Test."""
400
401 shell_command = 'reachability-quick-tests-show'
402
403
404# tenant policies
405def _tenantpolicy_updateable_args(parser):
406 parser.add_argument(
407 'source',
408 help=_('Source for the policy.'))
409 parser.add_argument(
410 '-source_port',
411 help=_('Source port for the policy. Optional.'))
412 parser.add_argument(
413 'destination',
414 help=_('Destination for the policy.'))
415 parser.add_argument(
416 '-destination_port',
417 help=_('Destination port for the policy. Optional.'))
418 parser.add_argument(
419 'action',
420 help=_('Action for matching traffic - permit or deny.'))
421 parser.add_argument(
422 '-protocol',
423 help=_('Protocol for matching traffic when specifying '
424 'source or destination port.'))
425 parser.add_argument(
426 '-nexthops',
427 help=_('Optional nexthops.'))
428
429
430def _tenantpolicy_updateable_args2body(parsed_args, body, client):
431 if parsed_args.source:
432 body['source'] = parsed_args.source
433 if parsed_args.source_port:
434 body['source_port'] = parsed_args.source_port
435 if parsed_args.destination:
436 body['destination'] = parsed_args.destination
437 if parsed_args.destination_port:
438 body['destination_port'] = parsed_args.destination_port
439 if parsed_args.action:
440 body['action'] = parsed_args.action
441 if parsed_args.protocol:
442 body['protocol'] = parsed_args.protocol
443 if parsed_args.nexthops:
444 body['nexthops'] = parsed_args.nexthops
445
446
447class TenantPolicy(extension.NeutronClientExtension):
448 resource = 'tenantpolicy'
449 resource_plural = 'tenantpolicies'
450 object_path = '/%s' % resource_plural
451 resource_path = '/%s/%%s' % resource_plural
452 versions = ['2.0']
453
454
455class TenantPoliciesList(extension.ClientExtensionList, TenantPolicy):
456 """List Tenant Policies"""
457
458 shell_command = 'tenant-policies-list'
459 list_columns = ['id', 'priority', 'source', 'source_port', 'destination',
460 'destination_port', 'action', 'nexthops']
461
462
463class TenantPoliciesCreate(extension.ClientExtensionCreate, TenantPolicy):
464 """Create a Tenant Policy."""
465
466 shell_command = 'tenant-policies-create'
467 list_columns = ['id', 'priority', 'source', 'source_port', 'destination',
468 'destination_port', 'action', 'protocol', 'nexthops']
469
470 def add_known_arguments(self, parser):
471 # create takes an extra argument of 'priority'
472 parser.add_argument(
473 'priority',
474 help=_('Priority for the policy. Valid range 1 to 2999'))
475 _tenantpolicy_updateable_args(parser)
476
477 def args2body(self, parsed_args):
478 body = {}
479 client = self.get_client()
480 # create takes an extra argument of 'priority'
481 if parsed_args.priority:
482 body['priority'] = parsed_args.priority
483 _tenantpolicy_updateable_args2body(parsed_args, body, client)
484 return {'tenantpolicy': body}
485
486
487class TenantPoliciesUpdate(extension.ClientExtensionUpdate, TenantPolicy):
488 """Update a Tenant Policy."""
489
490 shell_command = 'tenant-policies-update'
491 list_columns = ['id', 'priority', 'source', 'source_port', 'destination',
492 'destination_port', 'action', 'protocol', 'nexthops']
493
494 def add_known_arguments(self, parser):
495 _tenantpolicy_updateable_args(parser)
496
497 def args2body(self, parsed_args):
498 body = {}
499 client = self.get_client()
500 _tenantpolicy_updateable_args2body(parsed_args, body, client)
501 return {'tenantpolicy': body}
502
503
504class TenantPoliciesDelete(extension.ClientExtensionDelete, TenantPolicy):
505 """Delete a tenant policy."""
506
507 shell_command = 'tenant-policies-delete'
508
509
510class TenantPoliciesShow(extension.ClientExtensionShow, TenantPolicy):
511 """Show a tenant policy."""
512
513 shell_command = 'tenant-policies-show'
514
515
516# Force Sync Topology
517class ForceSyncTopology(extension.NeutronClientExtension):
518 resource = 'forcesynctopology'
519 resource_plural = 'forcesynctopologies'
520 object_path = '/%s' % resource_plural
521 resource_path = '/%s/%%s' % resource_plural
522 versions = ['2.0']
523
524
525class ForceSyncTopologiesUpdate(extension.ClientExtensionUpdate,
526 ForceSyncTopology):
527 """Force a complete Topology Sync to BCF controller."""
528
529 shell_command = 'force-bcf-sync'
530 list_columns = ['id', 'status']
531
532 def args2body(self, parsed_args):
533 body = {'timestamp_ms': 'now'}
534 return {'forcesynctopology': body}
535
536
537class ForceSyncTopologiesList(extension.ClientExtensionList,
538 ForceSyncTopology):
539 """Show the status of last scheduled Topology Sync to BCF."""
540
541 shell_command = 'bcf-sync-status'
542 list_columns = ['id', 'timestamp_ms', 'timestamp_datetime', 'status']
diff --git a/rhel/neutron-bsn-lldp.service b/rhel/neutron-bsn-lldp.service
deleted file mode 100644
index acef5cc..0000000
--- a/rhel/neutron-bsn-lldp.service
+++ /dev/null
@@ -1,14 +0,0 @@
1[Unit]
2Description=bsn lldp
3Wants=network-online.target
4After=syslog.target network.target network-online.target
5
6[Service]
7Type=simple
8ExecStart=/usr/bin/bsnlldp
9Restart=always
10StartLimitInterval=60s
11StartLimitBurst=3
12[Install]
13WantedBy=multi-user.target
14
diff --git a/rhel/python-networking-bigswitch.spec b/rhel/python-networking-bigswitch.spec
index 313c8b4..7fc3e2b 100644
--- a/rhel/python-networking-bigswitch.spec
+++ b/rhel/python-networking-bigswitch.spec
@@ -13,7 +13,6 @@ License: ASL 2.0
13URL: https://pypi.python.org/pypi/%{pypi_name} 13URL: https://pypi.python.org/pypi/%{pypi_name}
14Source0: https://pypi.python.org/packages/source/b/%{pypi_name}/%{pypi_name}-%{version}.tar.gz 14Source0: https://pypi.python.org/packages/source/b/%{pypi_name}/%{pypi_name}-%{version}.tar.gz
15Source1: neutron-bsn-agent.service 15Source1: neutron-bsn-agent.service
16Source2: neutron-bsn-lldp.service
17BuildArch: noarch 16BuildArch: noarch
18 17
19BuildRequires: python-devel 18BuildRequires: python-devel
@@ -46,13 +45,6 @@ Requires: python-%{pypi_name} = %{epoch}:%{version}-%{release}
46This package contains the Big Switch Networks 45This package contains the Big Switch Networks
47neutron agent for security groups. 46neutron agent for security groups.
48 47
49%package -n %{rpm_prefix}-lldp
50Summary: Neutron Big Switch Networks LLDP service
51Requires: python-%{pypi_name} = %{epoch}:%{version}-%{release}
52
53%description -n %{rpm_prefix}-lldp
54This package contains the Big Switch Networks neutron LLDP agent.
55
56%package doc 48%package doc
57Summary: Neutron Big Switch Networks plugin documentation 49Summary: Neutron Big Switch Networks plugin documentation
58 50
@@ -73,7 +65,6 @@ rm %{docpath}/.buildinfo
73%install 65%install
74%{__python2} setup.py install --skip-build --root %{buildroot} 66%{__python2} setup.py install --skip-build --root %{buildroot}
75install -p -D -m 644 %{SOURCE1} %{buildroot}%{_unitdir}/neutron-bsn-agent.service 67install -p -D -m 644 %{SOURCE1} %{buildroot}%{_unitdir}/neutron-bsn-agent.service
76install -p -D -m 644 %{SOURCE2} %{buildroot}%{_unitdir}/neutron-bsn-lldp.service
77mkdir -p %{buildroot}/%{_sysconfdir}/neutron/conf.d/neutron-bsn-agent 68mkdir -p %{buildroot}/%{_sysconfdir}/neutron/conf.d/neutron-bsn-agent
78mkdir -p %{lib_dir}/tests 69mkdir -p %{lib_dir}/tests
79for lib in %{lib_dir}/version.py %{lib_dir}/tests/test_server.py; do 70for lib in %{lib_dir}/version.py %{lib_dir}/tests/test_server.py; do
@@ -96,11 +87,6 @@ done
96%{_bindir}/neutron-bsn-agent 87%{_bindir}/neutron-bsn-agent
97%dir %{_sysconfdir}/neutron/conf.d/neutron-bsn-agent 88%dir %{_sysconfdir}/neutron/conf.d/neutron-bsn-agent
98 89
99%files -n %{rpm_prefix}-lldp
100%license LICENSE
101%{_unitdir}/neutron-bsn-lldp.service
102%{_bindir}/bsnlldp
103
104%files doc 90%files doc
105%license LICENSE 91%license LICENSE
106%doc README.rst 92%doc README.rst
@@ -108,15 +94,12 @@ done
108 94
109%post 95%post
110%systemd_post neutron-bsn-agent.service 96%systemd_post neutron-bsn-agent.service
111%systemd_post neutron-bsn-lldp.service
112 97
113%preun 98%preun
114%systemd_preun neutron-bsn-agent.service 99%systemd_preun neutron-bsn-agent.service
115%systemd_preun neutron-bsn-lldp.service
116 100
117%postun 101%postun
118%systemd_postun_with_restart neutron-bsn-agent.service 102%systemd_postun_with_restart neutron-bsn-agent.service
119%systemd_postun_with_restart neutron-bsn-lldp.service
120 103
121%changelog 104%changelog
122${change_log} 105${change_log}
diff --git a/setup.cfg b/setup.cfg
index 99bf2e5..31b7bab 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -29,7 +29,6 @@ setup-hooks =
29[entry_points] 29[entry_points]
30console_scripts = 30console_scripts =
31 neutron-bsn-agent = networking_bigswitch.plugins.bigswitch.agent.restproxy_agent:main 31 neutron-bsn-agent = networking_bigswitch.plugins.bigswitch.agent.restproxy_agent:main
32 bsnlldp = networking_bigswitch.bsnlldp.bsnlldp:main
33neutron.ml2.mechanism_drivers = 32neutron.ml2.mechanism_drivers =
34 bsn_ml2 = networking_bigswitch.plugins.ml2.drivers.mech_bigswitch.driver:BigSwitchMechanismDriver 33 bsn_ml2 = networking_bigswitch.plugins.ml2.drivers.mech_bigswitch.driver:BigSwitchMechanismDriver
35neutron.service_plugins = 34neutron.service_plugins =
@@ -37,8 +36,6 @@ neutron.service_plugins =
37 bsn_service_plugin = networking_bigswitch.plugins.bigswitch.bsn_service_plugin:BSNServicePlugin 36 bsn_service_plugin = networking_bigswitch.plugins.bigswitch.bsn_service_plugin:BSNServicePlugin
38neutron.db.alembic_migrations = 37neutron.db.alembic_migrations =
39 bsn_extensions = networking_bigswitch.plugins.bigswitch.db.migration:alembic_migrations 38 bsn_extensions = networking_bigswitch.plugins.bigswitch.db.migration:alembic_migrations
40neutronclient.extension =
41 bsn_extensions = networking_bigswitch.plugins.bigswitch.neutronclient.v2_0._bsn_plugin_client
42 39
43[build_sphinx] 40[build_sphinx]
44all_files = 1 41all_files = 1