Fix bgpcep-1node-bgp-ingest tests 13/102213/15
authorSangwook Ha <sangwook.ha@verizon.com>
Thu, 25 Aug 2022 03:53:56 +0000 (20:53 -0700)
committerSangwook Ha <sangwook.ha@verizon.com>
Sat, 27 Aug 2022 21:56:51 +0000 (14:56 -0700)
Python 2 and 'python' command is not available any more in ODL system VM
based on CentOS 8. Update Python scripts 'ipaddr.py', 'play.py' and
'bgp_app_peer.py' to support Python 3.

Use the RFC8040 URLs in 'bgp_app_peer.py' to address some of the failed
test cases in Chlrorine where RESTCONF draft implementation is removed.

Change-Id: I4ffde830df6211b1365b87203843e08134348d26
Signed-off-by: Sangwook Ha <sangwook.ha@verizon.com>
csit/libraries/BGPCEP/ipaddr.py
csit/libraries/BGPSpeaker.robot
csit/libraries/SSHKeywords.robot
csit/suites/bgpcep/bgpingest/bgp_app_peer_prefixcount.robot
csit/suites/bgpcep/bgpuser/bgp_app_peer_basic.robot
csit/suites/bgpcep/bgpuser/ebgp_peers_basic.robot
csit/suites/bgpcep/bgpuser/ibgp_peer_lsp.robot
csit/suites/netconf/notifications/notifications_basic.robot
tools/fastbgp/bgp_app_peer.py
tools/fastbgp/play.py

index c0fb69448ff58c0873e7be5b761f8dc261ab1e44..7b6d746386dcd7f465825b91c52bd6d28c3a6e7d 100644 (file)
@@ -529,7 +529,7 @@ class _BaseIP(_IPAddrBase):
         return "%s" % self._string_from_ip_int(self._ip)
 
     def __hash__(self):
-        return hash(hex(long(self._ip)))
+        return hash(hex(int(self._ip)))
 
     def _get_address_key(self):
         return (self._version, self)
@@ -1163,7 +1163,7 @@ class _BaseV4(object):
 
         """
         octets = []
-        for _ in xrange(4):
+        for _ in range(4):
             octets.insert(0, str(ip_int & 0xFF))
             ip_int >>= 8
         return ".".join(octets)
@@ -1272,7 +1272,7 @@ class IPv4Address(_BaseV4, _BaseIP):
         _BaseV4.__init__(self, address)
 
         # Efficient constructor from integer.
-        if isinstance(address, (int, long)):
+        if isinstance(address, int):
             self._ip = address
             if address < 0 or address > self._ALL_ONES:
                 raise AddressValueError(address)
@@ -1351,7 +1351,7 @@ class IPv4Network(_BaseV4, _BaseNet):
         _BaseV4.__init__(self, address)
 
         # Constructing from an integer or packed bytes.
-        if isinstance(address, (int, long, Bytes)):
+        if isinstance(address, (int, Bytes)):
             self.ip = IPv4Address(address)
             self._ip = self.ip._ip
             self._prefixlen = self._max_prefixlen
@@ -1450,7 +1450,7 @@ class _BaseV6(object):
         # Disregarding the endpoints, find '::' with nothing in between.
         # This indicates that a run of zeroes has been skipped.
         try:
-            (skip_index,) = [i for i in xrange(1, len(parts) - 1) if not parts[i]] or [
+            (skip_index,) = [i for i in range(1, len(parts) - 1) if not parts[i]] or [
                 None
             ]
         except ValueError:
@@ -1486,11 +1486,11 @@ class _BaseV6(object):
         try:
             # Now, parse the hextets into a 128-bit integer.
             ip_int = 0
-            for i in xrange(parts_hi):
+            for i in range(parts_hi):
                 ip_int <<= 16
                 ip_int |= self._parse_hextet(parts[i])
             ip_int <<= 16 * parts_skipped
-            for i in xrange(-parts_lo, 0):
+            for i in range(-parts_lo, 0):
                 ip_int <<= 16
                 ip_int |= self._parse_hextet(parts[i])
             return ip_int
@@ -1610,7 +1610,7 @@ class _BaseV6(object):
 
         ip_int = self._ip_int_from_string(ip_str)
         parts = []
-        for i in xrange(self._HEXTET_COUNT):
+        for i in range(self._HEXTET_COUNT):
             parts.append("%04x" % (ip_int & 0xFFFF))
             ip_int >>= 16
         parts.reverse()
@@ -1793,7 +1793,7 @@ class IPv6Address(_BaseV6, _BaseIP):
         _BaseV6.__init__(self, address)
 
         # Efficient constructor from integer.
-        if isinstance(address, (int, long)):
+        if isinstance(address, int):
             self._ip = address
             if address < 0 or address > self._ALL_ONES:
                 raise AddressValueError(address)
@@ -1867,7 +1867,7 @@ class IPv6Network(_BaseV6, _BaseNet):
         _BaseV6.__init__(self, address)
 
         # Constructing from an integer or packed bytes.
-        if isinstance(address, (int, long, Bytes)):
+        if isinstance(address, (int, Bytes)):
             self.ip = IPv6Address(address)
             self._ip = self.ip._ip
             self._prefixlen = self._max_prefixlen
index 9b853bd4b38d130ce4ddac0e288a169af0693932..4801bf936d94e1722ddbc8a43f72340272113015 100644 (file)
@@ -39,7 +39,7 @@ Start_BGP_Speaker
     ...    so it can be dumped into the logs later, when stopping it. This also avoids polluting the
     ...    output seen by "Read Until Prompt" with false propmpts so it won't stop prematurely
     ...    leading to a spurious test failure, messy log content or other misbehavior.
-    ${command} =    BuiltIn.Set_Variable    python play.py ${arguments} &> ${BGPSpeaker__OUTPUT_LOG}
+    ${command} =    BuiltIn.Set_Variable    python3 play.py ${arguments} &> ${BGPSpeaker__OUTPUT_LOG}
     BuiltIn.Log    ${command}
     ${output} =    SSHLibrary.Write    ${command}
 
@@ -64,7 +64,7 @@ Verify_BGP_Speaker_Connection
 Start_BGP_Manager
     [Arguments]    ${arguments}
     [Documentation]    Start the BGP manager python utility. Redirect its error output to a log file.
-    ${command}=    BuiltIn.Set_Variable    python play.py ${arguments} &> ${BGPSpeaker__OUTPUT_LOG}
+    ${command}=    BuiltIn.Set_Variable    python3 play.py ${arguments} &> ${BGPSpeaker__OUTPUT_LOG}
     BuiltIn.Log    ${command}
     ${output}=    SSHLibrary.Write    ${command}
 
index adfefcc5211f1c0cd2d6ffcc2abca39581f6b1cf..7042e7dcfe2e5a4513ade01191ee8192f3e11267 100644 (file)
@@ -134,9 +134,9 @@ Execute_Command_At_Cwd_Should_Pass
 
 Require_Python
     [Documentation]    Verify current SSH connection leads to machine with python working. Fatal fail otherwise.
-    ${passed} =    Execute_Command_Passes    python --help
+    ${passed} =    Execute_Command_Passes    python3 --help
     BuiltIn.Return_From_Keyword_If    ${passed}
-    BuiltIn.Fatal_Error    Python is not installed!
+    BuiltIn.Fatal_Error    Python is not installed!
 
 Assure_Library_Ipaddr
     [Arguments]    ${target_dir}=.
index 01e5ca0bef7e699d4e0f710fc55da8a8a8a564fb..379eccf77a357ea2a7c185909fb29d9560695444 100644 (file)
@@ -57,13 +57,13 @@ ${BGP_PEER_LOG_LEVEL}    info
 ${BGP_APP_PEER_LOG_LEVEL}    info
 ${ODL_LOG_LEVEL}    INFO
 ${ODL_BGP_LOG_LEVEL}    DEFAULT
-${BGP_PEER_COMMAND}    python play.py --amount 0 --myip=${TOOLS_SYSTEM_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --peerport=${ODL_BGP_PORT} --${BGP_PEER_LOG_LEVEL}
+${BGP_PEER_COMMAND}    python3 play.py --amount 0 --myip=${TOOLS_SYSTEM_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --peerport=${ODL_BGP_PORT} --${BGP_PEER_LOG_LEVEL}
 ${BGP_PEER_OPTIONS}    &>bgp_peer.log
 ${BGP_APP_PEER_ID}    10.0.0.10
-${BGP_APP_PEER_INITIAL_COMMAND}    python bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command post --count ${PREFILL} --prefix 8.0.0.0 --prefixlen 28 --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM}
-${BGP_APP_PEER_PUT_COMMAND}    python bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command put --count ${PREFILL} --prefix 8.0.0.0 --prefixlen 28 --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM}
-${BGP_APP_PEER_DELETE_ALL_COMMAND}    python bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command delete-all --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM}
-${BGP_APP_PEER_GET_COMMAND}    python bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command get --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM}
+${BGP_APP_PEER_INITIAL_COMMAND}    python3 bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command post --count ${PREFILL} --prefix 8.0.0.0 --prefixlen 28 --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM}
+${BGP_APP_PEER_PUT_COMMAND}    python3 bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command put --count ${PREFILL} --prefix 8.0.0.0 --prefixlen 28 --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM}
+${BGP_APP_PEER_DELETE_ALL_COMMAND}    python3 bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command delete-all --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM}
+${BGP_APP_PEER_GET_COMMAND}    python3 bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command get --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM}
 ${BGP_APP_PEER_OPTIONS}    &>bgp_app_peer.log
 ${TEST_DURATION_MULTIPLIER}    30
 ${last_prefix_count}    -1
@@ -114,7 +114,7 @@ Check_Bgp_Peer_Updates_For_Prefilled_Routes
 BGP_Application_Peer_Introduce_Single_Routes
     [Documentation]    Start BGP application peer tool and introduce routes.
     SSHLibrary.Switch Connection    bgp_app_peer_console
-    BGPcliKeywords.Start_Console_Tool    python bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command add --count ${remaining_prefixes} --prefix 12.0.0.0 --prefixlen 28 --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM} ${script_uri_opt}    ${BGP_APP_PEER_OPTIONS}
+    BGPcliKeywords.Start_Console_Tool    python3 bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command add --count ${remaining_prefixes} --prefix 12.0.0.0 --prefixlen 28 --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM} ${script_uri_opt}    ${BGP_APP_PEER_OPTIONS}
     BGPcliKeywords.Wait_Until_Console_Tool_Finish    ${bgp_filling_timeout}
     BGPcliKeywords.Store_File_To_Workspace    bgp_app_peer.log    bgp_app_peer_singles.log
 
@@ -209,7 +209,7 @@ Setup_Everything
     KarafKeywords.Execute_Controller_Karaf_Command_On_Background    log:set ${ODL_LOG_LEVEL}
     KarafKeywords.Execute_Controller_Karaf_Command_On_Background    log:set ${ODL_BGP_LOG_LEVEL} org.opendaylight.bgpcep
     KarafKeywords.Execute_Controller_Karaf_Command_On_Background    log:set ${ODL_BGP_LOG_LEVEL} org.opendaylight.protocol
-    ${script_uri_opt}=    Set Variable    --uri config/bgp-rib:application-rib/${BGP_APP_PEER_ID}/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/
+    ${script_uri_opt}=    Set Variable    --uri data/bgp-rib:application-rib=${BGP_APP_PEER_ID}/tables=bgp-types%3Aipv4-address-family,bgp-types%3Aunicast-subsequent-address-family
     BuiltIn.Set_Suite_Variable    ${script_uri_opt}
 
 Teardown_Everything
index 4339e8450e64f8e63db228960b688b343094683f..3871defc190281ab424711836a25c2dcb526bbfa 100644 (file)
@@ -67,14 +67,14 @@ ${TOOLS_SYSTEM_PROMPT}    ${DEFAULT_LINUX_PROMPT}
 ${HOLDTIME}       180
 ${BGP_PEER_LOG_LEVEL}    debug
 ${BGP_APP_PEER_LOG_LEVEL}    debug
-${BGP_PEER_COMMAND}    python play.py --amount 0 --myip=${TOOLS_SYSTEM_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --peerport=${ODL_BGP_PORT} --${BGP_PEER_LOG_LEVEL}
+${BGP_PEER_COMMAND}    python3 play.py --amount 0 --myip=${TOOLS_SYSTEM_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --peerport=${ODL_BGP_PORT} --${BGP_PEER_LOG_LEVEL}
 ${BGP_PEER_OPTIONS}    ${EMPTY}
 ${BGP_APP_PEER_ID}    ${ODL_SYSTEM_IP}
-${BGP_APP_PEER_POST_COMMAND}    python bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command post --count 3 --prefix 8.0.1.0 --prefixlen 28 --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM}
-${BGP_APP_PEER_PUT_COMMAND}    python bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command put --count 3 --prefix 8.0.1.0 --prefixlen 28 --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM}
-${BGP_APP_PEER_DELETE_COMMAND}    python bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command delete --count 3 --prefix 8.0.1.0 --prefixlen 28 --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM}
-${BGP_APP_PEER_DELETE_ALL_COMMAND}    python bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command delete-all --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM}
-${BGP_APP_PEER_GET_COMMAND}    python bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command get --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM}
+${BGP_APP_PEER_POST_COMMAND}    python3 bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command post --count 3 --prefix 8.0.1.0 --prefixlen 28 --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM}
+${BGP_APP_PEER_PUT_COMMAND}    python3 bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command put --count 3 --prefix 8.0.1.0 --prefixlen 28 --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM}
+${BGP_APP_PEER_DELETE_COMMAND}    python3 bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command delete --count 3 --prefix 8.0.1.0 --prefixlen 28 --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM}
+${BGP_APP_PEER_DELETE_ALL_COMMAND}    python3 bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command delete-all --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM}
+${BGP_APP_PEER_GET_COMMAND}    python3 bgp_app_peer.py --host ${ODL_SYSTEM_IP} --port ${RESTCONFPORT} --command get --${BGP_APP_PEER_LOG_LEVEL} --stream=${ODL_STREAM}
 ${BGP_APP_PEER_OPTIONS}    &>/dev/null
 ${BGP_APP_PEER_TIMEOUT}    30s
 ${BGP_PEER_APP_NAME}    example-bgp-peer-app
@@ -84,7 +84,7 @@ ${PROTOCOL_OPENCONFIG}    ${RIB_INSTANCE}
 ${DEVICE_NAME}    controller-config
 ${BGP_PEER_NAME}    example-bgp-peer
 ${RIB_INSTANCE}    example-bgp-rib
-${SCRIPT_URI_OPT}    --uri config/bgp-rib:application-rib/${ODL_SYSTEM_IP}/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/
+${SCRIPT_URI_OPT}    --uri data/bgp-rib:application-rib=${ODL_SYSTEM_IP}/tables=bgp-types%3Aipv4-address-family,bgp-types%3Aunicast-subsequent-address-family
 
 *** Test Cases ***
 Reconfigure_ODL_To_Accept_BGP_Peer_Connection
index a21ebce2daa310a411ae2c6dcc52f985de40e5ff..42ab199424571fd416e5f1d1f99f42aa7da7fbc6 100644 (file)
@@ -69,9 +69,9 @@ ${eBGP_PEER2_AS}    ${eBGP_PEERS_AS}
 ${iBGP_PEER1_LOG_FILE}    bgp_peer1.log
 ${eBGP_PEER1_LOG_FILE}    ebgp_peer1.log
 ${eBGP_PEER2_LOG_FILE}    ebgp_peer2.log
-${iBGP_PEER1_COMMAND}    python play.py --firstprefix ${iBGP_PEER1_FIRST_PREFIX_IP} --prefixlen ${iBGP_PEER1_PREFIX_LEN} --amount ${iBGP_PEER1_PREFIX_COUNT} --myip=${iBGP_PEER1_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --peerport=${ODL_BGP_PORT} --${BGP_PEER_LOG_LEVEL} --logfile ${iBGP_PEER1_LOG_FILE}
-${eBGP_PEER1_COMMAND}    python play.py --firstprefix ${eBGP_PEER1_FIRST_PREFIX_IP} --prefixlen ${eBGP_PEER1_PREFIX_LEN} --amount ${eBGP_PEER1_PREFIX_COUNT} --myip=${eBGP_PEER1_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --peerport=${ODL_BGP_PORT} --nexthop ${eBGP_PEER1_NEXT_HOP} --asnumber ${eBGP_PEER1_AS} --${BGP_PEER_LOG_LEVEL} --logfile ${eBGP_PEER1_LOG_FILE}
-${eBGP_PEER2_COMMAND}    python play.py --firstprefix ${eBGP_PEER2_FIRST_PREFIX_IP} --prefixlen ${eBGP_PEER2_PREFIX_LEN} --amount ${eBGP_PEER2_PREFIX_COUNT} --myip=${eBGP_PEER2_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --peerport=${ODL_BGP_PORT} --nexthop ${eBGP_PEER2_NEXT_HOP} --asnumber ${eBGP_PEER2_AS} --${BGP_PEER_LOG_LEVEL} --logfile ${eBGP_PEER2_LOG_FILE}
+${iBGP_PEER1_COMMAND}    python3 play.py --firstprefix ${iBGP_PEER1_FIRST_PREFIX_IP} --prefixlen ${iBGP_PEER1_PREFIX_LEN} --amount ${iBGP_PEER1_PREFIX_COUNT} --myip=${iBGP_PEER1_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --peerport=${ODL_BGP_PORT} --${BGP_PEER_LOG_LEVEL} --logfile ${iBGP_PEER1_LOG_FILE}
+${eBGP_PEER1_COMMAND}    python3 play.py --firstprefix ${eBGP_PEER1_FIRST_PREFIX_IP} --prefixlen ${eBGP_PEER1_PREFIX_LEN} --amount ${eBGP_PEER1_PREFIX_COUNT} --myip=${eBGP_PEER1_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --peerport=${ODL_BGP_PORT} --nexthop ${eBGP_PEER1_NEXT_HOP} --asnumber ${eBGP_PEER1_AS} --${BGP_PEER_LOG_LEVEL} --logfile ${eBGP_PEER1_LOG_FILE}
+${eBGP_PEER2_COMMAND}    python3 play.py --firstprefix ${eBGP_PEER2_FIRST_PREFIX_IP} --prefixlen ${eBGP_PEER2_PREFIX_LEN} --amount ${eBGP_PEER2_PREFIX_COUNT} --myip=${eBGP_PEER2_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --peerport=${ODL_BGP_PORT} --nexthop ${eBGP_PEER2_NEXT_HOP} --asnumber ${eBGP_PEER2_AS} --${BGP_PEER_LOG_LEVEL} --logfile ${eBGP_PEER2_LOG_FILE}
 ${iBGP_PEER1_OPTIONS}    &>${iBGP_PEER1_LOG_FILE}
 ${eBGP_PEER1_OPTIONS}    &>${eBGP_PEER1_LOG_FILE}
 ${eBGP_PEER2_OPTIONS}    &>${eBGP_PEER2_LOG_FILE}
index bebef36e76e403017f25e16c9f9632156e1853d7..2bb7d649012d0042f9e21850b49c53370030a1d0 100644 (file)
@@ -32,7 +32,7 @@ ${BGP_VARIABLES_FOLDER}    ${CURDIR}/../../../variables/bgpuser/
 ${COUNT}          1
 ${HOLDTIME}       180
 ${BGP_PEER_LOG_FILE}    bgp_peer.log
-${BGP_PEER_COMMAND}    python play.py --amount ${COUNT} --myip=${TOOLS_SYSTEM_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --peerport=${ODL_BGP_PORT} --${BGP_PEER_LOG_LEVEL} --logfile ${BGP_PEER_LOG_FILE} --bgpls True
+${BGP_PEER_COMMAND}    python3 play.py --amount ${COUNT} --myip=${TOOLS_SYSTEM_IP} --myport=${BGP_TOOL_PORT} --peerip=${ODL_SYSTEM_IP} --peerport=${ODL_BGP_PORT} --${BGP_PEER_LOG_LEVEL} --logfile ${BGP_PEER_LOG_FILE} --bgpls True
 ${BGP_PEER_OPTIONS}    &>${BGP_PEER_LOG_FILE}
 ${DEFAULT_RIB_CHECK_PERIOD}    1s
 ${DEFAULT_RIB_CHECK_TIMEOUT}    10s
index ad7bebc76c3a835a1fbc58b5ffee1fde245d3526..1e2e45aa457b2c5b552e0c9ac225592fb9f675c0 100644 (file)
@@ -93,7 +93,7 @@ List_DCN_Streams
 
 Start_Receiver
     [Documentation]    Start the websocket listener
-    ${output} =    BuiltIn.Run_Keyword_If    "${USE_RFC8040}" == "False"    SSHLibrary.Write    python wsreceiver.py --uri ${location} --count 2 --logfile ${RECEIVER_LOG_FILE} ${RECEIVER_OPTIONS}
+    ${output} =    BuiltIn.Run_Keyword_If    "${USE_RFC8040}" == "False"    SSHLibrary.Write    python3 wsreceiver.py --uri ${location} --count 2 --logfile ${RECEIVER_LOG_FILE} ${RECEIVER_OPTIONS}
     ...    ELSE    SSHLibrary.Write    python3 ssereceiver.py --uri ${location} --logfile ${RECEIVER_LOG_FILE}
     BuiltIn.Log    ${output}
     ${output} =    SSHLibrary.Read    delay=2s
index b3dfbfd66c60f7d775c03cfe460d0feb5b00aa81..d1a8a28d3f0cba819f8c36ee530ccbf7c038b78b 100755 (executable)
@@ -29,13 +29,13 @@ def _build_url(odl_ip, port, uri):
 
         :param port: controller's restconf port
 
-        :param uri: URI without /restconf/ to complete URL
+        :param uri: URI without /rests/ to complete URL
 
     Returns:
         :returns url: full restconf url corresponding to params
     """
 
-    url = "http://" + str(odl_ip) + ":" + port + "/restconf/" + uri
+    url = "http://" + str(odl_ip) + ":" + port + "/rests/" + uri
     return url
 
 
@@ -107,11 +107,11 @@ def _stream_data(
             logger.debug("...streaming chunk %s (prefix: %s)", chunk, prefix_str)
         logger.debug("xml data\n%s", xml_data)
         total_build_data_time_counter += time.time() - build_data_timestamp
-        yield xml_data
+        yield xml_data.encode()
 
 
 def send_request(
-    operation, odl_ip, port, uri, auth, xml_data=None, expect_status_code=200
+    operation, odl_ip, port, uri, auth, xml_data=None, expect_status_code=None
 ):
     """Send a http request.
 
@@ -122,7 +122,7 @@ def send_request(
 
         :param port: controller's restconf port
 
-        :param uri: URI without /restconf/ to complete URL
+        :param uri: URI without /rests/ to complete URL
 
         :param auth: authentication credentials
 
@@ -131,6 +131,9 @@ def send_request(
     Returns:
         :returns http response object
     """
+    if expect_status_code is None:
+        expect_status_code = [200]
+
     global total_response_time_counter
     global total_number_of_responses_counter
 
@@ -148,7 +151,7 @@ def send_request(
     except requests.exceptions.Timeout:
         logger.error("No response from %s", odl_ip)
     else:
-        if rsp.status_code == expect_status_code:
+        if rsp.status_code in expect_status_code:
             logger.debug("%s %s", rsp.request, rsp.request.url)
             logger.debug("Request headers: %s:", rsp.request.headers)
             logger.debug("Response: %s", rsp.text)
@@ -178,7 +181,7 @@ def get_prefixes(
 
         :param port: controller's restconf port
 
-        :param uri: URI without /restconf/ to complete URL
+        :param uri: URI without /rests/ to complete URL
 
         :param auth: authentication tupple as (user, password)
 
@@ -194,7 +197,7 @@ def get_prefixes(
         :returns None
     """
 
-    logger.info("Get all prefixes from %s:%s/restconf/%s", odl_ip, port, uri)
+    logger.info("Get all prefixes from %s:%s/rests/%s", odl_ip, port, uri)
     rsp = send_request("GET", odl_ip, port, uri, auth)
     if rsp is not None:
         s = rsp.text
@@ -231,7 +234,7 @@ def post_prefixes(
 
         :param port: controller's restconf port
 
-        :param uri: URI without /restconf/ to complete URL
+        :param uri: URI without /rests/ to complete URL
 
         :param auth: authentication tupple as (user, password)
 
@@ -249,7 +252,7 @@ def post_prefixes(
         :returns None
     """
     logger.info(
-        "Post %s prefix(es) in a single request (starting from %s/%s) into %s:%s/restconf/%s",
+        "Post %s prefix(es) in a single request (starting from %s/%s) into %s:%s/rests/%s",
         count,
         prefix_base,
         prefix_len,
@@ -259,7 +262,7 @@ def post_prefixes(
     )
     xml_stream = _stream_data(xml_template, prefix_base, prefix_len, count, route_key)
     send_request(
-        "POST", odl_ip, port, uri, auth, xml_data=xml_stream, expect_status_code=204
+        "POST", odl_ip, port, uri, auth, xml_data=xml_stream, expect_status_code=[201]
     )
 
 
@@ -281,7 +284,7 @@ def put_prefixes(
 
         :param port: controller's restconf port
 
-        :param uri: URI without /restconf/ to complete URL
+        :param uri: URI without /rests/ to complete URL
 
         :param auth: authentication tupple as (user, password)
 
@@ -296,9 +299,9 @@ def put_prefixes(
     Returns:
         :returns None
     """
-    uri_add_prefix = uri + _uri_suffix_ipv4_routes
+    uri_add_prefix = f"{uri}/{_uri_suffix_ipv4_routes}"
     logger.info(
-        "Put %s prefix(es) in a single request (starting from %s/%s) into %s:%s/restconf/%s",
+        "Put %s prefix(es) in a single request (starting from %s/%s) into %s:%s/rests/%s",
         count,
         prefix_base,
         prefix_len,
@@ -307,7 +310,15 @@ def put_prefixes(
         uri_add_prefix,
     )
     xml_stream = _stream_data(xml_template, prefix_base, prefix_len, count, route_key)
-    send_request("PUT", odl_ip, port, uri_add_prefix, auth, xml_data=xml_stream)
+    send_request(
+        "PUT",
+        odl_ip,
+        port,
+        uri_add_prefix,
+        auth,
+        xml_data=xml_stream,
+        expect_status_code=[201, 204],
+    )
 
 
 def add_prefixes(
@@ -328,7 +339,7 @@ def add_prefixes(
 
         :param port: controller's restconf port
 
-        :param uri: URI without /restconf/ to complete URL
+        :param uri: URI without /rests/ to complete URL
 
         :param auth: authentication tupple as (user, password)
 
@@ -344,7 +355,7 @@ def add_prefixes(
         :returns None
     """
     logger.info(
-        "Add %s prefixes (starting from %s/%s) into %s:%s/restconf/%s",
+        "Add %s prefixes (starting from %s/%s) into %s:%s/rests/%s",
         count,
         prefix_base,
         prefix_len,
@@ -352,12 +363,12 @@ def add_prefixes(
         port,
         uri,
     )
-    uri_add_prefix = uri + _uri_suffix_ipv4_routes
+    uri_add_prefix = f"{uri}/{_uri_suffix_ipv4_routes}"
     prefix_gap = 2 ** (32 - prefix_len)
     for prefix_index in range(count):
         prefix = prefix_base + prefix_index * prefix_gap
         logger.info(
-            "Adding prefix %s/%s to %s:%s/restconf/%s",
+            "Adding prefix %s/%s to %s:%s/rests/%s",
             prefix,
             prefix_len,
             odl_ip,
@@ -374,7 +385,7 @@ def add_prefixes(
             uri_add_prefix,
             auth,
             xml_data=xml_stream,
-            expect_status_code=204,
+            expect_status_code=[201],
         )
 
 
@@ -388,7 +399,7 @@ def delete_prefixes(
 
         :param port: controller's restconf port
 
-        :param uri: URI without /restconf/ to complete URL
+        :param uri: URI without /rests/ to complete URL
 
         :param auth: authentication tupple as (user, password)
 
@@ -404,7 +415,7 @@ def delete_prefixes(
         :returns None
     """
     logger.info(
-        "Delete %s prefix(es) (starting from %s/%s) from %s:%s/restconf/%s",
+        "Delete %s prefix(es) (starting from %s/%s) from %s:%s/rests/%s",
         count,
         prefix_base,
         prefix_len,
@@ -412,13 +423,13 @@ def delete_prefixes(
         port,
         uri,
     )
-    partkey = "/0"
-    uri_del_prefix = uri + _uri_suffix_ipv4_routes + _uri_suffix_ipv4_route
+    partkey = ",0"
+    uri_del_prefix = f"{uri}/{_uri_suffix_ipv4_routes}/{_uri_suffix_ipv4_route}"
     prefix_gap = 2 ** (32 - prefix_len)
     for prefix_index in range(count):
         prefix = prefix_base + prefix_index * prefix_gap
         logger.info(
-            "Deleting prefix %s/%s/%s from %s:%s/restconf/%s",
+            "Deleting prefix %s/%s/%s from %s:%s/rests/%s",
             prefix,
             prefix_len,
             partkey,
@@ -430,8 +441,9 @@ def delete_prefixes(
             "DELETE",
             odl_ip,
             port,
-            uri_del_prefix + str(prefix) + "%2F" + str(prefix_len) + partkey,
+            f"{uri_del_prefix}={prefix}%2F{prefix_len}{partkey}",
             auth,
+            expect_status_code=[204],
         )
 
 
@@ -452,7 +464,7 @@ def delete_all_prefixes(
 
         :param port: controller's restconf port
 
-        :param uri: URI without /restconf/ to complete URL
+        :param uri: URI without /rests/ to complete URL
 
         :param auth: authentication tupple as (user, password)
 
@@ -467,15 +479,17 @@ def delete_all_prefixes(
     Returns:
         :returns None
     """
-    logger.info("Delete all prefixes from %s:%s/restconf/%s", odl_ip, port, uri)
-    uri_del_all_prefixes = uri + _uri_suffix_ipv4_routes
-    send_request("DELETE", odl_ip, port, uri_del_all_prefixes, auth)
+    logger.info("Delete all prefixes from %s:%s/rests/%s", odl_ip, port, uri)
+    uri_del_all_prefixes = f"{uri}/{_uri_suffix_ipv4_routes}"
+    send_request(
+        "DELETE", odl_ip, port, uri_del_all_prefixes, auth, expect_status_code=[204]
+    )
 
 
 _commands = ["post", "put", "add", "delete", "delete-all", "get"]
-_uri_suffix_ipv4_routes = "bgp-inet:ipv4-routes/"
+_uri_suffix_ipv4_routes = "bgp-inet:ipv4-routes"
 _uri_suffix_ipv4_route = (
-    "bgp-inet:ipv4-route/"  # followed by IP address like 1.1.1.1%2F32
+    "bgp-inet:ipv4-route"  # followed by IP address like 1.1.1.1%2F32
 )
 
 if __name__ == "__main__":
@@ -508,9 +522,9 @@ if __name__ == "__main__":
     parser.add_argument(
         "--uri",
         help="The uri part of requests",
-        default="config/bgp-rib:application-rib/example-app-rib/"
-        "tables/bgp-types:ipv4-address-family/"
-        "bgp-types:unicast-subsequent-address-family/",
+        default="data/bgp-rib:application-rib=example-app-rib/"
+        "tables=bgp-types%3Aipv4-address-family,"
+        "bgp-types%3Aunicast-subsequent-address-family",
     )
     parser.add_argument(
         "--xml",
@@ -574,7 +588,7 @@ if __name__ == "__main__":
     prefix_base = args.prefix
     prefix_len = args.prefixlen
     count = args.count
-    uri = args.uri
+    uri = args.uri[:-1] if len(args.uri) > 0 and args.uri[-1] == "/" else args.uri
     stream = args.stream
     xml_template = args.xml
 
index c9d6e1bae01ef215e7b34616fa3a694e8cdc9983..6500cef1931ce52977a0e2c63565d860d28d41ac 100755 (executable)
@@ -12,16 +12,15 @@ EXABGP in this type of scenario."""
 # and is available at http://www.eclipse.org/legal/epl-v10.html
 
 from copy import deepcopy
-from SimpleXMLRPCServer import SimpleXMLRPCServer
+from xmlrpc.server import SimpleXMLRPCServer
 import argparse
 import binascii
 import ipaddr
 import logging
-import Queue
+import queue
 import select
 import socket
 import struct
-import thread
 import threading
 import time
 
@@ -299,8 +298,8 @@ def get_short_int_from_message(message, offset=16):
     Notes:
         default offset value is the BGP message size offset.
     """
-    high_byte_int = ord(message[offset])
-    low_byte_int = ord(message[offset + 1])
+    high_byte_int = message[offset]
+    low_byte_int = message[offset + 1]
     short_int = high_byte_int * 256 + low_byte_int
     return short_int
 
@@ -316,9 +315,9 @@ def get_prefix_list_from_hex(prefixes_hex):
     prefix_list = []
     offset = 0
     while offset < len(prefixes_hex):
-        prefix_bit_len_hex = prefixes_hex[offset]
+        prefix_bit_len_hex = prefixes_hex[offset : offset + 1]
         prefix_bit_len = int(binascii.b2a_hex(prefix_bit_len_hex), 16)
-        prefix_len = ((prefix_bit_len - 1) / 8) + 1
+        prefix_len = int((prefix_bit_len - 1) / 8) + 1
         prefix_hex = prefixes_hex[offset + 1 : offset + 1 + prefix_len]
         prefix = ".".join(str(i) for i in struct.unpack("BBBB", prefix_hex))
         offset += 1 + prefix_len
@@ -347,7 +346,7 @@ class MessageError(ValueError):
         Notes:
             Use a placeholder string if the message is to be empty.
         """
-        message = binascii.hexlify(self.msg)
+        message = binascii.hexlify(self.msg).decode()
         if message == "":
             message = "(empty message)"
         return self.text + ": " + message
@@ -372,7 +371,7 @@ def read_open_message(bgp_socket):
             "Message length (" + str(len(msg_in)) + ") is smaller than "
             "minimal length of OPEN message with 4-byte AS number (37)"
         )
-        logger.error(error_msg + ": " + binascii.hexlify(msg_in))
+        logger.error(error_msg + ": " + binascii.hexlify(msg_in).decode())
         raise MessageError(error_msg, msg_in)
     # TODO: We could check BGP marker, but it is defined only later;
     # decide what to do.
@@ -385,7 +384,7 @@ def read_open_message(bgp_socket):
             + str(len(msg_in))
             + ")"
         )
-        logger.error(error_msg + binascii.hexlify(msg_in))
+        logger.error(error_msg + binascii.hexlify(msg_in).decode())
         raise MessageError(error_msg, msg_in)
     logger.info("Open message received.")
     return msg_in
@@ -465,11 +464,19 @@ class MessageGenerator(object):
         self.lsteaddr_step = args.lsteaddrstep
         # Default values used for randomized part
         s1_slots = (
-            self.total_prefix_amount - self.remaining_prefixes_threshold - 1
-        ) / self.prefix_count_to_add_default + 1
-        s2_slots = (self.remaining_prefixes_threshold - 1) / (
-            self.prefix_count_to_add_default - self.prefix_count_to_del_default
-        ) + 1
+            int(
+                (self.total_prefix_amount - self.remaining_prefixes_threshold - 1)
+                / self.prefix_count_to_add_default
+            )
+            + 1
+        )
+        s2_slots = (
+            int(
+                (self.remaining_prefixes_threshold - 1)
+                / (self.prefix_count_to_add_default - self.prefix_count_to_del_default)
+            )
+            + 1
+        )
         # S1_First_Index = 0
         # S1_Last_Index = s1_slots * self.prefix_count_to_add_default - 1
         s2_first_index = s1_slots * self.prefix_count_to_add_default
@@ -480,8 +487,12 @@ class MessageGenerator(object):
             - 1
         )
         self.slot_gap_default = (
-            self.total_prefix_amount - self.remaining_prefixes_threshold - 1
-        ) / self.prefix_count_to_add_default + 1
+            int(
+                (self.total_prefix_amount - self.remaining_prefixes_threshold - 1)
+                / self.prefix_count_to_add_default
+            )
+            + 1
+        )
         self.randomize_lowest_default = s2_first_index
         self.randomize_highest_default = s2_last_index
         # Initialising counters
@@ -720,16 +731,15 @@ class MessageGenerator(object):
             :return: dictionary of LS NLRI parameters and values
         """
         # generating list of LS NLRI parameters
-        identifier = self.ls_nlri_default["Identifier"] + index / self.lsid_step
-        ipv4_tunnel_sender_address = (
-            self.ls_nlri_default["IPv4TunnelSenderAddress"] + index / self.lstsaddr_step
-        )
-        tunnel_id = self.ls_nlri_default["TunnelID"] + index / self.lstid_step
-        lsp_id = self.ls_nlri_default["LSPID"] + index / self.lspid_step
-        ipv4_tunnel_endpoint_address = (
-            self.ls_nlri_default["IPv4TunnelEndPointAddress"]
-            + index / self.lsteaddr_step
-        )
+        identifier = self.ls_nlri_default["Identifier"] + int(index / self.lsid_step)
+        ipv4_tunnel_sender_address = self.ls_nlri_default[
+            "IPv4TunnelSenderAddress"
+        ] + int(index / self.lstsaddr_step)
+        tunnel_id = self.ls_nlri_default["TunnelID"] + int(index / self.lstid_step)
+        lsp_id = self.ls_nlri_default["LSPID"] + int(index / self.lspid_step)
+        ipv4_tunnel_endpoint_address = self.ls_nlri_default[
+            "IPv4TunnelEndPointAddress"
+        ] + int(index / self.lsteaddr_step)
         ls_nlri_values = {
             "Identifier": identifier,
             "IPv4TunnelSenderAddress": ipv4_tunnel_sender_address,
@@ -928,7 +938,7 @@ class MessageGenerator(object):
             bgp_identifier = self.bgp_identifier_default
 
         # Marker
-        marker_hex = "\xFF" * 16
+        marker_hex = b"\xFF" * 16
 
         # Type
         type = 1
@@ -952,141 +962,141 @@ class MessageGenerator(object):
         bgp_identifier_hex = struct.pack(">I", bgp_identifier)
 
         # Optional Parameters
-        optional_parameters_hex = ""
+        optional_parameters_hex = b""
         if self.rfc4760 or self.allf:
             optional_parameter_hex = (
-                "\x02"  # Param type ("Capability Ad")
-                "\x06"  # Length (6 bytes)
-                "\x01"  # Capability type (NLRI Unicast),
+                b"\x02"  # Param type ("Capability Ad")
+                b"\x06"  # Length (6 bytes)
+                b"\x01"  # Capability type (NLRI Unicast),
                 # see RFC 4760, secton 8
-                "\x04"  # Capability value length
-                "\x00\x01"  # AFI (Ipv4)
-                "\x00"  # (reserved)
-                "\x01"  # SAFI (Unicast)
+                b"\x04"  # Capability value length
+                b"\x00\x01"  # AFI (Ipv4)
+                b"\x00"  # (reserved)
+                b"\x01"  # SAFI (Unicast)
             )
             optional_parameters_hex += optional_parameter_hex
 
         if self.ipv6 or self.allf:
             optional_parameter_hex = (
-                "\x02"  # Param type ("Capability Ad")
-                "\x06"  # Length (6 bytes)
-                "\x01"  # Multiprotocol extetension capability,
-                "\x04"  # Capability value length
-                "\x00\x02"  # AFI (IPV6)
-                "\x00"  # (reserved)
-                "\x01"  # SAFI (UNICAST)
+                b"\x02"  # Param type ("Capability Ad")
+                b"\x06"  # Length (6 bytes)
+                b"\x01"  # Multiprotocol extetension capability,
+                b"\x04"  # Capability value length
+                b"\x00\x02"  # AFI (IPV6)
+                b"\x00"  # (reserved)
+                b"\x01"  # SAFI (UNICAST)
             )
             optional_parameters_hex += optional_parameter_hex
 
         if self.bgpls or self.allf:
             optional_parameter_hex = (
-                "\x02"  # Param type ("Capability Ad")
-                "\x06"  # Length (6 bytes)
-                "\x01"  # Capability type (NLRI Unicast),
+                b"\x02"  # Param type ("Capability Ad")
+                b"\x06"  # Length (6 bytes)
+                b"\x01"  # Capability type (NLRI Unicast),
                 # see RFC 4760, secton 8
-                "\x04"  # Capability value length
-                "\x40\x04"  # AFI (BGP-LS)
-                "\x00"  # (reserved)
-                "\x47"  # SAFI (BGP-LS)
+                b"\x04"  # Capability value length
+                b"\x40\x04"  # AFI (BGP-LS)
+                b"\x00"  # (reserved)
+                b"\x47"  # SAFI (BGP-LS)
             )
             optional_parameters_hex += optional_parameter_hex
 
         if self.evpn or self.allf:
             optional_parameter_hex = (
-                "\x02"  # Param type ("Capability Ad")
-                "\x06"  # Length (6 bytes)
-                "\x01"  # Multiprotocol extetension capability,
-                "\x04"  # Capability value length
-                "\x00\x19"  # AFI (L2-VPN)
-                "\x00"  # (reserved)
-                "\x46"  # SAFI (EVPN)
+                b"\x02"  # Param type ("Capability Ad")
+                b"\x06"  # Length (6 bytes)
+                b"\x01"  # Multiprotocol extetension capability,
+                b"\x04"  # Capability value length
+                b"\x00\x19"  # AFI (L2-VPN)
+                b"\x00"  # (reserved)
+                b"\x46"  # SAFI (EVPN)
             )
             optional_parameters_hex += optional_parameter_hex
 
         if self.mvpn or self.allf:
             optional_parameter_hex = (
-                "\x02"  # Param type ("Capability Ad")
-                "\x06"  # Length (6 bytes)
-                "\x01"  # Multiprotocol extetension capability,
-                "\x04"  # Capability value length
-                "\x00\x01"  # AFI (IPV4)
-                "\x00"  # (reserved)
-                "\x05"  # SAFI (MCAST-VPN)
+                b"\x02"  # Param type ("Capability Ad")
+                b"\x06"  # Length (6 bytes)
+                b"\x01"  # Multiprotocol extetension capability,
+                b"\x04"  # Capability value length
+                b"\x00\x01"  # AFI (IPV4)
+                b"\x00"  # (reserved)
+                b"\x05"  # SAFI (MCAST-VPN)
             )
             optional_parameters_hex += optional_parameter_hex
             optional_parameter_hex = (
-                "\x02"  # Param type ("Capability Ad")
-                "\x06"  # Length (6 bytes)
-                "\x01"  # Multiprotocol extetension capability,
-                "\x04"  # Capability value length
-                "\x00\x02"  # AFI (IPV6)
-                "\x00"  # (reserved)
-                "\x05"  # SAFI (MCAST-VPN)
+                b"\x02"  # Param type ("Capability Ad")
+                b"\x06"  # Length (6 bytes)
+                b"\x01"  # Multiprotocol extetension capability,
+                b"\x04"  # Capability value length
+                b"\x00\x02"  # AFI (IPV6)
+                b"\x00"  # (reserved)
+                b"\x05"  # SAFI (MCAST-VPN)
             )
             optional_parameters_hex += optional_parameter_hex
 
         if self.l3vpn_mcast or self.allf:
             optional_parameter_hex = (
-                "\x02"  # Param type ("Capability Ad")
-                "\x06"  # Length (6 bytes)
-                "\x01"  # Multiprotocol extetension capability,
-                "\x04"  # Capability value length
-                "\x00\x01"  # AFI (IPV4)
-                "\x00"  # (reserved)
-                "\x81"  # SAFI (L3VPN-MCAST)
+                b"\x02"  # Param type ("Capability Ad")
+                b"\x06"  # Length (6 bytes)
+                b"\x01"  # Multiprotocol extetension capability,
+                b"\x04"  # Capability value length
+                b"\x00\x01"  # AFI (IPV4)
+                b"\x00"  # (reserved)
+                b"\x81"  # SAFI (L3VPN-MCAST)
             )
             optional_parameters_hex += optional_parameter_hex
             optional_parameter_hex = (
-                "\x02"  # Param type ("Capability Ad")
-                "\x06"  # Length (6 bytes)
-                "\x01"  # Multiprotocol extetension capability,
-                "\x04"  # Capability value length
-                "\x00\x02"  # AFI (IPV6)
-                "\x00"  # (reserved)
-                "\x81"  # SAFI (L3VPN-MCAST)
+                b"\x02"  # Param type ("Capability Ad")
+                b"\x06"  # Length (6 bytes)
+                b"\x01"  # Multiprotocol extetension capability,
+                b"\x04"  # Capability value length
+                b"\x00\x02"  # AFI (IPV6)
+                b"\x00"  # (reserved)
+                b"\x81"  # SAFI (L3VPN-MCAST)
             )
             optional_parameters_hex += optional_parameter_hex
 
         if self.l3vpn or self.allf:
             optional_parameter_hex = (
-                "\x02"  # Param type ("Capability Ad")
-                "\x06"  # Length (6 bytes)
-                "\x01"  # Multiprotocol extetension capability,
-                "\x04"  # Capability value length
-                "\x00\x01"  # AFI (IPV4)
-                "\x00"  # (reserved)
-                "\x80"  # SAFI (L3VPN-UNICAST)
+                b"\x02"  # Param type ("Capability Ad")
+                b"\x06"  # Length (6 bytes)
+                b"\x01"  # Multiprotocol extetension capability,
+                b"\x04"  # Capability value length
+                b"\x00\x01"  # AFI (IPV4)
+                b"\x00"  # (reserved)
+                b"\x80"  # SAFI (L3VPN-UNICAST)
             )
             optional_parameters_hex += optional_parameter_hex
             optional_parameter_hex = (
-                "\x02"  # Param type ("Capability Ad")
-                "\x06"  # Length (6 bytes)
-                "\x01"  # Multiprotocol extetension capability,
-                "\x04"  # Capability value length
-                "\x00\x02"  # AFI (IPV6)
-                "\x00"  # (reserved)
-                "\x80"  # SAFI (L3VPN-UNICAST)
+                b"\x02"  # Param type ("Capability Ad")
+                b"\x06"  # Length (6 bytes)
+                b"\x01"  # Multiprotocol extetension capability,
+                b"\x04"  # Capability value length
+                b"\x00\x02"  # AFI (IPV6)
+                b"\x00"  # (reserved)
+                b"\x80"  # SAFI (L3VPN-UNICAST)
             )
             optional_parameters_hex += optional_parameter_hex
 
         if self.rt_constrain or self.allf:
             optional_parameter_hex = (
-                "\x02"  # Param type ("Capability Ad")
-                "\x06"  # Length (6 bytes)
-                "\x01"  # Multiprotocol extetension capability,
-                "\x04"  # Capability value length
-                "\x00\x01"  # AFI (IPV4)
-                "\x00"  # (reserved)
-                "\x84"  # SAFI (ROUTE-TARGET-CONSTRAIN)
+                b"\x02"  # Param type ("Capability Ad")
+                b"\x06"  # Length (6 bytes)
+                b"\x01"  # Multiprotocol extetension capability,
+                b"\x04"  # Capability value length
+                b"\x00\x01"  # AFI (IPV4)
+                b"\x00"  # (reserved)
+                b"\x84"  # SAFI (ROUTE-TARGET-CONSTRAIN)
             )
             optional_parameters_hex += optional_parameter_hex
 
         optional_parameter_hex = (
-            "\x02"  # Param type ("Capability Ad")
-            "\x06"  # Length (6 bytes)
-            "\x41"  # "32 bit AS Numbers Support"
+            b"\x02"  # Param type ("Capability Ad")
+            b"\x06"  # Length (6 bytes)
+            b"\x41"  # "32 bit AS Numbers Support"
             # (see RFC 6793, section 3)
-            "\x04"  # Capability value length
+            b"\x04"  # Capability value length
         )
         optional_parameter_hex += struct.pack(
             ">I", my_autonomous_system
@@ -1096,20 +1106,20 @@ class MessageGenerator(object):
         if self.grace != 8:
             b = list(bin(self.grace)[2:])
             b = b + [0] * (3 - len(b))
-            length = "\x08"
+            length = b"\x08"
             if b[1] == "1":
-                restart_flag = "\x80\x05"
+                restart_flag = b"\x80\x05"
             else:
-                restart_flag = "\x00\x05"
+                restart_flag = b"\x00\x05"
             if b[2] == "1":
-                ipv4_flag = "\x80"
+                ipv4_flag = b"\x80"
             else:
-                ipv4_flag = "\x00"
+                ipv4_flag = b"\x00"
             if b[0] == "1":
-                ll_gr = "\x47\x07\x00\x01\x01\x00\x00\x00\x1e"
-                length = "\x11"
+                ll_gr = b"\x47\x07\x00\x01\x01\x00\x00\x00\x1e"
+                length = b"\x11"
             else:
-                ll_gr = ""
+                ll_gr = b""
             logger.debug("Grace parameters list: {}".format(b))
             # "\x02" Param type ("Capability Ad")
             # :param length: Length of whole message
@@ -1122,8 +1132,8 @@ class MessageGenerator(object):
             # "\x00"  Ipv4 Flag (customizable - turned on when grace == 1,3,5,7)
             # "\x47\x07\x00\x01\x01\x00\x00\x00\x1e" ipv4 ll-graceful-restart capability, timer 30sec
             # ll-gr turned on when grace is between 4-7
-            optional_parameter_hex = "\x02{}\x40\x06{}\x00\x01\x01{}{}".format(
-                length, restart_flag, ipv4_flag, ll_gr
+            optional_parameter_hex = (
+                f"\x02{length}\x40\x06{restart_flag}\x00\x01\x01{ipv4_flag}{ll_gr}"
             )
             optional_parameters_hex += optional_parameter_hex
 
@@ -1160,50 +1170,59 @@ class MessageGenerator(object):
 
         if self.log_debug:
             logger.debug("OPEN message encoding")
-            logger.debug("  Marker=0x" + binascii.hexlify(marker_hex))
+            logger.debug("  Marker=0x" + binascii.hexlify(marker_hex).decode())
             logger.debug(
-                "  Length=" + str(length) + " (0x" + binascii.hexlify(length_hex) + ")"
+                "  Length="
+                + str(length)
+                + " (0x"
+                + binascii.hexlify(length_hex).decode()
+                + ")"
             )
             logger.debug(
-                "  Type=" + str(type) + " (0x" + binascii.hexlify(type_hex) + ")"
+                "  Type="
+                + str(type)
+                + " (0x"
+                + binascii.hexlify(type_hex).decode()
+                + ")"
             )
             logger.debug(
                 "  Version="
                 + str(version)
                 + " (0x"
-                + binascii.hexlify(version_hex)
+                + binascii.hexlify(version_hex).decode()
                 + ")"
             )
             logger.debug(
                 "  My Autonomous System="
                 + str(my_autonomous_system_2_bytes)
                 + " (0x"
-                + binascii.hexlify(my_autonomous_system_hex_2_bytes)
+                + binascii.hexlify(my_autonomous_system_hex_2_bytes).decode()
                 + ")"
             )
             logger.debug(
                 "  Hold Time="
                 + str(hold_time)
                 + " (0x"
-                + binascii.hexlify(hold_time_hex)
+                + binascii.hexlify(hold_time_hex).decode()
                 + ")"
             )
             logger.debug(
                 "  BGP Identifier="
                 + str(bgp_identifier)
                 + " (0x"
-                + binascii.hexlify(bgp_identifier_hex)
+                + binascii.hexlify(bgp_identifier_hex).decode()
                 + ")"
             )
             logger.debug(
                 "  Optional Parameters Length="
                 + str(optional_parameters_length)
                 + " (0x"
-                + binascii.hexlify(optional_parameters_length_hex)
+                + binascii.hexlify(optional_parameters_length_hex).decode()
                 + ")"
             )
             logger.debug(
-                "  Optional Parameters=0x" + binascii.hexlify(optional_parameters_hex)
+                "  Optional Parameters=0x"
+                + binascii.hexlify(optional_parameters_hex).decode()
             )
             logger.debug("OPEN message encoded: 0x%s", binascii.b2a_hex(message_hex))
 
@@ -1220,7 +1239,7 @@ class MessageGenerator(object):
         originator_id=None,
         cluster_list_item=None,
         end_of_rib=False,
-        **ls_nlri_params
+        **ls_nlri_params,
     ):
         """Generates an UPDATE Message (rfc4271#section-4.3)
 
@@ -1257,16 +1276,16 @@ class MessageGenerator(object):
         ls_nlri.update(ls_nlri_params)
 
         # Marker
-        marker_hex = "\xFF" * 16
+        marker_hex = b"\xFF" * 16
 
         # Type
         type = 2
         type_hex = struct.pack("B", type)
 
         # Withdrawn Routes
-        withdrawn_routes_hex = ""
+        withdrawn_routes_hex = b""
         if not self.bgpls:
-            bytes = ((wr_prefix_length - 1) / 8) + 1
+            bytes = int((wr_prefix_length - 1) / 8) + 1
             for prefix in wr_prefixes:
                 withdrawn_route_hex = (
                     struct.pack("B", wr_prefix_length)
@@ -1280,67 +1299,67 @@ class MessageGenerator(object):
 
         # TODO: to replace hardcoded string by encoding?
         # Path Attributes
-        path_attributes_hex = ""
+        path_attributes_hex = b""
         if not self.skipattr:
             path_attributes_hex += (
-                "\x40"  # Flags ("Well-Known")
-                "\x01"  # Type (ORIGIN)
-                "\x01"  # Length (1)
-                "\x00"  # Origin: IGP
+                b"\x40"  # Flags ("Well-Known")
+                b"\x01"  # Type (ORIGIN)
+                b"\x01"  # Length (1)
+                b"\x00"  # Origin: IGP
             )
             path_attributes_hex += (
-                "\x40"  # Flags ("Well-Known")
-                "\x02"  # Type (AS_PATH)
-                "\x06"  # Length (6)
-                "\x02"  # AS segment type (AS_SEQUENCE)
-                "\x01"  # AS segment length (1)
+                b"\x40"  # Flags ("Well-Known")
+                b"\x02"  # Type (AS_PATH)
+                b"\x06"  # Length (6)
+                b"\x02"  # AS segment type (AS_SEQUENCE)
+                b"\x01"  # AS segment length (1)
             )
             my_as_hex = struct.pack(">I", my_autonomous_system)
             path_attributes_hex += my_as_hex  # AS segment (4 bytes)
             path_attributes_hex += (
-                "\x40"  # Flags ("Well-Known")
-                "\x05"  # Type (LOCAL_PREF)
-                "\x04"  # Length (4)
-                "\x00\x00\x00\x64"  # (100)
+                b"\x40"  # Flags ("Well-Known")
+                b"\x05"  # Type (LOCAL_PREF)
+                b"\x04"  # Length (4)
+                b"\x00\x00\x00\x64"  # (100)
             )
         if nlri_prefixes != []:
             path_attributes_hex += (
-                "\x40"  # Flags ("Well-Known")
-                "\x03"  # Type (NEXT_HOP)
-                "\x04"  # Length (4)
+                b"\x40"  # Flags ("Well-Known")
+                b"\x03"  # Type (NEXT_HOP)
+                b"\x04"  # Length (4)
             )
             next_hop_hex = struct.pack(">I", int(next_hop))
             path_attributes_hex += next_hop_hex  # IP address of the next hop (4 bytes)
             if originator_id is not None:
                 path_attributes_hex += (
-                    "\x80"  # Flags ("Optional, non-transitive")
-                    "\x09"  # Type (ORIGINATOR_ID)
-                    "\x04"  # Length (4)
+                    b"\x80"  # Flags ("Optional, non-transitive")
+                    b"\x09"  # Type (ORIGINATOR_ID)
+                    b"\x04"  # Length (4)
                 )  # ORIGINATOR_ID (4 bytes)
                 path_attributes_hex += struct.pack(">I", int(originator_id))
             if cluster_list_item is not None:
                 path_attributes_hex += (
-                    "\x80"  # Flags ("Optional, non-transitive")
-                    "\x0a"  # Type (CLUSTER_LIST)
-                    "\x04"  # Length (4)
+                    b"\x80"  # Flags ("Optional, non-transitive")
+                    b"\x0a"  # Type (CLUSTER_LIST)
+                    b"\x04"  # Length (4)
                 )  # one CLUSTER_LIST item (4 bytes)
                 path_attributes_hex += struct.pack(">I", int(cluster_list_item))
 
         if self.bgpls and not end_of_rib:
             path_attributes_hex += (
-                "\x80"  # Flags ("Optional, non-transitive")
-                "\x0e"  # Type (MP_REACH_NLRI)
-                "\x22"  # Length (34)
-                "\x40\x04"  # AFI (BGP-LS)
-                "\x47"  # SAFI (BGP-LS)
-                "\x04"  # Next Hop Length (4)
+                b"\x80"  # Flags ("Optional, non-transitive")
+                b"\x0e"  # Type (MP_REACH_NLRI)
+                b"\x22"  # Length (34)
+                b"\x40\x04"  # AFI (BGP-LS)
+                b"\x47"  # SAFI (BGP-LS)
+                b"\x04"  # Next Hop Length (4)
             )
             path_attributes_hex += struct.pack(">I", int(next_hop))
-            path_attributes_hex += "\x00"  # Reserved
+            path_attributes_hex += b"\x00"  # Reserved
             path_attributes_hex += (
-                "\x00\x05"  # LS-NLRI.NLRIType (IPv4 TE LSP NLRI)
-                "\x00\x15"  # LS-NLRI.TotalNLRILength (21)
-                "\x07"  # LS-NLRI.Variable.ProtocolID (RSVP-TE)
+                b"\x00\x05"  # LS-NLRI.NLRIType (IPv4 TE LSP NLRI)
+                b"\x00\x15"  # LS-NLRI.TotalNLRILength (21)
+                b"\x07"  # LS-NLRI.Variable.ProtocolID (RSVP-TE)
             )
             path_attributes_hex += struct.pack(">Q", int(ls_nlri["Identifier"]))
             path_attributes_hex += struct.pack(
@@ -1359,9 +1378,9 @@ class MessageGenerator(object):
         )
 
         # Network Layer Reachability Information
-        nlri_hex = ""
+        nlri_hex = b""
         if not self.bgpls:
-            bytes = ((nlri_prefix_length - 1) / 8) + 1
+            bytes = int((nlri_prefix_length - 1) / 8) + 1
             for prefix in nlri_prefixes:
                 nlri_prefix_hex = (
                     struct.pack("B", nlri_prefix_length)
@@ -1399,18 +1418,26 @@ class MessageGenerator(object):
 
         if self.log_debug:
             logger.debug("UPDATE message encoding")
-            logger.debug("  Marker=0x" + binascii.hexlify(marker_hex))
+            logger.debug("  Marker=0x" + binascii.hexlify(marker_hex).decode())
             logger.debug(
-                "  Length=" + str(length) + " (0x" + binascii.hexlify(length_hex) + ")"
+                "  Length="
+                + str(length)
+                + " (0x"
+                + binascii.hexlify(length_hex).decode()
+                + ")"
             )
             logger.debug(
-                "  Type=" + str(type) + " (0x" + binascii.hexlify(type_hex) + ")"
+                "  Type="
+                + str(type)
+                + " (0x"
+                + binascii.hexlify(type_hex).decode()
+                + ")"
             )
             logger.debug(
                 "  withdrawn_routes_length="
                 + str(withdrawn_routes_length)
                 + " (0x"
-                + binascii.hexlify(withdrawn_routes_length_hex)
+                + binascii.hexlify(withdrawn_routes_length_hex).decode()
                 + ")"
             )
             logger.debug(
@@ -1419,7 +1446,7 @@ class MessageGenerator(object):
                 + "/"
                 + str(wr_prefix_length)
                 + " (0x"
-                + binascii.hexlify(withdrawn_routes_hex)
+                + binascii.hexlify(withdrawn_routes_hex).decode()
                 + ")"
             )
             if total_path_attributes_length:
@@ -1427,13 +1454,13 @@ class MessageGenerator(object):
                     "  Total Path Attributes Length="
                     + str(total_path_attributes_length)
                     + " (0x"
-                    + binascii.hexlify(total_path_attributes_length_hex)
+                    + binascii.hexlify(total_path_attributes_length_hex).decode()
                     + ")"
                 )
                 logger.debug(
                     "  Path Attributes="
                     + "(0x"
-                    + binascii.hexlify(path_attributes_hex)
+                    + binascii.hexlify(path_attributes_hex).decode()
                     + ")"
                 )
                 logger.debug("    Origin=IGP")
@@ -1451,17 +1478,19 @@ class MessageGenerator(object):
                 + "/"
                 + str(nlri_prefix_length)
                 + " (0x"
-                + binascii.hexlify(nlri_hex)
+                + binascii.hexlify(nlri_hex).decode()
                 + ")"
             )
-            logger.debug("UPDATE message encoded: 0x" + binascii.b2a_hex(message_hex))
+            logger.debug(
+                "UPDATE message encoded: 0x" + binascii.b2a_hex(message_hex).decode()
+            )
 
         # updating counter
         self.updates_sent += 1
         # returning encoded message
         return message_hex
 
-    def notification_message(self, error_code, error_subcode, data_hex=""):
+    def notification_message(self, error_code, error_subcode, data_hex=b""):
         """Generates a NOTIFICATION Message (rfc4271#section-4.5)
 
         Arguments:
@@ -1473,7 +1502,7 @@ class MessageGenerator(object):
         """
 
         # Marker
-        marker_hex = "\xFF" * 16
+        marker_hex = b"\xFF" * 16
 
         # Type
         type = 3
@@ -1508,28 +1537,36 @@ class MessageGenerator(object):
 
         if self.log_debug:
             logger.debug("NOTIFICATION message encoding")
-            logger.debug("  Marker=0x" + binascii.hexlify(marker_hex))
+            logger.debug("  Marker=0x" + binascii.hexlify(marker_hex).decode())
             logger.debug(
-                "  Length=" + str(length) + " (0x" + binascii.hexlify(length_hex) + ")"
+                "  Length="
+                + str(length)
+                + " (0x"
+                + binascii.hexlify(length_hex).decode()
+                + ")"
             )
             logger.debug(
-                "  Type=" + str(type) + " (0x" + binascii.hexlify(type_hex) + ")"
+                "  Type="
+                + str(type)
+                + " (0x"
+                + binascii.hexlify(type_hex).decode()
+                + ")"
             )
             logger.debug(
                 "  Error Code="
                 + str(error_code)
                 + " (0x"
-                + binascii.hexlify(error_code_hex)
+                + binascii.hexlify(error_code_hex).decode()
                 + ")"
             )
             logger.debug(
                 "  Error Subode="
                 + str(error_subcode)
                 + " (0x"
-                + binascii.hexlify(error_subcode_hex)
+                + binascii.hexlify(error_subcode_hex).decode()
                 + ")"
             )
-            logger.debug("  Data=" + " (0x" + binascii.hexlify(data_hex) + ")")
+            logger.debug("  Data=" + " (0x" + binascii.hexlify(data_hex).decode() + ")")
             logger.debug(
                 "NOTIFICATION message encoded: 0x%s", binascii.b2a_hex(message_hex)
             )
@@ -1544,7 +1581,7 @@ class MessageGenerator(object):
         """
 
         # Marker
-        marker_hex = "\xFF" * 16
+        marker_hex = b"\xFF" * 16
 
         # Type
         type = 4
@@ -1559,15 +1596,24 @@ class MessageGenerator(object):
 
         if self.log_debug:
             logger.debug("KEEP ALIVE message encoding")
-            logger.debug("  Marker=0x" + binascii.hexlify(marker_hex))
+            logger.debug("  Marker=0x" + binascii.hexlify(marker_hex).decode())
             logger.debug(
-                "  Length=" + str(length) + " (0x" + binascii.hexlify(length_hex) + ")"
+                "  Length="
+                + str(length)
+                + " (0x"
+                + binascii.hexlify(length_hex).decode()
+                + ")"
             )
             logger.debug(
-                "  Type=" + str(type) + " (0x" + binascii.hexlify(type_hex) + ")"
+                "  Type="
+                + str(type)
+                + " (0x"
+                + binascii.hexlify(type_hex).decode()
+                + ")"
             )
             logger.debug(
-                "KEEP ALIVE message encoded: 0x%s", binascii.b2a_hex(message_hex)
+                "KEEP ALIVE message encoded: 0x%s",
+                binascii.b2a_hex(message_hex).decode(),
             )
 
         return message_hex
@@ -1704,7 +1750,7 @@ class ReadTracker(object):
         # Countdown towards next size computation.
         self.bytes_to_read = self.header_length
         # Incremental buffer for message under read.
-        self.msg_in = ""
+        self.msg_in = b""
         # Initialising counters
         self.updates_received = 0
         self.prefixes_introduced = 0
@@ -1751,32 +1797,36 @@ class ReadTracker(object):
                 # TODO: Should we do validation and exit on anything
                 # besides update or keepalive?
                 # Prepare state for reading another message.
-                message_type_hex = self.msg_in[self.header_length]
-                if message_type_hex == "\x01":
+                message_type_hex = self.msg_in[
+                    self.header_length : self.header_length + 1
+                ]
+                if message_type_hex == b"\x01":
                     logger.info(
-                        "OPEN message received: 0x%s", binascii.b2a_hex(self.msg_in)
+                        "OPEN message received: 0x%s",
+                        binascii.b2a_hex(self.msg_in).decode(),
                     )
-                elif message_type_hex == "\x02":
+                elif message_type_hex == b"\x02":
                     logger.debug(
-                        "UPDATE message received: 0x%s", binascii.b2a_hex(self.msg_in)
+                        "UPDATE message received: 0x%s",
+                        binascii.b2a_hex(self.msg_in).decode(),
                     )
                     self.decode_update_message(self.msg_in)
-                elif message_type_hex == "\x03":
+                elif message_type_hex == b"\x03":
                     logger.info(
                         "NOTIFICATION message received: 0x%s",
-                        binascii.b2a_hex(self.msg_in),
+                        binascii.b2a_hex(self.msg_in).decode(),
                     )
-                elif message_type_hex == "\x04":
+                elif message_type_hex == b"\x04":
                     logger.info(
                         "KEEP ALIVE message received: 0x%s",
-                        binascii.b2a_hex(self.msg_in),
+                        binascii.b2a_hex(self.msg_in).decode(),
                     )
                 else:
                     logger.warning(
                         "Unexpected message received: 0x%s",
-                        binascii.b2a_hex(self.msg_in),
+                        binascii.b2a_hex(self.msg_in).decode(),
                     )
-                self.msg_in = ""
+                self.msg_in = b""
                 self.reading_header = True
                 self.bytes_to_read = self.header_length
         # We should not act upon peer_hold_time if we are reading
@@ -1794,14 +1844,14 @@ class ReadTracker(object):
         hex_to_decode = path_attributes_hex
 
         while len(hex_to_decode):
-            attr_flags_hex = hex_to_decode[0]
+            attr_flags_hex = hex_to_decode[0:1]
             attr_flags = int(binascii.b2a_hex(attr_flags_hex), 16)
             #            attr_optional_bit = attr_flags & 128
             #            attr_transitive_bit = attr_flags & 64
             #            attr_partial_bit = attr_flags & 32
             attr_extended_length_bit = attr_flags & 16
 
-            attr_type_code_hex = hex_to_decode[1]
+            attr_type_code_hex = hex_to_decode[1:2]
             attr_type_code = int(binascii.b2a_hex(attr_type_code_hex), 16)
 
             if attr_extended_length_bit:
@@ -1810,7 +1860,7 @@ class ReadTracker(object):
                 attr_value_hex = hex_to_decode[4 : 4 + attr_length]
                 hex_to_decode = hex_to_decode[4 + attr_length :]
             else:
-                attr_length_hex = hex_to_decode[2]
+                attr_length_hex = hex_to_decode[2:3]
                 attr_length = int(binascii.b2a_hex(attr_length_hex), 16)
                 attr_value_hex = hex_to_decode[3 : 3 + attr_length]
                 hex_to_decode = hex_to_decode[3 + attr_length :]
@@ -1880,12 +1930,12 @@ class ReadTracker(object):
                     "  Address Family Identifier=0x%s",
                     binascii.b2a_hex(address_family_identifier_hex),
                 )
-                subsequent_address_family_identifier_hex = attr_value_hex[2]
+                subsequent_address_family_identifier_hex = attr_value_hex[2:3]
                 logger.debug(
                     "  Subsequent Address Family Identifier=0x%s",
                     binascii.b2a_hex(subsequent_address_family_identifier_hex),
                 )
-                next_hop_netaddr_len_hex = attr_value_hex[3]
+                next_hop_netaddr_len_hex = attr_value_hex[3:4]
                 next_hop_netaddr_len = int(
                     binascii.b2a_hex(next_hop_netaddr_len_hex), 16
                 )
@@ -1903,7 +1953,8 @@ class ReadTracker(object):
                     next_hop_netaddr,
                     binascii.b2a_hex(next_hop_netaddr_hex),
                 )
-                reserved_hex = attr_value_hex[4 + next_hop_netaddr_len]
+                reserved_byte_pos = 4 + next_hop_netaddr_len
+                reserved_hex = attr_value_hex[reserved_byte_pos : reserved_byte_pos + 1]
                 logger.debug("  Reserved=0x%s", binascii.b2a_hex(reserved_hex))
                 nlri_hex = attr_value_hex[4 + next_hop_netaddr_len + 1 :]
                 logger.debug(
@@ -1926,7 +1977,7 @@ class ReadTracker(object):
                     "  Address Family Identifier=0x%s",
                     binascii.b2a_hex(address_family_identifier_hex),
                 )
-                subsequent_address_family_identifier_hex = attr_value_hex[2]
+                subsequent_address_family_identifier_hex = attr_value_hex[2:3]
                 logger.debug(
                     "  Subsequent Address Family Identifier=0x%s",
                     binascii.b2a_hex(subsequent_address_family_identifier_hex),
@@ -1973,7 +2024,7 @@ class ReadTracker(object):
 
         with self.storage as stor:
             # this will replace the previously stored message
-            stor["update"] = binascii.hexlify(msg)
+            stor["update"] = binascii.hexlify(msg).decode()
 
         logger.debug("Evpn {}".format(self.evpn))
         if self.evpn:
@@ -2140,7 +2191,7 @@ class WriteTracker(object):
         # TODO: Would attribute docstrings add anything substantial?
         self.sending_message = False
         self.bytes_to_send = 0
-        self.msg_out = ""
+        self.msg_out = b""
 
     def enqueue_message_for_sending(self, message):
         """Enqueue message and change state.
@@ -2245,7 +2296,7 @@ class StateTracker(object):
             logger.info("Received message: {}".format(msg))
             msgbin = binascii.unhexlify(msg)
             self.writer.enqueue_message_for_sending(msgbin)
-        except Queue.Empty:
+        except queue.Empty:
             pass
         # Now we know what our priorities are, we have to check
         # which actions are available.
@@ -2358,12 +2409,12 @@ def job(arguments, inqueue, storage):
     # FIXME: Add parameter to send default open message first,
     # to work with "you first" peers.
     msg_in = read_open_message(bgp_socket)
-    logger.info(binascii.hexlify(msg_in))
-    storage["open"] = binascii.hexlify(msg_in)
+    logger.info(binascii.hexlify(msg_in).decode())
+    storage["open"] = binascii.hexlify(msg_in).decode()
     timer = TimeTracker(msg_in)
     generator = MessageGenerator(arguments)
     msg_out = generator.open_message()
-    logger.debug("Sending the OPEN message: " + binascii.hexlify(msg_out))
+    logger.debug("Sending the OPEN message: " + binascii.hexlify(msg_out).decode())
     # Send our open message to the peer.
     bgp_socket.send(msg_out)
     # Wait for confirming keepalive.
@@ -2372,13 +2423,13 @@ def job(arguments, inqueue, storage):
     msg_in = bgp_socket.recv(19)
     if msg_in != generator.keepalive_message():
         error_msg = "Open not confirmed by keepalive, instead got"
-        logger.error(error_msg + ": " + binascii.hexlify(msg_in))
+        logger.error(error_msg + ": " + binascii.hexlify(msg_in).decode())
         raise MessageError(error_msg, msg_in)
     timer.reset_peer_hold_time()
     # Send the keepalive to indicate the connection is accepted.
     timer.snapshot()  # Remember this time.
     msg_out = generator.keepalive_message()
-    logger.debug("Sending a KEEP ALIVE message: " + binascii.hexlify(msg_out))
+    logger.debug("Sending a KEEP ALIVE message: " + binascii.hexlify(msg_out).decode())
     bgp_socket.send(msg_out)
     # Use the remembered time.
     timer.reset_my_keepalive_time(timer.snapshot_time)
@@ -2448,11 +2499,11 @@ def threaded_job(arguments):
     myip_current = arguments.myip
     port = arguments.port
     thread_args = []
-    rpcqueue = Queue.Queue()
+    rpcqueue = queue.Queue()
     storage = SafeDict()
 
     while 1:
-        amount_per_util = (amount_left - 1) / utils_left + 1  # round up
+        amount_per_util = int((amount_left - 1) / utils_left) + 1  # round up
         amount_left -= amount_per_util
         utils_left -= 1
 
@@ -2470,7 +2521,9 @@ def threaded_job(arguments):
     try:
         # Create threads
         for t in thread_args:
-            thread.start_new_thread(job, (t, rpcqueue, storage))
+            threading.Thread(
+                target=job, args=(t, rpcqueue, storage), daemon=True
+            ).start()
     except Exception:
         print("Error: unable to start thread.")
         raise SystemExit(2)